/*** Copyright (C) 2021-2024 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuConditionVariable.Generic.hpp Date: 2021-6-14 Author: Reece ***/ #pragma once #include "AuIConditionMutexEx.hpp" #if defined(AURORA_IS_MODERNNT_DERIVED) #include "AuConditionVariable.NT.hpp" #elif defined(AURORA_IS_LINUX_DERIVED) #include "AuConditionVariable.Linux.hpp" #else #define _AURUNTIME_GENERICCV #include "AuConditionMutex.Generic.hpp" namespace Aurora::Threading::Primitives { #pragma pack(push) #pragma pack(4) struct ConditionVariableGeneric final { ConditionVariableGeneric(); ~ConditionVariableGeneric(); bool WaitForSignalNsEx(GenericConditionMutex *pMutex, AuUInt64 timeout, bool bSpin = true); void Signal(); void Broadcast(); bool WaitOne(AuUInt64 qwTimeout, bool bSpin); private: bool TryTakeOneNoSpin(); bool TryTakeOneSpin(); AuUInt32 uState_ {}; AuUInt32 uSleeping_ {}; }; #pragma pack(pop) using ConditionVariableInternal = ConditionVariableGeneric; struct ConditionVariableGenericImpl final : IConditionVariable { inline ConditionVariableGenericImpl(const AuSPtr &mutex) : mutex(mutex) { } auline AuSPtr GetMutex() override { return mutex; } auline bool WaitForSignal(AuUInt32 timeout) override { return cond.WaitForSignalNsEx(&std::static_pointer_cast(this->mutex)->mutex, AuMSToNS(timeout)); } auline bool WaitForSignalNS(AuUInt64 qwTimeout) override { return cond.WaitForSignalNsEx(&std::static_pointer_cast(this->mutex)->mutex, qwTimeout); } inline bool WaitForSignalNsEx(const std::shared_ptr &pMutex, AuUInt64 timeout) { return cond.WaitForSignalNsEx(pMutex.get(), timeout); } auline void Signal() override { cond.Signal(); } auline void Broadcast() override { cond.Broadcast(); } ConditionVariableGeneric cond; std::shared_ptr mutex; }; static const auto kSizeOfDummyCondVar = sizeof(ConditionVariableInternal); } #endif