Jamie Reece Wilson
ceb67798f1
[+] IThreadPool::IncrementAbortFenceOnWorker [+] IThreadPool::QueryAbortFence [+] IThreadPool::QueryShouldAbort
162 lines
6.2 KiB
C++
162 lines
6.2 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: IThreadPool.hpp
|
|
Date: 2021-11-1
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
namespace Aurora::IO::Loop
|
|
{
|
|
struct ILoopQueue;
|
|
struct ILoopSource;
|
|
}
|
|
|
|
namespace Aurora::Async
|
|
{
|
|
AUE_DEFINE(ERunMode,
|
|
(
|
|
eLowLatencyYield, // uses high perf cond var + yield + trylock
|
|
eLowLatencyFreqKernel, // uses high perf cond var + timeout(freqency)
|
|
eEfficient // delegates sleep to the kernel once kernel objects are scheduled
|
|
));
|
|
|
|
struct RunMode
|
|
{
|
|
ERunMode mode;
|
|
AuUInt16 freqMsTick;
|
|
};
|
|
|
|
struct IThreadPool
|
|
{
|
|
// Spawning
|
|
virtual bool Spawn(WorkerId_t workerId) = 0;
|
|
|
|
// Event runner threads release the thread pool upon encountering a zero work condition,
|
|
// allowing for a clean exit out of event driven apps, without the headache of carefully
|
|
// chaining together exit callbacks.
|
|
//
|
|
// Applications that aren't designed around an event driven model should set/keep running
|
|
// mode to false to keep-alive the runners during work exhaustion
|
|
//
|
|
// tl'dr: runner = true, async app; runner = false, thread pool
|
|
virtual void SetRunningMode(bool bRunnerMode) = 0;
|
|
|
|
// Converts the current thread into an async thread
|
|
// Use with RunOnce, Poll
|
|
virtual bool Create(WorkerId_t workerId) = 0;
|
|
|
|
//virtual bool CreateAndRun(WorkerId_t workerId) = 0;
|
|
|
|
// @returns any threads with runner = true
|
|
virtual bool InRunnerMode() = 0;
|
|
|
|
// Manual execution for ::Create() users and those wishing to nest ticks
|
|
virtual bool Poll() = 0;
|
|
|
|
// Block for one
|
|
virtual bool RunOnce() = 0;
|
|
|
|
// Block for standard execution
|
|
virtual bool Run() = 0;
|
|
|
|
// Poll for any counted
|
|
virtual AuUInt32 PollAndCount(bool bStrict = true) = 0;
|
|
|
|
// Alternative ::Poll that's safer to use with mixed IO
|
|
// Returns exact amount of AuAsync callbacks dispatched
|
|
virtual AuUInt32 RunAllPending() = 0;
|
|
|
|
//
|
|
virtual void Shutdown() = 0;
|
|
virtual bool Exiting() = 0;
|
|
|
|
//
|
|
virtual AuSPtr<IWorkItem> NewWorkItem(const WorkerId_t &worker,
|
|
const AuSPtr<IWorkItemHandler> &task) = 0;
|
|
|
|
virtual AuSPtr<IWorkItem> NewWorkFunction(const WorkerId_t &worker,
|
|
AuVoidFunc callback) = 0;
|
|
|
|
virtual AuSPtr<IWorkItem> NewFence() = 0;
|
|
|
|
//
|
|
virtual Threading::Threads::ThreadShared_t ResolveHandle(WorkerId_t) = 0;
|
|
|
|
//
|
|
virtual AuBST<ThreadGroup_t, AuList<ThreadId_t>> GetThreads() = 0;
|
|
|
|
//
|
|
virtual WorkerId_t GetCurrentThread() = 0;
|
|
|
|
// Synchronization
|
|
// Note: syncing to yourself will nullify requireSignal to prevent deadlock conditions
|
|
virtual bool Sync(WorkerId_t workerId,
|
|
AuUInt32 timeoutMs = 0,
|
|
bool bRequireSignal = false) = 0;
|
|
|
|
virtual void Signal(WorkerId_t workerId) = 0;
|
|
|
|
virtual AuSPtr<IO::Loop::ILoopSource> WorkerToLoopSource(WorkerId_t id) = 0;
|
|
|
|
virtual void SyncAllSafe() = 0;
|
|
|
|
// Features
|
|
|
|
/**
|
|
* @brief
|
|
* @param id
|
|
* @param feature
|
|
* @param bDontBlockUntilComplete inverse of block until complete.
|
|
default: block until after IThreadFeature::Init
|
|
*/
|
|
virtual void AddFeature(WorkerId_t id,
|
|
AuSPtr<Threading::Threads::IThreadFeature> feature,
|
|
bool bDontBlockUntilComplete = false) = 0;
|
|
|
|
// Debug
|
|
virtual void AssertInThreadGroup(ThreadGroup_t group) = 0;
|
|
virtual void AssertWorker(WorkerId_t id) = 0;
|
|
|
|
// AuIO overlapped-IO glue
|
|
virtual AuSPtr<IO::Loop::ILoopQueue> ToKernelWorkQueue() = 0;
|
|
virtual AuSPtr<IO::Loop::ILoopQueue> ToKernelWorkQueue(WorkerId_t workerId) = 0;
|
|
virtual void UpdateWorkMode(WorkerId_t workerId, RunMode mode) = 0;
|
|
virtual ERunMode GetCurrentThreadRunMode() = 0;
|
|
virtual ERunMode GetThreadRunMode(WorkerId_t workerId) = 0;
|
|
|
|
//
|
|
virtual AuSPtr<Aurora::Threading::IWaitable> GetShutdownEvent() = 0;
|
|
|
|
/**
|
|
* @brief Prevents preemptive shutdown in ::SetRunningMode(true) mode given loosely held delegation thread pools
|
|
* @param pPool
|
|
*/
|
|
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;
|
|
};
|
|
} |