[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