Improve journal/cloud cache locking and add access time tracking.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 17 Aug 2010 22:23:40 +0000 (15:23 -0700)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Tue, 17 Aug 2010 22:23:40 +0000 (15:23 -0700)
bluesky/bluesky-private.h
bluesky/debug.c
bluesky/log.c

index 46a6690..65f356b 100644 (file)
@@ -265,6 +265,7 @@ struct _BlueSkyLog {
 struct _BlueSkyCacheFile {
     GMutex *lock;
     GCond *cond;
+    gint refcount;
     int type;                   // Only one of CLOUDLOG_{JOURNAL,CLOUD}
     int log_dir;
     int log_seq;
@@ -275,6 +276,7 @@ struct _BlueSkyCacheFile {
     BlueSkyFS *fs;
     BlueSkyLog *log;
     gboolean fetching, ready;
+    int64_t atime;              // Access time, for cache management
 };
 
 BlueSkyLog *bluesky_log_new(const char *log_directory);
index 9d875bd..207cb7b 100644 (file)
@@ -55,8 +55,10 @@ static void cache_dump(gpointer key, gpointer value, gpointer user_data)
 {
     BlueSkyCacheFile *cache = (BlueSkyCacheFile *)value;
 
-    g_print("%s addr=%p mapcount=%d",
-            cache->filename, cache->addr, cache->mapcount);
+    int64_t age = bluesky_get_current_time() - cache->atime;
+    g_print("%s addr=%p mapcount=%d refcount=%d atime_age=%f",
+            cache->filename, cache->addr, cache->mapcount, cache->refcount,
+            age / 1e6);
     if (cache->fetching)
         g_print(" (fetching)");
     g_print("\n");
index 0918d37..9ba75b4 100644 (file)
@@ -273,6 +273,11 @@ void bluesky_log_finish_all(GList *log_items)
  * to it. */
 static int page_size = 0;
 
+void bluesky_cachefile_unref(BlueSkyCacheFile *cachefile)
+{
+    g_atomic_int_add(&cachefile->refcount, -1);
+}
+
 static void cloudlog_fetch_complete(BlueSkyStoreAsync *async,
                                     BlueSkyCacheFile *cachefile)
 {
@@ -293,12 +298,13 @@ static void cloudlog_fetch_complete(BlueSkyStoreAsync *async,
     g_free(pathname);
     cachefile->fetching = FALSE;
     cachefile->ready = TRUE;
+    bluesky_cachefile_unref(cachefile);
     g_cond_broadcast(cachefile->cond);
     g_mutex_unlock(cachefile->lock);
 }
 
 /* Find the BlueSkyCacheFile object for the given journal or cloud log segment.
- * Returns the object in the locked state. */
+ * Returns the object in the locked state and with a reference taken. */
 BlueSkyCacheFile *bluesky_cachefile_lookup(BlueSkyFS *fs,
                                          int clouddir, int log_seq)
 {
@@ -332,11 +338,13 @@ BlueSkyCacheFile *bluesky_cachefile_lookup(BlueSkyFS *fs,
         map->log_seq = log_seq;
         map->log = log;
         g_atomic_int_set(&map->mapcount, 0);
+        g_atomic_int_set(&map->refcount, 0);
 
         g_hash_table_insert(log->mmap_cache, GINT_TO_POINTER(log_seq), map);
 
         // If the log file is stored in the cloud, we may need to fetch it
         if (clouddir >= 0) {
+            g_atomic_int_inc(&map->refcount);
             map->fetching = TRUE;
             g_print("Starting fetch of %s from cloud\n", logname);
             BlueSkyStoreAsync *async = bluesky_store_async_new(fs->store);
@@ -353,6 +361,7 @@ BlueSkyCacheFile *bluesky_cachefile_lookup(BlueSkyFS *fs,
     }
 
     g_mutex_unlock(log->mmap_lock);
+    g_atomic_int_inc(&map->refcount);
     return map;
 }
 
@@ -380,6 +389,7 @@ BlueSkyRCStr *bluesky_log_map_object(BlueSkyFS *fs, int log_dir,
 
         if (fd < 0) {
             fprintf(stderr, "Error opening logfile %s: %m\n", map->filename);
+            bluesky_cachefile_unref(map);
             g_mutex_unlock(map->lock);
             return NULL;
         }
@@ -390,6 +400,7 @@ BlueSkyRCStr *bluesky_log_map_object(BlueSkyFS *fs, int log_dir,
         map->len = length;
 
         g_print("Re-mapped log segment %d...\n", log_seq);
+        g_atomic_int_inc(&map->refcount);
 
         close(fd);
     }
@@ -397,7 +408,9 @@ BlueSkyRCStr *bluesky_log_map_object(BlueSkyFS *fs, int log_dir,
     g_mutex_unlock(log->mmap_lock);
 
     BlueSkyRCStr *str;
+    map->atime = bluesky_get_current_time();
     str = bluesky_string_new_from_mmap(map, log_offset, log_size);
+    bluesky_cachefile_unref(map);
     g_mutex_unlock(map->lock);
     return str;
 }
@@ -409,13 +422,12 @@ void bluesky_mmap_unref(BlueSkyCacheFile *mmap)
 
     if (g_atomic_int_dec_and_test(&mmap->mapcount)) {
         g_mutex_lock(mmap->lock);
-        if (g_atomic_int_get(&mmap->mapcount) > 0) {
+        if (g_atomic_int_get(&mmap->mapcount) == 0) {
             g_print("Unmapped log segment %d...\n", mmap->log_seq);
             munmap((void *)mmap->addr, mmap->len);
             mmap->addr = NULL;
-            return;
+            g_atomic_int_add(&mmap->refcount, -1);
         }
         g_mutex_unlock(mmap->lock);
     }
 }
-