/*** Copyright (C) 2023-2024 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuConditionVariable.Linux.hpp Date: 2023-8-11 Author: Reece ***/ #pragma once #if !defined(_AURUNTIME_GENERICCV) #include "AuConditionMutex.Linux.hpp" namespace Aurora::Threading::Primitives { #pragma pack(push) #pragma pack(4) struct ConditionVariableLinux final { ConditionVariableLinux(); ~ConditionVariableLinux(); bool WaitForSignalNsEx(LinuxConditionMutex *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 = ConditionVariableLinux; struct ConditionVariableImpl final : IConditionVariable { inline ConditionVariableImpl(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(); } ConditionVariableInternal cond; std::shared_ptr mutex; }; static const auto kSizeOfDummyCondVar = sizeof(ConditionVariableInternal); } #endif