From: Stefan Dösinger stefan@codeweavers.com
Why is this in the cache and not the caller? To allow for future improvements, e.g. reader-writer locks, that allow for simultaneous reads while iterating over the cache.
Why trylock? If we try to add a new pipeline to the cache while iterating over existing pipelines during startup, it is better to discard that new pipeline than block until after all pipelines are loaded. --- libs/vkd3d/cache.c | 14 +++++++++++--- libs/vkd3d/vkd3d_private.h | 11 +++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d/cache.c b/libs/vkd3d/cache.c index 04126c2f0..c7f543a64 100644 --- a/libs/vkd3d/cache.c +++ b/libs/vkd3d/cache.c @@ -49,6 +49,7 @@ struct vkd3d_shader_cache struct vkd3d_shader_cache_desc desc; struct list cache_list_entry;
+ struct vkd3d_mutex lock; struct rb_tree tree;
char name[1]; @@ -133,6 +134,7 @@ int vkd3d_shader_cache_open(const char *name, object->desc = *desc; memcpy(object->name, name, size); rb_init(&object->tree, vkd3d_shader_cache_compare_key); + vkd3d_mutex_init(&object->lock);
list_add_head(&cache_list, &object->cache_list_entry); vkd3d_mutex_unlock(&cache_list_mutex); @@ -160,6 +162,7 @@ void vkd3d_shader_cache_close(struct vkd3d_shader_cache *cache) vkd3d_mutex_unlock(&cache_list_mutex);
rb_destroy(&cache->tree, vkd3d_shader_cache_clear, NULL); + vkd3d_mutex_destroy(&cache->lock);
vkd3d_free(cache); } @@ -193,13 +196,18 @@ static uint64_t hash_key(const void *key, size_t size)
static bool vkd3d_shader_cache_trylock(struct vkd3d_shader_cache *cache) { - /* Not yet implemented. */ - return true; + if (cache->desc.flags & (VKD3D_SHADER_CACHE_FLAGS_NO_SERIALIZE | VKD3D_SHADER_CACHE_FLAGS_READ_ONLY)) + return true; + + return vkd3d_mutex_trylock(&cache->lock); }
static void vkd3d_shader_cache_unlock(struct vkd3d_shader_cache *cache) { - /* Not yet implemented. */ + if (cache->desc.flags & (VKD3D_SHADER_CACHE_FLAGS_NO_SERIALIZE | VKD3D_SHADER_CACHE_FLAGS_READ_ONLY)) + return; + + vkd3d_mutex_unlock(&cache->lock); }
int vkd3d_shader_cache_put(struct vkd3d_shader_cache *cache, diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 71945ea18..bbe8fa72c 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -221,6 +221,11 @@ static inline void vkd3d_mutex_lock(struct vkd3d_mutex *lock) EnterCriticalSection(&lock->lock); }
+static inline bool vkd3d_mutex_trylock(struct vkd3d_mutex *lock) +{ + return TryEnterCriticalSection(&lock->lock); +} + static inline void vkd3d_mutex_unlock(struct vkd3d_mutex *lock) { LeaveCriticalSection(&lock->lock); @@ -325,6 +330,12 @@ static inline void vkd3d_mutex_lock(struct vkd3d_mutex *lock) ERR("Could not lock the mutex, error %d.\n", ret); }
+static inline bool vkd3d_mutex_trylock(struct vkd3d_mutex *lock) +{ + /* FIXME: Untested. */ + return !pthread_mutex_trylock(&lock->lock); +} + static inline void vkd3d_mutex_unlock(struct vkd3d_mutex *lock) { int ret;