Commit 015f2207 authored by Matt Turner's avatar Matt Turner

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's avatarTimothy Arceri <t_arceri@yahoo.com.au>
Reviewed-by: Brian Paul's avatarBrian Paul <brianp@vmware.com>
parent aded1160
......@@ -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);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment