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 <t_arceri@yahoo.com.au> Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user