[+] IThreadPool::IncrementAbortFenceOnPool
[+] IThreadPool::IncrementAbortFenceOnWorker [+] IThreadPool::QueryAbortFence [+] IThreadPool::QueryShouldAbort
This commit is contained in:
parent
5565189d2c
commit
ceb67798f1
@ -134,5 +134,29 @@ namespace Aurora::Async
|
|||||||
* @param pPool
|
* @param pPool
|
||||||
*/
|
*/
|
||||||
virtual void AddDependency(AuSPtr<IThreadPool> pPool) = 0;
|
virtual void AddDependency(AuSPtr<IThreadPool> pPool) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
virtual void IncrementAbortFenceOnPool() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param workerId
|
||||||
|
*/
|
||||||
|
virtual void IncrementAbortFenceOnWorker(WorkerId_t workerId) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual AuUInt64 QueryAbortFence(AuOptional<WorkerId_t> optWorkerId) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param uFenceMagic
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
virtual bool QueryShouldAbort(AuOptional<WorkerId_t> optWorkerId, AuUInt64 uFenceMagic) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -78,6 +78,26 @@ namespace Aurora::Async
|
|||||||
ThreadPool::Shutdown();
|
ThreadPool::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AsyncApp::IncrementAbortFenceOnPool()
|
||||||
|
{
|
||||||
|
ThreadPool::IncrementAbortFenceOnPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncApp::IncrementAbortFenceOnWorker(WorkerId_t workerId)
|
||||||
|
{
|
||||||
|
ThreadPool::IncrementAbortFenceOnWorker(workerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt64 AsyncApp::QueryAbortFence(AuOptional<WorkerId_t> optWorkerId)
|
||||||
|
{
|
||||||
|
return ThreadPool::QueryAbortFence(optWorkerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncApp::QueryShouldAbort(AuOptional<WorkerId_t> optWorkerId, AuUInt64 uFenceMagic)
|
||||||
|
{
|
||||||
|
return ThreadPool::QueryShouldAbort(optWorkerId, uFenceMagic);
|
||||||
|
}
|
||||||
|
|
||||||
AUKN_SYM IAsyncApp *GetAsyncApp()
|
AUKN_SYM IAsyncApp *GetAsyncApp()
|
||||||
{
|
{
|
||||||
return gAsyncAppMem.get();
|
return gAsyncAppMem.get();
|
||||||
|
@ -57,6 +57,12 @@ namespace Aurora::Async
|
|||||||
AuSPtr<Aurora::Threading::IWaitable> GetShutdownEvent() override;
|
AuSPtr<Aurora::Threading::IWaitable> GetShutdownEvent() override;
|
||||||
void AddDependency(AuSPtr<IThreadPool> pPool) override;
|
void AddDependency(AuSPtr<IThreadPool> pPool) override;
|
||||||
|
|
||||||
|
void IncrementAbortFenceOnPool() override;
|
||||||
|
void IncrementAbortFenceOnWorker(WorkerId_t workerId) override;
|
||||||
|
|
||||||
|
AuUInt64 QueryAbortFence(AuOptional<WorkerId_t> optWorkerId) override;
|
||||||
|
bool QueryShouldAbort(AuOptional<WorkerId_t> optWorkerId, AuUInt64 uFenceMagic) override;
|
||||||
|
|
||||||
void CleanUpWorker(WorkerId_t wid) override;
|
void CleanUpWorker(WorkerId_t wid) override;
|
||||||
void CleanWorkerPoolReservedZeroFree() override;
|
void CleanWorkerPoolReservedZeroFree() override;
|
||||||
|
|
||||||
|
@ -19,6 +19,11 @@ namespace Aurora::Async
|
|||||||
virtual void RunAsync() = 0;
|
virtual void RunAsync() = 0;
|
||||||
|
|
||||||
virtual void CancelAsync() {}
|
virtual void CancelAsync() {}
|
||||||
|
|
||||||
|
inline virtual AuOptional<AuPair<AuUInt32, AuUInt32>> QueryFences()
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AsyncFuncRunnable : IAsyncRunnable
|
struct AsyncFuncRunnable : IAsyncRunnable
|
||||||
|
@ -704,6 +704,18 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
for (const auto &id : toBarrier)
|
||||||
|
{
|
||||||
|
if (trySelfPid == id)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AuAtomicAdd(&this->uAtomicShutdownCookie, 1u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Time for fuckiness
|
// Time for fuckiness
|
||||||
|
|
||||||
// Specify the root-level shutdown flag for 'ok, u can work, but you're shutting down after sync barrier'
|
// Specify the root-level shutdown flag for 'ok, u can work, but you're shutting down after sync barrier'
|
||||||
@ -1172,6 +1184,58 @@ namespace Aurora::Async
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
void ThreadPool::IncrementAbortFenceOnPool()
|
||||||
|
{
|
||||||
|
AuAtomicAdd(&this->uAtomicShutdownCookie, 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreadPool::IncrementAbortFenceOnWorker(WorkerId_t workerId)
|
||||||
|
{
|
||||||
|
if (auto pState = this->GetThreadHandle(workerId))
|
||||||
|
{
|
||||||
|
AuAtomicAdd(&pState->uShutdownFence, 1u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuUInt64 ThreadPool::QueryAbortFence(AuOptional<WorkerId_t> optWorkerId)
|
||||||
|
{
|
||||||
|
if (auto pState = this->GetThreadHandle(optWorkerId.value_or(GetCurrentWorkerPId())))
|
||||||
|
{
|
||||||
|
return (AuUInt64(pState->uShutdownFence) << 32ull) | AuUInt64(this->uAtomicShutdownCookie);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this->uAtomicShutdownCookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ThreadPool::QueryShouldAbort(AuOptional<WorkerId_t> optWorkerId, AuUInt64 uFenceMagic)
|
||||||
|
|
||||||
|
{
|
||||||
|
auto uSelfCookie = AuBitsToLower(uFenceMagic);
|
||||||
|
if (uSelfCookie != AuAtomicLoad(&this->uAtomicShutdownCookie))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto uThreadCookie = AuBitsToHigher(uFenceMagic);
|
||||||
|
if (!uThreadCookie)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto pState = this->GetThreadHandle(optWorkerId.value_or(GetCurrentWorkerPId())))
|
||||||
|
{
|
||||||
|
return uThreadCookie != pState->uShutdownFence;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// internal api
|
// internal api
|
||||||
|
|
||||||
|
@ -19,11 +19,13 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
virtual bool WaitFor(WorkerId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms) = 0;
|
virtual bool WaitFor(WorkerId_t unlocker, const AuSPtr<Threading::IWaitable> &primitive, AuUInt32 ms) = 0;
|
||||||
virtual void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable) = 0;
|
virtual void Run(WorkerId_t target, AuSPtr<IAsyncRunnable> runnable) = 0;
|
||||||
|
virtual AuSPtr<ThreadState> GetThreadHandle(WorkerId_t id) = 0;
|
||||||
virtual IThreadPool *ToThreadPool() = 0;
|
virtual IThreadPool *ToThreadPool() = 0;
|
||||||
|
|
||||||
AuUInt32 uAtomicCounter {};
|
AuUInt32 uAtomicCounter {};
|
||||||
AuUInt32 uAtomicIOProcessors {};
|
AuUInt32 uAtomicIOProcessors {};
|
||||||
AuUInt32 uAtomicIOProcessorsWorthlessSources {};
|
AuUInt32 uAtomicIOProcessorsWorthlessSources {};
|
||||||
|
AuUInt32 uAtomicShutdownCookie {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -86,6 +88,12 @@ namespace Aurora::Async
|
|||||||
virtual AuSPtr<AuThreading::IWaitable> GetShutdownEvent() override;
|
virtual AuSPtr<AuThreading::IWaitable> GetShutdownEvent() override;
|
||||||
virtual void AddDependency(AuSPtr<IThreadPool> pPool) override;
|
virtual void AddDependency(AuSPtr<IThreadPool> pPool) override;
|
||||||
|
|
||||||
|
virtual void IncrementAbortFenceOnPool() override;
|
||||||
|
virtual void IncrementAbortFenceOnWorker(WorkerId_t workerId) override;
|
||||||
|
|
||||||
|
virtual AuUInt64 QueryAbortFence(AuOptional<WorkerId_t> optWorkerId) override;
|
||||||
|
virtual bool QueryShouldAbort(AuOptional<WorkerId_t> optWorkerId, AuUInt64 uFenceMagic) override;
|
||||||
|
|
||||||
bool IsSelfDepleted();
|
bool IsSelfDepleted();
|
||||||
bool IsDepleted();
|
bool IsDepleted();
|
||||||
|
|
||||||
|
@ -74,5 +74,8 @@ namespace Aurora::Async
|
|||||||
AuAUInt32 cvHasWork {};
|
AuAUInt32 cvHasWork {};
|
||||||
AuSPtr<AuLoop::ILSEvent> eventLs;
|
AuSPtr<AuLoop::ILSEvent> eventLs;
|
||||||
AuSPtr<AuLoop::ILoopSource> asyncLoopSourceShared;
|
AuSPtr<AuLoop::ILoopSource> asyncLoopSourceShared;
|
||||||
|
|
||||||
|
//
|
||||||
|
AuUInt32 uShutdownFence { 1 };
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -23,9 +23,8 @@ namespace Aurora::Async
|
|||||||
const WorkerPId_t &worker,
|
const WorkerPId_t &worker,
|
||||||
AuVoidFunc &&func) :
|
AuVoidFunc &&func) :
|
||||||
WorkItem(owner, worker, {}),
|
WorkItem(owner, worker, {}),
|
||||||
func(func)
|
func(func)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkItem::WorkItem(IThreadPoolInternal *owner,
|
WorkItem::WorkItem(IThreadPoolInternal *owner,
|
||||||
@ -34,6 +33,12 @@ namespace Aurora::Async
|
|||||||
worker_(worker), task_(task), owner_(owner),
|
worker_(worker), task_(task), owner_(owner),
|
||||||
finishedEvent_(false, true, true)
|
finishedEvent_(false, true, true)
|
||||||
{
|
{
|
||||||
|
this->uShutdownCookie = owner->uAtomicShutdownCookie;
|
||||||
|
|
||||||
|
if (auto pWorker = this->GetState())
|
||||||
|
{
|
||||||
|
this->optOtherCookie = pWorker->uShutdownFence;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorkItem::~WorkItem()
|
WorkItem::~WorkItem()
|
||||||
@ -262,11 +267,45 @@ namespace Aurora::Async
|
|||||||
void WorkItem::CancelAsync()
|
void WorkItem::CancelAsync()
|
||||||
{
|
{
|
||||||
AU_TRY_LOCK_GUARD_NAMED(this->lock2, asd);
|
AU_TRY_LOCK_GUARD_NAMED(this->lock2, asd);
|
||||||
Fail();
|
this->Fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
AuOptional<AuPair<AuUInt32, AuUInt32>> WorkItem::QueryFences()
|
||||||
|
{
|
||||||
|
return AuPair<AuUInt32, AuUInt32>{ this->uShutdownCookie, this->optOtherCookie.ValueOr(0) };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorkItem::CheckAlive()
|
||||||
|
{
|
||||||
|
if (this->owner_ &&
|
||||||
|
this->uShutdownCookie != this->owner_->uAtomicShutdownCookie)
|
||||||
|
{
|
||||||
|
this->Fail();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->optOtherCookie)
|
||||||
|
{
|
||||||
|
if (auto pWorker = this->GetState())
|
||||||
|
{
|
||||||
|
if (this->optOtherCookie.value() != pWorker->uShutdownFence)
|
||||||
|
{
|
||||||
|
this->Fail();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorkItem::DispatchTask(IWorkItemHandler::ProcessInfo &info)
|
void WorkItem::DispatchTask(IWorkItemHandler::ProcessInfo &info)
|
||||||
{
|
{
|
||||||
|
if (!this->CheckAlive())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->task_)
|
if (this->task_)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -277,12 +316,21 @@ namespace Aurora::Async
|
|||||||
{
|
{
|
||||||
// TODO: runtime config for root level exception caught behaviour
|
// TODO: runtime config for root level exception caught behaviour
|
||||||
SysPushErrorCatch();
|
SysPushErrorCatch();
|
||||||
Fail();
|
this->Fail();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuSPtr<ThreadState> WorkItem::GetState()
|
||||||
|
{
|
||||||
|
if (!this->worker_.HasValue())
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return this->owner_->GetThreadHandle(this->worker_.value());
|
||||||
|
}
|
||||||
|
|
||||||
void WorkItem::RunAsyncLocked2()
|
void WorkItem::RunAsyncLocked2()
|
||||||
{
|
{
|
||||||
AU_LOCK_GUARD(this->lock2);
|
AU_LOCK_GUARD(this->lock2);
|
||||||
@ -349,7 +397,7 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
if (!WaitForLocked(info.waitFor))
|
if (!WaitForLocked(info.waitFor))
|
||||||
{
|
{
|
||||||
Fail();
|
this->Fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -361,7 +409,7 @@ namespace Aurora::Async
|
|||||||
}
|
}
|
||||||
case ETickType::eFailed:
|
case ETickType::eFailed:
|
||||||
{
|
{
|
||||||
Fail();
|
this->Fail();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -453,6 +501,13 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
void FuncWorker::DispatchTask(IWorkItemHandler::ProcessInfo &info)
|
void FuncWorker::DispatchTask(IWorkItemHandler::ProcessInfo &info)
|
||||||
{
|
{
|
||||||
|
auto func = AuExchange(this->func, {});
|
||||||
|
|
||||||
|
if (!this->CheckAlive())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (func)
|
if (func)
|
||||||
{
|
{
|
||||||
func();
|
func();
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Aurora::Async
|
namespace Aurora::Async
|
||||||
{
|
{
|
||||||
|
struct ThreadState;
|
||||||
|
|
||||||
struct WorkItem :
|
struct WorkItem :
|
||||||
IWorkItem,
|
IWorkItem,
|
||||||
IAsyncRunnable,
|
IAsyncRunnable,
|
||||||
@ -49,6 +51,11 @@ namespace Aurora::Async
|
|||||||
EWorkPrio GetPrio() override;
|
EWorkPrio GetPrio() override;
|
||||||
void SetPrio(EWorkPrio prio) override;
|
void SetPrio(EWorkPrio prio) override;
|
||||||
|
|
||||||
|
AuOptional<AuPair<AuUInt32, AuUInt32>> QueryFences();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool CheckAlive();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RunAsyncLocked();
|
void RunAsyncLocked();
|
||||||
void RunAsyncLocked2();
|
void RunAsyncLocked2();
|
||||||
@ -60,6 +67,9 @@ namespace Aurora::Async
|
|||||||
|
|
||||||
virtual void DispatchTask(IWorkItemHandler::ProcessInfo &info);
|
virtual void DispatchTask(IWorkItemHandler::ProcessInfo &info);
|
||||||
|
|
||||||
|
IThreadPoolInternal *owner_ {};
|
||||||
|
AuSPtr<ThreadState> GetState();
|
||||||
|
|
||||||
AuSPtr<IWorkItemHandler> task_;
|
AuSPtr<IWorkItemHandler> task_;
|
||||||
AuOptionalEx<WorkerPId_t> worker_;
|
AuOptionalEx<WorkerPId_t> worker_;
|
||||||
EWorkPrio prio_ = EWorkPrio::eNormalPrio;
|
EWorkPrio prio_ = EWorkPrio::eNormalPrio;
|
||||||
@ -68,13 +78,14 @@ namespace Aurora::Async
|
|||||||
AuThreadPrimitives::CriticalSection lock;
|
AuThreadPrimitives::CriticalSection lock;
|
||||||
AuThreadPrimitives::CriticalSection lock2;
|
AuThreadPrimitives::CriticalSection lock2;
|
||||||
AuThreadPrimitives::Event finishedEvent_;
|
AuThreadPrimitives::Event finishedEvent_;
|
||||||
|
AuUInt32 uShutdownCookie {};
|
||||||
|
AuOptionalEx<AuUInt32> optOtherCookie {};
|
||||||
|
|
||||||
bool finished {};
|
bool finished {};
|
||||||
bool failed {};
|
bool failed {};
|
||||||
bool dispatchPending_ {};
|
bool dispatchPending_ {};
|
||||||
AuUInt64 dispatchTimeNs_ {};
|
AuUInt64 dispatchTimeNs_ {};
|
||||||
AuUInt64 delayTimeNs_ {};
|
AuUInt64 delayTimeNs_ {};
|
||||||
IThreadPoolInternal *owner_ {};
|
|
||||||
|
|
||||||
void Fail();
|
void Fail();
|
||||||
bool Schedule();
|
bool Schedule();
|
||||||
|
Loading…
Reference in New Issue
Block a user