15 #include <type_traits> 19 #if defined(__INTEL_COMPILER) 21 #elif defined(_MSC_VER) 23 #elif defined(__GNUC__) 27 #if defined(_M_IA64) || defined(__ia64__) 29 #elif defined(_WIN64) || defined(__amd64__) || defined(_M_X64) || defined(__x86_64__) 31 #elif defined(_M_IX86) || defined(__i386__) 33 #elif defined(_M_PPC) || defined(__powerpc__) 36 #define AE_ARCH_UNKNOWN 41 #define AE_UNUSED(x) ((void)x) 45 #if defined(AE_VCPP) || defined(AE_ICC) 46 #define AE_FORCEINLINE __forceinline 49 #define AE_FORCEINLINE inline 51 #define AE_FORCEINLINE inline 56 #if defined(AE_VCPP) || defined(AE_ICC) 57 #define AE_ALIGN(x) __declspec(align(x)) 59 #define AE_ALIGN(x) __attribute__((aligned(x))) 62 #define AE_ALIGN(x) __attribute__((aligned(x))) 84 #if (defined(AE_VCPP) && (_MSC_VER < 1700 || defined(__cplusplus_cli))) || defined(AE_ICC) 89 #if defined(AE_ARCH_X64) || defined(AE_ARCH_X86) 90 #define AeFullSync _mm_mfence 91 #define AeLiteSync _mm_mfence 92 #elif defined(AE_ARCH_IA64) 93 #define AeFullSync __mf 94 #define AeLiteSync __mf 95 #elif defined(AE_ARCH_PPC) 96 #include <ppcintrinsics.h> 97 #define AeFullSync __sync 98 #define AeLiteSync __lwsync 103 #pragma warning(push) 104 #pragma warning(disable: 4365) // Disable erroneous 'conversion from long to unsigned int, signed/unsigned mismatch' error when using `assert` 105 #ifdef __cplusplus_cli 106 #pragma managed(push, off) 120 default: assert(
false);
127 #if defined(AE_ARCH_X86) || defined(AE_ARCH_X64) 140 default: assert(
false);
170 default: assert(
false);
189 default: assert(
false);
201 default: assert(
false);
210 #if !defined(AE_VCPP) || (_MSC_VER >= 1700 && !defined(__cplusplus_cli)) 211 #define AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC 214 #ifdef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC 230 #pragma warning(disable: 4100) // Get rid of (erroneous) 'unreferenced formal parameter' warning 233 #ifdef __cplusplus_cli 240 #pragma warning(default: 4100) 246 #ifndef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC 254 #if defined(AE_ARCH_X64) || defined(AE_ARCH_X86) 255 if (
sizeof(T) == 4)
return _InterlockedExchangeAdd((
long volatile*)&value, (
long)increment);
256 #if defined(_M_AMD64) 257 else if (
sizeof(T) == 8)
return _InterlockedExchangeAdd64((
long long volatile*)&value, (
long long)increment);
260 #error Unsupported platform 262 assert(
false &&
"T must be either a 32 or 64 bit type");
268 #if defined(AE_ARCH_X64) || defined(AE_ARCH_X86) 269 if (
sizeof(T) == 4)
return _InterlockedExchangeAdd((
long volatile*)&value, (
long)increment);
270 #if defined(_M_AMD64) 271 else if (
sizeof(T) == 8)
return _InterlockedExchangeAdd64((
long long volatile*)&value, (
long long)increment);
274 #error Unsupported platform 276 assert(
false &&
"T must be either a 32 or 64 bit type");
308 #ifndef AE_USE_STD_ATOMIC_FOR_WEAK_ATOMIC 313 std::atomic<T> value;
330 struct _SECURITY_ATTRIBUTES;
331 __declspec(dllimport)
void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES* lpSemaphoreAttributes,
long lInitialCount,
long lMaximumCount,
const wchar_t* lpName);
332 __declspec(dllimport)
int __stdcall CloseHandle(
void* hObject);
333 __declspec(dllimport)
unsigned long __stdcall WaitForSingleObject(
void* hHandle,
unsigned long dwMilliseconds);
334 __declspec(dllimport)
int __stdcall ReleaseSemaphore(
void* hSemaphore,
long lReleaseCount,
long* lpPreviousCount);
336 #elif defined(__MACH__) 337 #include <mach/mach.h> 338 #elif defined(__unix__) 339 #include <semaphore.h> 373 Semaphore(
const Semaphore& other);
374 Semaphore& operator=(
const Semaphore& other);
377 Semaphore(
int initialCount = 0)
379 assert(initialCount >= 0);
380 const long maxLong = 0x7fffffff;
381 m_hSema = CreateSemaphoreW(
nullptr, initialCount, maxLong,
nullptr);
386 CloseHandle(m_hSema);
391 const unsigned long infinite = 0xffffffff;
392 WaitForSingleObject(m_hSema, infinite);
395 void signal(
int count = 1)
397 ReleaseSemaphore(m_hSema, count,
nullptr);
400 #elif defined(__MACH__) 410 Semaphore(
const Semaphore& other);
411 Semaphore& operator=(
const Semaphore& other);
414 Semaphore(
int initialCount = 0)
416 assert(initialCount >= 0);
417 semaphore_create(mach_task_self(), &m_sema, SYNC_POLICY_FIFO, initialCount);
422 semaphore_destroy(mach_task_self(), m_sema);
427 semaphore_wait(m_sema);
432 semaphore_signal(m_sema);
435 void signal(
int count)
439 semaphore_signal(m_sema);
443 #elif defined(__unix__) 452 Semaphore(
const Semaphore& other);
453 Semaphore& operator=(
const Semaphore& other);
456 Semaphore(
int initialCount = 0)
458 assert(initialCount >= 0);
459 sem_init(&m_sema, 0, initialCount);
464 sem_destroy(&m_sema);
473 rc = sem_wait(&m_sema);
475 while (rc == -1 && errno == EINTR);
483 void signal(
int count)
492 #error Unsupported platform! (No semaphore wrapper available) 501 typedef std::make_signed<std::size_t>::type
ssize_t;
507 void waitWithPartialSpinning()
516 if (m_count.
load() > 0)
533 assert(initialCount >= 0);
538 if (m_count.
load() > 0)
549 waitWithPartialSpinning();
556 assert(oldCount >= -1);
566 return count > 0 ? count : 0;
572 #if defined(AE_VCPP) && (_MSC_VER < 1700 || defined(__cplusplus_cli)) 574 #ifdef __cplusplus_cli Definition: atomicops.h:73
weak_atomic()
Definition: atomicops.h:228
Definition: atomicops.h:79
Definition: atomicops.h:68
void signal(ssize_t count=1)
Definition: atomicops.h:552
AE_FORCEINLINE T load() const
Definition: atomicops.h:293
AE_FORCEINLINE T fetch_add_release(T increment)
Definition: atomicops.h:300
void wait()
Definition: atomicops.h:546
weak_atomic(weak_atomic &&other)
Definition: atomicops.h:238
LightweightSemaphore(ssize_t initialCount=0)
Definition: atomicops.h:531
memory_order
Definition: atomicops.h:70
weak_atomic(weak_atomic const &other)
Definition: atomicops.h:237
Definition: atomicops.h:74
Definition: atomicops.h:75
Definition: atomicops.h:498
AE_FORCEINLINE void compiler_fence(memory_order order)
Definition: atomicops.h:181
std::make_signed< std::size_t >::type ssize_t
Definition: atomicops.h:501
AE_FORCEINLINE T fetch_add_acquire(T increment)
Definition: atomicops.h:295
Definition: atomicops.h:225
AE_FORCEINLINE weak_atomic const & operator=(U &&x)
Definition: atomicops.h:281
AE_FORCEINLINE void fence(memory_order order)
Definition: atomicops.h:193
Definition: atomicops.h:72
Definition: atomicops.h:71
AE_FORCEINLINE weak_atomic const & operator=(weak_atomic const &other)
Definition: atomicops.h:287
bool tryWait()
Definition: atomicops.h:536
weak_atomic(U &&x)
Definition: atomicops.h:232
ssize_t availableApprox() const
Definition: atomicops.h:563
#define AE_FORCEINLINE
Definition: atomicops.h:51