[gimp] Correct startup flaw in idle swapper start.



commit 717d8b4e5617914abca7e0fac2614b7a021aea2f
Author: Monty <xiphmont gmail com>
Date:   Wed May 27 20:40:50 2009 -0400

    Correct startup flaw in idle swapper start.
    
    Check that the cache itself is idle. Previously it would start during
    transforms and long pyramid rendering ops and toss writes and large
    seeks into the tile cache while it was potentially under heavy pressure.
    
    Also increase its flush rate more to be more in line with modern system
    and editing needs.
---
 app/base/tile-cache.c |  105 ++++++++++++++++++++++++++++++++++++-------------
 app/base/tile-cache.h |    1 +
 app/base/tile-swap.c  |    5 ++-
 3 files changed, 82 insertions(+), 29 deletions(-)

diff --git a/app/base/tile-cache.c b/app/base/tile-cache.c
index 8c8e8cf..4fb7f87 100644
--- a/app/base/tile-cache.c
+++ b/app/base/tile-cache.c
@@ -27,17 +27,15 @@
 #include "tile-rowhints.h"
 #include "tile-private.h"
 
-
-#define IDLE_SWAPPER_TIMEOUT  250
-
+#define IDLE_SWAPPER_START              1000
+#define IDLE_SWAPPER_INTERVAL_MS        20
+#define IDLE_SWAPPER_TILES_PER_INTERVAL 10
 
 static gboolean  tile_cache_zorch_next     (void);
 static void      tile_cache_flush_internal (Tile     *tile);
-
 static gboolean  tile_idle_preswap         (gpointer  data);
 static void      tile_verify(void);
 
-
 typedef struct _TileList
 {
   Tile *first;
@@ -49,6 +47,7 @@ static gulong        max_cache_size   = 0;
 static gulong        cur_cache_dirty  = 0;
 static TileList      tile_list        = { NULL, NULL };
 static guint         idle_swapper     = 0;
+static guint         idle_delay       = 0;
 static Tile         *idle_scan_last   = NULL;
 
 #ifdef TILE_PROFILING
@@ -112,6 +111,12 @@ tile_cache_exit (void)
 }
 
 void
+tile_cache_suspend_idle_swapper(void)
+{
+  idle_delay = 1;
+}
+
+void
 tile_cache_insert (Tile *tile)
 {
 
@@ -208,6 +213,7 @@ tile_cache_insert (Tile *tile)
   }
   tile_list.last = tile;
   tile->cached = TRUE;
+  idle_delay = 1;
 
   if (PENDING_WRITE(tile))
     {
@@ -216,15 +222,16 @@ tile_cache_insert (Tile *tile)
       if(!idle_scan_last)
 	idle_scan_last=tile;
       
-      if (! idle_swapper &&
-          cur_cache_dirty * 2 > max_cache_size)
+      if (!idle_swapper)
         {
 
 #ifdef TILE_PROFILING
-	  g_printerr("idle swapper -> running");
+	  g_printerr("idle swapper -> started\n");
+	  g_printerr("idle swapper -> waiting");
 #endif
+	  idle_delay = 0;
           idle_swapper = g_timeout_add_full (G_PRIORITY_LOW,
-                                             IDLE_SWAPPER_TIMEOUT,
+                                             IDLE_SWAPPER_START,
                                              tile_idle_preswap,
                                              NULL, NULL);
         }
@@ -250,6 +257,7 @@ tile_cache_set_size (gulong cache_size)
 {
   TILE_CACHE_LOCK;
 
+  idle_delay = 1;
   max_cache_size = cache_size;
 
   while (cur_cache_size > max_cache_size)
@@ -309,6 +317,7 @@ tile_cache_zorch_next (void)
 
   if (PENDING_WRITE(tile))
     {
+      idle_delay = 1;
       tile_swap_out (tile);
     }
 
@@ -327,52 +336,92 @@ tile_cache_zorch_next (void)
 }
 
 static gboolean
-tile_idle_preswap (gpointer data)
+tile_idle_preswap_run (gpointer data)
 {
   Tile *tile;
+  int count = 0;
 
-  if (cur_cache_dirty * 2 < max_cache_size)
+  if (idle_delay)
     {
 #ifdef TILE_PROFILING
-      g_printerr("\nidle swapper -> stopped\n");
+      g_printerr("\nidle swapper -> waiting");
 #endif
-      idle_swapper = 0;
+      idle_delay = 0;
+      idle_swapper = g_timeout_add_full (G_PRIORITY_LOW,
+                                         IDLE_SWAPPER_START,
+                                         tile_idle_preswap,
+                                         NULL, NULL);
       return FALSE;
     }
 
   TILE_CACHE_LOCK;
 
 #ifdef TILE_PROFILING
-  tile_verify();
   g_printerr(".");
-  tile_idle_swapout++;
 #endif
 
   tile = idle_scan_last;
 
-  while(tile){
-    if(PENDING_WRITE(tile)){
-      idle_scan_last = tile->next;
-      
-      tile_swap_out (tile);
-      if(!PENDING_WRITE(tile))
-	cur_cache_dirty -= tile->size;
-
-      TILE_CACHE_UNLOCK;
-      return TRUE;
+  while(tile)
+    {
+      if(PENDING_WRITE(tile))
+        {
+          idle_scan_last = tile->next;
+          
+#ifdef TILE_PROFILING
+          tile_idle_swapout++;
+#endif
+          tile_swap_out (tile);
+          if(!PENDING_WRITE(tile))
+            cur_cache_dirty -= tile->size;
+          count++;
+          
+          if(count>=IDLE_SWAPPER_TILES_PER_INTERVAL) 
+            {
+              TILE_CACHE_UNLOCK;
+              return TRUE;
+            }
+        }
+      tile = tile->next;
     }
-    tile = tile->next;
-  }
   
   g_printerr("\nidle swapper -> stopped\n");
   idle_scan_last = NULL;
   idle_swapper = 0;
-  
+
+#ifdef TILE_PROFILING
+  tile_verify();
+#endif
+
   TILE_CACHE_UNLOCK;
   
   return FALSE;
 }
 
+static gboolean
+tile_idle_preswap (gpointer data)
+{
+  
+  if (idle_delay){
+#ifdef TILE_PROFILING
+    g_printerr(".");
+#endif
+    idle_delay = 0;
+    return TRUE;
+  }
+  
+#ifdef TILE_PROFILING
+  tile_verify();
+  g_printerr("\nidle swapper -> running");
+#endif
+  
+  idle_swapper = g_timeout_add_full (G_PRIORITY_LOW,
+				     IDLE_SWAPPER_INTERVAL_MS,
+				     tile_idle_preswap_run,
+				     NULL, NULL);
+  return FALSE;
+}
+
 #ifdef TILE_PROFILING
 static void
 tile_verify(void)
diff --git a/app/base/tile-cache.h b/app/base/tile-cache.h
index 3128150..09ba4e2 100644
--- a/app/base/tile-cache.h
+++ b/app/base/tile-cache.h
@@ -23,6 +23,7 @@ void   tile_cache_init     (gulong  cache_size);
 void   tile_cache_exit     (void);
 
 void   tile_cache_set_size (gulong  cache_size);
+void   tile_cache_suspend_idle_swapper(void);
 
 void   tile_cache_insert   (Tile   *tile);
 void   tile_cache_flush    (Tile   *tile);
diff --git a/app/base/tile-swap.c b/app/base/tile-swap.c
index b19d211..6953867 100644
--- a/app/base/tile-swap.c
+++ b/app/base/tile-swap.c
@@ -50,6 +50,7 @@
 #include "tile-rowhints.h"
 #include "tile-swap.h"
 #include "tile-private.h"
+#include "tile-cache.h"
 
 #include "gimp-intl.h"
 
@@ -374,7 +375,9 @@ tile_swap_default_in (SwapFile *swap_file,
   if (tile->data)
     return;
 
-#ifdef TILE_PROFILING
+  tile_cache_suspend_idle_swapper();
+
+#ifdef TILE_PROFILING  
   g_get_current_time(&now);
   tile_total_swapin++;
 



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