30# ifndef WIN32_LEAN_AND_MEAN
31# define WIN32_LEAN_AND_MEAN
36# include <Processthreadsapi.h>
39#elif defined(__i386__) || defined(__x86_64__)
40# if defined(__clang__)
41# include <emmintrin.h>
42# elif defined(__INTEL_COMPILER)
43# include <immintrin.h>
47#include <libcopp/utils/config/libcopp_build_features.h>
64# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE() YieldProcessor()
67#elif defined(__GNUC__) || defined(__clang__)
68# if defined(__i386__) || defined(__x86_64__)
75# if defined(__clang__) || defined(__INTEL_COMPILER)
76# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE() _mm_pause()
78# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE() __builtin_ia32_pause()
81# elif defined(__ia64__) || defined(__ia64)
87# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE() __asm__ __volatile__("hint @pause")
88# elif defined(__arm__) && !defined(__ANDROID__)
93# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE() __asm__ __volatile__("yield")
99#if !defined(__LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE)
100# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE()
108#if 0 && defined(_MSC_VER)
112# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD() SwitchToThread()
114#elif defined(__linux__) || defined(__unix__)
116# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD() sched_yield()
119#ifndef __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD
120# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD() __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE()
128#if defined(__LIBCOPP_UTIL_LOCK_ATOMIC_INT_TYPE_ATOMIC_STD)
138# if defined(__GNUC__) && !defined(__clang__)
139# if (__GNUC__ * 100 + __GNUC_MINOR__) <= 407
140# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_YIELD() __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD()
141# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_SLEEP() __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD()
145# ifndef __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_YIELD
146# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_YIELD() ::std::this_thread::yield()
148# ifndef __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_SLEEP
149# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_SLEEP() ::std::this_thread::sleep_for(::std::chrono::milliseconds(1))
152#elif defined(_MSC_VER)
153# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_YIELD() Sleep(0)
154# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_SLEEP() Sleep(1)
157#ifndef __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_YIELD
158# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_YIELD()
159# define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_SLEEP() __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD()
174#define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_WAIT(x) \
176 unsigned char try_lock_times = static_cast<unsigned char>(x); \
177 if (try_lock_times < 4) { \
178 } else if (try_lock_times < 16) { \
179 __LIBCOPP_UTIL_LOCK_SPIN_LOCK_PAUSE(); \
180 } else if (try_lock_times < 32) { \
181 __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_YIELD(); \
182 } else if (try_lock_times < 64) { \
183 __LIBCOPP_UTIL_LOCK_SPIN_LOCK_CPU_YIELD(); \
185 __LIBCOPP_UTIL_LOCK_SPIN_LOCK_THREAD_SLEEP(); \
174#define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_WAIT(x) \ …
189LIBCOPP_COPP_NAMESPACE_BEGIN
199 typedef enum { UNLOCKED = 0, LOCKED = 1 } lock_state_t;
200 LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type<
201#if LIBCOPP_MACRO_ENABLE_MULTI_THREAD
204 LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type<unsigned int>
210 inline spin_lock() noexcept { lock_status_.store(UNLOCKED); }
213 unsigned char try_times = 0;
214 while (lock_status_.exchange(
static_cast<unsigned int>(LOCKED),
215 LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_acq_rel) == LOCKED)
220 lock_status_.store(
static_cast<unsigned int>(UNLOCKED),
221 LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_release);
225 return lock_status_.load(LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_acquire) == LOCKED;
229 return lock_status_.exchange(
static_cast<unsigned int>(LOCKED),
230 LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_acq_rel) == UNLOCKED;
234 return lock_status_.exchange(
static_cast<unsigned int>(UNLOCKED),
235 LIBCOPP_COPP_NAMESPACE_ID::util::lock::memory_order_acq_rel) == LOCKED;
240LIBCOPP_COPP_NAMESPACE_END
atomic wrapper fo integers Licensed under the MIT licenses.
LIBCOPP_COPP_NAMESPACE_ID::util::lock::atomic_int_type< LIBCOPP_COPP_NAMESPACE_ID::util::lock::unsafe_int_type< unsigned int > > lock_status_
bool try_unlock() noexcept
bool is_locked() noexcept
#define __LIBCOPP_UTIL_LOCK_SPIN_LOCK_WAIT(x)