summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/tests/cache_test.c47
-rw-r--r--src/util/disk_cache.c41
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.
*/