101 lines
2.5 KiB
C++
101 lines
2.5 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
|
|
{
|
|
static const auto kDefaultWaitPerProcess = 64;
|
|
|
|
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<AuUInt64> qwNanosecondsAbs;
|
|
AuOptionalEx<AuUInt32> uDownsizeMask;
|
|
AuUInt32 uWordSize {};
|
|
};
|
|
|
|
struct WaitEntry
|
|
{
|
|
WaitEntry();
|
|
~WaitEntry();
|
|
|
|
WaitEntry *pNext {};
|
|
WaitEntry *pBefore {};
|
|
|
|
// synch
|
|
AuUInt32 uAtomic {}; // fastpath
|
|
Primitives::ConditionMutexInternal mutex; // mutex ctor must come before var
|
|
Primitives::ConditionVariableInternal 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 bReleaseOnWake {};
|
|
|
|
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 ProcessListWait
|
|
{
|
|
WaitEntry *pHead {};
|
|
WaitEntry *pTail {};
|
|
};
|
|
|
|
struct ProcessWaitNodeContainer
|
|
{
|
|
AuUInt32 uAtomic {};
|
|
#if defined(WOA_ENABLE_OLD_SHORT_LIST)
|
|
WaitEntry entries[kDefaultWaitPerProcess];
|
|
#endif
|
|
ProcessListWait waitList;
|
|
|
|
WaitEntry *WaitBufferFrom(const void *pAddress, AuUInt8 uSize);
|
|
|
|
template <typename T>
|
|
bool IterateWake(T callback);
|
|
|
|
void Lock();
|
|
|
|
void Unlock();
|
|
};
|
|
|
|
struct ProcessWaitContainer
|
|
{
|
|
ProcessWaitNodeContainer list[kDefaultWaitPerProcess];
|
|
|
|
WaitEntry *WaitBufferFrom(const void *pAddress, AuUInt8 uSize);
|
|
|
|
template <typename T>
|
|
bool IterateWake(const void *pAddress, T callback);
|
|
};
|
|
} |