/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SOOPrimitives.hpp Date: 2023-3-21 Author: Reece ***/ #pragma once #if defined(AURORA_COMPILER_MSVC) #pragma warning(push) #pragma warning(disable: 4141) #endif namespace Aurora::Threading::Primitives { static const auto kDefaultPrimitiveSize64 = 128; // Define all the sizes of the primitives on each platform by word-size, preprocessed to filter irrelevant/unknown architectures: #if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86) static const auto kPrimitiveSize64NTMutex = 16; static const auto kPrimitiveSize64NTSemaphore = 64; static const auto kPrimitiveSize64NTCS = 32; static const auto kPrimitiveSize64NTEvent = 64; static const auto kPrimitiveSize64NTRWLock = 88; static const auto kPrimitiveSize64NTCond = 32; static const auto kPrimitiveSize64NTCondMutex = 16; static const auto kPrimitiveSize32NTMutex = 8; static const auto kPrimitiveSize32NTSemaphore = 36; static const auto kPrimitiveSize32NTCS = 20; static const auto kPrimitiveSize32NTEvent = 36; static const auto kPrimitiveSize32NTRWLock = 56; static const auto kPrimitiveSize32NTCond = 20; static const auto kPrimitiveSize32NTCondMutex = 8; // TODO: Other platforms... #else // TBD #endif // Platform selection: #if defined(AURORA_IS_MODERNNT_DERIVED) static const auto kPrimitiveSize64Mutex = kPrimitiveSize64NTMutex; static const auto kPrimitiveSize64Semaphore = kPrimitiveSize64NTSemaphore; static const auto kPrimitiveSize64CS = kPrimitiveSize64NTCS; static const auto kPrimitiveSize64Event = kPrimitiveSize64NTEvent; static const auto kPrimitiveSize64RWLock = kPrimitiveSize64NTRWLock; static const auto kPrimitiveSize64Cond = kPrimitiveSize64NTCond; static const auto kPrimitiveSize64CondMutex = kPrimitiveSize64NTCondMutex; static const auto kPrimitiveSize32Mutex = kPrimitiveSize32NTMutex; static const auto kPrimitiveSize32Semaphore = kPrimitiveSize32NTSemaphore; static const auto kPrimitiveSize32CS = kPrimitiveSize32NTCS; static const auto kPrimitiveSize32Event = kPrimitiveSize32NTEvent; static const auto kPrimitiveSize32RWLock = kPrimitiveSize32NTRWLock; static const auto kPrimitiveSize32Cond = kPrimitiveSize32NTCond; static const auto kPrimitiveSize32CondMutex = kPrimitiveSize32NTCondMutex; #define AURT_ENABLE_HYPER_MUTEX #else static const auto kPrimitiveSize64Mutex = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64Semaphore = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64CS = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64Event = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64RWLock = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64Cond = kDefaultPrimitiveSize64; static const auto kPrimitiveSize64CondMutex = kDefaultPrimitiveSize64; #endif #if defined(AURORA_IS_64BIT) static const auto kPrimitiveSizeMutex = kPrimitiveSize64Mutex; static const auto kPrimitiveSizeSemaphore = kPrimitiveSize64Semaphore; static const auto kPrimitiveSizeCS = kPrimitiveSize64CS; static const auto kPrimitiveSizeEvent = kPrimitiveSize64Event; static const auto kPrimitiveSizeRWLock = kPrimitiveSize64RWLock; static const auto kPrimitiveSizeCond = kPrimitiveSize64Cond; static const auto kPrimitiveSizeCondMutex = kPrimitiveSize64CondMutex; #else static const auto kPrimitiveSizeMutex = kPrimitiveSize32Mutex; static const auto kPrimitiveSizeSemaphore = kPrimitiveSize32Semaphore; static const auto kPrimitiveSizeCS = kPrimitiveSize32CS; static const auto kPrimitiveSizeEvent = kPrimitiveSize32Event; static const auto kPrimitiveSizeRWLock = kPrimitiveSize32RWLock; static const auto kPrimitiveSizeCond = kPrimitiveSize32Cond; static const auto kPrimitiveSizeCondMutex = kPrimitiveSize32CondMutex; #endif static const auto kPrimitiveSizeSemaphoreCV = AuPageRoundUp(8 + kPrimitiveSizeSemaphore + 4, sizeof(AuUInt)); struct AUKN_SYM HyperWaitable : IWaitable { auline inline void Lock() final override { if (AuAtomicTestAndSet(&this->state_, 0u) == 0) { return; } SlowLock(); } virtual void SlowLock() = 0; protected: volatile AuUInt32 state_ {}; }; #if defined(AURT_ENABLE_HYPER_MUTEX) using IHyperWaitable = HyperWaitable; #else using IHyperWaitable = IWaitable; #endif } #if defined(AURORA_COMPILER_MSVC) #pragma warning(pop) #endif