83 lines
2.1 KiB
C++
83 lines
2.1 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;
|
|
AuUInt32 uWordSize {};
|
|
};
|
|
|
|
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);
|
|
};
|
|
} |