AuroraRuntime/Source/Threading/AuWakeOnAddress.hpp
Reece e82ec4a343 [+] IWaitable::LockNS(...)
[+] AuThreading.WakeAllOnAddress
[+] AuThreading.WakeOnAddress
[+] AuThreading.WakeNOnAddress
[+] AuThreading.TryWaitOnAddress
[+] AuThreading.WaitOnAddress
[*] Further optimize synch primitives
[+] AuThreadPrimitives::RWRenterableLock
2023-03-12 15:27:28 +00:00

82 lines
2.0 KiB
C++

/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuWakeOnAddress.hpp
Date: 2023-3-10
Author: Reece
***/
#pragma once
#include "Primitives/AuConditionMutex.Generic.hpp"
#include "Primitives/AuConditionVariable.Generic.hpp"
namespace Aurora::Threading /*::Primitives for this file only!*/
{
static const auto kDefaultWaitPerProcess = 32;
struct WaitState;
struct WaitBuffer
{
char buffer[8];
AuUInt8 uSize;
static WaitBuffer From(const void *pBuf, AuUInt8 uSize);
bool Compare(const void *pBuf);
bool Compare(WaitState &state);
};
struct WaitState
{
WaitBuffer compare;
AuOptionalEx<AuUInt64> qwNanoseconds;
AuOptionalEx<AuUInt32> uDownsizeMask;
};
struct WaitEntry
{
WaitEntry();
~WaitEntry();
// synch
AuUInt32 uAtomic {}; // fastpath
Primitives::ConditionMutexImpl mutex; // mutex ctor must come before var
Primitives::ConditionVariableImpl variable; // ...and something all 2007+ micro and monolithic kernels should have to yield for an event
// state
const void *pAddress {};
AuUInt8 uSize {};
// bookkeeping (parent container)
bool bOverflow {};
bool TryAcquire(const void *pAddress, AuUInt8 uSize);
void Release();
bool SleepOn(WaitState &state);
bool TryWake(const void *pAddress);
bool TryWakeNoLock(const void *pAddress);
bool TryWakeNoLockNoReallyNoLock(const void *pAddress);
};
struct ProcessWaitContainer
{
AuUInt32 uAtomic {};
WaitEntry entries[kDefaultWaitPerProcess];
AuList<AuSPtr<WaitEntry>> overflow;
AuSPtr<WaitEntry> WaitBufferFrom(void *pAddress, AuUInt8 uSize);
template <typename T>
bool IterateAll(T callback);
template <typename T>
bool IterateForceNoCreateDuringOp(T callback);
void Lock();
void Unlock();
void Remove(WaitEntry *pParent);
};
}