22#if defined(__INTEL_COMPILER)
24#elif defined(_MSC_VER)
26#elif defined(__GNUC__)
30#if defined(_M_IA64) || defined(__ia64__)
32#elif defined(_WIN64) || defined(__amd64__) || defined(_M_X64) || defined(__x86_64__)
34#elif defined(_M_IX86) || defined(__i386__)
36#elif defined(_M_PPC) || defined(__powerpc__)
39#define AE_ARCH_UNKNOWN
44#define AE_UNUSED(x) ((void)x)
47#if defined(__has_feature)
48#if __has_feature(thread_sanitizer)
49#if __cplusplus >= 201703L
50namespace moodycamel {
inline int ae_tsan_global; }
51#define AE_TSAN_ANNOTATE_RELEASE() AnnotateHappensBefore(__FILE__, __LINE__, (void *)(&::moodycamel::ae_tsan_global))
52#define AE_TSAN_ANNOTATE_ACQUIRE() AnnotateHappensAfter(__FILE__, __LINE__, (void *)(&::moodycamel::ae_tsan_global))
53extern "C" void AnnotateHappensBefore(
const char*,
int,
void*);
54extern "C" void AnnotateHappensAfter(
const char*,
int,
void*);
56#define AE_NO_TSAN __attribute__((no_sanitize("thread")))
63#ifndef AE_TSAN_ANNOTATE_RELEASE
64#define AE_TSAN_ANNOTATE_RELEASE()
65#define AE_TSAN_ANNOTATE_ACQUIRE()
70#if defined(AE_VCPP) || defined(AE_ICC)
71#define AE_FORCEINLINE __forceinline
74#define AE_FORCEINLINE inline
76#define AE_FORCEINLINE inline
81#if defined(AE_VCPP) || defined(AE_ICC)
82#define AE_ALIGN(x) __declspec(align(x))
84#define AE_ALIGN(x) __attribute__((aligned(x)))
87#define AE_ALIGN(x) __attribute__((aligned(x)))
109#if (defined(AE_VCPP) && (_MSC_VER < 1700 || defined(__cplusplus_cli))) || (defined(AE_ICC) && __INTEL_COMPILER < 1600)
114#if defined(AE_ARCH_X64) || defined(AE_ARCH_X86)
115#define AeFullSync _mm_mfence
116#define AeLiteSync _mm_mfence
117#elif defined(AE_ARCH_IA64)
118#define AeFullSync __mf
119#define AeLiteSync __mf
120#elif defined(AE_ARCH_PPC)
121#include <ppcintrinsics.h>
122#define AeFullSync __sync
123#define AeLiteSync __lwsync
129#pragma warning(disable: 4365)
130#ifdef __cplusplus_cli
131#pragma managed(push, off)
145 default: assert(
false);
152#if defined(AE_ARCH_X86) || defined(AE_ARCH_X64)
165 default: assert(
false);
195 default: assert(
false);
214 default: assert(
false);
226 default: assert(
false);
235#if !defined(AE_VCPP) || (_MSC_VER >= 1700 && !defined(__cplusplus_cli))
236#define AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC
239#ifdef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC
256#pragma warning(disable: 4100)
259#ifdef __cplusplus_cli
272#ifndef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC
280#if defined(AE_ARCH_X64) || defined(AE_ARCH_X86)
281 if (
sizeof(T) == 4)
return _InterlockedExchangeAdd((
long volatile*)&value, (
long)increment);
283 else if (
sizeof(T) == 8)
return _InterlockedExchangeAdd64((
long long volatile*)&value, (
long long)increment);
286#error Unsupported platform
288 assert(
false &&
"T must be either a 32 or 64 bit type");
294#if defined(AE_ARCH_X64) || defined(AE_ARCH_X86)
295 if (
sizeof(T) == 4)
return _InterlockedExchangeAdd((
long volatile*)&value, (
long)increment);
297 else if (
sizeof(T) == 8)
return _InterlockedExchangeAdd64((
long long volatile*)&value, (
long long)increment);
300#error Unsupported platform
302 assert(
false &&
"T must be either a 32 or 64 bit type");
334#ifndef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC
339 std::atomic<T> value;
356 struct _SECURITY_ATTRIBUTES;
357 __declspec(dllimport)
void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes,
long lInitialCount,
long lMaximumCount,
const wchar_t* lpName);
358 __declspec(dllimport)
int __stdcall CloseHandle(
void* hObject);
359 __declspec(dllimport)
unsigned long __stdcall WaitForSingleObject(
void* hHandle,
unsigned long dwMilliseconds);
360 __declspec(dllimport)
int __stdcall ReleaseSemaphore(
void* hSemaphore,
long lReleaseCount,
long* lpPreviousCount);
362#elif defined(__MACH__)
363#include <mach/mach.h>
364#elif defined(__unix__)
365#include <semaphore.h>
366#elif defined(FREERTOS)
403 Semaphore(
const Semaphore& other);
404 Semaphore& operator=(
const Semaphore& other);
407 AE_NO_TSAN Semaphore(
int initialCount = 0) : m_hSema()
409 assert(initialCount >= 0);
410 const long maxLong = 0x7fffffff;
411 m_hSema = CreateSemaphoreW(
nullptr, initialCount, maxLong,
nullptr);
417 CloseHandle(m_hSema);
422 const unsigned long infinite = 0xffffffff;
423 return WaitForSingleObject(m_hSema, infinite) == 0;
428 return WaitForSingleObject(m_hSema, 0) == 0;
431 bool timed_wait(std::uint64_t usecs)
AE_NO_TSAN
433 return WaitForSingleObject(m_hSema, (
unsigned long)(usecs / 1000)) == 0;
438 while (!ReleaseSemaphore(m_hSema, count,
nullptr));
441#elif defined(__MACH__)
451 Semaphore(
const Semaphore& other);
452 Semaphore& operator=(
const Semaphore& other);
455 AE_NO_TSAN Semaphore(
int initialCount = 0) : m_sema()
457 assert(initialCount >= 0);
458 kern_return_t rc = semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
459 assert(rc == KERN_SUCCESS);
465 semaphore_destroy(mach_task_self(), m_sema);
470 return semaphore_wait(m_sema) == KERN_SUCCESS;
475 return timed_wait(0);
478 bool timed_wait(std::uint64_t timeout_usecs)
AE_NO_TSAN
481 ts.tv_sec =
static_cast<unsigned int>(timeout_usecs / 1000000);
482 ts.tv_nsec =
static_cast<int>((timeout_usecs % 1000000) * 1000);
485 kern_return_t rc = semaphore_timedwait(m_sema, ts);
486 return rc == KERN_SUCCESS;
491 while (semaphore_signal(m_sema) != KERN_SUCCESS);
498 while (semaphore_signal(m_sema) != KERN_SUCCESS);
502#elif defined(__unix__)
511 Semaphore(
const Semaphore& other);
512 Semaphore& operator=(
const Semaphore& other);
515 AE_NO_TSAN Semaphore(
int initialCount = 0) : m_sema()
517 assert(initialCount >= 0);
518 int rc = sem_init(&m_sema, 0,
static_cast<unsigned int>(initialCount));
525 sem_destroy(&m_sema);
534 rc = sem_wait(&m_sema);
536 while (rc == -1 && errno == EINTR);
544 rc = sem_trywait(&m_sema);
545 }
while (rc == -1 && errno == EINTR);
549 bool timed_wait(std::uint64_t usecs)
AE_NO_TSAN
552 const int usecs_in_1_sec = 1000000;
553 const int nsecs_in_1_sec = 1000000000;
554 clock_gettime(CLOCK_REALTIME, &ts);
555 ts.tv_sec +=
static_cast<time_t
>(usecs / usecs_in_1_sec);
556 ts.tv_nsec +=
static_cast<long>(usecs % usecs_in_1_sec) * 1000;
559 if (ts.tv_nsec >= nsecs_in_1_sec) {
560 ts.tv_nsec -= nsecs_in_1_sec;
566 rc = sem_timedwait(&m_sema, &ts);
567 }
while (rc == -1 && errno == EINTR);
573 while (sem_post(&m_sema) == -1);
580 while (sem_post(&m_sema) == -1);
584#elif defined(FREERTOS)
591 SemaphoreHandle_t m_sema;
593 Semaphore(
const Semaphore& other);
594 Semaphore& operator=(
const Semaphore& other);
597 AE_NO_TSAN Semaphore(
int initialCount = 0) : m_sema()
599 assert(initialCount >= 0);
600 m_sema = xSemaphoreCreateCounting(
static_cast<UBaseType_t
>(~0ull),
static_cast<UBaseType_t
>(initialCount));
606 vSemaphoreDelete(m_sema);
611 return xSemaphoreTake(m_sema, portMAX_DELAY) == pdTRUE;
618 if (xPortIsInsideInterrupt())
619 return xSemaphoreTakeFromISR(m_sema, NULL) == pdTRUE;
620 return xSemaphoreTake(m_sema, 0) == pdTRUE;
623 bool timed_wait(std::uint64_t usecs)
AE_NO_TSAN
625 std::uint64_t msecs = usecs / 1000;
626 TickType_t ticks =
static_cast<TickType_t
>(msecs / portTICK_PERIOD_MS);
629 return xSemaphoreTake(m_sema, ticks) == pdTRUE;
637 if (xPortIsInsideInterrupt())
638 rc = xSemaphoreGiveFromISR(m_sema, NULL);
640 rc = xSemaphoreGive(m_sema);
641 assert(rc == pdTRUE);
652#error Unsupported platform! (No semaphore wrapper available)
667 bool waitWithPartialSpinning(std::int64_t timeout_usecs = -1)
AE_NO_TSAN
676 if (m_count.
load() > 0)
686 if (timeout_usecs < 0)
691 if (timeout_usecs > 0 && m_sema.timed_wait(
static_cast<uint64_t
>(timeout_usecs)))
705 if (oldCount > 0 && m_sema.try_wait())
713 assert(initialCount >= 0);
718 if (m_count.
load() > 0)
728 return tryWait() || waitWithPartialSpinning();
733 return tryWait() || waitWithPartialSpinning(timeout_usecs);
740 assert(oldCount >= -1);
750 return count > 0 ?
static_cast<std::size_t
>(count) : 0;
756#if defined(AE_VCPP) && (_MSC_VER < 1700 || defined(__cplusplus_cli))
758#ifdef __cplusplus_cli
#define AE_TSAN_ANNOTATE_RELEASE()
Definition: atomicops.h:64
#define AE_UNUSED(x)
Definition: atomicops.h:44
#define AE_TSAN_ANNOTATE_ACQUIRE()
Definition: atomicops.h:65
#define AE_FORCEINLINE
Definition: atomicops.h:76
#define AE_NO_TSAN
Definition: atomicops.h:61
Definition: atomicops.h:659
bool wait(std::int64_t timeout_usecs) AE_NO_TSAN
Definition: atomicops.h:731
void signal(ssize_t count=1) AE_NO_TSAN
Definition: atomicops.h:736
std::make_signed< std::size_t >::type ssize_t
Definition: atomicops.h:661
AE_NO_TSAN LightweightSemaphore(ssize_t initialCount=0)
Definition: atomicops.h:711
bool wait() AE_NO_TSAN
Definition: atomicops.h:726
std::size_t availableApprox() const AE_NO_TSAN
Definition: atomicops.h:747
bool tryWait() AE_NO_TSAN
Definition: atomicops.h:716
Definition: atomicops.h:251
AE_FORCEINLINE weak_atomic const & operator=(U &&x) AE_NO_TSAN
Definition: atomicops.h:307
AE_NO_TSAN weak_atomic(weak_atomic &&other)
Definition: atomicops.h:264
AE_NO_TSAN weak_atomic(weak_atomic const &other)
Definition: atomicops.h:263
AE_FORCEINLINE T fetch_add_release(T increment) AE_NO_TSAN
Definition: atomicops.h:326
AE_FORCEINLINE T load() const AE_NO_TSAN
Definition: atomicops.h:319
AE_NO_TSAN weak_atomic()
Definition: atomicops.h:253
AE_NO_TSAN weak_atomic(U &&x)
Definition: atomicops.h:258
AE_FORCEINLINE weak_atomic const & operator=(weak_atomic const &other) AE_NO_TSAN
Definition: atomicops.h:313
AE_FORCEINLINE T fetch_add_acquire(T increment) AE_NO_TSAN
Definition: atomicops.h:321
Definition: atomicops.h:93
AE_FORCEINLINE void compiler_fence(memory_order order) AE_NO_TSAN
Definition: atomicops.h:206
memory_order
Definition: atomicops.h:95
@ memory_order_acq_rel
Definition: atomicops.h:99
@ memory_order_seq_cst
Definition: atomicops.h:100
@ memory_order_acquire
Definition: atomicops.h:97
@ memory_order_relaxed
Definition: atomicops.h:96
@ memory_order_sync
Definition: atomicops.h:104
@ memory_order_release
Definition: atomicops.h:98
AE_FORCEINLINE void fence(memory_order order) AE_NO_TSAN
Definition: atomicops.h:218
type
Definition: setup.py:37