aboutsummaryrefslogtreecommitdiff
path: root/src/zenutil/workerpools.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-10-10 18:09:53 +0200
committerGitHub Enterprise <[email protected]>2025-10-10 18:09:53 +0200
commitc4801320150ea0c492cf343d490a0a339432f060 (patch)
treed3013ef82c1707e38db3abac94d1fec0ca352394 /src/zenutil/workerpools.cpp
parentshorten thread pool names for Linux which has a limit of 15 characters (#563) (diff)
downloadzen-c4801320150ea0c492cf343d490a0a339432f060.tar.xz
zen-c4801320150ea0c492cf343d490a0a339432f060.zip
add ability to limit concurrency (#565)
effective concurrency in zenserver can be limited via the `--corelimit=<N>` option on the command line. Any value passed in here will be used instead of the return value from `std::thread::hardware_concurrency()` if it is lower. * added --corelimit option to zenserver * made sure thread pools are configured lazily and not during global init * added log output indicating effective and HW concurrency * added change log entry * removed debug logging from ZenEntryPoint::Run() also removed main thread naming on Linux since it makes the output from `top` and similar tools confusing (it shows `main` instead of `zenserver`)
Diffstat (limited to 'src/zenutil/workerpools.cpp')
-rw-r--r--src/zenutil/workerpools.cpp115
1 files changed, 68 insertions, 47 deletions
diff --git a/src/zenutil/workerpools.cpp b/src/zenutil/workerpools.cpp
index 55c91e68e..1bab39b2a 100644
--- a/src/zenutil/workerpools.cpp
+++ b/src/zenutil/workerpools.cpp
@@ -11,98 +11,119 @@ ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
namespace {
- const int LargeWorkerThreadPoolTreadCount = gsl::narrow<int>(Max(std::thread::hardware_concurrency() - 1u, 2u));
- const int MediumWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((std::thread::hardware_concurrency() / 4u), 2u));
- const int SmallWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((std::thread::hardware_concurrency() / 8u), 1u));
- const int TinyWorkerThreadPoolTreadCount = 1;
- static bool IsShutDown = false;
+ struct WorkerPools
+ {
+ const int LargeWorkerThreadPoolTreadCount = gsl::narrow<int>(Max(GetHardwareConcurrency() - 1u, 2u));
+ const int MediumWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((GetHardwareConcurrency() / 4u), 2u));
+ const int SmallWorkerThreadPoolTreadCount = gsl::narrow<int>(Max((GetHardwareConcurrency() / 8u), 1u));
+ const int TinyWorkerThreadPoolTreadCount = 1;
- RwLock PoolLock;
+ bool IsShutDown = false;
- struct WorkerPool
- {
- std::unique_ptr<WorkerThreadPool> Pool;
- const int TreadCount;
- const std::string_view Name;
- };
+ RwLock PoolLock;
- WorkerPool BurstLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large"};
- WorkerPool BackgroundLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large_bg"};
+ struct WorkerPool
+ {
+ std::unique_ptr<WorkerThreadPool> Pool;
+ const int TreadCount;
+ const std::string_view Name;
+ };
- WorkerPool BurstMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium"};
- WorkerPool BackgroundMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium_bg"};
+ WorkerPool BurstLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large"};
+ WorkerPool BackgroundLargeWorkerPool = {.TreadCount = LargeWorkerThreadPoolTreadCount, .Name = "large_bg"};
- WorkerPool BurstSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small"};
- WorkerPool BackgroundSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small_bg"};
+ WorkerPool BurstMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium"};
+ WorkerPool BackgroundMediumWorkerPool = {.TreadCount = MediumWorkerThreadPoolTreadCount, .Name = "medium_bg"};
- WorkerPool BurstTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny"};
- WorkerPool BackgroundTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny_bg"};
+ WorkerPool BurstSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small"};
+ WorkerPool BackgroundSmallWorkerPool = {.TreadCount = SmallWorkerThreadPoolTreadCount, .Name = "small_bg"};
- WorkerPool SyncWorkerPool = {.TreadCount = 0, .Name = "synctp"};
+ WorkerPool BurstTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny"};
+ WorkerPool BackgroundTinyWorkerPool = {.TreadCount = TinyWorkerThreadPoolTreadCount, .Name = "tiny_bg"};
- WorkerThreadPool& EnsurePoolPtr(WorkerPool& Pool)
- {
+ WorkerPool SyncWorkerPool = {.TreadCount = 0, .Name = "synctp"};
+
+ WorkerThreadPool& EnsurePoolPtr(WorkerPool& Pool)
{
- RwLock::SharedLockScope _(PoolLock);
- if (Pool.Pool)
{
- return *Pool.Pool;
+ RwLock::SharedLockScope _(PoolLock);
+ if (Pool.Pool)
+ {
+ return *Pool.Pool;
+ }
}
+ RwLock::ExclusiveLockScope _(PoolLock);
+ ZEN_ASSERT(!IsShutDown);
+ if (!Pool.Pool)
+ {
+ Pool.Pool.reset(new WorkerThreadPool(Pool.TreadCount, Pool.Name));
+ }
+ return *Pool.Pool;
}
- RwLock::ExclusiveLockScope _(PoolLock);
- ZEN_ASSERT(!IsShutDown);
- if (!Pool.Pool)
+
+ void Shutdown()
{
- Pool.Pool.reset(new WorkerThreadPool(Pool.TreadCount, Pool.Name));
+ RwLock::ExclusiveLockScope _(PoolLock);
+ IsShutDown = true;
+ BurstLargeWorkerPool.Pool.reset();
+ BackgroundLargeWorkerPool.Pool.reset();
+ BurstMediumWorkerPool.Pool.reset();
+ BackgroundMediumWorkerPool.Pool.reset();
+ BurstSmallWorkerPool.Pool.reset();
+ BackgroundSmallWorkerPool.Pool.reset();
+ BurstTinyWorkerPool.Pool.reset();
+ BackgroundTinyWorkerPool.Pool.reset();
+ SyncWorkerPool.Pool.reset();
}
- return *Pool.Pool;
+ };
+
+ WorkerPools& Pools()
+ {
+ static WorkerPools _;
+ return _;
}
+
} // namespace
WorkerThreadPool&
GetLargeWorkerPool(EWorkloadType WorkloadType)
{
- return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstLargeWorkerPool : BackgroundLargeWorkerPool);
+ auto& p = Pools();
+ return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstLargeWorkerPool : p.BackgroundLargeWorkerPool);
}
WorkerThreadPool&
GetMediumWorkerPool(EWorkloadType WorkloadType)
{
- return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstMediumWorkerPool : BackgroundMediumWorkerPool);
+ auto& p = Pools();
+ return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstMediumWorkerPool : p.BackgroundMediumWorkerPool);
}
WorkerThreadPool&
GetSmallWorkerPool(EWorkloadType WorkloadType)
{
- return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstSmallWorkerPool : BackgroundSmallWorkerPool);
+ auto& p = Pools();
+ return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstSmallWorkerPool : p.BackgroundSmallWorkerPool);
}
WorkerThreadPool&
GetTinyWorkerPool(EWorkloadType WorkloadType)
{
- return EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? BurstTinyWorkerPool : BackgroundTinyWorkerPool);
+ auto& p = Pools();
+ return p.EnsurePoolPtr(WorkloadType == EWorkloadType::Burst ? p.BurstTinyWorkerPool : p.BackgroundTinyWorkerPool);
}
WorkerThreadPool&
GetSyncWorkerPool()
{
- return EnsurePoolPtr(SyncWorkerPool);
+ auto& p = Pools();
+ return p.EnsurePoolPtr(p.SyncWorkerPool);
}
void
ShutdownWorkerPools()
{
- RwLock::ExclusiveLockScope _(PoolLock);
- IsShutDown = true;
- BurstLargeWorkerPool.Pool.reset();
- BackgroundLargeWorkerPool.Pool.reset();
- BurstMediumWorkerPool.Pool.reset();
- BackgroundMediumWorkerPool.Pool.reset();
- BurstSmallWorkerPool.Pool.reset();
- BackgroundSmallWorkerPool.Pool.reset();
- BurstTinyWorkerPool.Pool.reset();
- BackgroundTinyWorkerPool.Pool.reset();
- SyncWorkerPool.Pool.reset();
+ Pools().Shutdown();
}
} // namespace zen