/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ConditionVariable.Win32.hpp Date: 2021-6-12 Author: Reece ***/ #pragma once #if !defined(_AURUNTIME_GENERICCV) #include "AuConditionMutex.NT.hpp" namespace Aurora::Threading::Primitives { struct ConditionVariableImpl final : IConditionVariable { ConditionVariableImpl(const AuSPtr &mutex); auline AuSPtr GetMutex() override; auline bool WaitForSignal(AuUInt32 timeout) override; bool WaitForSignalNsEx(const std::shared_ptr &pMutex, AuUInt64 timeout); bool WaitForSignalNS(AuUInt64 qwTimeout) override; auline void Signal() override; auline void Broadcast() override; auline bool CheckOut(); private: #if defined(AURORA_FORCE_SRW_LOCKS) CONDITION_VARIABLE winCond_; #else AuUInt32 wlist {}; AuUInt32 signalCount {}; #endif std::shared_ptr mutex_; }; struct CondVarDummy : IConditionVariable { private: #if defined(AURORA_FORCE_SRW_LOCKS) CONDITION_VARIABLE winCond_; #else AuUInt32 wlist {}; AuUInt32 signalCount {}; #endif }; static const auto kSizeOfDummyCondVar = sizeof(CondVarDummy); static const auto kBoolRequiredLateSet = true; static const auto kShiftCountByBits = 8u; // ...otherwise // assume undefined behaviour past: // * bit zero is used for atomic bit test and yield loops // ( keyed events are an optimization mechanism for Windows XPs spinloop i had accidentally recreated in xenus. ) // ( originally, nt yielding sucked with the most barebones spinlock being dumb a hypervisor-unaware, smt-aware, spinner. ) // ( keyed events would then go in these spinners to serve as an early futex as early back as the year 2001-3 (?). ) // * bit one might be used under some niche versions of windows // (hearsay paranoia) // i actually have no reason to believe windows ever implemented lock-awareness into the kernel // i think it might be fine to skip the whole bit zero thing, but still, im going to say keep the min=2 // worst case scenario, we end up using these bits (we did). } #endif