util/disk_cache: hash timestamps into the cache keys
authorGrazvydas Ignotas <notasas@gmail.com>
Wed, 15 Mar 2017 23:09:29 +0000 (01:09 +0200)
committerTimothy Arceri <tarceri@itsqueeze.com>
Fri, 24 Mar 2017 00:20:09 +0000 (11:20 +1100)
Instead of using a directory, hash the timestamps into the cache keys
themselves. Since there is no more timestamp directory, there is no more
need for deleting the cache of other mesa versions and we rely on
eviction to clean up the old cache entries. This solves the problem of
using several incarnations of disk_cache at the same time, where one
deletes a directory belonging to the other, like when both OpenGL and
gallium nine are used simultaneously (or several different mesa
installations).

v2: using additional blob instead of trying to clone sha1 state

v3: (Timothy Arceri) don't use an opaque data type to store
    timestamp.

V4: (Timothy Arceri) use blob to store driver keys just make sure
    to store null terminator for strings, and make sure blob is
    defined by disk_cache and not it's users.

Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100091

src/compiler/glsl/tests/cache_test.c
src/util/disk_cache.c

index b1b3c33535e750474861e38d138c3bcced9331e4..b604943feeb01ad80cfd2afa16767e3b0237477d 100644 (file)
@@ -128,7 +128,7 @@ rmrf_local(const char *path)
 }
 
 static void
-check_timestamp_and_gpu_id_directories_created(char *cache_dir)
+check_directories_created(char *cache_dir)
 {
    bool sub_dirs_created = false;
 
@@ -184,13 +184,13 @@ test_disk_cache_create(void)
    /* Create string with expected directory hierarchy */
    char expected_dir_h[255];
    sprintf(expected_dir_h, "%s%s%s", CACHE_TEST_TMP "/xdg-cache-home/mesa/",
-           get_arch_bitness_str(), "/make_check/test");
+           get_arch_bitness_str(), "/test");
 
    mkdir(CACHE_TEST_TMP, 0755);
    cache = disk_cache_create("test", "make_check");
    expect_non_null(cache, "disk_cache_create with XDG_CACHE_HOME set");
 
-   check_timestamp_and_gpu_id_directories_created(expected_dir_h);
+   check_directories_created(expected_dir_h);
 
    disk_cache_destroy(cache);
 
@@ -205,13 +205,13 @@ test_disk_cache_create(void)
 
    sprintf(expected_dir_h, "%s%s%s", CACHE_TEST_TMP
            "/mesa-glsl-cache-dir/mesa/", get_arch_bitness_str(),
-           "/make_check/test");
+           "/test");
 
    mkdir(CACHE_TEST_TMP, 0755);
    cache = disk_cache_create("test", "make_check");
    expect_non_null(cache, "disk_cache_create with MESA_GLSL_CACHE_DIR set");
 
-   check_timestamp_and_gpu_id_directories_created(expected_dir_h);
+   check_directories_created(expected_dir_h);
 
    disk_cache_destroy(cache);
 }
index 17a6b5e0c4f75bf0ac91815453f8f8894b8f9eb1..a7f18fcc1f2e620f999ceeb52263b44d2d82d52c 100644 (file)
@@ -82,6 +82,10 @@ struct disk_cache {
 
    /* Maximum size of all cached objects (in bytes). */
    uint64_t max_size;
+
+   /* Driver cache keys. */
+   uint8_t *driver_keys_blob;
+   size_t driver_keys_blob_size;
 };
 
 struct disk_cache_put_job {
@@ -158,45 +162,8 @@ concatenate_and_mkdir(void *ctx, const char *path, const char *name)
       return NULL;
 }
 
-static int
-remove_dir(const char *fpath, const struct stat *sb,
-           int typeflag, struct FTW *ftwbuf)
-{
-   if (S_ISREG(sb->st_mode))
-      unlink(fpath);
-   else if (S_ISDIR(sb->st_mode))
-      rmdir(fpath);
-
-   return 0;
-}
-
-static void
-remove_old_cache_directories(void *mem_ctx, const char *path,
-                             const char *timestamp)
-{
-   DIR *dir = opendir(path);
-
-   struct dirent* d_entry;
-   while((d_entry = readdir(dir)) != NULL)
-   {
-      char *full_path =
-         ralloc_asprintf(mem_ctx, "%s/%s", path, d_entry->d_name);
-
-      struct stat sb;
-      if (stat(full_path, &sb) == 0 && S_ISDIR(sb.st_mode) &&
-          strcmp(d_entry->d_name, timestamp) != 0 &&
-          strcmp(d_entry->d_name, "..") != 0 &&
-          strcmp(d_entry->d_name, ".") != 0) {
-         nftw(full_path, remove_dir, 20, FTW_DEPTH);
-      }
-   }
-
-   closedir(dir);
-}
-
 static char *
-create_mesa_cache_dir(void *mem_ctx, const char *path, const char *timestamp,
-                      const char *gpu_name)
+create_mesa_cache_dir(void *mem_ctx, const char *path, const char *gpu_name)
 {
    char *new_path = concatenate_and_mkdir(mem_ctx, path, "mesa");
    if (new_path == NULL)
@@ -211,13 +178,6 @@ create_mesa_cache_dir(void *mem_ctx, const char *path, const char *timestamp,
    if (new_path == NULL)
       return NULL;
 
-   /* Remove cache directories for old Mesa versions */
-   remove_old_cache_directories(mem_ctx, new_path, timestamp);
-
-   new_path = concatenate_and_mkdir(mem_ctx, new_path, timestamp);
-   if (new_path == NULL)
-      return NULL;
-
    new_path = concatenate_and_mkdir(mem_ctx, new_path, gpu_name);
    if (new_path == NULL)
       return NULL;
@@ -261,8 +221,7 @@ disk_cache_create(const char *gpu_name, const char *timestamp)
       if (mkdir_if_needed(path) == -1)
          goto fail;
 
-      path = create_mesa_cache_dir(local, path, timestamp,
-                                   gpu_name);
+      path = create_mesa_cache_dir(local, path, gpu_name);
       if (path == NULL)
          goto fail;
    }
@@ -274,8 +233,7 @@ disk_cache_create(const char *gpu_name, const char *timestamp)
          if (mkdir_if_needed(xdg_cache_home) == -1)
             goto fail;
 
-         path = create_mesa_cache_dir(local, xdg_cache_home, timestamp,
-                                      gpu_name);
+         path = create_mesa_cache_dir(local, xdg_cache_home, gpu_name);
          if (path == NULL)
             goto fail;
       }
@@ -311,7 +269,7 @@ disk_cache_create(const char *gpu_name, const char *timestamp)
       if (path == NULL)
          goto fail;
 
-      path = create_mesa_cache_dir(local, path, timestamp, gpu_name);
+      path = create_mesa_cache_dir(local, path, gpu_name);
       if (path == NULL)
          goto fail;
    }
@@ -412,6 +370,17 @@ disk_cache_create(const char *gpu_name, const char *timestamp)
     */
    util_queue_init(&cache->cache_queue, "disk_cache", 32, 1);
 
+   /* Create driver id keys */
+   size_t ts_size = strlen(timestamp) + 1;
+   cache->driver_keys_blob_size = ts_size;
+
+   cache->driver_keys_blob =
+      ralloc_size(cache, cache->driver_keys_blob_size);
+   if (!cache->driver_keys_blob)
+      goto fail;
+
+   memcpy(cache->driver_keys_blob, timestamp, ts_size);
+
    /* Seed our rand function */
    s_rand_xorshift128plus(cache->seed_xorshift128plus, true);
 
@@ -1078,7 +1047,13 @@ void
 disk_cache_compute_key(struct disk_cache *cache, const void *data, size_t size,
                        cache_key key)
 {
-   _mesa_sha1_compute(data, size, key);
+   struct mesa_sha1 ctx;
+
+   _mesa_sha1_init(&ctx);
+   _mesa_sha1_update(&ctx, cache->driver_keys_blob,
+                     cache->driver_keys_blob_size);
+   _mesa_sha1_update(&ctx, data, size);
+   _mesa_sha1_final(&ctx, key);
 }
 
 #endif /* ENABLE_SHADER_CACHE */