[Mesa-dev] [PATCH 4/8] util/disk_cache: make disk_cache_put() compatible with u_queue
Timothy Arceri
tarceri at itsqueeze.com
Fri Mar 10 02:28:51 UTC 2017
---
src/compiler/glsl/shader_cache.cpp | 5 ++++-
src/compiler/glsl/tests/cache_test.c | 29 ++++++++++++++++++++-----
src/gallium/drivers/radeonsi/si_state_shaders.c | 9 ++++++--
src/mesa/state_tracker/st_shader_cache.c | 5 ++++-
src/util/disk_cache.c | 27 +++++++++++++----------
src/util/disk_cache.h | 7 ++----
6 files changed, 55 insertions(+), 27 deletions(-)
diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp
index 6e2c527..1865e96 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -1269,21 +1269,24 @@ shader_cache_write_program_metadata(struct gl_context *ctx,
char sha1_buf[41];
for (unsigned i = 0; i < prog->NumShaders; i++) {
disk_cache_put_key(cache, prog->Shaders[i]->sha1);
if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
fprintf(stderr, "marking shader: %s\n",
_mesa_sha1_format(sha1_buf, prog->Shaders[i]->sha1));
}
}
- disk_cache_put(cache, prog->data->sha1, metadata->data, metadata->size);
+ struct disk_cache_put_job *dc_job =
+ disk_cache_create_put_job(cache, prog->data->sha1, metadata->data,
+ metadata->size, metadata);
+ disk_cache_put(dc_job, 0);
free(metadata);
if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
fprintf(stderr, "putting program metadata in cache: %s\n",
_mesa_sha1_format(sha1_buf, prog->data->sha1));
}
}
bool
diff --git a/src/compiler/glsl/tests/cache_test.c b/src/compiler/glsl/tests/cache_test.c
index 7a1ff0a..a2b33f7 100644
--- a/src/compiler/glsl/tests/cache_test.c
+++ b/src/compiler/glsl/tests/cache_test.c
@@ -251,31 +251,37 @@ test_put_and_get(void)
cache = disk_cache_create("test", "make_check");
_mesa_sha1_compute(blob, sizeof(blob), blob_key);
/* Ensure that disk_cache_get returns nothing before anything is added. */
result = disk_cache_get(cache, blob_key, &size);
expect_null(result, "disk_cache_get with non-existent item (pointer)");
expect_equal(size, 0, "disk_cache_get with non-existent item (size)");
/* Simple test of put and get. */
- disk_cache_put(cache, blob_key, blob, sizeof(blob));
+ struct disk_cache_put_job *dc_job =
+ disk_cache_create_put_job(cache, blob_key, blob, sizeof(blob), NULL);
+ disk_cache_put(dc_job, 0);
+ free(dc_job);
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)");
free(result);
/* Test put and get of a second item. */
_mesa_sha1_compute(string, sizeof(string), string_key);
- disk_cache_put(cache, string_key, string, sizeof(string));
+ dc_job = disk_cache_create_put_job(cache, string_key, string,
+ sizeof(string), NULL);
+ disk_cache_put(dc_job, 0);
+ free(dc_job);
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)");
free(result);
/* Set the cache size to 1KB and add a 1KB item to force an eviction. */
disk_cache_destroy(cache);
@@ -297,21 +303,23 @@ test_put_and_get(void)
* That's actually expected given how the eviction code is
* implemented, (which expects to only evict once things are more
* interestingly full than that).
*
* For this test, we force this signature to land in the same
* directory as the original blob first written to the cache.
*/
_mesa_sha1_compute(one_KB, 1024, one_KB_key);
one_KB_key[0] = blob_key_byte_zero;
- disk_cache_put(cache, one_KB_key, one_KB, 1024);
+ dc_job = disk_cache_create_put_job(cache, one_KB_key, one_KB, 1024, NULL);
+ disk_cache_put(dc_job, 0);
+ free(dc_job);
free(one_KB);
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
@@ -327,42 +335,51 @@ test_put_and_get(void)
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");
- disk_cache_put(cache, blob_key, blob, sizeof(blob));
- disk_cache_put(cache, string_key, string, sizeof(string));
+ dc_job = disk_cache_create_put_job(cache, blob_key, blob, sizeof(blob),
+ NULL);
+ disk_cache_put(dc_job, 0);
+ free(dc_job);
+ dc_job = disk_cache_create_put_job(cache, string_key, string,
+ sizeof(string), NULL);
+ disk_cache_put(dc_job, 0);
+ free(dc_job);
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, 3, "no eviction before overflow with MAX_SIZE=1M");
/* Finally, check eviction again after adding an object of size 1M. */
one_MB = calloc(1024, 1024);
_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);
+ dc_job = disk_cache_create_put_job(cache, one_MB_key, one_MB, 1024 * 1024,
+ NULL);
+ disk_cache_put(dc_job, 0);
+ free(dc_job);
free(one_MB);
count = 0;
if (does_cache_contain(cache, blob_key))
count++;
if (does_cache_contain(cache, string_key))
count++;
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 9cde0aa..343cb83 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -201,22 +201,27 @@ static bool si_shader_cache_insert_shader(struct si_screen *sscreen,
return false;
if (_mesa_hash_table_insert(sscreen->shader_cache, tgsi_binary,
hw_binary) == NULL) {
FREE(hw_binary);
return false;
}
if (sscreen->b.disk_shader_cache && insert_into_disk_cache) {
_mesa_sha1_compute(tgsi_binary, *((uint32_t *)tgsi_binary), key);
- disk_cache_put(sscreen->b.disk_shader_cache, key, hw_binary,
- *((uint32_t *) hw_binary));
+
+ struct disk_cache_put_job *dc_job =
+ disk_cache_create_put_job(sscreen->b.disk_shader_cache,
+ key, hw_binary,
+ *((uint32_t *) hw_binary),
+ NULL);
+ disk_cache_put(dc_job, 0);
}
return true;
}
static bool si_shader_cache_load_shader(struct si_screen *sscreen,
void *tgsi_binary,
struct si_shader *shader)
{
struct hash_entry *entry =
diff --git a/src/mesa/state_tracker/st_shader_cache.c b/src/mesa/state_tracker/st_shader_cache.c
index 4383194..040fbc1 100644
--- a/src/mesa/state_tracker/st_shader_cache.c
+++ b/src/mesa/state_tracker/st_shader_cache.c
@@ -40,21 +40,24 @@ write_stream_out_to_cache(struct blob *blob,
static void
write_tgsi_to_cache(struct blob *blob, struct pipe_shader_state *tgsi,
struct st_context *st, unsigned char *sha1,
unsigned num_tokens)
{
blob_write_uint32(blob, num_tokens);
blob_write_bytes(blob, tgsi->tokens,
num_tokens * sizeof(struct tgsi_token));
- disk_cache_put(st->ctx->Cache, sha1, blob->data, blob->size);
+ struct disk_cache_put_job *dc_job =
+ disk_cache_create_put_job(st->ctx->Cache, sha1, blob->data, blob->size,
+ blob);
+ disk_cache_put(dc_job, 0);
}
/**
* Store tgsi and any other required state in on-disk shader cache.
*/
void
st_store_tgsi_in_disk_cache(struct st_context *st, struct gl_program *prog,
struct pipe_shader_state *out_state,
unsigned num_tokens)
{
diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c
index 37b3576..e0b540c 100644
--- a/src/util/disk_cache.c
+++ b/src/util/disk_cache.c
@@ -761,48 +761,50 @@ disk_cache_destroy_put_job(void *job, int thread_index)
free(dc_job);
}
}
struct cache_entry_file_data {
uint32_t crc32;
uint32_t uncompressed_size;
};
void
-disk_cache_put(struct disk_cache *cache,
- const cache_key key,
- const void *data,
- size_t size)
+disk_cache_put(void *job, int thread_index)
{
+ if (!job)
+ return;
+
+ struct disk_cache_put_job *dc_job = (struct disk_cache_put_job *) job;
+
int fd = -1, fd_final = -1, err, ret;
size_t len;
char *filename = NULL, *filename_tmp = NULL;
- filename = get_cache_file(cache, key);
+ 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
* a partially written file).
*/
if (asprintf(&filename_tmp, "%s.tmp", filename) == -1)
goto done;
fd = open(filename_tmp, O_WRONLY | O_CLOEXEC | O_CREAT, 0644);
/* Make the two-character subdirectory within the cache as needed. */
if (fd == -1) {
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)
goto done;
}
/* With the temporary file open, we take an exclusive flock on
* it. If the flock fails, then another process still has the file
* open with the flock held. So just let that file be responsible
* for writing the file.
@@ -821,52 +823,53 @@ disk_cache_put(struct disk_cache *cache,
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 (*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) {
ret = write(fd, ((uint8_t *) &cf_data) + len, cf_data_size - len);
if (ret == -1) {
unlink(filename_tmp);
goto done;
}
}
/* Now, finally, write out the contents to the temporary file, then
* 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;
}
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)
close(fd_final);
/* This close finally releases the flock, (now that the final dile
* has been renamed into place and the size has been added).
*/
if (fd != -1)
close(fd);
if (filename_tmp)
diff --git a/src/util/disk_cache.h b/src/util/disk_cache.h
index 136140e..19eb1a9 100644
--- a/src/util/disk_cache.h
+++ b/src/util/disk_cache.h
@@ -156,22 +156,21 @@ disk_cache_destroy_put_job(void *job, int thread_index);
/**
* Store an item in the cache under the name \key.
*
* The item can be retrieved later with disk_cache_get(), (unless the item has
* been evicted in the interim).
*
* Any call to disk_cache_put() may cause an existing, random item to be
* evicted from the cache.
*/
void
-disk_cache_put(struct disk_cache *cache, const cache_key key,
- const void *data, size_t size);
+disk_cache_put(void *job, int thread_index);
/**
* Retrieve an item previously stored in the cache with the name <key>.
*
* The item must have been previously stored with a call to disk_cache_put().
*
* If \size is non-NULL, then, on successful return, it will be set to the
* size of the object.
*
* \return A pointer to the stored object if found. NULL if the object
@@ -225,23 +224,21 @@ disk_cache_create_put_job(struct disk_cache *cache, const cache_key key,
const void *data, size_t size, void *mem)
{
return NULL;
}
static inline void
disk_cache_destroy_put_job(void *job, int thread_index) {
return;
}
-static inline void
-disk_cache_put(struct disk_cache *cache, const cache_key key,
- const void *data, size_t size)
+disk_cache_put(void *job, int thread_index)
{
return;
}
static inline void
disk_cache_remove(struct disk_cache *cache, const cache_key key)
{
return;
}
--
2.9.3
More information about the mesa-dev
mailing list