/*** 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; auline bool WaitForSignalNsEx(const AuSPtr &pMutex, AuUInt64 timeout); auline bool WaitForSignalNS(AuUInt64 qwTimeout); auline void Signal() override; auline void Broadcast() override; auline bool CheckOut(bool &bRet); 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; // Future (Reece): I got future plans 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 2000 (?). ) // ( that does, in fact, mean the free-toddlers crying about how 'windows stole muh kernels totally originally idea' is entirely wrong at each sub-point. ) // ( though, keyed didn't see much use until Windows Vistas synch primitives were built on top of them. ) // ( infamously missing 100ths scale nanosecond yimeouts and an inablity to lock with a timeout. ) // ( raymond chen once claimed they didnt make it to xp because they werent fast enough ) // ( raymond chen once claimed a "con" of keyedevents were that they were linear ) // ( problem is, as far as i can tell, they didnt really change. whats worse, WakeOnAddress (windows 8+) // ( ...inherits the issue of not having relative/abs nanosecond scale timeouts AND the issue the primitives sucking. ) // ( WakeOnAddress is nothing more than keyed events 2.0 - but with userland list keeping. ) // ( scratch the concept of how i implement WakeOnAddress with lists, how older nts waited with lists under lock, ) // ( they use hashmaps with "le meme lockless" interactions which are surly less expensive than reusing tls allocations ?! ) // ( whether or not its even faster is still up for debate. its just easier to use. ) // * bit one might be used under some niche versions of windows // (hearsay paranoia) // i actually have zero 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. // .... // =8 is future proof // =2 is recommended // =0 would require a bit of a require. i think this is how other people use keyed events nowadays } #endif