diff options
-rw-r--r-- | src/compiler/glsl/tests/cache_test.c | 47 | ||||
-rw-r--r-- | src/util/disk_cache.c | 41 |
2 files changed, 75 insertions, 13 deletions
diff --git a/src/compiler/glsl/tests/cache_test.c b/src/compiler/glsl/tests/cache_test.c index 7a1ff0ac5bc..61ee630395a 100644 --- a/src/compiler/glsl/tests/cache_test.c +++ b/src/compiler/glsl/tests/cache_test.c @@ -32,6 +32,7 @@ #include <stdarg.h> #include <inttypes.h> #include <limits.h> +#include <time.h> #include <unistd.h> #include "util/mesa-sha1.h" @@ -231,6 +232,26 @@ does_cache_contain(struct disk_cache *cache, cache_key key) } static void +wait_until_file_written(struct disk_cache *cache, cache_key key) +{ + struct timespec req; + struct timespec rem; + + /* Set 100ms delay */ + req.tv_sec = 0; + req.tv_nsec = 100000000; + + unsigned retries = 0; + while (retries++ < 20) { + if (does_cache_contain(cache, key)) { + break; + } + + nanosleep(&req, &rem); + } +} + +static void test_put_and_get(void) { struct disk_cache *cache; @@ -260,6 +281,11 @@ test_put_and_get(void) /* Simple test of put and get. */ disk_cache_put(cache, blob_key, blob, sizeof(blob)); + /* disk_cache_put() hands things off to a thread give it some time to + * finish. + */ + wait_until_file_written(cache, blob_key); + result = disk_cache_get(cache, blob_key, &size); expect_equal_str(blob, result, "disk_cache_get of existing item (pointer)"); expect_equal(size, sizeof(blob), "disk_cache_get of existing item (size)"); @@ -270,6 +296,11 @@ test_put_and_get(void) _mesa_sha1_compute(string, sizeof(string), string_key); disk_cache_put(cache, string_key, string, sizeof(string)); + /* disk_cache_put() hands things off to a thread give it some time to + * finish. + */ + wait_until_file_written(cache, string_key); + result = disk_cache_get(cache, string_key, &size); expect_equal_str(result, string, "2nd disk_cache_get of existing item (pointer)"); expect_equal(size, sizeof(string), "2nd disk_cache_get of existing item (size)"); @@ -308,6 +339,11 @@ test_put_and_get(void) free(one_KB); + /* disk_cache_put() hands things off to a thread give it some time to + * 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)"); @@ -337,6 +373,12 @@ test_put_and_get(void) disk_cache_put(cache, blob_key, blob, sizeof(blob)); disk_cache_put(cache, string_key, string, sizeof(string)); + /* disk_cache_put() hands things off to a thread give it some time to + * finish. + */ + wait_until_file_written(cache, blob_key); + wait_until_file_written(cache, string_key); + count = 0; if (does_cache_contain(cache, blob_key)) count++; @@ -359,6 +401,11 @@ test_put_and_get(void) free(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); + count = 0; if (does_cache_contain(cache, blob_key)) count++; diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c index ae2861d656e..2d37f45e338 100644 --- a/src/util/disk_cache.c +++ b/src/util/disk_cache.c @@ -780,17 +780,17 @@ struct cache_entry_file_data { uint32_t uncompressed_size; }; -void -disk_cache_put(struct disk_cache *cache, - const cache_key key, - const void *data, - size_t size) +static void +cache_put(void *job, int thread_index) { + assert(job); + int fd = -1, fd_final = -1, err, ret; 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(cache, key); + filename = get_cache_file(dc_job->cache, dc_job->key); if (filename == NULL) goto done; @@ -808,7 +808,7 @@ disk_cache_put(struct disk_cache *cache, if (errno != ENOENT) goto done; - make_cache_file_directory(cache, key); + make_cache_file_directory(dc_job->cache, dc_job->key); fd = open(filename_tmp, O_WRONLY | O_CLOEXEC | O_CREAT, 0644); if (fd == -1) @@ -841,15 +841,15 @@ disk_cache_put(struct disk_cache *cache, * Before we do that, if the cache is too large, evict something * else first. */ - if (*cache->size + size > cache->max_size) - evict_random_item(cache); + if (*dc_job->cache->size + dc_job->size > dc_job->cache->max_size) + evict_random_item(dc_job->cache); /* 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(data, size); - cf_data.uncompressed_size = size; + 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) { @@ -864,7 +864,8 @@ disk_cache_put(struct disk_cache *cache, * rename them atomically to the destination filename, and also * perform an atomic increment of the total cache size. */ - size_t file_size = deflate_and_write_to_disk(data, size, fd, filename_tmp); + size_t file_size = deflate_and_write_to_disk(dc_job->data, dc_job->size, + fd, filename_tmp); if (file_size == 0) { unlink(filename_tmp); goto done; @@ -872,7 +873,7 @@ disk_cache_put(struct disk_cache *cache, rename(filename_tmp, filename); file_size += cf_data_size; - p_atomic_add(cache->size, file_size); + p_atomic_add(dc_job->cache->size, file_size); done: if (fd_final != -1) @@ -888,6 +889,20 @@ disk_cache_put(struct disk_cache *cache, free(filename); } +void +disk_cache_put(struct disk_cache *cache, const cache_key key, + const void *data, size_t size) +{ + struct disk_cache_put_job *dc_job = + create_put_job(cache, key, data, size); + + if (dc_job) { + util_queue_fence_init(&dc_job->fence); + util_queue_add_job(&cache->cache_queue, dc_job, &dc_job->fence, + cache_put, destroy_put_job); + } +} + /** * Decompresses cache entry, returns true if successful. */ |