AuroraRuntime/Include/Aurora/Threading/Primitives/SOOPrimitives.hpp
2023-07-25 12:27:08 +01:00

130 lines
4.8 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 = 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<AuUInt>(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