From 7180c1f2d064761a6a37d973a9c26647f73b28cf Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 9 Nov 2018 16:03:39 +0300 Subject: [PATCH] typemap: make use of volatile qualifier Use shared lock for volatile pointers Use no lock for const volatile pointers --- Utilities/typemap.h | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/Utilities/typemap.h b/Utilities/typemap.h index d12a4074f7..e7d36e730b 100644 --- a/Utilities/typemap.h +++ b/Utilities/typemap.h @@ -396,7 +396,10 @@ namespace utils void release() { - if constexpr (type_const()) + if constexpr (type_const() && type_volatile()) + { + } + else if constexpr (type_const() || type_volatile()) { m_block->m_mutex.unlock_shared(); } @@ -484,6 +487,7 @@ namespace utils ullong create(Args&&... args) { static_assert(!type_const()); + static_assert(!type_volatile()); const ullong result = ++m_head->m_create_count; @@ -593,6 +597,11 @@ namespace utils { return std::is_const_v>; } + + static constexpr bool type_volatile() + { + return std::is_volatile_v>; + } }; // Dynamic object collection, one or more per any type; shall not be initialized before main() @@ -772,7 +781,9 @@ namespace utils if constexpr (constexpr uint last = typeinfo_count::max_count - 1) { // If max_count > 1 only id_new is supported - static_assert(std::is_same_v && !std::is_const_v>); + static_assert(std::is_same_v); + static_assert(!std::is_const_v>); + static_assert(!std::is_volatile_v>); // Try to acquire the semaphore if (UNLIKELY(!head->m_sema.try_inc(last + 1))) @@ -806,6 +817,7 @@ namespace utils if constexpr (std::is_same_v) { static_assert(!std::is_const_v>); + static_assert(!std::is_volatile_v>); if (block->m_type != 0 || !block->m_mutex.try_lock()) { @@ -940,6 +952,7 @@ namespace utils { // Initialize object if necessary static_assert(!std::is_const_v>); + static_assert(!std::is_volatile_v>); if constexpr (std::is_lvalue_reference_v) { @@ -1008,8 +1021,9 @@ namespace utils { // Use reader lock for const access constexpr bool is_const = std::is_const_v>; + constexpr bool is_volatile = std::is_volatile_v>; - // Already locked + // Already locked or lock is unnecessary if constexpr (!Lock) { return true; @@ -1024,7 +1038,7 @@ namespace utils if constexpr (Try) { - if constexpr (is_const) + if constexpr (is_const || is_volatile) { return block->m_mutex.try_lock_shared(); } @@ -1033,7 +1047,7 @@ namespace utils return block->m_mutex.try_lock(); } } - else if constexpr (is_const) + else if constexpr (is_const || is_volatile) { if (LIKELY(block->m_mutex.is_lockable())) { @@ -1075,7 +1089,7 @@ namespace utils { if (array[I].m_block) { - if constexpr (std::is_const_v>) + if constexpr (std::is_const_v> || std::is_volatile_v>) { array[I].m_block->m_mutex.unlock_shared(); } @@ -1117,6 +1131,22 @@ namespace utils return {array[I]...}; } + template + static constexpr bool does_need_lock() + { + if constexpr (std::is_same_v, id_new_t>) + { + return false; + } + + if constexpr (std::is_const_v> && std::is_volatile_v>) + { + return false; + } + + return true; + } + public: // Lock any objects by their identifiers, special tags id_new/id_any/id_always, or search predicates template > @@ -1131,7 +1161,7 @@ namespace utils std::array result{this->init_ptr(std::forward(ids))...}; // Whether requires locking after init_ptr - using locks_t = std::integer_sequence, id_new_t>...>; + using locks_t = std::integer_sequence()...>; // Array index helper using seq_t = std::index_sequence_for;