mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 04:58:05 +02:00
glsl: protect glsl_type with a mutex
glsl_type has several static hash tables and a static ralloc context. They need to be protected by a mutex as they are not thread-safe. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=69200 Signed-off-by: Chia-I Wu <olv@lunarg.com> Reviewed-by: Brian Paul <brianp@vmware.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
a6706163cb
commit
2d64e4ffba
2 changed files with 62 additions and 10 deletions
|
|
@ -29,6 +29,7 @@ extern "C" {
|
|||
#include "program/hash_table.h"
|
||||
}
|
||||
|
||||
mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP;
|
||||
hash_table *glsl_type::array_types = NULL;
|
||||
hash_table *glsl_type::record_types = NULL;
|
||||
hash_table *glsl_type::interface_types = NULL;
|
||||
|
|
@ -53,9 +54,14 @@ glsl_type::glsl_type(GLenum gl_type,
|
|||
vector_elements(vector_elements), matrix_columns(matrix_columns),
|
||||
length(0)
|
||||
{
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
init_ralloc_type_ctx();
|
||||
assert(name != NULL);
|
||||
this->name = ralloc_strdup(this->mem_ctx, name);
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
|
||||
/* Neither dimension is zero or both dimensions are zero.
|
||||
*/
|
||||
assert((vector_elements == 0) == (matrix_columns == 0));
|
||||
|
|
@ -71,9 +77,14 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type,
|
|||
sampler_array(array), sampler_type(type), interface_packing(0),
|
||||
length(0)
|
||||
{
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
init_ralloc_type_ctx();
|
||||
assert(name != NULL);
|
||||
this->name = ralloc_strdup(this->mem_ctx, name);
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
|
||||
memset(& fields, 0, sizeof(fields));
|
||||
|
||||
if (base_type == GLSL_TYPE_SAMPLER) {
|
||||
|
|
@ -95,11 +106,14 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
init_ralloc_type_ctx();
|
||||
assert(name != NULL);
|
||||
this->name = ralloc_strdup(this->mem_ctx, name);
|
||||
this->fields.structure = ralloc_array(this->mem_ctx,
|
||||
glsl_struct_field, length);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
this->fields.structure[i].type = fields[i].type;
|
||||
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
|
||||
|
|
@ -110,6 +124,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||
this->fields.structure[i].sample = fields[i].sample;
|
||||
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
|
||||
}
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
}
|
||||
|
||||
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
||||
|
|
@ -123,6 +139,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
init_ralloc_type_ctx();
|
||||
assert(name != NULL);
|
||||
this->name = ralloc_strdup(this->mem_ctx, name);
|
||||
|
|
@ -138,6 +156,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
|
|||
this->fields.structure[i].sample = fields[i].sample;
|
||||
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
|
||||
}
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -285,6 +305,8 @@ const glsl_type *glsl_type::get_scalar_type() const
|
|||
void
|
||||
_mesa_glsl_release_types(void)
|
||||
{
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
if (glsl_type::array_types != NULL) {
|
||||
hash_table_dtor(glsl_type::array_types);
|
||||
glsl_type::array_types = NULL;
|
||||
|
|
@ -294,6 +316,8 @@ _mesa_glsl_release_types(void)
|
|||
hash_table_dtor(glsl_type::record_types);
|
||||
glsl_type::record_types = NULL;
|
||||
}
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -316,7 +340,10 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) :
|
|||
* NUL.
|
||||
*/
|
||||
const unsigned name_length = strlen(array->name) + 10 + 3;
|
||||
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
|
||||
if (length == 0)
|
||||
snprintf(n, name_length, "%s[]", array->name);
|
||||
|
|
@ -452,12 +479,6 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
|
|||
const glsl_type *
|
||||
glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
|
||||
{
|
||||
|
||||
if (array_types == NULL) {
|
||||
array_types = hash_table_ctor(64, hash_table_string_hash,
|
||||
hash_table_string_compare);
|
||||
}
|
||||
|
||||
/* Generate a name using the base type pointer in the key. This is
|
||||
* done because the name of the base type may not be unique across
|
||||
* shaders. For example, two shaders may have different record types
|
||||
|
|
@ -466,9 +487,19 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
|
|||
char key[128];
|
||||
snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
|
||||
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
if (array_types == NULL) {
|
||||
array_types = hash_table_ctor(64, hash_table_string_hash,
|
||||
hash_table_string_compare);
|
||||
}
|
||||
|
||||
const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
|
||||
|
||||
if (t == NULL) {
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
t = new glsl_type(base, array_size);
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
hash_table_insert(array_types, (void *) t, ralloc_strdup(mem_ctx, key));
|
||||
}
|
||||
|
|
@ -477,6 +508,8 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
|
|||
assert(t->length == array_size);
|
||||
assert(t->fields.array == base);
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
@ -575,13 +608,17 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
|
|||
{
|
||||
const glsl_type key(fields, num_fields, name);
|
||||
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
if (record_types == NULL) {
|
||||
record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
|
||||
}
|
||||
|
||||
const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
|
||||
if (t == NULL) {
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
t = new glsl_type(fields, num_fields, name);
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
hash_table_insert(record_types, (void *) t, t);
|
||||
}
|
||||
|
|
@ -590,6 +627,8 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
|
|||
assert(t->length == num_fields);
|
||||
assert(strcmp(t->name, name) == 0);
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
@ -602,13 +641,17 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
|
|||
{
|
||||
const glsl_type key(fields, num_fields, packing, block_name);
|
||||
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
if (interface_types == NULL) {
|
||||
interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
|
||||
}
|
||||
|
||||
const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
|
||||
if (t == NULL) {
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
t = new glsl_type(fields, num_fields, packing, block_name);
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
hash_table_insert(interface_types, (void *) t, t);
|
||||
}
|
||||
|
|
@ -617,6 +660,8 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
|
|||
assert(t->length == num_fields);
|
||||
assert(strcmp(t->name, block_name) == 0);
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,16 +122,18 @@ struct glsl_type {
|
|||
* easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
|
||||
static void* operator new(size_t size)
|
||||
{
|
||||
if (glsl_type::mem_ctx == NULL) {
|
||||
glsl_type::mem_ctx = ralloc_context(NULL);
|
||||
assert(glsl_type::mem_ctx != NULL);
|
||||
}
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
|
||||
/* mem_ctx should have been created by the static members */
|
||||
assert(glsl_type::mem_ctx != NULL);
|
||||
|
||||
void *type;
|
||||
|
||||
type = ralloc_size(glsl_type::mem_ctx, size);
|
||||
assert(type != NULL);
|
||||
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +141,9 @@ struct glsl_type {
|
|||
* ralloc_free in that case. */
|
||||
static void operator delete(void *type)
|
||||
{
|
||||
mtx_lock(&glsl_type::mutex);
|
||||
ralloc_free(type);
|
||||
mtx_unlock(&glsl_type::mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -618,6 +622,9 @@ struct glsl_type {
|
|||
bool record_compare(const glsl_type *b) const;
|
||||
|
||||
private:
|
||||
|
||||
static mtx_t mutex;
|
||||
|
||||
/**
|
||||
* ralloc context for all glsl_type allocations
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue