From: Stefan Dösinger <stefan(a)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; -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/541