From 018532410aef593959b4a7b7405d551fb3a55281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Vital?= Date: Wed, 9 Aug 2023 15:43:42 +0200 Subject: [PATCH 1/2] [image] ImageCache: add peeking mutex to allow other threads to read cache content while load operation --- src/aliceVision/image/ImageCache.hpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/aliceVision/image/ImageCache.hpp b/src/aliceVision/image/ImageCache.hpp index 98fd6c7d01..fc5c782575 100644 --- a/src/aliceVision/image/ImageCache.hpp +++ b/src/aliceVision/image/ImageCache.hpp @@ -263,16 +263,19 @@ class ImageCache /** * @brief Load a new image corresponding to the given key and add it as a new entry in the cache. * @param[in] key the key used to identify the entry in the cache + * @param[in] lockPeek lock on the peeking mutex, will be released */ template - void load(const CacheKey& key); + void load(const CacheKey& key, std::unique_lock& lockPeek); CacheInfo _info; ImageReadOptions _options; std::unordered_map _imagePtrs; /// ordered from LRU (Least Recently Used) to MRU (Most Recently Used) std::list _keys; - mutable std::mutex _mutex; + + mutable std::mutex _mutexGeneral; + mutable std::mutex _mutexPeek; }; @@ -289,7 +292,7 @@ std::shared_ptr> ImageCache::get(const std::string& filename, int do << "request was made with downscale level " << downscaleLevel); } - const std::lock_guard lock(_mutex); + std::unique_lock lockPeek(_mutexPeek); ALICEVISION_LOG_TRACE("[image] ImageCache: reading " << filename << " with downscale level " << downscaleLevel @@ -320,6 +323,8 @@ std::shared_ptr> ImageCache::get(const std::string& filename, int do } } + const std::lock_guard lockGeneral(_mutexGeneral); + // retrieve image size int width, height; readImageSize(filename, width, height); @@ -328,7 +333,7 @@ std::shared_ptr> ImageCache::get(const std::string& filename, int do // add image to cache if it fits in capacity if (memSize + _info.contentSize <= _info.capacity) { - load(keyReq); + load(keyReq, lockPeek); ALICEVISION_LOG_TRACE("[image] ImageCache: " << toString()); return _imagePtrs.at(keyReq).get(); @@ -355,7 +360,7 @@ std::shared_ptr> ImageCache::get(const std::string& filename, int do _info.nbRemoveUnused++; - load(keyReq); + load(keyReq, lockPeek); ALICEVISION_LOG_TRACE("[image] ImageCache: " << toString()); return _imagePtrs.at(keyReq).get(); @@ -394,7 +399,7 @@ std::shared_ptr> ImageCache::get(const std::string& filename, int do // add image to cache if it fits in maxSize if (memSize + _info.contentSize <= _info.maxSize) { - load(keyReq); + load(keyReq, lockPeek); ALICEVISION_LOG_TRACE("[image] ImageCache: " << toString()); return _imagePtrs.at(keyReq).get(); @@ -406,8 +411,10 @@ std::shared_ptr> ImageCache::get(const std::string& filename, int do } template -void ImageCache::load(const CacheKey& key) +void ImageCache::load(const CacheKey& key, std::unique_lock& lockPeek) { + lockPeek.unlock(); + auto img = std::make_shared>(); // load image from disk @@ -419,6 +426,8 @@ void ImageCache::load(const CacheKey& key) imageAlgo::resizeImage(key.downscaleLevel, *img); } + lockPeek.lock(); + _info.nbLoadFromDisk++; // create wrapper around shared pointer @@ -442,7 +451,7 @@ bool ImageCache::contains(const std::string& filename, int downscaleLevel) const << "request was made with downscale level " << downscaleLevel); } - const std::lock_guard lock(_mutex); + const std::lock_guard lockPeek(_mutexPeek); using TInfo = ColorTypeInfo; From d02eb4cd64f81a616b13566eec1677f59482e844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Vital?= Date: Wed, 9 Aug 2023 16:06:25 +0200 Subject: [PATCH 2/2] [image] ImageCache: use scoped_lock instead of lock_guard --- src/aliceVision/image/ImageCache.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aliceVision/image/ImageCache.hpp b/src/aliceVision/image/ImageCache.hpp index fc5c782575..e1ca7a319f 100644 --- a/src/aliceVision/image/ImageCache.hpp +++ b/src/aliceVision/image/ImageCache.hpp @@ -323,7 +323,7 @@ std::shared_ptr> ImageCache::get(const std::string& filename, int do } } - const std::lock_guard lockGeneral(_mutexGeneral); + const std::scoped_lock lockGeneral(_mutexGeneral); // retrieve image size int width, height; @@ -451,7 +451,7 @@ bool ImageCache::contains(const std::string& filename, int downscaleLevel) const << "request was made with downscale level " << downscaleLevel); } - const std::lock_guard lockPeek(_mutexPeek); + const std::scoped_lock lockPeek(_mutexPeek); using TInfo = ColorTypeInfo;