2023-11-11 10:11:09 +00:00
|
|
|
/***
|
|
|
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
|
|
|
|
File: AuThreadState.hpp
|
|
|
|
Date: 2023-11-04
|
|
|
|
Author: Reece
|
|
|
|
***/
|
|
|
|
#include <Source/RuntimeInternal.hpp>
|
|
|
|
#include "Async.hpp"
|
|
|
|
#include "AuThreadState.hpp"
|
|
|
|
#include <Source/IO/Loop/LSAsync.hpp>
|
|
|
|
#include "ThreadWorkerQueueShim.hpp"
|
|
|
|
|
|
|
|
namespace Aurora::Async
|
|
|
|
{
|
|
|
|
ThreadStateSync::ThreadStateSync():
|
|
|
|
cvVariable(AuUnsafeRaiiToShared(cvWorkMutex.AsPointer()))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2024-03-26 18:37:24 +00:00
|
|
|
ThreadStateBase::ThreadStateBase()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ThreadStateBase::~ThreadStateBase()
|
|
|
|
{
|
|
|
|
if (this->asyncLoop)
|
|
|
|
{
|
|
|
|
this->asyncLoop->pParent = nullptr;
|
|
|
|
|
|
|
|
if (this->asyncLoop)
|
|
|
|
{
|
|
|
|
(void)this->asyncLoop->SourceRemove(this->sync.eventLs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-11 10:11:09 +00:00
|
|
|
bool ThreadStateSync::Init()
|
|
|
|
{
|
|
|
|
this->eventLs = AuLoop::NewLSAsync();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ThreadStateBase::Init()
|
|
|
|
{
|
|
|
|
if (!(this->asyncLoop = AuMakeShared<AsyncLoop>()))
|
|
|
|
{
|
|
|
|
SysPushErrorMemory();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
this->asyncLoop->pParent = this;
|
|
|
|
|
|
|
|
if (!this->asyncLoop->Init())
|
|
|
|
{
|
|
|
|
SysPushErrorNested();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this->sync.Init())
|
|
|
|
{
|
|
|
|
SysPushErrorNested();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this->asyncLoop->SourceAdd(this->sync.eventLs))
|
|
|
|
{
|
|
|
|
SysPushErrorNested();
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2024-07-12 19:40:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
void ThreadStateBase::Deinit()
|
|
|
|
{
|
|
|
|
AuResetMember(this->singletons);
|
|
|
|
}
|
2023-11-11 10:11:09 +00:00
|
|
|
|
2024-01-23 22:35:18 +00:00
|
|
|
void ThreadStateSync::SetEvent(bool bBoth, bool bHasWork)
|
2023-11-11 10:11:09 +00:00
|
|
|
{
|
2024-05-03 10:32:31 +00:00
|
|
|
if (bHasWork)
|
|
|
|
{
|
|
|
|
AuAtomicAdd(&this->cvHasWork, 1u);
|
|
|
|
}
|
|
|
|
|
2023-11-11 10:11:09 +00:00
|
|
|
if (auto pEvent = this->eventLs)
|
|
|
|
{
|
|
|
|
if (AuAtomicTestAndSet(&this->cvLSActive, 0u) == 0)
|
|
|
|
{
|
|
|
|
pEvent->Set();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bBoth)
|
|
|
|
{
|
|
|
|
this->cvWorkMutex->Lock();
|
|
|
|
this->cvWorkMutex->Unlock();
|
|
|
|
|
|
|
|
this->cvVariable->Signal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThreadStateSync::UpdateCVState(ThreadState *pState)
|
|
|
|
{
|
2024-09-05 16:38:54 +00:00
|
|
|
auto uState = AuAtomicLoad(&pState->sync.cvHasWork);
|
2023-11-11 10:11:09 +00:00
|
|
|
auto uMin = AuMin(uState, pState->pendingWorkItems.size());
|
2024-09-05 16:38:54 +00:00
|
|
|
if (!uMin)
|
|
|
|
{
|
|
|
|
uMin = 1;
|
|
|
|
}
|
2023-11-11 10:11:09 +00:00
|
|
|
|
|
|
|
while (uState &&
|
|
|
|
AuAtomicCompareExchange<AuUInt32>(&pState->sync.cvHasWork, uState - uMin, uState) != uState)
|
|
|
|
{
|
|
|
|
uState = pState->sync.cvHasWork;
|
|
|
|
|
|
|
|
if (uState < uMin)
|
|
|
|
{
|
|
|
|
uMin = uState;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|