From 015f2207cfa2334fb3bca5b6b941666ebf73e829 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Thu, 30 Jul 2015 14:31:04 -0700 Subject: [PATCH] mesa: Replace uses of Shared->Mutex with hash-table mutexes We were locking the Shared->Mutex and then using calling functions like _mesa_HashInsert that do additional per-hash-table locking internally. Instead just lock each hash-table's mutex and use functions like _mesa_HashInsertLocked and the new _mesa_HashRemoveLocked. In order to do this, we need to remove the locking from _mesa_HashFindFreeKeyBlock since it will always be called with the per-hash-table lock taken. Reviewed-by: Timothy Arceri Reviewed-by: Brian Paul --- src/mesa/main/arbprogram.c | 7 ++++++- src/mesa/main/atifragshader.c | 6 +++++- src/mesa/main/bufferobj.c | 26 ++++++++++++++------------ src/mesa/main/dlist.c | 8 ++++---- src/mesa/main/fbobject.c | 32 +++++++++++++++++++------------- src/mesa/main/hash.c | 4 ---- src/mesa/main/samplerobj.c | 23 ++++++++++++++++++----- src/mesa/main/shaderapi.c | 10 ++++++++-- src/mesa/main/texobj.c | 12 ++++-------- 9 files changed, 78 insertions(+), 50 deletions(-) diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c index f474951d729..3f7acda9f32 100644 --- a/src/mesa/main/arbprogram.c +++ b/src/mesa/main/arbprogram.c @@ -200,13 +200,18 @@ _mesa_GenProgramsARB(GLsizei n, GLuint *ids) if (!ids) return; + _mesa_HashLockMutex(ctx->Shared->Programs); + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n); /* Insert pointer to dummy program as placeholder */ for (i = 0; i < (GLuint) n; i++) { - _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram); + _mesa_HashInsertLocked(ctx->Shared->Programs, first + i, + &_mesa_DummyProgram); } + _mesa_HashUnlockMutex(ctx->Shared->Programs); + /* Return the program names */ for (i = 0; i < (GLuint) n; i++) { ids[i] = first + i; diff --git a/src/mesa/main/atifragshader.c b/src/mesa/main/atifragshader.c index 34f45c68008..83a449a1b13 100644 --- a/src/mesa/main/atifragshader.c +++ b/src/mesa/main/atifragshader.c @@ -201,11 +201,15 @@ _mesa_GenFragmentShadersATI(GLuint range) return 0; } + _mesa_HashLockMutex(ctx->Shared->ATIShaders); + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range); for (i = 0; i < range; i++) { - _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader); + _mesa_HashInsertLocked(ctx->Shared->ATIShaders, first + i, &DummyShader); } + _mesa_HashUnlockMutex(ctx->Shared->ATIShaders); + return first; } diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index e60a8ea5237..22073dd28b8 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -1097,8 +1097,11 @@ _mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer) struct gl_buffer_object * _mesa_lookup_bufferobj_locked(struct gl_context *ctx, GLuint buffer) { - return (struct gl_buffer_object *) - _mesa_HashLookupLocked(ctx->Shared->BufferObjects, buffer); + if (buffer == 0) + return NULL; + else + return (struct gl_buffer_object *) + _mesa_HashLookupLocked(ctx->Shared->BufferObjects, buffer); } /** @@ -1283,10 +1286,11 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) return; } - mtx_lock(&ctx->Shared->Mutex); + _mesa_HashLockMutex(ctx->Shared->BufferObjects); for (i = 0; i < n; i++) { - struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, ids[i]); + struct gl_buffer_object *bufObj = + _mesa_lookup_bufferobj_locked(ctx, ids[i]); if (bufObj) { struct gl_vertex_array_object *vao = ctx->Array.VAO; GLuint j; @@ -1395,7 +1399,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) } /* The ID is immediately freed for re-use */ - _mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]); + _mesa_HashRemoveLocked(ctx->Shared->BufferObjects, ids[i]); /* Make sure we do not run into the classic ABA problem on bind. * We don't want to allow re-binding a buffer object that's been * "deleted" by glDeleteBuffers(). @@ -1411,7 +1415,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids) } } - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); } @@ -1445,7 +1449,7 @@ create_buffers(GLsizei n, GLuint *buffers, bool dsa) /* * This must be atomic (generation and allocation of buffer object IDs) */ - mtx_lock(&ctx->Shared->Mutex); + _mesa_HashLockMutex(ctx->Shared->BufferObjects); first = _mesa_HashFindFreeKeyBlock(ctx->Shared->BufferObjects, n); @@ -1460,17 +1464,17 @@ create_buffers(GLsizei n, GLuint *buffers, bool dsa) buf = ctx->Driver.NewBufferObject(ctx, buffers[i]); if (!buf) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); return; } } else buf = &DummyBufferObject; - _mesa_HashInsert(ctx->Shared->BufferObjects, buffers[i], buf); + _mesa_HashInsertLocked(ctx->Shared->BufferObjects, buffers[i], buf); } - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); } /** @@ -1512,9 +1516,7 @@ _mesa_IsBuffer(GLuint id) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - mtx_lock(&ctx->Shared->Mutex); bufObj = _mesa_lookup_bufferobj(ctx, id); - mtx_unlock(&ctx->Shared->Mutex); return bufObj && bufObj != &DummyBufferObject; } diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index b15826c5a2b..43e2ffb3a78 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -9228,15 +9228,15 @@ _mesa_GenLists(GLsizei range) /* * Make this an atomic operation */ - mtx_lock(&ctx->Shared->Mutex); + _mesa_HashLockMutex(ctx->Shared->DisplayList); base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range); if (base) { /* reserve the list IDs by with empty/dummy lists */ GLint i; for (i = 0; i < range; i++) { - _mesa_HashInsert(ctx->Shared->DisplayList, base + i, - make_list(base + i, 1)); + _mesa_HashInsertLocked(ctx->Shared->DisplayList, base + i, + make_list(base + i, 1)); } } @@ -9258,7 +9258,7 @@ _mesa_GenLists(GLsizei range) } } - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashUnlockMutex(ctx->Shared->DisplayList); return base; } diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index c81f5a083eb..b751bf01532 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -1287,8 +1287,8 @@ _mesa_IsRenderbuffer(GLuint renderbuffer) static struct gl_renderbuffer * -allocate_renderbuffer(struct gl_context *ctx, GLuint renderbuffer, - const char *func) +allocate_renderbuffer_locked(struct gl_context *ctx, GLuint renderbuffer, + const char *func) { struct gl_renderbuffer *newRb; @@ -1299,10 +1299,8 @@ allocate_renderbuffer(struct gl_context *ctx, GLuint renderbuffer, return NULL; } assert(newRb->AllocStorage); - mtx_lock(&ctx->Shared->Mutex); - _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb); + _mesa_HashInsertLocked(ctx->Shared->RenderBuffers, renderbuffer, newRb); newRb->RefCount = 1; /* referenced by hash table */ - mtx_unlock(&ctx->Shared->Mutex); return newRb; } @@ -1336,7 +1334,10 @@ bind_renderbuffer(GLenum target, GLuint renderbuffer, bool allow_user_names) } if (!newRb) { - newRb = allocate_renderbuffer(ctx, renderbuffer, "glBindRenderbufferEXT"); + _mesa_HashLockMutex(ctx->Shared->RenderBuffers); + newRb = allocate_renderbuffer_locked(ctx, renderbuffer, + "glBindRenderbufferEXT"); + _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); } } else { @@ -1643,6 +1644,8 @@ create_render_buffers(struct gl_context *ctx, GLsizei n, GLuint *renderbuffers, if (!renderbuffers) return; + _mesa_HashLockMutex(ctx->Shared->RenderBuffers); + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n); for (i = 0; i < n; i++) { @@ -1650,14 +1653,15 @@ create_render_buffers(struct gl_context *ctx, GLsizei n, GLuint *renderbuffers, renderbuffers[i] = name; if (dsa) { - allocate_renderbuffer(ctx, name, func); + allocate_renderbuffer_locked(ctx, name, func); } else { /* insert a dummy renderbuffer into the hash table */ - mtx_lock(&ctx->Shared->Mutex); - _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer); - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashInsertLocked(ctx->Shared->RenderBuffers, name, + &DummyRenderbuffer); } } + + _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); } @@ -2684,6 +2688,8 @@ create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa) if (!framebuffers) return; + _mesa_HashLockMutex(ctx->Shared->FrameBuffers); + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n); for (i = 0; i < n; i++) { @@ -2700,10 +2706,10 @@ create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa) else fb = &DummyFramebuffer; - mtx_lock(&ctx->Shared->Mutex); - _mesa_HashInsert(ctx->Shared->FrameBuffers, name, fb); - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashInsertLocked(ctx->Shared->FrameBuffers, name, fb); } + + _mesa_HashUnlockMutex(ctx->Shared->FrameBuffers); } diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c index 85c29cd1c7d..7d8a5fd3337 100644 --- a/src/mesa/main/hash.c +++ b/src/mesa/main/hash.c @@ -468,10 +468,8 @@ GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys) { const GLuint maxKey = ~((GLuint) 0) - 1; - mtx_lock(&table->Mutex); if (maxKey - numKeys > table->MaxKey) { /* the quick solution */ - mtx_unlock(&table->Mutex); return table->MaxKey + 1; } else { @@ -489,13 +487,11 @@ _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys) /* this key not in use, check if we've found enough */ freeCount++; if (freeCount == numKeys) { - mtx_unlock(&table->Mutex); return freeStart; } } } /* cannot allocate a block of numKeys consecutive keys */ - mtx_unlock(&table->Mutex); return 0; } } diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c index 74761953044..14f2b45fe1d 100644 --- a/src/mesa/main/samplerobj.c +++ b/src/mesa/main/samplerobj.c @@ -50,6 +50,15 @@ _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) _mesa_HashLookup(ctx->Shared->SamplerObjects, name); } +static struct gl_sampler_object * +_mesa_lookup_samplerobj_locked(struct gl_context *ctx, GLuint name) +{ + if (name == 0) + return NULL; + else + return (struct gl_sampler_object *) + _mesa_HashLookupLocked(ctx->Shared->SamplerObjects, name); +} static inline void begin_samplerobj_lookups(struct gl_context *ctx) @@ -186,15 +195,19 @@ create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers, if (!samplers) return; + _mesa_HashLockMutex(ctx->Shared->SamplerObjects); + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count); /* Insert the ID and pointer to new sampler object into hash table */ for (i = 0; i < count; i++) { struct gl_sampler_object *sampObj = ctx->Driver.NewSamplerObject(ctx, first + i); - _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj); + _mesa_HashInsertLocked(ctx->Shared->SamplerObjects, first + i, sampObj); samplers[i] = first + i; } + + _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); } void GLAPIENTRY @@ -225,13 +238,13 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers) return; } - mtx_lock(&ctx->Shared->Mutex); + _mesa_HashLockMutex(ctx->Shared->SamplerObjects); for (i = 0; i < count; i++) { if (samplers[i]) { GLuint j; struct gl_sampler_object *sampObj = - _mesa_lookup_samplerobj(ctx, samplers[i]); + _mesa_lookup_samplerobj_locked(ctx, samplers[i]); if (sampObj) { /* If the sampler is currently bound, unbind it. */ @@ -243,14 +256,14 @@ _mesa_DeleteSamplers(GLsizei count, const GLuint *samplers) } /* The ID is immediately freed for re-use */ - _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]); + _mesa_HashRemoveLocked(ctx->Shared->SamplerObjects, samplers[i]); /* But the object exists until its reference count goes to zero */ _mesa_reference_sampler_object(ctx, &sampObj, NULL); } } } - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); } diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index ae37e94f3a8..3c85b41c88c 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -305,9 +305,11 @@ create_shader(struct gl_context *ctx, GLenum type) return 0; } + _mesa_HashLockMutex(ctx->Shared->ShaderObjects); name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); sh = ctx->Driver.NewShader(ctx, name, type); - _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh); + _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh); + _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); return name; } @@ -319,14 +321,18 @@ create_shader_program(struct gl_context *ctx) GLuint name; struct gl_shader_program *shProg; + _mesa_HashLockMutex(ctx->Shared->ShaderObjects); + name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); shProg = _mesa_new_shader_program(name); - _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg); + _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg); assert(shProg->RefCount == 1); + _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); + return name; } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index c9502bda236..ed630bd0dd1 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -1219,7 +1219,7 @@ create_textures(struct gl_context *ctx, GLenum target, /* * This must be atomic (generation and allocation of texture IDs) */ - mtx_lock(&ctx->Shared->Mutex); + _mesa_HashLockMutex(ctx->Shared->TexObjects); first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n); @@ -1229,18 +1229,18 @@ create_textures(struct gl_context *ctx, GLenum target, GLuint name = first + i; texObj = ctx->Driver.NewTextureObject(ctx, name, target); if (!texObj) { - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashUnlockMutex(ctx->Shared->TexObjects); _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sTextures", caller); return; } /* insert into hash table */ - _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); + _mesa_HashInsertLocked(ctx->Shared->TexObjects, texObj->Name, texObj); textures[i] = name; } - mtx_unlock(&ctx->Shared->Mutex); + _mesa_HashUnlockMutex(ctx->Shared->TexObjects); } /*@}*/ @@ -1489,9 +1489,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) /* The texture _name_ is now free for re-use. * Remove it from the hash table now. */ - mtx_lock(&ctx->Shared->Mutex); _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); - mtx_unlock(&ctx->Shared->Mutex); /* Unreference the texobj. If refcount hits zero, the texture * will be deleted. @@ -1723,9 +1721,7 @@ _mesa_BindTexture( GLenum target, GLuint texName ) } /* and insert it into hash table */ - mtx_lock(&ctx->Shared->Mutex); _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj); - mtx_unlock(&ctx->Shared->Mutex); } } -- 2.30.2