From b7a1325c3c9e6ba2ad7ad7bfd071aef2dfbab6be Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 7 May 2025 04:53:16 +0200 Subject: [PATCH] BLI: use blender::Mutex by default which wraps tbb::mutex This patch adds a new `BLI_mutex.hh` header which adds `blender::Mutex` as alias for either `tbb::mutex` or `std::mutex` depending on whether TBB is enabled. Description copied from the patch: ``` /** * blender::Mutex should be used as the default mutex in Blender. It implements a subset of the API * of std::mutex but has overall better guaranteed properties. It can be used with RAII helpers * like std::lock_guard. However, it is not compatible with e.g. std::condition_variable. So one * still has to use std::mutex for that case. * * The mutex provided by TBB has these properties: * - It's as fast as a spin-lock in the non-contended case, i.e. when no other thread is trying to * lock the mutex at the same time. * - In the contended case, it spins a couple of times but then blocks to avoid draining system * resources by spinning for a long time. * - It's only 1 byte large, compared to e.g. 40 bytes when using the std::mutex of GCC. This makes * it more feasible to have many smaller mutexes which can improve scalability of algorithms * compared to using fewer larger mutexes. Also it just reduces "memory slop" across Blender. * - It is *not* a fair mutex, i.e. it's not guaranteed that a thread will ever be able to lock the * mutex when there are always more than one threads that try to lock it. In the majority of * cases, using a fair mutex just causes extra overhead without any benefit. std::mutex is not * guaranteed to be fair either. */ ``` The performance benchmark suggests that the impact is negilible in almost all cases. The only benchmarks that show interesting behavior are the once testing foreach zones in Geometry Nodes. These tests are explicitly testing overhead, which I still have to reduce over time. So it's not unexpected that changing the mutex has an impact there. What's interesting is that on macos the performance improves a lot while on linux it gets worse. Since that overhead should eventually be removed almost entirely, I don't really consider that blocking. Links: * Documentation of different mutex flavors in TBB: https://www.intel.com/content/www/us/en/docs/onetbb/developer-guide-api-reference/2021-12/mutex-flavors.html * Older implementation of a similar mutex by me: https://archive.blender.org/developer/differential/0016/0016711/index.html * Interesting read regarding how a mutex can be this small: https://webkit.org/blog/6161/locking-in-webkit/ Pull Request: https://projects.blender.org/blender/blender/pulls/138370 --- .../blender/asset_system/AS_asset_library.hh | 4 +- source/blender/blenfont/intern/blf.cc | 3 +- .../blenfont/intern/blf_internal_types.hh | 4 +- .../BKE_bake_geometry_nodes_modifier.hh | 3 +- .../blenkernel/BKE_bake_items_serialize.hh | 5 +- source/blender/blenkernel/BKE_geometry_set.hh | 4 +- source/blender/blenkernel/BKE_mesh_types.hh | 6 +-- source/blender/blenkernel/BKE_node_runtime.hh | 6 +-- source/blender/blenkernel/BKE_volume_grid.hh | 4 +- source/blender/blenkernel/intern/cachefile.cc | 5 +- source/blender/blenkernel/intern/icons.cc | 4 +- source/blender/blenkernel/intern/instances.cc | 2 +- source/blender/blenkernel/intern/rigidbody.cc | 4 +- source/blender/blenkernel/intern/volume.cc | 5 +- .../intern/volume_grid_file_cache.cc | 2 +- source/blender/blenlib/BLI_cache_mutex.hh | 6 +-- source/blender/blenlib/BLI_concurrent_map.hh | 5 +- .../blenlib/BLI_enumerable_thread_specific.hh | 4 +- source/blender/blenlib/BLI_mutex.hh | 51 +++++++++++++++++++ source/blender/blenlib/CMakeLists.txt | 1 + source/blender/blenlib/intern/memory_cache.cc | 4 +- .../blender/blenlib/intern/mesh_intersect.cc | 4 +- source/blender/depsgraph/intern/depsgraph.hh | 4 +- .../depsgraph/intern/depsgraph_registry.cc | 11 ++-- .../draw/engines/eevee/eevee_lightcache.cc | 5 +- .../draw/engines/eevee/eevee_shader.hh | 4 +- source/blender/draw/intern/draw_attributes.cc | 2 +- source/blender/draw/intern/draw_attributes.hh | 7 +-- .../draw/intern/draw_cache_impl_curves.cc | 2 +- .../draw/intern/draw_cache_impl_pointcloud.cc | 2 +- .../intern/draw_cache_impl_subdivision.cc | 2 +- source/blender/draw/intern/draw_debug.hh | 3 +- .../intern/grease_pencil_edit.cc | 2 +- .../blender/editors/render/render_opengl.cc | 4 +- .../editors/sculpt_paint/sculpt_undo.cc | 2 +- .../blender/editors/space_clip/clip_editor.cc | 4 +- .../spreadsheet_data_source_geometry.hh | 2 +- .../intern/lazy_function_graph_executor.cc | 14 ++--- source/blender/gpu/intern/gpu_context.cc | 4 +- .../blender/gpu/intern/gpu_profile_report.hh | 4 +- .../imbuf/movie/intern/ffmpeg_swscale.cc | 3 +- source/blender/modifiers/intern/MOD_nodes.cc | 2 +- .../NOD_geometry_nodes_closure_location.hh | 4 +- .../nodes/geometry/nodes/node_geo_bake.cc | 2 +- .../nodes/node_geo_remove_attribute.cc | 2 +- .../intern/geometry_nodes_lazy_function.cc | 2 +- source/blender/render/intern/render_types.h | 5 +- source/blender/render/intern/tile_highlight.h | 5 +- .../blender/sequencer/intern/strip_lookup.cc | 4 +- .../sequencer/intern/thumbnail_cache.cc | 3 +- 50 files changed, 149 insertions(+), 97 deletions(-) create mode 100644 source/blender/blenlib/BLI_mutex.hh diff --git a/source/blender/asset_system/AS_asset_library.hh b/source/blender/asset_system/AS_asset_library.hh index 029466d76b9..60630151062 100644 --- a/source/blender/asset_system/AS_asset_library.hh +++ b/source/blender/asset_system/AS_asset_library.hh @@ -9,13 +9,13 @@ #pragma once #include -#include #include #include "AS_asset_catalog.hh" #include "DNA_asset_types.h" +#include "BLI_mutex.hh" #include "BLI_set.hh" #include "BLI_string_ref.hh" #include "BLI_vector.hh" @@ -82,7 +82,7 @@ class AssetLibrary { * within the catalog service may still happen without the mutex being locked. They should be * protected separately. */ std::unique_ptr catalog_service_; - std::mutex catalog_service_mutex_; + Mutex catalog_service_mutex_; std::optional import_method_; /** Assets owned by this library may be imported with a different method than set in diff --git a/source/blender/blenfont/intern/blf.cc b/source/blender/blenfont/intern/blf.cc index 30c6e7df307..a81fe3f2fbe 100644 --- a/source/blender/blenfont/intern/blf.cc +++ b/source/blender/blenfont/intern/blf.cc @@ -14,7 +14,6 @@ #include #include #include -#include #include @@ -49,7 +48,7 @@ FontBLF *global_font[BLF_MAX_FONT] = {nullptr}; int blf_mono_font = -1; int blf_mono_font_render = -1; -static std::mutex g_blf_load_mutex; +static blender::Mutex g_blf_load_mutex; static FontBLF *blf_get(int fontid) { diff --git a/source/blender/blenfont/intern/blf_internal_types.hh b/source/blender/blenfont/intern/blf_internal_types.hh index 9a0ea4ee297..47846cc2018 100644 --- a/source/blender/blenfont/intern/blf_internal_types.hh +++ b/source/blender/blenfont/intern/blf_internal_types.hh @@ -10,13 +10,13 @@ #include #include -#include #include "DNA_vec_types.h" #include "BLF_api.hh" #include "BLI_map.hh" +#include "BLI_mutex.hh" #include "BLI_vector.hh" #include "GPU_texture.hh" @@ -397,5 +397,5 @@ struct FontBLF { FontBufInfoBLF buf_info; /** Mutex lock for glyph cache. */ - std::mutex glyph_cache_mutex; + blender::Mutex glyph_cache_mutex; }; diff --git a/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh b/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh index 8fd97185d31..fafbe9f9c37 100644 --- a/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh +++ b/source/blender/blenkernel/BKE_bake_geometry_nodes_modifier.hh @@ -8,6 +8,7 @@ #pragma once +#include "BLI_mutex.hh" #include "BLI_sub_frame.hh" #include "BKE_bake_items.hh" @@ -98,7 +99,7 @@ struct BakeNodeCache { }; struct ModifierCache { - mutable std::mutex mutex; + mutable Mutex mutex; /** * Set of nested node IDs (see #bNestedNodeRef) that is expected to be baked in the next * evaluation. This is filled and cleared by the bake operator. diff --git a/source/blender/blenkernel/BKE_bake_items_serialize.hh b/source/blender/blenkernel/BKE_bake_items_serialize.hh index ca1a894336e..4f9b8aaec47 100644 --- a/source/blender/blenkernel/BKE_bake_items_serialize.hh +++ b/source/blender/blenkernel/BKE_bake_items_serialize.hh @@ -10,6 +10,7 @@ #include "BLI_fileops.hh" #include "BLI_function_ref.hh" +#include "BLI_mutex.hh" #include "BLI_serialize.hh" #include "BKE_bake_items.hh" @@ -141,7 +142,7 @@ class BlobReadSharing : NonCopyable, NonMovable { /** * Use a mutex so that #read_shared can be implemented in a thread-safe way. */ - mutable std::mutex mutex_; + mutable Mutex mutex_; /** * Map used to detect when some data has been previously loaded. This keeps strong * references to #ImplicitSharingInfo. @@ -166,7 +167,7 @@ class BlobReadSharing : NonCopyable, NonMovable { class DiskBlobReader : public BlobReader { private: const std::string blobs_dir_; - mutable std::mutex mutex_; + mutable Mutex mutex_; mutable Map> open_input_streams_; public: diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index 946770bd59a..1adb327730e 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -9,7 +9,6 @@ */ #include -#include #include "BLI_bounds_types.hh" #include "BLI_function_ref.hh" @@ -17,6 +16,7 @@ #include "BLI_map.hh" #include "BLI_math_vector_types.hh" #include "BLI_memory_counter_fwd.hh" +#include "BLI_mutex.hh" /* For #Map. */ #include "BKE_attribute.hh" @@ -605,7 +605,7 @@ class CurveComponent : public GeometryComponent { * even when the new curve data structure is used. */ mutable Curve *curve_for_render_ = nullptr; - mutable std::mutex curve_for_render_mutex_; + mutable Mutex curve_for_render_mutex_; public: CurveComponent(); diff --git a/source/blender/blenkernel/BKE_mesh_types.hh b/source/blender/blenkernel/BKE_mesh_types.hh index e59a9efc2a6..0da02471ac0 100644 --- a/source/blender/blenkernel/BKE_mesh_types.hh +++ b/source/blender/blenkernel/BKE_mesh_types.hh @@ -9,7 +9,6 @@ */ #include -#include #include #include "BLI_array.hh" @@ -18,6 +17,7 @@ #include "BLI_implicit_sharing.hh" #include "BLI_kdopbvh.hh" #include "BLI_math_vector_types.hh" +#include "BLI_mutex.hh" #include "BLI_shared_cache.hh" #include "BLI_vector.hh" #include "BLI_virtual_array_fwd.hh" @@ -136,10 +136,10 @@ struct MeshRuntime { * threads, access and use must be protected by the #eval_mutex lock. */ Mesh *mesh_eval = nullptr; - std::mutex eval_mutex; + Mutex eval_mutex; /** Needed to ensure some thread-safety during render data pre-processing. */ - std::mutex render_mutex; + Mutex render_mutex; /** Implicit sharing user count for #Mesh::face_offset_indices. */ const ImplicitSharingInfo *face_offsets_sharing_info = nullptr; diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 657d4d29c41..b339cf241dc 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -9,11 +9,11 @@ #pragma once #include -#include #include "BLI_cache_mutex.hh" #include "BLI_math_vector_types.hh" #include "BLI_multi_value_map.hh" +#include "BLI_mutex.hh" #include "BLI_set.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" @@ -70,7 +70,7 @@ struct NodeLinkError { }; struct LoggedZoneGraphs { - std::mutex mutex; + Mutex mutex; /** * Technically there can be more than one graph per zone because the zone can be invoked in * different contexts. However, for the purpose of logging here, we only need one at a time @@ -158,7 +158,7 @@ class bNodeTreeRuntime : NonCopyable, NonMovable { * evaluate the node group. Caching it here allows us to reuse the preprocessed node tree in case * its used multiple times. */ - std::mutex geometry_nodes_lazy_function_graph_info_mutex; + Mutex geometry_nodes_lazy_function_graph_info_mutex; std::unique_ptr geometry_nodes_lazy_function_graph_info; diff --git a/source/blender/blenkernel/BKE_volume_grid.hh b/source/blender/blenkernel/BKE_volume_grid.hh index 1324c46b4ef..2a6bb39981e 100644 --- a/source/blender/blenkernel/BKE_volume_grid.hh +++ b/source/blender/blenkernel/BKE_volume_grid.hh @@ -13,13 +13,13 @@ #ifdef WITH_OPENVDB # include -# include # include # include "BKE_volume_enums.hh" # include "BKE_volume_grid_type_traits.hh" # include "BLI_implicit_sharing_ptr.hh" +# include "BLI_mutex.hh" # include "BLI_string_ref.hh" # include "openvdb_fwd.hh" @@ -80,7 +80,7 @@ class VolumeGridData : public ImplicitSharingMixin { /** * A mutex that needs to be locked whenever working with the data members below. */ - mutable std::mutex mutex_; + mutable Mutex mutex_; /** * The actual grid. Depending on the current state, is in one of multiple possible states: * - Empty: When the grid is lazy-loaded and no meta-data is provided. diff --git a/source/blender/blenkernel/intern/cachefile.cc b/source/blender/blenkernel/intern/cachefile.cc index 5dae5299608..d435571c00a 100644 --- a/source/blender/blenkernel/intern/cachefile.cc +++ b/source/blender/blenkernel/intern/cachefile.cc @@ -16,6 +16,7 @@ #include "BLI_fileops.h" #include "BLI_ghash.h" #include "BLI_listbase.h" +#include "BLI_mutex.hh" #include "BLI_path_utils.hh" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -46,8 +47,6 @@ # include "usd.hh" #endif -#include - static void cachefile_handle_free(CacheFile *cache_file); static void cache_file_init_data(ID *id) @@ -153,7 +152,7 @@ IDTypeInfo IDType_ID_CF = { }; /* TODO: make this per cache file to avoid global locks. */ -static std::mutex cache_mutex; +static blender::Mutex cache_mutex; void BKE_cachefile_reader_open(CacheFile *cache_file, CacheReader **reader, diff --git a/source/blender/blenkernel/intern/icons.cc b/source/blender/blenkernel/intern/icons.cc index f042f96bbe3..0ce3315203e 100644 --- a/source/blender/blenkernel/intern/icons.cc +++ b/source/blender/blenkernel/intern/icons.cc @@ -9,7 +9,6 @@ #include #include #include -#include #include "CLG_log.h" @@ -21,6 +20,7 @@ #include "BLI_fileops.h" #include "BLI_ghash.h" #include "BLI_linklist_lockfree.h" +#include "BLI_mutex.hh" #include "BLI_threads.h" #include "BLI_utildefines.h" @@ -55,7 +55,7 @@ static int gNextIconId = 1; /* Protected by gIconMutex. */ static int gFirstIconId = 1; -static std::mutex gIconMutex; +static blender::Mutex gIconMutex; /* Queue of icons for deferred deletion. */ struct DeferredIconDeleteNode { diff --git a/source/blender/blenkernel/intern/instances.cc b/source/blender/blenkernel/intern/instances.cc index c48a028659f..3432d824b18 100644 --- a/source/blender/blenkernel/intern/instances.cc +++ b/source/blender/blenkernel/intern/instances.cc @@ -332,7 +332,7 @@ void Instances::remove_unused_references() const Span reference_handles = this->reference_handles(); Array usage_by_handle(tot_references_before, false); - std::mutex mutex; + Mutex mutex; /* Loop over all instances to see which references are used. */ threading::parallel_for(IndexRange(tot_instances), 1000, [&](IndexRange range) { diff --git a/source/blender/blenkernel/intern/rigidbody.cc b/source/blender/blenkernel/intern/rigidbody.cc index 320208ea81b..cadafd1f52e 100644 --- a/source/blender/blenkernel/intern/rigidbody.cc +++ b/source/blender/blenkernel/intern/rigidbody.cc @@ -12,7 +12,6 @@ #include #include #include -#include #include "CLG_log.h" @@ -22,6 +21,7 @@ #include "BLI_math_matrix.h" #include "BLI_math_rotation.h" #include "BLI_math_vector.h" +#include "BLI_mutex.hh" #ifdef WITH_BULLET # include "RBI_api.h" @@ -83,7 +83,7 @@ static void RB_constraint_delete(void * /*con*/) {} struct RigidBodyWorld_Runtime { rbDynamicsWorld *physics_world = nullptr; - std::mutex mutex; + blender::Mutex mutex; ~RigidBodyWorld_Runtime() { diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 0ec7f0f1093..25120fb1f4c 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -72,7 +72,6 @@ using blender::bke::GVolumeGrid; #ifdef WITH_OPENVDB # include -# include # include # include @@ -110,7 +109,7 @@ struct VolumeGridVector : public std::list { /* Mutex for file loading of grids list. `const` write access to the fields after this must be * protected by locking with this mutex. */ - mutable std::mutex mutex; + mutable blender::Mutex mutex; /* Absolute file path that grids have been loaded from. */ char filepath[FILE_MAX]; /* File loading error message. */ @@ -480,7 +479,7 @@ bool BKE_volume_load(const Volume *volume, const Main *bmain) } /* Double-checked lock. */ - std::lock_guard lock(const_grids.mutex); + std::lock_guard lock(const_grids.mutex); if (BKE_volume_is_loaded(volume)) { return const_grids.error_msg.empty(); } diff --git a/source/blender/blenkernel/intern/volume_grid_file_cache.cc b/source/blender/blenkernel/intern/volume_grid_file_cache.cc index cc4eab202cf..d9e02781a6e 100644 --- a/source/blender/blenkernel/intern/volume_grid_file_cache.cc +++ b/source/blender/blenkernel/intern/volume_grid_file_cache.cc @@ -62,7 +62,7 @@ struct FileCache { * Singleton cache that's shared throughout the application. */ struct GlobalCache { - std::mutex mutex; + Mutex mutex; Map file_map; }; diff --git a/source/blender/blenlib/BLI_cache_mutex.hh b/source/blender/blenlib/BLI_cache_mutex.hh index 0470a9eafbb..884984cc5fb 100644 --- a/source/blender/blenlib/BLI_cache_mutex.hh +++ b/source/blender/blenlib/BLI_cache_mutex.hh @@ -21,7 +21,7 @@ * protected data should generally be placed next to each other. * * Each #CacheMutex protects exactly one cache, so multiple cache mutexes have to be used when a - * class has multiple caches. That is contrary to a "custom" solution using `std::mutex` where one + * class has multiple caches. That is contrary to a "custom" solution using `Mutex` where one * mutex could protect multiple caches at the cost of higher lock contention. * * To make sure the cache is up to date, call `CacheMutex::ensure` and pass in the function that @@ -63,15 +63,15 @@ */ #include -#include #include "BLI_function_ref.hh" +#include "BLI_mutex.hh" namespace blender { class CacheMutex { private: - std::mutex mutex_; + Mutex mutex_; std::atomic cache_valid_ = false; public: diff --git a/source/blender/blenlib/BLI_concurrent_map.hh b/source/blender/blenlib/BLI_concurrent_map.hh index 82e0fca0d40..b4fd01a27aa 100644 --- a/source/blender/blenlib/BLI_concurrent_map.hh +++ b/source/blender/blenlib/BLI_concurrent_map.hh @@ -24,6 +24,7 @@ # endif # endif #else +# include "BLI_mutex.hh" # include "BLI_set.hh" #endif @@ -163,7 +164,7 @@ class ConcurrentMap { using UsedSet = Set; struct Accessor { - std::unique_lock mutex; + std::unique_lock mutex; std::pair *data = nullptr; std::pair *operator->() @@ -172,7 +173,7 @@ class ConcurrentMap { } }; - std::mutex mutex_; + Mutex mutex_; UsedSet set_; public: diff --git a/source/blender/blenlib/BLI_enumerable_thread_specific.hh b/source/blender/blenlib/BLI_enumerable_thread_specific.hh index 10ef0dd33a0..4b9de833362 100644 --- a/source/blender/blenlib/BLI_enumerable_thread_specific.hh +++ b/source/blender/blenlib/BLI_enumerable_thread_specific.hh @@ -28,9 +28,9 @@ #else # include # include -# include # include "BLI_map.hh" +# include "BLI_mutex.hh" #endif #include "BLI_utility_mixins.hh" @@ -81,7 +81,7 @@ template class EnumerableThreadSpecific : NonCopyable, NonMovable { #else /* WITH_TBB */ private: - std::mutex mutex_; + Mutex mutex_; /* Maps thread ids to their corresponding values. The values are not embedded in the map, so that * their addresses do not change when the map grows. */ Map> values_; diff --git a/source/blender/blenlib/BLI_mutex.hh b/source/blender/blenlib/BLI_mutex.hh new file mode 100644 index 00000000000..700c2b28ca2 --- /dev/null +++ b/source/blender/blenlib/BLI_mutex.hh @@ -0,0 +1,51 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +/* Always include that so that `BLI_mutex.hh` can be used as replacement to including . + * Otherwise it might be confusing if both are included explicitly in a file. That also makes the + * difference between compiling with and without TBB smaller. */ +#include // IWYU pragma: export + +#ifdef WITH_TBB +# include +#endif + +namespace blender { + +#ifdef WITH_TBB + +/** + * blender::Mutex should be used as the default mutex in Blender. It implements a subset of the API + * of std::mutex but has overall better guaranteed properties. It can be used with RAII helpers + * like std::lock_guard. However, it is not compatible with e.g. std::condition_variable. So one + * still has to use std::mutex for that case. + * + * The mutex provided by TBB has these properties: + * - It's as fast as a spin-lock in the non-contended case, i.e. when no other thread is trying to + * lock the mutex at the same time. + * - In the contended case, it spins a couple of times but then blocks to avoid draining system + * resources by spinning for a long time. + * - It's only 1 byte large, compared to e.g. 40 bytes when using the std::mutex of GCC. This makes + * it more feasible to have many smaller mutexes which can improve scalability of algorithms + * compared to using fewer larger mutexes. Also it just reduces "memory slop" across Blender. + * - It is *not* a fair mutex, i.e. it's not guaranteed that a thread will ever be able to lock the + * mutex when there are always more than one threads that try to lock it. In the majority of + * cases, using a fair mutex just causes extra overhead without any benefit. std::mutex is not + * guaranteed to be fair either. + */ +using Mutex = tbb::mutex; + +/* If this is not true anymore at some point, the comment above needs to be updated. */ +static_assert(sizeof(Mutex) == 1); + +#else + +/** Use std::mutex as a fallback when compiling without TBB. */ +using Mutex = std::mutex; + +#endif + +} // namespace blender diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index a7d0b5057b4..fb41d245c6d 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -337,6 +337,7 @@ set(SRC BLI_mesh_intersect.hh BLI_mmap.h BLI_multi_value_map.hh + BLI_mutex.hh BLI_noise.h BLI_noise.hh BLI_offset_indices.hh diff --git a/source/blender/blenlib/intern/memory_cache.cc b/source/blender/blenlib/intern/memory_cache.cc index 8d3458c3fb9..7c99bdb59f5 100644 --- a/source/blender/blenlib/intern/memory_cache.cc +++ b/source/blender/blenlib/intern/memory_cache.cc @@ -7,12 +7,12 @@ */ #include -#include #include #include "BLI_concurrent_map.hh" #include "BLI_memory_cache.hh" #include "BLI_memory_counter.hh" +#include "BLI_mutex.hh" namespace blender::memory_cache { @@ -43,7 +43,7 @@ struct Cache { */ std::atomic size_in_bytes = 0; - std::mutex global_mutex; + Mutex global_mutex; /** Amount of memory currently used in the cache. */ MemoryCount memory; /** diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc index 0fc79032906..193c7e64c0d 100644 --- a/source/blender/blenlib/intern/mesh_intersect.cc +++ b/source/blender/blenlib/intern/mesh_intersect.cc @@ -14,7 +14,6 @@ # include # include # include -# include # include # include "BLI_array.hh" @@ -28,6 +27,7 @@ # include "BLI_math_vector.h" # include "BLI_math_vector_mpq_types.hh" # include "BLI_math_vector_types.hh" +# include "BLI_mutex.hh" # include "BLI_polyfill_2d.h" # include "BLI_set.hh" # include "BLI_sort.hh" @@ -329,7 +329,7 @@ class IMeshArena::IMeshArenaImpl : NonCopyable, NonMovable { int next_face_id_ = 0; /* Need a lock when multi-threading to protect allocation of new elements. */ - std::mutex mutex_; + Mutex mutex_; public: void reserve(int vert_num_hint, int face_num_hint) diff --git a/source/blender/depsgraph/intern/depsgraph.hh b/source/blender/depsgraph/intern/depsgraph.hh index ea4b6ca790e..840f99956d9 100644 --- a/source/blender/depsgraph/intern/depsgraph.hh +++ b/source/blender/depsgraph/intern/depsgraph.hh @@ -16,13 +16,13 @@ #include #include -#include #include "MEM_guardedalloc.h" #include "DNA_ID.h" /* for ID_Type and INDEX_ID_MAX */ #include "BLI_linear_allocator.hh" +#include "BLI_mutex.hh" #include "BLI_set.hh" #include "BLI_threads.h" /* for SpinLock */ @@ -193,7 +193,7 @@ struct Depsgraph { */ Vector> sync_writeback_callbacks; /** Needs to be locked when adding a writeback callback during evaluation. */ - std::mutex sync_writeback_callbacks_mutex; + Mutex sync_writeback_callbacks_mutex; MEM_CXX_CLASS_ALLOC_FUNCS("Depsgraph"); }; diff --git a/source/blender/depsgraph/intern/depsgraph_registry.cc b/source/blender/depsgraph/intern/depsgraph_registry.cc index 3d87d02ca6b..244405c191a 100644 --- a/source/blender/depsgraph/intern/depsgraph_registry.cc +++ b/source/blender/depsgraph/intern/depsgraph_registry.cc @@ -6,9 +6,8 @@ * \ingroup depsgraph */ -#include - #include "BLI_map.hh" +#include "BLI_mutex.hh" #include "BLI_vector_set.hh" #include "intern/depsgraph_registry.hh" @@ -27,7 +26,7 @@ namespace blender::deg { using GraphSetPtr = std::unique_ptr>; struct GraphRegistry { Map
map; - std::mutex mutex; + Mutex mutex; }; static GraphRegistry &get_graph_registry() @@ -41,7 +40,7 @@ void register_graph(Depsgraph *depsgraph) GraphRegistry &graph_registry = get_graph_registry(); Main *bmain = depsgraph->bmain; - std::lock_guard lock{graph_registry.mutex}; + std::lock_guard lock{graph_registry.mutex}; graph_registry.map .lookup_or_add_cb(bmain, []() { return std::make_unique>(); }) ->add_new(depsgraph); @@ -52,7 +51,7 @@ void unregister_graph(Depsgraph *depsgraph) Main *bmain = depsgraph->bmain; GraphRegistry &graph_registry = get_graph_registry(); - std::lock_guard lock{graph_registry.mutex}; + std::lock_guard lock{graph_registry.mutex}; GraphSetPtr &graphs = graph_registry.map.lookup(bmain); graphs->remove(depsgraph); @@ -65,7 +64,7 @@ void unregister_graph(Depsgraph *depsgraph) Span get_all_registered_graphs(Main *bmain) { GraphRegistry &graph_registry = get_graph_registry(); - std::lock_guard lock{graph_registry.mutex}; + std::lock_guard lock{graph_registry.mutex}; GraphSetPtr *graphs = graph_registry.map.lookup_ptr(bmain); if (graphs) { return **graphs; diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.cc b/source/blender/draw/engines/eevee/eevee_lightcache.cc index 857349ce1ec..784c33960f1 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.cc +++ b/source/blender/draw/engines/eevee/eevee_lightcache.cc @@ -8,8 +8,6 @@ * Contains everything about light baking. */ -#include - #include "DRW_engine.hh" #include "DRW_render.hh" @@ -18,6 +16,7 @@ #include "DNA_lightprobe_types.h" +#include "BLI_mutex.hh" #include "BLI_threads.h" #include "BLI_time.h" @@ -74,7 +73,7 @@ class LightBake { Vector original_probes_; /** Frame to copy to original objects during update. This is needed to avoid race conditions. */ Vector bake_result_; - std::mutex result_mutex_; + Mutex result_mutex_; public: LightBake(Main *bmain, diff --git a/source/blender/draw/engines/eevee/eevee_shader.hh b/source/blender/draw/engines/eevee/eevee_shader.hh index 352cfc9764a..a483d220a4a 100644 --- a/source/blender/draw/engines/eevee/eevee_shader.hh +++ b/source/blender/draw/engines/eevee/eevee_shader.hh @@ -14,7 +14,9 @@ #include #include +#include "BLI_mutex.hh" #include "BLI_string_ref.hh" + #include "DRW_render.hh" #include "GPU_material.hh" #include "GPU_shader.hh" @@ -170,7 +172,7 @@ class ShaderModule { private: std::array shaders_; BatchHandle compilation_handle_ = 0; - std::mutex mutex_; + Mutex mutex_; class SpecializationsKey { private: diff --git a/source/blender/draw/intern/draw_attributes.cc b/source/blender/draw/intern/draw_attributes.cc index 91b343332f1..42544ab6e75 100644 --- a/source/blender/draw/intern/draw_attributes.cc +++ b/source/blender/draw/intern/draw_attributes.cc @@ -48,7 +48,7 @@ void drw_attributes_clear(DRW_Attributes *attributes) *attributes = {}; } -void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, std::mutex &render_mutex) +void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, Mutex &render_mutex) { if (src->num_requests == 0) { return; diff --git a/source/blender/draw/intern/draw_attributes.hh b/source/blender/draw/intern/draw_attributes.hh index dac6a1761c7..594e80ffd33 100644 --- a/source/blender/draw/intern/draw_attributes.hh +++ b/source/blender/draw/intern/draw_attributes.hh @@ -10,10 +10,9 @@ #pragma once -#include - #include "DNA_customdata_types.h" +#include "BLI_mutex.hh" #include "BLI_sys_types.h" #include "GPU_shader.hh" @@ -55,9 +54,7 @@ static_assert(sizeof(DRW_MeshCDMask) <= sizeof(uint32_t), "DRW_MeshCDMask exceed void drw_attributes_clear(DRW_Attributes *attributes); -void drw_attributes_merge(DRW_Attributes *dst, - const DRW_Attributes *src, - std::mutex &render_mutex); +void drw_attributes_merge(DRW_Attributes *dst, const DRW_Attributes *src, Mutex &render_mutex); /* Return true if all requests in b are in a. */ bool drw_attributes_overlap(const DRW_Attributes *a, const DRW_Attributes *b); diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 7f69b509ea0..aebf89def45 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -100,7 +100,7 @@ struct CurvesBatchCache { * some locking would be necessary because multiple objects can use the same curves data with * different materials, etc. This is a placeholder to make multi-threading easier in the future. */ - std::mutex render_mutex; + Mutex render_mutex; }; static bool batch_cache_is_dirty(const Curves &curves) diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc index 0523f522ce9..e9208997f7b 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc @@ -90,7 +90,7 @@ struct PointCloudBatchCache { * some locking would be necessary because multiple objects can use the same object data with * different materials, etc. This is a placeholder to make multi-threading easier in the future. */ - std::mutex render_mutex; + Mutex render_mutex; }; static PointCloudBatchCache *pointcloud_batch_cache_get(PointCloud &pointcloud) diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 0faa298fe88..b8ca283b6c6 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -1580,7 +1580,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache &cache, static OpenSubdiv_EvaluatorCache *g_subdiv_evaluator_cache = nullptr; static uint64_t g_subdiv_evaluator_users = 0; /* The evaluator cache is global, so we cannot allow concurrent usage and need synchronization. */ -static std::mutex g_subdiv_eval_mutex; +static Mutex g_subdiv_eval_mutex; static bool draw_subdiv_create_requested_buffers(Object &ob, Mesh &mesh, diff --git a/source/blender/draw/intern/draw_debug.hh b/source/blender/draw/intern/draw_debug.hh index bf8a2e35c02..985500b4d25 100644 --- a/source/blender/draw/intern/draw_debug.hh +++ b/source/blender/draw/intern/draw_debug.hh @@ -16,6 +16,7 @@ #pragma once #include "BLI_math_vector_types.hh" +#include "BLI_mutex.hh" #include "DNA_object_types.h" @@ -93,7 +94,7 @@ class DebugDraw { /* Reference counter used by GPUContext to allow freeing of DebugDrawBuf before the last * context is destroyed. */ int ref_count_ = 0; - std::mutex ref_count_mutex_; + Mutex ref_count_mutex_; public: void reset(); diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc index 1b5d561ea7c..eb452b909a0 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_edit.cc @@ -2407,7 +2407,7 @@ static struct Clipboard { } *grease_pencil_clipboard = nullptr; /** The clone brush accesses the clipboard from multiple threads. Protect from parallel access. */ -std::mutex grease_pencil_clipboard_lock; +blender::Mutex grease_pencil_clipboard_lock; static Clipboard &ensure_grease_pencil_clipboard() { diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index 8fe19998e21..ea8c06be2a3 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -9,7 +9,6 @@ #include #include #include -#include #include "MEM_guardedalloc.h" @@ -17,6 +16,7 @@ #include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_math_color_blend.h" +#include "BLI_mutex.hh" #include "BLI_string.h" #include "BLI_task.h" #include "BLI_task.hh" @@ -113,7 +113,7 @@ struct OGLRender : public RenderJobBase { GPUViewport *viewport = nullptr; - std::mutex reports_mutex; + blender::Mutex reports_mutex; ReportList *reports = nullptr; int cfrao = 0; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index fd74a9f4fc0..74041d90682 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -238,7 +238,7 @@ struct StepData { bool applied; - std::mutex nodes_mutex; + Mutex nodes_mutex; /** * #undo::Node is stored per #pbvh::Node to reduce data storage needed for changes only impacting diff --git a/source/blender/editors/space_clip/clip_editor.cc b/source/blender/editors/space_clip/clip_editor.cc index e240cf3f7fb..87cdcaeb966 100644 --- a/source/blender/editors/space_clip/clip_editor.cc +++ b/source/blender/editors/space_clip/clip_editor.cc @@ -9,7 +9,6 @@ #include #include #include -#include #include #ifndef WIN32 @@ -25,6 +24,7 @@ #include "BLI_fileops.h" #include "BLI_listbase.h" +#include "BLI_mutex.hh" #include "BLI_rect.h" #include "BLI_task.h" #include "BLI_utildefines.h" @@ -682,7 +682,7 @@ struct PrefetchQueue { */ bool forward; - std::mutex mutex; + blender::Mutex mutex; bool *stop; bool *do_update; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh index 17ce9d2230d..52b8c819edf 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh @@ -55,7 +55,7 @@ class GeometryDataSource : public DataSource { /* Some data is computed on the fly only when it is requested. Computing it does not change the * logical state of this data source. Therefore, the corresponding methods are const and need to * be protected with a mutex. */ - mutable std::mutex mutex_; + mutable Mutex mutex_; mutable ResourceScope scope_; public: diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index a5b64051f2f..8105278e823 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -42,10 +42,10 @@ */ #include -#include #include "BLI_enumerable_thread_specific.hh" #include "BLI_function_ref.hh" +#include "BLI_mutex.hh" #include "BLI_stack.hh" #include "BLI_task.h" #include "BLI_task.hh" @@ -130,11 +130,6 @@ struct OutputState { }; struct NodeState { - /** - * Needs to be locked when any data in this state is accessed that is not explicitly marked as - * not needing the lock. - */ - mutable std::mutex mutex; /** * States of the individual input and output sockets. One can index into these arrays without * locking. However, to access data inside, a lock is needed unless noted otherwise. @@ -149,6 +144,11 @@ struct NodeState { * cases. */ int missing_required_inputs = 0; + /** + * Needs to be locked when any data in this state is accessed that is not explicitly marked as + * not needing the lock. + */ + mutable Mutex mutex; /** * Is set to true once the node is done with its work, i.e. when all outputs that may be used * have been computed. @@ -274,7 +274,7 @@ struct CurrentTask { /** * Mutex used to protect #scheduled_nodes when the executor uses multi-threading. */ - std::mutex mutex; + Mutex mutex; /** * Nodes that have been scheduled to execute next. */ diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 99868e772c7..0ef0d3987e6 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -53,7 +53,7 @@ using namespace blender::gpu; static thread_local Context *active_ctx = nullptr; -static std::mutex backend_users_mutex; +static blender::Mutex backend_users_mutex; static int num_backend_users = 0; static void gpu_backend_create(); @@ -271,7 +271,7 @@ void GPU_context_end_frame(GPUContext *ctx) * Used to avoid crash on some old drivers. * \{ */ -static std::mutex main_context_mutex; +static blender::Mutex main_context_mutex; void GPU_context_main_lock() { diff --git a/source/blender/gpu/intern/gpu_profile_report.hh b/source/blender/gpu/intern/gpu_profile_report.hh index 048fae0f5ae..c69ce5f3d29 100644 --- a/source/blender/gpu/intern/gpu_profile_report.hh +++ b/source/blender/gpu/intern/gpu_profile_report.hh @@ -3,7 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_map.hh" +#include "BLI_mutex.hh" #include "BLI_string_ref.hh" + #include #include #include @@ -16,7 +18,7 @@ namespace blender::gpu { class ProfileReport { private: std::fstream _report; - std::mutex _mutex; + Mutex _mutex; Map _thread_ids; ProfileReport() diff --git a/source/blender/imbuf/movie/intern/ffmpeg_swscale.cc b/source/blender/imbuf/movie/intern/ffmpeg_swscale.cc index 9e17fa14532..ad712debabb 100644 --- a/source/blender/imbuf/movie/intern/ffmpeg_swscale.cc +++ b/source/blender/imbuf/movie/intern/ffmpeg_swscale.cc @@ -12,6 +12,7 @@ # include # include +# include "BLI_mutex.hh" # include "BLI_threads.h" # include "BLI_vector.hh" @@ -39,7 +40,7 @@ struct SwscaleContext { bool is_used = false; }; -static std::mutex swscale_cache_lock; +static blender::Mutex swscale_cache_lock; static int64_t swscale_cache_timestamp = 0; static blender::Vector *swscale_cache = nullptr; diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 70b9a28581e..ca3b5465058 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -950,7 +950,7 @@ static void check_property_socket_sync(const Object *ob, class NodesModifierBakeDataBlockMap : public bake::BakeDataBlockMap { /** Protects access to `new_mappings` which may be added to from multiple threads. */ - std::mutex mutex_; + Mutex mutex_; public: Map old_mappings; diff --git a/source/blender/nodes/NOD_geometry_nodes_closure_location.hh b/source/blender/nodes/NOD_geometry_nodes_closure_location.hh index ee257449e8f..491fc8ab5f1 100644 --- a/source/blender/nodes/NOD_geometry_nodes_closure_location.hh +++ b/source/blender/nodes/NOD_geometry_nodes_closure_location.hh @@ -5,9 +5,9 @@ #pragma once #include -#include #include "BLI_compute_context.hh" +#include "BLI_mutex.hh" #include "BLI_vector.hh" struct bNodeTree; @@ -32,7 +32,7 @@ struct ClosureSourceLocation { }; struct ClosureEvalLog { - std::mutex mutex; + Mutex mutex; Vector evaluations; }; diff --git a/source/blender/nodes/geometry/nodes/node_geo_bake.cc b/source/blender/nodes/geometry/nodes/node_geo_bake.cc index c67caf5a3a8..be2f2707c6d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_bake.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_bake.cc @@ -186,7 +186,7 @@ static bake::BakeSocketConfig make_bake_socket_config(const Span map_; public: diff --git a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc index 5cb588d1974..139c75be7be 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc @@ -64,7 +64,7 @@ static void node_geo_exec(GeoNodeExecParams params) wildcard_suffix = StringRef(pattern).substr(wildcard_index + 1); } - std::mutex attribute_log_mutex; + Mutex attribute_log_mutex; Set removed_attributes; Set failed_attributes; diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index cc44c3310a4..ef6e5ba7ff8 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1738,7 +1738,7 @@ class GeometryNodesLazyFunctionLogger : public lf::GraphExecutor::Logger { } } - static inline std::mutex dump_error_context_mutex; + static inline Mutex dump_error_context_mutex; void dump_when_outputs_are_missing(const lf::FunctionNode &node, Span missing_sockets, diff --git a/source/blender/render/intern/render_types.h b/source/blender/render/intern/render_types.h index 3de5a036f4f..44e8038e1bb 100644 --- a/source/blender/render/intern/render_types.h +++ b/source/blender/render/intern/render_types.h @@ -12,10 +12,9 @@ /* exposed internal in render module only! */ /* ------------------------------------------------------------------------- */ -#include - #include "DNA_scene_types.h" +#include "BLI_mutex.hh" #include "BLI_threads.h" #include "RE_compositor.hh" @@ -216,7 +215,7 @@ struct Render : public BaseRender { /* Compositor. * NOTE: Use bare pointer instead of smart pointer because the it is a fully opaque type. */ blender::render::Compositor *compositor = nullptr; - std::mutex compositor_mutex; + blender::Mutex compositor_mutex; /* Callbacks for the corresponding base class method implementation. */ void (*display_init_cb)(void *handle, RenderResult *rr) = nullptr; diff --git a/source/blender/render/intern/tile_highlight.h b/source/blender/render/intern/tile_highlight.h index b6a77d664f8..56513664eac 100644 --- a/source/blender/render/intern/tile_highlight.h +++ b/source/blender/render/intern/tile_highlight.h @@ -10,11 +10,10 @@ #include "DNA_vec_types.h" +#include "BLI_mutex.hh" #include "BLI_set.hh" #include "BLI_vector.hh" -#include - struct RenderResult; namespace blender::render { @@ -57,7 +56,7 @@ class TilesHighlight { void highlight_tile(const Tile &tile); void unhighlight_tile(const Tile &tile); - mutable std::mutex mutex_; + mutable Mutex mutex_; Set highlighted_tiles_set_; /* Cached flat list of currently highlighted tiles for a fast access via API. */ diff --git a/source/blender/sequencer/intern/strip_lookup.cc b/source/blender/sequencer/intern/strip_lookup.cc index 49e33e1ca24..9ca8776e75a 100644 --- a/source/blender/sequencer/intern/strip_lookup.cc +++ b/source/blender/sequencer/intern/strip_lookup.cc @@ -15,16 +15,16 @@ #include "BLI_listbase.h" #include "BLI_map.hh" +#include "BLI_mutex.hh" #include "BLI_vector_set.hh" #include -#include #include "MEM_guardedalloc.h" namespace blender::seq { -static std::mutex lookup_lock; +static Mutex lookup_lock; struct StripLookup { blender::Map strip_by_name; diff --git a/source/blender/sequencer/intern/thumbnail_cache.cc b/source/blender/sequencer/intern/thumbnail_cache.cc index e4b2e313eef..639cece34c8 100644 --- a/source/blender/sequencer/intern/thumbnail_cache.cc +++ b/source/blender/sequencer/intern/thumbnail_cache.cc @@ -8,6 +8,7 @@ #include "BLI_map.hh" #include "BLI_math_base.h" +#include "BLI_mutex.hh" #include "BLI_path_utils.hh" #include "BLI_set.hh" #include "BLI_task.hh" @@ -38,7 +39,7 @@ static constexpr int MAX_THUMBNAILS = 5000; // #define DEBUG_PRINT_THUMB_JOB_TIMES -static std::mutex thumb_cache_mutex; +static Mutex thumb_cache_mutex; /* Thumbnail cache is a map keyed by media file path, with values being * the various thumbnails that are loaded for it (mostly images would contain just