177 lines
7.1 KiB
C++
177 lines
7.1 KiB
C++
/***
|
|
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 = 32;
|
|
|
|
// 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 = 12;
|
|
static const auto kPrimitiveSize64NTSemaphore = 24;
|
|
static const auto kPrimitiveSize64NTCS = 28;
|
|
static const auto kPrimitiveSize64NTEvent = 24;
|
|
static const auto kPrimitiveSize64NTRWLock = 56;
|
|
static const auto kPrimitiveSize64NTCond = 32;
|
|
static const auto kPrimitiveSize64NTCondMutex = 16;
|
|
|
|
static const auto kPrimitiveSize32NTMutex = 8;
|
|
static const auto kPrimitiveSize32NTSemaphore = 20;
|
|
static const auto kPrimitiveSize32NTCS = 20;
|
|
static const auto kPrimitiveSize32NTEvent = 20;
|
|
static const auto kPrimitiveSize32NTRWLock = 44;
|
|
static const auto kPrimitiveSize32NTCond = 20;
|
|
static const auto kPrimitiveSize32NTCondMutex = 8;
|
|
|
|
static const auto kPrimitiveSize64LinuxMutex = 16;
|
|
static const auto kPrimitiveSize64LinuxSemaphore = 16;
|
|
static const auto kPrimitiveSize64LinuxCS = 32;
|
|
static const auto kPrimitiveSize64LinuxEvent = 32;
|
|
static const auto kPrimitiveSize64LinuxRWLock = 64;
|
|
static const auto kPrimitiveSize64LinuxCond = 32;
|
|
static const auto kPrimitiveSize64LinuxCondMutex = 16;
|
|
|
|
// TODO: These values aren't quite correct yet:
|
|
static const auto kPrimitiveSize32LinuxMutex = 12;
|
|
static const auto kPrimitiveSize32LinuxSemaphore = 12;
|
|
static const auto kPrimitiveSize32LinuxCS = 32;
|
|
static const auto kPrimitiveSize32LinuxEvent = 32;
|
|
static const auto kPrimitiveSize32LinuxRWLock = 64;
|
|
static const auto kPrimitiveSize32LinuxCond = 32;
|
|
static const auto kPrimitiveSize32LinuxCondMutex = 12;
|
|
|
|
// 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
|
|
|
|
#elif defined(AURORA_PLATFORM_LINUX)
|
|
|
|
static const auto kPrimitiveSize64Mutex = kPrimitiveSize64LinuxMutex;
|
|
static const auto kPrimitiveSize64Semaphore = kPrimitiveSize64LinuxSemaphore;
|
|
static const auto kPrimitiveSize64CS = kPrimitiveSize64LinuxCS;
|
|
static const auto kPrimitiveSize64Event = kPrimitiveSize64LinuxEvent;
|
|
static const auto kPrimitiveSize64RWLock = kPrimitiveSize64LinuxRWLock;
|
|
static const auto kPrimitiveSize64Cond = kPrimitiveSize64LinuxCond;
|
|
static const auto kPrimitiveSize64CondMutex = kPrimitiveSize64LinuxCondMutex;
|
|
|
|
static const auto kPrimitiveSize32Mutex = kPrimitiveSize32LinuxMutex;
|
|
static const auto kPrimitiveSize32Semaphore = kPrimitiveSize32LinuxSemaphore;
|
|
static const auto kPrimitiveSize32CS = kPrimitiveSize32LinuxCS;
|
|
static const auto kPrimitiveSize32Event = kPrimitiveSize32LinuxEvent;
|
|
static const auto kPrimitiveSize32RWLock = kPrimitiveSize32LinuxRWLock;
|
|
static const auto kPrimitiveSize32Cond = kPrimitiveSize32LinuxCond;
|
|
static const auto kPrimitiveSize32CondMutex = kPrimitiveSize32LinuxCondMutex;
|
|
|
|
#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 * 2;
|
|
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<AuUInt>(8 + kPrimitiveSizeSemaphore + 4, sizeof(AuUInt));
|
|
|
|
|
|
#if (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
|
|
#pragma pack(push)
|
|
#pragma pack(4)
|
|
#endif
|
|
|
|
struct AUKN_SYM HyperWaitable : IWaitable
|
|
{
|
|
auline inline void Lock() final override
|
|
{
|
|
if (AuAtomicTestAndSet(&this->state_, 0u) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SlowLock();
|
|
}
|
|
|
|
virtual void SlowLock() = 0;
|
|
|
|
protected:
|
|
AuAUInt32 state_ {};
|
|
};
|
|
|
|
#if (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
|
|
#pragma pack(pop)
|
|
#endif
|
|
|
|
#if defined(AURT_ENABLE_HYPER_MUTEX)
|
|
using IHyperWaitable = HyperWaitable;
|
|
#else
|
|
using IHyperWaitable = IWaitable;
|
|
#endif
|
|
}
|
|
|
|
#if defined(AURORA_COMPILER_MSVC)
|
|
#pragma warning(pop)
|
|
#endif |