/*** 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 NewWorkItem(const WorkerId_t &worker, const AuSPtr &task, bool bSupportsBlocking = false) = 0; virtual AuSPtr NewFence() = 0; // virtual Threading::Threads::ThreadShared_t ResolveHandle(WorkerId_t) = 0; // virtual AuBST> 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 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 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 ToKernelWorkQueue() = 0; virtual AuSPtr 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; }; }