[Mesa-dev] [PATCH 4/5] util/disk_cache: actually enforce cache size

Timothy Arceri tarceri at itsqueeze.com
Tue Mar 14 02:08:11 UTC 2017


From: Alan Swanson <reiver at improbability.net>

Currently only a one in one out eviction so if at max_size and
cache files were to constantly increase in size then so would the
cache. Restrict to limit of 8 evictions per new cache entry.

V2: (Timothy Arceri) fix make check tests
---
 src/compiler/glsl/tests/cache_test.c | 22 +++++++++++++++++++---
 src/util/disk_cache.c                |  6 +++++-
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/compiler/glsl/tests/cache_test.c b/src/compiler/glsl/tests/cache_test.c
index 10505d4..5ad438c 100644
--- a/src/compiler/glsl/tests/cache_test.c
+++ b/src/compiler/glsl/tests/cache_test.c
@@ -345,30 +345,38 @@ test_put_and_get(void)
     * finish.
     */
    wait_until_file_written(cache, one_KB_key);
 
    result = disk_cache_get(cache, one_KB_key, &size);
    expect_non_null(result, "3rd disk_cache_get of existing item (pointer)");
    expect_equal(size, 1024, "3rd disk_cache_get of existing item (size)");
 
    free(result);
 
-   /* Ensure eviction happened by checking that only one of the two
-    * previously-added items can still be fetched.
+   /* Ensure eviction happened by checking that both of the previous
+    * cache itesm were evicted.
     */
+   bool contains_1KB_file = false;
    count = 0;
    if (does_cache_contain(cache, blob_key))
        count++;
 
    if (does_cache_contain(cache, string_key))
        count++;
 
+   if (does_cache_contain(cache, one_KB_key)) {
+      count++;
+      contains_1KB_file = true;
+   }
+
+   expect_true(contains_1KB_file,
+               "disk_cache_put eviction last file == MAX_SIZE (1KB)");
    expect_equal(count, 1, "disk_cache_put eviction with MAX_SIZE=1K");
 
    /* Now increase the size to 1M, add back both items, and ensure all
     * three that have been added are available via disk_cache_get.
     */
    disk_cache_destroy(cache);
 
    setenv("MESA_GLSL_CACHE_MAX_SIZE", "1M", 1);
    cache = disk_cache_create("test", "make_check");
 
@@ -399,31 +407,39 @@ test_put_and_get(void)
    _mesa_sha1_compute(one_MB, 1024 * 1024, one_MB_key);
    one_MB_key[0] = blob_key_byte_zero;;
 
    disk_cache_put(cache, one_MB_key, one_MB, 1024 * 1024, one_MB);
 
    /* disk_cache_put() hands things off to a thread give it some time to
     * finish.
     */
    wait_until_file_written(cache, one_MB_key);
 
+   bool contains_1MB_file = false;
    count = 0;
    if (does_cache_contain(cache, blob_key))
        count++;
 
    if (does_cache_contain(cache, string_key))
        count++;
 
    if (does_cache_contain(cache, one_KB_key))
        count++;
 
-   expect_equal(count, 2, "eviction after overflow with MAX_SIZE=1M");
+   if (does_cache_contain(cache, one_MB_key)) {
+      count++;
+      contains_1MB_file = true;
+   }
+
+   expect_true(contains_1MB_file,
+               "disk_cache_put eviction last file == MAX_SIZE (1MB)");
+   expect_equal(count, 1, "eviction after overflow with MAX_SIZE=1M");
 
    disk_cache_destroy(cache);
 }
 
 static void
 test_put_key_and_get_key(void)
 {
    struct disk_cache *cache;
    bool result;
 
diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c
index 2ab236a..7fc35f1 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -801,20 +801,21 @@ struct cache_entry_file_data {
    uint32_t crc32;
    uint32_t uncompressed_size;
 };
 
 static void
 cache_put(void *job, int thread_index)
 {
    assert(job);
 
    int fd = -1, fd_final = -1, err, ret;
+   unsigned i = 0;
    size_t len;
    char *filename = NULL, *filename_tmp = NULL;
    struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *) job;
 
    filename = get_cache_file(dc_job->cache, dc_job->key);
    if (filename == NULL)
       goto done;
 
    /* Write to a temporary file to allow for an atomic rename to the
     * final destination filename, (to prevent any readers from seeing
@@ -856,22 +857,25 @@ cache_put(void *job, int thread_index)
    if (fd_final != -1)
       goto done;
 
    /* OK, we're now on the hook to write out a file that we know is
     * not in the cache, and is also not being written out to the cache
     * by some other process.
     *
     * Before we do that, if the cache is too large, evict something
     * else first.
     */
-   if (*dc_job->cache->size + dc_job->size > dc_job->cache->max_size)
+   while ((*dc_job->cache->size + dc_job->size > dc_job->cache->max_size) &&
+          i < 8) {
       evict_lru_item(dc_job->cache);
+      i++;
+   }
 
    /* Create CRC of the data and store at the start of the file. We will
     * read this when restoring the cache and use it to check for corruption.
     */
    struct cache_entry_file_data cf_data;
    cf_data.crc32 = util_hash_crc32(dc_job->data, dc_job->size);
    cf_data.uncompressed_size = dc_job->size;
 
    size_t cf_data_size = sizeof(cf_data);
    for (len = 0; len < cf_data_size; len += ret) {
-- 
2.9.3



More information about the mesa-dev mailing list