[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