[Mesa-dev] [PATCH 1/2] mesa: use new _mesa_reference_shared_state() function
Jose Fonseca
jfonseca at vmware.com
Wed Feb 1 02:35:58 PST 2012
Looks solid to me Brian.
Jose
----- Original Message -----
> 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
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
More information about the mesa-dev
mailing list