/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ThreadPool.hpp Date: 2021-10-30 Author: Reece ***/ #pragma once namespace Aurora::Async { struct GroupState; struct ThreadState; struct IAsyncRunnable; //class WorkItem; struct IThreadPoolInternal { virtual bool WaitFor(WorkerId_t unlocker, const AuSPtr &primitive, AuUInt32 ms) = 0; virtual void Run(WorkerId_t target, AuSPtr runnable) = 0; virtual IThreadPool *ToThreadPool() = 0; AuUInt32 uAtomicCounter {}; AuUInt32 uAtomicIOProcessors {}; AuUInt32 uAtomicIOProcessorsWorthlessSources {}; }; struct ThreadPool : IThreadPool, IThreadPoolInternal, AuEnableSharedFromThis { ThreadPool(); // IThreadPoolInternal bool WaitFor(WorkerPId_t unlocker, const AuSPtr &primitive, AuUInt32 ms); bool WaitFor(WorkerId_t unlocker, const AuSPtr &primitive, AuUInt32 ms) override; void Run(WorkerId_t target, AuSPtr runnable) override; void Run(WorkerId_t target, AuSPtr runnable, bool bIncrement); IThreadPool *ToThreadPool() override; // IThreadPool virtual bool Spawn(WorkerId_t workerId) override; virtual void SetRunningMode(bool eventRunning) override; virtual bool Create(WorkerId_t workerId) override; virtual bool InRunnerMode() override; virtual bool Poll() override; virtual bool RunOnce() override; virtual bool Run() override; virtual void Shutdown() override; virtual bool Exiting() override; virtual AuUInt32 PollAndCount(bool bStrict = true) override; virtual AuUInt32 RunAllPending() override; virtual AuSPtr NewWorkItem(const WorkerId_t &worker, const AuSPtr &task) override; virtual AuSPtr NewWorkFunction(const WorkerId_t &worker, AuVoidFunc callback) override; virtual AuSPtr NewFence() override; virtual Threading::Threads::ThreadShared_t ResolveHandle(WorkerId_t) override; virtual AuBST> GetThreads() override; virtual WorkerId_t GetCurrentThread() override; virtual bool Sync(WorkerId_t workerId, AuUInt32 timeoutMs, bool requireSignal) override; virtual void Signal(WorkerId_t workerId) override; virtual AuSPtr WorkerToLoopSource(WorkerId_t id) override; virtual void SyncAllSafe() override; virtual void AddFeature(WorkerId_t id, AuSPtr feature, bool async) override; virtual void AssertInThreadGroup(ThreadGroup_t group) override; virtual void AssertWorker(WorkerId_t id) override; virtual AuSPtr ToKernelWorkQueue() override; virtual AuSPtr ToKernelWorkQueue(WorkerId_t workerId) override; virtual void UpdateWorkMode(WorkerId_t workerId, RunMode mode) override; virtual ERunMode GetCurrentThreadRunMode() override; virtual ERunMode GetThreadRunMode(WorkerId_t workerId) override; virtual AuSPtr GetShutdownEvent() override; virtual void AddDependency(AuSPtr pPool) override; bool IsSelfDepleted(); bool IsDepleted(); //virtual bool ScheduleLoopSource(const AuSPtr &loopSource, WorkerId_t workerId, AuUInt32 timeout, const AuConsumer, bool> &callback) override; // Internal API bool Spawn(WorkerId_t workerId, bool create); bool InternalRunOne(AuSPtr, bool block, AuUInt32 &uCount); bool PollInternal(AuSPtr, bool block, AuUInt32 &uCount); void DoThing(ThreadState *pState); size_t GetThreadWorkersCount(ThreadGroup_t group); virtual void CleanUpWorker(WorkerId_t wid) {}; virtual void CleanWorkerPoolReservedZeroFree() {}; // calls shutdown under async apps // Secret old fiber api bool CtxYield(); int CtxPollPush(); void CtxPollReturn(const AuSPtr &state, int status, bool hitTask); // TLS handle struct WorkerWPId_t : WorkerId_t { WorkerWPId_t() {} WorkerWPId_t(const WorkerPId_t &ref) : WorkerId_t(ref.first, ref.second), pool(ref.pool) {} AuWPtr pool; }; AuThreads::TLSVariable tlsWorkerId; AuSPtr GetThreadHandle(WorkerId_t id); private: // TODO: BarrierMultiple bool Barrier(WorkerId_t, AuUInt32 ms, bool requireSignal, bool drop); protected: void Entrypoint(WorkerId_t id); private: void EarlyExitTick(); void ThisExiting(); AuSPtr GetGroup(ThreadGroup_t type); AuSPtr GetThreadState(); AuSPtr GetThreadStateNoWarn(); AuList> GetThreadHandles(WorkerId_t id); AuSPtr threadGroups_[255]; AuUInt32 shuttingdown_ {}; bool shutdown {}; AuThreadPrimitives::RWRenterableLock rwlock_; AuThreadPrimitives::Event shutdownEvent_; bool runnersRunning_ {}; AuList> listWeakDeps_; AuList> listWeakDepsParents_; friend struct KeepGroupAlive; }; }