mesa: Use atomics for buffer objects reference counts.
authorMathias Fröhlich <mathias.froehlich@web.de>
Sat, 3 Feb 2018 14:06:16 +0000 (15:06 +0100)
committerMathias Fröhlich <Mathias.Froehlich@gmx.net>
Tue, 6 Feb 2018 20:20:14 +0000 (21:20 +0100)
The mutex is currently used for reference counting and updating
the minmax index cache.
The change uses atomics directly for reference counting and
the mutex for the minmax cache.
This is safe since the reference count is not modified beside
in _mesa_reference_buffer_object where atomics aim to be used.
While using the minmax cache, the calling code holds a reference
to the buffer object. Thus unreferencing or even referencing the
buffer object does not need to be serialized with accessing
the minmax cache.
The change reduces the time _mesa_reference_buffer_object_ takes
by about a factor of two when looking at perf results for some
of my favorite use cases.

Signed-off-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/bufferobj.c
src/mesa/main/mtypes.h
src/mesa/vbo/vbo_minmax_index.c

index c1dfdfba82342de6a21f4f3dc54505067d9aed62..67f9cd0a902b18158e44bef4ea80dcef9024f8fa 100644 (file)
@@ -46,6 +46,7 @@
 #include "texstore.h"
 #include "transformfeedback.h"
 #include "varray.h"
+#include "util/u_atomic.h"
 
 
 /* Debug flags */
@@ -471,7 +472,7 @@ _mesa_delete_buffer_object(struct gl_context *ctx,
    bufObj->RefCount = -1000;
    bufObj->Name = ~0;
 
-   simple_mtx_destroy(&bufObj->Mutex);
+   simple_mtx_destroy(&bufObj->MinMaxCacheMutex);
    free(bufObj->Label);
    free(bufObj);
 }
@@ -490,16 +491,9 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
 {
    if (*ptr) {
       /* Unreference the old buffer */
-      GLboolean deleteFlag = GL_FALSE;
       struct gl_buffer_object *oldObj = *ptr;
 
-      simple_mtx_lock(&oldObj->Mutex);
-      assert(oldObj->RefCount > 0);
-      oldObj->RefCount--;
-      deleteFlag = (oldObj->RefCount == 0);
-      simple_mtx_unlock(&oldObj->Mutex);
-
-      if (deleteFlag) {
+      if (p_atomic_dec_zero(&oldObj->RefCount)) {
         assert(ctx->Driver.DeleteBuffer);
          ctx->Driver.DeleteBuffer(ctx, oldObj);
       }
@@ -510,12 +504,8 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
 
    if (bufObj) {
       /* reference new buffer */
-      simple_mtx_lock(&bufObj->Mutex);
-      assert(bufObj->RefCount > 0);
-
-      bufObj->RefCount++;
+      p_atomic_inc(&bufObj->RefCount);
       *ptr = bufObj;
-      simple_mtx_unlock(&bufObj->Mutex);
    }
 }
 
@@ -547,11 +537,11 @@ _mesa_initialize_buffer_object(struct gl_context *ctx,
                                GLuint name)
 {
    memset(obj, 0, sizeof(struct gl_buffer_object));
-   simple_mtx_init(&obj->Mutex, mtx_plain);
    obj->RefCount = 1;
    obj->Name = name;
    obj->Usage = GL_STATIC_DRAW_ARB;
 
+   simple_mtx_init(&obj->MinMaxCacheMutex, mtx_plain);
    if (get_no_minmax_cache())
       obj->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE;
 }
@@ -870,7 +860,7 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
    GLuint i;
 
    memset(&DummyBufferObject, 0, sizeof(DummyBufferObject));
-   simple_mtx_init(&DummyBufferObject.Mutex, mtx_plain);
+   simple_mtx_init(&DummyBufferObject.MinMaxCacheMutex, mtx_plain);
    DummyBufferObject.RefCount = 1000*1000*1000; /* never delete */
 
    _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj,
index 3a67d43420fed980e42cd99e8017caca76a7c047..b6d606386e563e3f4341c70541a1b1b3cbb9e53f 100644 (file)
@@ -1443,7 +1443,6 @@ typedef enum
  */
 struct gl_buffer_object
 {
-   simple_mtx_t Mutex;
    GLint RefCount;
    GLuint Name;
    GLchar *Label;       /**< GL_KHR_debug */
@@ -1464,6 +1463,7 @@ struct gl_buffer_object
    struct gl_buffer_mapping Mappings[MAP_COUNT];
 
    /** Memoization of min/max index computations for static index buffers */
+   simple_mtx_t MinMaxCacheMutex;
    struct hash_table *MinMaxCache;
    unsigned MinMaxCacheHitIndices;
    unsigned MinMaxCacheMissIndices;
index c9d20201672ff55dd341d4dfce96857a947c2d9a..d1298dcdc3a03b5b086701e87a7c0611319bf1fb 100644 (file)
@@ -115,7 +115,7 @@ vbo_get_minmax_cached(struct gl_buffer_object *bufferObj,
    if (!vbo_use_minmax_cache(bufferObj))
       return GL_FALSE;
 
-   simple_mtx_lock(&bufferObj->Mutex);
+   simple_mtx_lock(&bufferObj->MinMaxCacheMutex);
 
    if (bufferObj->MinMaxCacheDirty) {
       /* Disable the cache permanently for this BO if the number of hits
@@ -166,7 +166,7 @@ out_invalidate:
    }
 
 out_disable:
-   simple_mtx_unlock(&bufferObj->Mutex);
+   simple_mtx_unlock(&bufferObj->MinMaxCacheMutex);
    return found;
 }
 
@@ -184,7 +184,7 @@ vbo_minmax_cache_store(struct gl_context *ctx,
    if (!vbo_use_minmax_cache(bufferObj))
       return;
 
-   simple_mtx_lock(&bufferObj->Mutex);
+   simple_mtx_lock(&bufferObj->MinMaxCacheMutex);
 
    if (!bufferObj->MinMaxCache) {
       bufferObj->MinMaxCache =
@@ -223,7 +223,7 @@ vbo_minmax_cache_store(struct gl_context *ctx,
       free(entry);
 
 out:
-   simple_mtx_unlock(&bufferObj->Mutex);
+   simple_mtx_unlock(&bufferObj->MinMaxCacheMutex);
 }