[Mesa-dev] [PATCH 1/2] mesa: use new _mesa_reference_shared_state() function
Brian Paul
brianp at vmware.com
Tue Jan 31 17:34:08 PST 2012
This cleans up the reference counting of shared context state.
The next patch will use this to fix an actual bug.
NOTE: This is a candidate for the 8.0 branch.
---
src/mesa/main/context.c | 28 ++++++++++++--------------
src/mesa/main/shared.c | 48 +++++++++++++++++++++++++++++-----------------
src/mesa/main/shared.h | 11 +++++----
3 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index f39cab5..43e7438 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -939,13 +939,10 @@ _mesa_initialize_context(struct gl_context *ctx,
return GL_FALSE;
}
- _glthread_LOCK_MUTEX(shared->Mutex);
- ctx->Shared = shared;
- shared->RefCount++;
- _glthread_UNLOCK_MUTEX(shared->Mutex);
+ _mesa_reference_shared_state(ctx, &ctx->Shared, shared);
if (!init_attrib_groups( ctx )) {
- _mesa_release_shared_state(ctx, ctx->Shared);
+ _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
return GL_FALSE;
}
@@ -973,7 +970,7 @@ _mesa_initialize_context(struct gl_context *ctx,
}
if (!ctx->Exec) {
- _mesa_release_shared_state(ctx, ctx->Shared);
+ _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
return GL_FALSE;
}
#endif
@@ -1002,7 +999,7 @@ _mesa_initialize_context(struct gl_context *ctx,
#if FEATURE_dlist
ctx->Save = _mesa_create_save_table();
if (!ctx->Save) {
- _mesa_release_shared_state(ctx, ctx->Shared);
+ _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
free(ctx->Exec);
return GL_FALSE;
}
@@ -1140,7 +1137,7 @@ _mesa_free_context_data( struct gl_context *ctx )
free(ctx->Save);
/* Shared context state (display lists, textures, etc) */
- _mesa_release_shared_state( ctx, ctx->Shared );
+ _mesa_reference_shared_state(ctx, &ctx->Shared, NULL);
/* needs to be after freeing shared state */
_mesa_free_display_list_data(ctx);
@@ -1540,17 +1537,18 @@ GLboolean
_mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare)
{
if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {
- struct gl_shared_state *oldSharedState = ctx->Shared;
+ struct gl_shared_state *oldShared = NULL;
- ctx->Shared = ctxToShare->Shared;
-
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- ctx->Shared->RefCount++;
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ /* save ref to old state to prevent it from being deleted immediately */
+ _mesa_reference_shared_state(ctx, &oldShared, ctx->Shared);
+
+ /* update ctx's Shared pointer */
+ _mesa_reference_shared_state(ctx, &ctx->Shared, ctxToShare->Shared);
update_default_objects(ctx);
- _mesa_release_shared_state(ctx, oldSharedState);
+ /* release the old shared state */
+ _mesa_reference_shared_state(ctx, &oldShared, NULL);
return GL_TRUE;
}
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index c3e93b5..c07ce82 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -388,28 +388,40 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
/**
- * Decrement shared state object reference count and potentially free it
- * and all children structures.
- *
- * \param ctx GL context.
- * \param shared shared state pointer.
- *
- * \sa free_shared_state().
+ * gl_shared_state objects are ref counted.
+ * If ptr's refcount goes to zero, free the shared state.
*/
void
-_mesa_release_shared_state(struct gl_context *ctx,
- struct gl_shared_state *shared)
+_mesa_reference_shared_state(struct gl_context *ctx,
+ struct gl_shared_state **ptr,
+ struct gl_shared_state *state)
{
- GLint RefCount;
-
- _glthread_LOCK_MUTEX(shared->Mutex);
- RefCount = --shared->RefCount;
- _glthread_UNLOCK_MUTEX(shared->Mutex);
+ if (*ptr == state)
+ return;
+
+ if (*ptr) {
+ /* unref old state */
+ struct gl_shared_state *old = *ptr;
+ GLboolean delete;
+
+ _glthread_LOCK_MUTEX(old->Mutex);
+ assert(old->RefCount >= 1);
+ old->RefCount--;
+ delete = (old->RefCount == 0);
+ _glthread_UNLOCK_MUTEX(old->Mutex);
+
+ if (delete) {
+ free_shared_state(ctx, old);
+ }
- assert(RefCount >= 0);
+ *ptr = NULL;
+ }
- if (RefCount == 0) {
- /* free shared state */
- free_shared_state( ctx, shared );
+ if (state) {
+ /* reference new state */
+ _glthread_LOCK_MUTEX(state->Mutex);
+ state->RefCount++;
+ *ptr = state;
+ _glthread_UNLOCK_MUTEX(state->Mutex);
}
}
diff --git a/src/mesa/main/shared.h b/src/mesa/main/shared.h
index 55516a8..3fe4578 100644
--- a/src/mesa/main/shared.h
+++ b/src/mesa/main/shared.h
@@ -27,13 +27,14 @@
struct gl_context;
-struct gl_shared_state *
-_mesa_alloc_shared_state(struct gl_context *ctx);
+void
+_mesa_reference_shared_state(struct gl_context *ctx,
+ struct gl_shared_state **ptr,
+ struct gl_shared_state *state);
-void
-_mesa_release_shared_state(struct gl_context *ctx,
- struct gl_shared_state *shared);
+struct gl_shared_state *
+_mesa_alloc_shared_state(struct gl_context *ctx);
#endif
--
1.7.3.4
More information about the mesa-dev
mailing list