diff --git a/src/utility/shared_spinlock.hpp b/src/utility/shared_spinlock.hpp index e14722d6..4142cf91 100644 --- a/src/utility/shared_spinlock.hpp +++ b/src/utility/shared_spinlock.hpp @@ -4,10 +4,7 @@ #define GA_UTILITY_SHARED_SPINLOCK_HPP #include "utility.hpp" -#include "spinlock.hpp" #include -#include -#include #include #include @@ -20,16 +17,15 @@ namespace gapp::detail { while (true) { - while (cntr_.load(std::memory_order_relaxed)) GAPP_PAUSE(); if (try_lock()) break; - std::this_thread::yield(); + while (cntr_.load(std::memory_order_relaxed)) GAPP_PAUSE(); } } bool try_lock() noexcept { std::uint32_t expected = 0; - return cntr_.compare_exchange_strong(expected, WRITER, std::memory_order_acq_rel, std::memory_order_relaxed); + return cntr_.compare_exchange_strong(expected, WRITER, std::memory_order_acquire, std::memory_order_relaxed); } void unlock() noexcept @@ -39,15 +35,15 @@ namespace gapp::detail void lock_shared() noexcept { - cntr_.fetch_add(1, std::memory_order_release); + cntr_.fetch_add(1, std::memory_order_relaxed); while (cntr_.load(std::memory_order_relaxed) >= WRITER) GAPP_PAUSE(); - std::ignore = cntr_.load(std::memory_order_acquire); + std::atomic_thread_fence(std::memory_order_acquire); + GAPP_ANNOTATE_TSAN_ACQUIRE(&cntr_); } bool try_lock_shared() noexcept { - cntr_.fetch_add(1, std::memory_order_release); - if (cntr_.load(std::memory_order_acquire) < WRITER) return true; + if (cntr_.fetch_add(1, std::memory_order_acquire) < WRITER) return true; cntr_.fetch_sub(1, std::memory_order_relaxed); return false; } diff --git a/src/utility/spinlock.hpp b/src/utility/spinlock.hpp index 3a6efdcc..4c7e58dd 100644 --- a/src/utility/spinlock.hpp +++ b/src/utility/spinlock.hpp @@ -5,7 +5,6 @@ #include "utility.hpp" #include -#include namespace gapp::detail { @@ -16,9 +15,8 @@ namespace gapp::detail { while (true) { - while (locked_.test(std::memory_order_relaxed)) GAPP_PAUSE(); if (!locked_.test_and_set(std::memory_order_acquire)) break; - std::this_thread::yield(); + while (locked_.test(std::memory_order_relaxed)) GAPP_PAUSE(); } } diff --git a/src/utility/utility.hpp b/src/utility/utility.hpp index 6a3cf4c6..f247937a 100644 --- a/src/utility/utility.hpp +++ b/src/utility/utility.hpp @@ -86,6 +86,25 @@ #endif +#if defined(__has_feature) +# if __has_feature(thread_sanitizer) && __has_include() +# include +# define GAPP_ANNOTATE_TSAN_ACQUIRE(p) __tsan_acquire(p) +# define GAPP_ANNOTATE_TSAN_RELEASE(p) __tsan_release(p) +# else +# define GAPP_ANNOTATE_TSAN_ACQUIRE(p) +# define GAPP_ANNOTATE_TSAN_RELEASE(p) +# endif +#elif defined(__SANITIZE_THREAD__) && __has_include() +# include +# define GAPP_ANNOTATE_TSAN_ACQUIRE(p) __tsan_acquire(p) +# define GAPP_ANNOTATE_TSAN_RELEASE(p) __tsan_release(p) +#else +# define GAPP_ANNOTATE_TSAN_ACQUIRE(p) +# define GAPP_ANNOTATE_TSAN_RELEASE(p) +#endif + + #if defined(_WIN32) && !defined(GAPP_BUILD_STATIC) # if defined(gapp_EXPORTS) # define GAPP_API __declspec(dllexport)