Detect the number of available CPU cores by using either sched_getaffinity(), GetProcessAffinityMask() or sysconf(), depending on the target platform.

This commit is contained in:
LoRd_MuldeR 2022-03-31 23:05:34 +02:00
parent fdc1c8b0d8
commit 69df385d57
Signed by: mulder
GPG Key ID: 2B5913365F57E03F
8 changed files with 87 additions and 67 deletions

View File

@ -3,6 +3,12 @@
/* This work has been released under the CC0 1.0 Universal license! */ /* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/ /******************************************************************************/
#ifdef _WIN32
# define _CRT_SECURE_NO_WARNINGS 1
#else
# define _GNU_SOURCE 1
#endif
/* Internal */ /* Internal */
#include "thread.h" #include "thread.h"
#include "compiler.h" #include "compiler.h"
@ -16,10 +22,17 @@
# define PTW32_STATIC_LIB 1 # define PTW32_STATIC_LIB 1
#endif #endif
#include <pthread.h> #include <pthread.h>
#include <sched.h>
/* System info */ /* Platform */
#ifdef __unix__ #if defined(__linux__) || defined(PTW32_VERSION) || defined(__CYGWIN__)
# include <sys/sysinfo.h> # define HAVE_SCHED_GETAFFINITY 1
#elif defined(_WIN32)
# define WIN32_LEAN_AND_MEAN 1
# define HAVE_GETPROCESSAFFINITYMASK 1
# include <Windows.h>
#else
# include <unistd.h> /* fall back to sysconf() function */
#endif #endif
/* States */ /* States */
@ -120,6 +133,35 @@ while(0)
} \ } \
while(0) while(0)
// ==========================================================================
// System info
// ==========================================================================
static size_t detect_available_cpu_count(void)
{
long num_processors = 0L;
#if defined(HAVE_SCHED_GETAFFINITY)
cpu_set_t cpu_mask;
CPU_ZERO(&cpu_mask);
if (sched_getaffinity(0, sizeof(cpu_set_t), &cpu_mask) == 0)
{
num_processors = CPU_COUNT(&cpu_mask);
}
#elif defined(HAVE_GETPROCESSAFFINITYMASK)
DWORD_PTR proc_mask, sys_mask;
if (GetProcessAffinityMask(GetCurrentProcess(), &proc_mask, &sys_mask))
{
for (; proc_mask != 0U; proc_mask &= proc_mask - 1U)
{
++num_processors;
}
}
#else
num_processors = sysconf(_SC_NPROCESSORS_ONLN);
#endif
return (num_processors > 0) ? ((size_t)num_processors) : 1U;
}
// ========================================================================== // ==========================================================================
// Thread main // Thread main
// ========================================================================== // ==========================================================================
@ -157,28 +199,6 @@ static void *worker_thread_main(void *const arg)
} }
} }
// ==========================================================================
// System info
// ==========================================================================
#if defined(__unix__)
# define NUM_PROCESSORS_FUNC get_nprocs
#elif defined(PTW32_VERSION)
# define NUM_PROCESSORS_FUNC pthread_num_processors_np
#endif
static size_t detect_cpu_count(void)
{
#ifdef NUM_PROCESSORS_FUNC
const int cpu_count = NUM_PROCESSORS_FUNC();
if (cpu_count > 0)
{
return (size_t) cpu_count;
}
#endif
return 1U;
}
// ========================================================================== // ==========================================================================
// Thread pool API // Thread pool API
// ========================================================================== // ==========================================================================
@ -188,7 +208,7 @@ thrdpl_t *slunkcrypt_thrdpl_create(const size_t count, const thrdpl_worker_t wor
size_t i; size_t i;
thrdpl_t *thrdpl = NULL; thrdpl_t *thrdpl = NULL;
const size_t cpu_count = BOUND(1U, (count > 0U) ? count : detect_cpu_count(), MAX_THREADS); const size_t cpu_count = BOUND(1U, (count > 0U) ? count : detect_available_cpu_count(), MAX_THREADS);
if (cpu_count < 2U) if (cpu_count < 2U)
{ {
return NULL; return NULL;