[gegl/threaded-base-classes] buffer: protect get_tile with tile_storage instead of 2d list of tiles



commit d63fe50b4bf94ad1a344f6ffba149a32d7c8d687
Author: Øyvind Kolås <pippin gimp org>
Date:   Fri Jun 27 23:16:15 2014 +0200

    buffer: protect get_tile with tile_storage instead of 2d list of tiles

 gegl/buffer/gegl-buffer-access.c      |   21 ++------------
 gegl/buffer/gegl-buffer-iterator.c    |   16 +---------
 gegl/buffer/gegl-buffer.c             |   49 +++++++++++++++++++++++++++++---
 gegl/buffer/gegl-tile-handler-cache.c |    5 +++-
 gegl/buffer/gegl-tile-source.h        |   17 ++++++++++-
 5 files changed, 68 insertions(+), 40 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 3f723ba..e36a704 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -304,8 +304,6 @@ gegl_buffer_flush (GeglBuffer *buffer)
                             GEGL_TILE_FLUSH, 0,0,0,NULL);
 }
 
-static GMutex mutexes[256];
-
 static inline void
 gegl_buffer_iterate_write (GeglBuffer          *buffer,
                            const GeglRectangle *roi,
@@ -335,7 +333,6 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
   gint abyss_x_total  = buffer_abyss_x + buffer->abyss.width;
   gint abyss_y_total  = buffer_abyss_y + buffer->abyss.height;
   gint factor         = 1<<level;
-  gboolean threaded   = gegl_config()->threads > 1;
   const Babl *fish;
 
   /* roi specified, override buffers extent */
@@ -395,19 +392,7 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
           index_x = gegl_tile_indice (tiledx, tile_width);
           index_y = gegl_tile_indice (tiledy, tile_height);
 
-          if (threaded)
-            {
-              g_mutex_lock (&mutexes[(index_x&15) * 16 + (index_y&15)]);
-              tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
-                                                index_x, index_y, level);
-              g_mutex_unlock (&mutexes[(index_x&15) * 16 + (index_y&15)]);
-            }
-          else
-            {
-              tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
-                                                index_x, index_y, level);
-            }
-
+          tile = gegl_buffer_get_tile (buffer, index_x, index_y, level);
 
           lskip = (buffer_abyss_x) - (buffer_x + bufx);
           /* gap between left side of tile, and abyss */
@@ -1684,8 +1669,8 @@ gegl_buffer_copy (GeglBuffer          *src,
                 dtx = gegl_tile_indice (dst_x, tile_width);
                 dty = gegl_tile_indice (dst_y, tile_height);
 
-                src_tile = gegl_tile_source_get_tile ((GeglTileSource*)(src),
-                                                      stx, sty, 0);
+                src_tile = gegl_buffer_get_tile ((GeglTileSource*)(src),
+                                                 stx, sty, 0);
 
                 dst_tile = gegl_tile_dup (src_tile);
                 dst_tile->tile_storage = dst->tile_storage;
diff --git a/gegl/buffer/gegl-buffer-iterator.c b/gegl/buffer/gegl-buffer-iterator.c
index a8bfe50..585829a 100644
--- a/gegl/buffer/gegl-buffer-iterator.c
+++ b/gegl/buffer/gegl-buffer-iterator.c
@@ -290,7 +290,6 @@ increment_rects (GeglBufferIterator *iter)
   return TRUE;
 }
 
-static GMutex mutexes[256];
 static void
 get_tile (GeglBufferIterator *iter,
           int        index)
@@ -319,18 +318,7 @@ get_tile (GeglBufferIterator *iter,
       int tile_x = gegl_tile_indice (iter->roi[index].x + shift_x, tile_width);
       int tile_y = gegl_tile_indice (iter->roi[index].y + shift_y, tile_height);
 
-      if (threaded)
-        {
-          g_mutex_lock (&mutexes[(ABS(tile_x) % 16) * 16 + (ABS(tile_y)%16)]);
-          sub->current_tile = gegl_tile_source_get_tile ((GeglTileSource *)(buf),
-                                                         tile_x, tile_y, 0);
-          g_mutex_unlock (&mutexes[(ABS(tile_x) % 16) * 16 + (ABS(tile_y)%16)]);
-        }
-      else
-        {
-          sub->current_tile = gegl_tile_source_get_tile ((GeglTileSource *)(buf),
-                                                         tile_x, tile_y, 0);
-        }
+      sub->current_tile = gegl_buffer_get_tile (buf, tile_x, tile_y, 0);
 
       if (sub->flags & GEGL_BUFFER_WRITE)
         gegl_tile_lock (sub->current_tile);
@@ -449,7 +437,7 @@ prepare_iteration (GeglBufferIterator *iter)
               (buf->extent.width  == buf->tile_width) &&
               (buf->extent.height == buf->tile_height))
             {
-              sub->linear_tile = gegl_tile_source_get_tile ((GeglTileSource *)(sub->buffer), 0, 0, 0);
+              sub->linear_tile = gegl_buffer_get_tile (sub->buffer, 0, 0, 0);
 
               if (sub->flags & GEGL_BUFFER_WRITE)
                 gegl_tile_lock (sub->linear_tile);
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index 1deb848..a1bbfb3 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -697,10 +697,10 @@ gegl_buffer_constructor (GType                  type,
 }
 
 static GeglTile *
-gegl_buffer_get_tile (GeglTileSource *source,
-                      gint            x,
-                      gint            y,
-                      gint            z)
+gegl_buffer_get_tile_int (GeglTileSource *source,
+                          gint            x,
+                          gint            y,
+                          gint            z)
 {
   GeglTileHandler *handler = (GeglTileHandler*) (source);
   GeglTile        *tile   = NULL;
@@ -751,7 +751,7 @@ gegl_buffer_command (GeglTileSource *source,
   switch (command)
     {
       case GEGL_TILE_GET:
-        return gegl_buffer_get_tile (source, x, y, z);
+        return gegl_buffer_get_tile_int (source, x, y, z);
       default:
         return gegl_tile_handler_source_command (handler, command, x, y, z, data);
     }
@@ -1184,3 +1184,42 @@ glong gegl_buffer_signal_connect (GeglBuffer *buffer,
   buffer->changed_signal_connections++;
   return g_signal_connect(buffer, detailed_signal, c_handler, data);
 } 
+
+GeglTile *
+gegl_buffer_get_tile (GeglBuffer *buffer,
+                      gint        x,
+                      gint        y,
+                      gint        z)
+{
+  GeglTileSource  *source  = (GeglTileSource*)buffer;
+  GeglTile *tile;
+
+  static int threaded = -1;
+
+  if (threaded == -1)
+  {
+    threaded = gegl_config()->threads > 1;
+  }
+
+  g_assert (source);
+
+  if (threaded)
+  {
+    GeglTileStorage *tile_storage = buffer->tile_storage;
+    g_assert (tile_storage);
+
+    g_mutex_lock (&tile_storage->mutex);
+
+    tile = gegl_tile_source_command (source, GEGL_TILE_GET,
+                                     x, y, z, NULL);
+
+    g_mutex_unlock (&tile_storage->mutex);
+  }
+  else
+  {
+    return gegl_tile_source_command (source, GEGL_TILE_GET,
+                                     x, y, z, NULL);
+  }
+
+  return tile;
+}
diff --git a/gegl/buffer/gegl-tile-handler-cache.c b/gegl/buffer/gegl-tile-handler-cache.c
index cf897e2..12bb60d 100644
--- a/gegl/buffer/gegl-tile-handler-cache.c
+++ b/gegl/buffer/gegl-tile-handler-cache.c
@@ -347,7 +347,6 @@ gegl_tile_handler_cache_get_tile (GeglTileHandlerCache *cache,
       {
         g_printerr ("NULL tile in %s %p %i %i %i %p\n", __FUNCTION__, result, result->x, result->y, 
result->z,
                 result->tile);
-        g_mutex_unlock (&mutex);
         return NULL;
       }
       return gegl_tile_ref (result->tile);
@@ -420,8 +419,10 @@ gegl_tile_handler_cache_invalidate (GeglTileHandlerCache *cache,
       item->tile->tile_storage = NULL;
       gegl_tile_mark_as_stored (item->tile); /* to cheat it out of being stored */
       gegl_tile_unref (item->tile);
+
       g_queue_unlink (cache_queue, &item->link);
       cache->items = g_slist_remove (cache->items, item);
+
       g_hash_table_remove (cache_ht, item);
       g_slice_free (CacheItem, item);
     }
@@ -484,6 +485,8 @@ gegl_tile_handler_cache_insert (GeglTileHandlerCache *cache,
   // XXX : remove entry if it already exists
   gegl_tile_handler_cache_void (cache, x, y, z);
 
+  /* XXX: this is a window when the tile is a zero tile during update */
+
   g_mutex_lock (&mutex);
   cache_total  += item->tile->size;
   g_queue_push_head_link (cache_queue, &item->link);
diff --git a/gegl/buffer/gegl-tile-source.h b/gegl/buffer/gegl-tile-source.h
index de0186f..ba63a38 100644
--- a/gegl/buffer/gegl-tile-source.h
+++ b/gegl/buffer/gegl-tile-source.h
@@ -90,11 +90,24 @@ gegl_tile_source_get_tile (GeglTileSource *source,
                            gint            y,
                            gint            z)
 {
-  GeglTile *tile = gegl_tile_source_command (source, GEGL_TILE_GET,
-                                             x, y, z, NULL);
+  
+  GeglTile *tile;
+  
+
+  tile = gegl_tile_source_command (source, GEGL_TILE_GET,
+                                   x, y, z, NULL);
+
   return tile;
 }
 
+
+GeglTile *
+gegl_buffer_get_tile (GeglBuffer *buffer,
+                      gint        x,
+                      gint        y,
+                      gint        z);
+
+
 /**
  * gegl_tile_source_set_tile:
  * @source: a GeglTileSource *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]