[Mesa-dev] [PATCH 2/2] mesa: Replace uses of Shared->Mutex with hash-table mutexes
Matt Turner
mattst88 at gmail.com
Thu May 19 19:46:22 UTC 2016
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 <t_arceri at yahoo.com.au>
Reviewed-by: Brian Paul <brianp at vmware.com>
---
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 f474951..3f7acda 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 34f45c6..83a449a 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 e60a8ea..22073dd 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 b15826c..43e2ffb 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 c81f5a0..b751bf0 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 85c29cd..7d8a5fd 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 7476195..14f2b45 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 ae37e94..3c85b41 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 c9502bd..ed630bd 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.7.3
More information about the mesa-dev
mailing list