[Mesa-dev] [PATCH] glsl: Make access to type flyweight global state thread safe

Ian Romanick idr at freedesktop.org
Mon Oct 22 14:26:43 PDT 2012


From: Ian Romanick <ian.d.romanick at intel.com>

This should fix some problems related to compiling shaders in different
contextes from multiple threads.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54773
Cc: w_tresspassers at yahoo.co.jp
---
 src/glsl/builtin_types.h | 16 ++++++++--------
 src/glsl/glsl_types.cpp  | 36 +++++++++++++++++++++++++++++++-----
 src/glsl/glsl_types.h    |  4 ++--
 3 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/src/glsl/builtin_types.h b/src/glsl/builtin_types.h
index d75c562..59ad915 100644
--- a/src/glsl/builtin_types.h
+++ b/src/glsl/builtin_types.h
@@ -92,7 +92,7 @@ static const struct glsl_struct_field gl_DepthRangeParameters_fields[] = {
 const glsl_type glsl_type::builtin_structure_types[] = {
    glsl_type(gl_DepthRangeParameters_fields,
              Elements(gl_DepthRangeParameters_fields),
-             "gl_DepthRangeParameters"),
+             "gl_DepthRangeParameters", false),
 };
 /*@}*/
 
@@ -158,25 +158,25 @@ static const struct glsl_struct_field gl_FogParameters_fields[] = {
 const glsl_type glsl_type::builtin_110_deprecated_structure_types[] = {
    glsl_type(gl_PointParameters_fields,
              Elements(gl_PointParameters_fields),
-             "gl_PointParameters"),
+             "gl_PointParameters", false),
    glsl_type(gl_MaterialParameters_fields,
              Elements(gl_MaterialParameters_fields),
-             "gl_MaterialParameters"),
+             "gl_MaterialParameters", false),
    glsl_type(gl_LightSourceParameters_fields,
              Elements(gl_LightSourceParameters_fields),
-             "gl_LightSourceParameters"),
+             "gl_LightSourceParameters", false),
    glsl_type(gl_LightModelParameters_fields,
              Elements(gl_LightModelParameters_fields),
-             "gl_LightModelParameters"),
+             "gl_LightModelParameters", false),
    glsl_type(gl_LightModelProducts_fields,
              Elements(gl_LightModelProducts_fields),
-             "gl_LightModelProducts"),
+             "gl_LightModelProducts", false),
    glsl_type(gl_LightProducts_fields,
              Elements(gl_LightProducts_fields),
-             "gl_LightProducts"),
+             "gl_LightProducts", false),
    glsl_type(gl_FogParameters_fields,
              Elements(gl_FogParameters_fields),
-             "gl_FogParameters"),
+             "gl_FogParameters", false),
 };
 /*@}*/
 
diff --git a/src/glsl/glsl_types.cpp b/src/glsl/glsl_types.cpp
index 2aa51f0..f51d10c 100644
--- a/src/glsl/glsl_types.cpp
+++ b/src/glsl/glsl_types.cpp
@@ -35,6 +35,7 @@ extern "C" {
 hash_table *glsl_type::array_types = NULL;
 hash_table *glsl_type::record_types = NULL;
 void *glsl_type::mem_ctx = NULL;
+_glthread_DECLARE_STATIC_MUTEX(type_mutex);
 
 void
 glsl_type::init_ralloc_type_ctx(void)
@@ -55,8 +56,11 @@ glsl_type::glsl_type(GLenum gl_type,
    vector_elements(vector_elements), matrix_columns(matrix_columns),
    length(0)
 {
+   _glthread_LOCK_MUTEX(type_mutex);
    init_ralloc_type_ctx();
    this->name = ralloc_strdup(this->mem_ctx, name);
+   _glthread_UNLOCK_MUTEX(type_mutex);
+
    /* Neither dimension is zero or both dimensions are zero.
     */
    assert((vector_elements == 0) == (matrix_columns == 0));
@@ -73,13 +77,16 @@ glsl_type::glsl_type(GLenum gl_type,
    vector_elements(0), matrix_columns(0),
    length(0)
 {
+   _glthread_LOCK_MUTEX(type_mutex);
    init_ralloc_type_ctx();
    this->name = ralloc_strdup(this->mem_ctx, name);
+   _glthread_UNLOCK_MUTEX(type_mutex);
+
    memset(& fields, 0, sizeof(fields));
 }
 
 glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
-		     const char *name) :
+		     const char *name, bool already_locked) :
    base_type(GLSL_TYPE_STRUCT),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
    sampler_type(0),
@@ -88,6 +95,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
 {
    unsigned int i;
 
+   if (!already_locked)
+      _glthread_LOCK_MUTEX(type_mutex);
    init_ralloc_type_ctx();
    this->name = ralloc_strdup(this->mem_ctx, name);
    this->fields.structure = ralloc_array(this->mem_ctx,
@@ -97,6 +106,9 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
       this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
 						     fields[i].name);
    }
+
+   if (!already_locked)
+      _glthread_UNLOCK_MUTEX(type_mutex);
 }
 
 static void
@@ -350,6 +362,7 @@ const glsl_type *glsl_type::get_scalar_type() const
 void
 _mesa_glsl_release_types(void)
 {
+   _glthread_LOCK_MUTEX(type_mutex);
    if (glsl_type::array_types != NULL) {
       hash_table_dtor(glsl_type::array_types);
       glsl_type::array_types = NULL;
@@ -359,10 +372,12 @@ _mesa_glsl_release_types(void)
       hash_table_dtor(glsl_type::record_types);
       glsl_type::record_types = NULL;
    }
+   _glthread_UNLOCK_MUTEX(type_mutex);
 }
 
 
-glsl_type::glsl_type(const glsl_type *array, unsigned length) :
+glsl_type::glsl_type(const glsl_type *array, unsigned length,
+		     bool already_locked) :
    base_type(GLSL_TYPE_ARRAY),
    sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
    sampler_type(0),
@@ -381,8 +396,15 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) :
     * NUL.
     */
    const unsigned name_length = strlen(array->name) + 10 + 3;
+
+   if (!already_locked)
+      _glthread_LOCK_MUTEX(type_mutex);
+
    char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
 
+   if (!already_locked)
+      _glthread_UNLOCK_MUTEX(type_mutex);
+
    if (length == 0)
       snprintf(n, name_length, "%s[]", array->name);
    else
@@ -454,6 +476,7 @@ const glsl_type *
 glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
 {
 
+   _glthread_LOCK_MUTEX(type_mutex);
    if (array_types == NULL) {
       array_types = hash_table_ctor(64, hash_table_string_hash,
 				    hash_table_string_compare);
@@ -469,10 +492,11 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
 
    const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
    if (t == NULL) {
-      t = new glsl_type(base, array_size);
+      t = new glsl_type(base, array_size, true);
 
       hash_table_insert(array_types, (void *) t, ralloc_strdup(mem_ctx, key));
    }
+   _glthread_UNLOCK_MUTEX(type_mutex);
 
    assert(t->base_type == GLSL_TYPE_ARRAY);
    assert(t->length == array_size);
@@ -535,7 +559,8 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
 			       unsigned num_fields,
 			       const char *name)
 {
-   const glsl_type key(fields, num_fields, name);
+   _glthread_LOCK_MUTEX(type_mutex);
+   const glsl_type key(fields, num_fields, name, true);
 
    if (record_types == NULL) {
       record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
@@ -543,10 +568,11 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
 
    const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
    if (t == NULL) {
-      t = new glsl_type(fields, num_fields, name);
+      t = new glsl_type(fields, num_fields, name, true);
 
       hash_table_insert(record_types, (void *) t, t);
    }
+   _glthread_UNLOCK_MUTEX(type_mutex);
 
    assert(t->base_type == GLSL_TYPE_STRUCT);
    assert(t->length == num_fields);
diff --git a/src/glsl/glsl_types.h b/src/glsl/glsl_types.h
index 915d1a2..ce1ee92 100644
--- a/src/glsl/glsl_types.h
+++ b/src/glsl/glsl_types.h
@@ -489,10 +489,10 @@ private:
 
    /** Constructor for record types */
    glsl_type(const glsl_struct_field *fields, unsigned num_fields,
-	     const char *name);
+	     const char *name, bool already_locked);
 
    /** Constructor for array types */
-   glsl_type(const glsl_type *array, unsigned length);
+   glsl_type(const glsl_type *array, unsigned length, bool already_locked);
 
    /** Hash table containing the known array types. */
    static struct hash_table *array_types;
-- 
1.7.11.4



More information about the mesa-dev mailing list