diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp index 5ab9afc2e437b17f0142e9975bbeec27ce2461dd..14a68bf8b6d9d144bdf861fa572d93d1a46ba7cd 100644 --- a/emper/Runtime.cpp +++ b/emper/Runtime.cpp @@ -264,6 +264,23 @@ auto Runtime::getDefaultWorkerCount() -> workerid_t { return static_cast<workerid_t>(workerCountInt); } + // The CPU count reported by sysconf(_SC_NPROCESSORS_ONLN), sysconf(_SC_NPROCESSORS_CONF) + // or std::thread::hardware_concurrency() may not match the CPU count available + // to the emper process. + // This can happen for example if we run EMPER in a container or qemu.o + // GNU nproc(1) does report the correct CPU count using pthread_getaffinity_np + // which fills a cpu_set with the CPUs the current process can be scheduled on + // therefore we use this more precise CPU count if possible. + // Code inspiration taken from: + // https://github.com/coreutils/gnulib/blob/90e79512d8b385801218d6e9c4d88ff77186560b/lib/nproc.c#L206 + cpu_set_t set; + if (pthread_getaffinity_np(pthread_self(), sizeof(set), &set) == 0) { + unsigned long count = CPU_COUNT(&set); + if (count > 0) { + return count; + } + } + return std::thread::hardware_concurrency(); }