/*** Copyright (C) 2024 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuIOThreadPool.cpp Date: 2024-2-25 Author: Reece ***/ #include #include "AuIOThreadPool.hpp" namespace Aurora::IO::Async { static AuMutex gMutex; static AuAsync::WorkerPId_t gDefaultGroup; static AuSPtr gThreadPool; static AuList> gWorkersRegistered; static AuUInt gJobRunners = 4; AUKN_SYM void UseSpecifiedWorkerGroup(AuAsync::WorkerPId_t worker) { AU_LOCK_GUARD(gMutex); gDefaultGroup = worker; } static AuAsync::WorkerPId_t SpawnDefaultGroup() { AuAsync::WorkerPId_t ret; // TODO: gJobRunners = runtime config? gThreadPool = AuAsync::NewThreadPool(); if (!gThreadPool) { return {}; } ret = { gThreadPool, 0, AuAsync::kThreadIdAny }; for (AU_ITERATE_N(i, gJobRunners)) { AuAsync::WorkerPId_t copy = ret; copy.second = i; if (!gThreadPool->Spawn(copy)) { if (i > 1) { return ret; } else { return {}; } } } return ret; } static AuAsync::WorkerPId_t GetAuxWorkerPool() { if (gDefaultGroup) { return gDefaultGroup; } else { return gDefaultGroup = SpawnDefaultGroup(); } } AuAsync::WorkerPId_t GetAuxWorkerPoolAndRegister() { AU_LOCK_GUARD(gMutex); if (auto worker = GetAuxWorkerPool()) { if (auto selfWorker = AuAsync::GetCurrentWorkerPId()) { if (gWorkersRegistered.size() > 10) { AuRemoveAllIf(gWorkersRegistered, [](AuWPtr wpThat) { return wpThat.expired(); }); } for (const auto &wpThat : gWorkersRegistered) { if (auto pThat = AuTryLockMemoryType(wpThat)) { if (pThat == selfWorker.GetPool()) { return worker; } } } gWorkersRegistered.push_back(selfWorker.GetPool()); selfWorker.GetPool()->AddDependency(worker.GetPool()); } return worker; } else { SysPanic("No async threadpool"); } } }