/* Copyright (C) 2002-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3cores.ctr */ /** @file dk3cores.c The dk3cores module. */ #line 70 "dk3cores.ctr" #ifndef _WIN32_WINNT /** On Windows use minimum Windows version required for functions in this module. */ #define _WIN32_WINNT 0x0501 #endif #include "dk3all.h" #if MACOS || DK3_HAVE_SYS_SYSCTL_H #include #endif #include "dk3cores.h" #include "dk3unused.h" #line 88 "dk3cores.ctr" #if DK3_ON_WINDOWS typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); typedef void (WINAPI *LPFN_GETSYSTEMINFO) (LPSYSTEM_INFO); #endif int dk3cores_is_wow64(void) { int back = 0; #if DK3_ON_WINDOWS LPFN_ISWOW64PROCESS fnIsWow64Process; /* Function address */ BOOL bIsWow64 = FALSE; /* Flag: Is Wow64 process. */ #if DK3_CHAR_SIZE > 1 fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandleW( L"kernel32" ), "IsWow64Process" ); #else fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandleA("kernel32"), "IsWow64Process" ); #endif if(NULL != fnIsWow64Process) { if(fnIsWow64Process(GetCurrentProcess(), &bIsWow64)) { if(bIsWow64) { back = 1; } } } #endif return back; } #if !DK3_ON_WINDOWS /** Compare two unsigned long numbers. @param l Pointer to left number. @param r Pointer to right number. @param cr Comparison criteria, ignored. @return Comparison result. */ static int dk3cores_compare_lu(void const *l, void const *r, int DK3_ARG_UNUSED(cr) ) { int back = 0; unsigned long const *ull; unsigned long const *ulr; DK3_UNUSED_ARG(cr) if(l) { if(r) { ull = (unsigned long const *)l; ulr = (unsigned long const *)r; if((*ull) > (*ulr)) { back = 1; } else { if((*ull) < (*ulr)) { back = -1; } } } else back = 1; } else { if(r) back = -1; } return back; } /** Retrieve number of cores from /proc/cpuinfo. @param src Pointer to information source indicator variable. @return Number of cores found, 1 for default. */ static size_t dk3cores_from_proc_cpuinfo(int *src) { char line[1024]; /* Input text line buffer. */ FILE *fipo = NULL; /* Input file. */ char *pc = NULL; /* Current word pointer. */ char *pn = NULL; /* Next text pointer. */ dk3_sto_t *scores = NULL; /* Storage for found core numbers. */ dk3_sto_it_t *icores = NULL; /* Iterator through core numbers storage. */ unsigned long *ulp = NULL; /* New unsigned long memory. */ unsigned long ul = 0UL; /* Result variable for sscanf(). */ unsigned long maxul = 0UL; /* Maximum core ID found so far. */ int memerr = 0; /* Flag: Memory allocation error occured. */ size_t back = 0; #line 180 "dk3cores.ctr" scores = dk3sto_open_app(NULL); if(scores) { dk3sto_set_comp(scores, dk3cores_compare_lu, 0); icores = dk3sto_it_open(scores); if(icores) { fipo = fopen("/proc/cpuinfo", "r"); if(fipo) { while(fgets(line, sizeof(line), fipo)) { pc = dk3str_c8_start(line, NULL); if(pc) { dk3str_c8_delnl(line); #line 191 "dk3cores.ctr" pn = dk3str_c8_next(pc, NULL); if(0 == strcmp(pc, "core")) { pc = pn; if(pc) { pn = dk3str_c8_next(pc, NULL); if(0 == strcmp(pc, "id")) { pc = pn; if(pc) { if(':' == *pc) { pc++; #if VERSION_BEFORE_20140716 if(1 == sscanf(pc, "%lu", &ul)) #else if(0 != dk3ma_ul_from_c8_string(&ul, pc, NULL)) #endif { #line 207 "dk3cores.ctr" if(ul > maxul) { maxul = ul; } if (NULL != src) { *src = DK3_CORES_SRC_CPUINFO; } ulp = (unsigned long *)dk3sto_it_find_like( icores, (void *)(&ul), 0 ); if(NULL == ulp) { ulp = dk3_new(unsigned long,1); if(ulp) { if(!dk3sto_add(scores, (void *)ulp)) { memerr = 1; } } else { memerr = 1; } } } } } } } } } } fclose(fipo); } else { #line 232 "dk3cores.ctr" } dk3sto_it_reset(icores); while(NULL != (ulp = (unsigned long *)dk3sto_it_next(icores))) { back++; #line 236 "dk3cores.ctr" dk3_delete(ulp); } dk3sto_it_close(icores); } else { #line 240 "dk3cores.ctr" memerr = 1; } dk3sto_close(scores); } else { #line 244 "dk3cores.ctr" memerr = 1; } if(memerr) { #line 247 "dk3cores.ctr" if(back < (size_t)(maxul + 1UL)) { #line 248 "dk3cores.ctr" back = (size_t)(maxul + 1UL); } } if(back < 1) { #line 252 "dk3cores.ctr" back = 1; } #line 254 "dk3cores.ctr" return back; } #endif size_t dk3cores_get_num(int *src) { size_t back = 1; int found = DK3_CORES_SRC_NONE; #if DK3_ON_WINDOWS SYSTEM_INFO si; /* System information structure. */ LPFN_GETSYSTEMINFO fngetsysteminfo; /* Function address. */ char *ptr; /* Environment variable text. */ unsigned u; /* Core number from environment. */ #elif MACOS || (DK3_HAVE_SYSCTL && defined(CTL_HW) && defined(HW_AVAILCPU) && defined(HW_NCPU)) uint32_t count = 0; /* Number of cores found. */ size_t len = 0; /* Argument length for sysctl(). */ int mib[4]; /* Mib for sysctl(). */ int scres = 0; /* Result from sysctl(). */ #endif #line 278 "dk3cores.ctr" #if DK3_ON_WINDOWS if(dk3cores_is_wow64()) { #line 280 "dk3cores.ctr" #if DK3_CHAR_SIZE > 1 fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress( GetModuleHandleW( L"kernel32" ), "GetNativeSystemInfo" ); #else fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress( GetModuleHandleA("kernel32"), "GetNativeSystemInfo" ); #endif if(NULL != fngetsysteminfo) { #line 290 "dk3cores.ctr" fngetsysteminfo(&si); found = DK3_CORES_SRC_SYSTEM; back = (size_t)(si.dwNumberOfProcessors); } else { #line 294 "dk3cores.ctr" #if DK3_CHAR_SIZE > 1 fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress( GetModuleHandleW( L"kernel32" ), "GetSystemInfo" ); #else fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress( GetModuleHandleA("kernel32"), "GetSystemInfo" ); #endif if(NULL != fngetsysteminfo) { #line 304 "dk3cores.ctr" fngetsysteminfo(&si); found = DK3_CORES_SRC_SYSTEM; back = (size_t)(si.dwNumberOfProcessors); } else { #line 308 "dk3cores.ctr" } } } else { #line 311 "dk3cores.ctr" #if DK3_CHAR_SIZE > 1 fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress( GetModuleHandleW( L"kernel32" ), "GetSystemInfo" ); #else fngetsysteminfo = (LPFN_GETSYSTEMINFO)GetProcAddress( GetModuleHandleA("kernel32"), "GetSystemInfo" ); #endif if(NULL != fngetsysteminfo) { #line 321 "dk3cores.ctr" fngetsysteminfo(&si); found = DK3_CORES_SRC_SYSTEM; back = (size_t)(si.dwNumberOfProcessors); } else { #line 325 "dk3cores.ctr" } } if((DK3_CORES_SRC_NONE == found) || (back < 1)) { #line 328 "dk3cores.ctr" ptr = getenv("NUMBER_OF_PROCESSORS"); if(ptr) { #line 330 "dk3cores.ctr" #if VERSION_BEFORE_20140716 if(1 == sscanf(ptr, "%u", &u)) #else if (0 != dk3ma_ui_from_c8_string(&u, ptr, NULL)) #endif { #line 336 "dk3cores.ctr" back = (size_t)u; found = DK3_CORES_SRC_ENVIRONMENT; } else { #line 339 "dk3cores.ctr" } } else { #line 341 "dk3cores.ctr" } } #elif DK3_HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN) #line 345 "dk3cores.ctr" back = (size_t)sysconf(_SC_NPROCESSORS_ONLN); found = DK3_CORES_SRC_SYSTEM; #elif DK3_HAVE_SYSCONF && defined(_SC_NPROC_ONLN) #line 349 "dk3cores.ctr" back = (size_t)sysconf(_SC_NPROC_ONLN); found = DK3_CORES_SRC_SYSTEM; #elif DK3_HAVE_MPCTL && defined(MPC_GETNUMSPUS) #line 353 "dk3cores.ctr" back = (size_t)mpctl(MPC_GETNUMSPUS, NULL, NULL); found = DK3_CORES_SRC_SYSTEM; #elif DK3_HAVE_MPCTL && defined(MPC_GETNUMCPUS) #line 357 "dk3cores.ctr" back = (size_t)mpctl(MPC_GETNUMCPUS, NULL, NULL); found = DK3_CORES_SRC_SYSTEM; #elif MACOS || (DK3_HAVE_SYSCTL && defined(CTL_HW) && defined(HW_AVAILCPU) && defined(HW_NCPU)) #line 361 "dk3cores.ctr" mib[0] = CTL_HW; mib[1] = HW_AVAILCPU; len = sizeof(count); scres = sysctl(mib, 2, &count, &len, NULL, 0); if((0 != scres) || (count < 1)) { #line 364 "dk3cores.ctr" mib[0] = CTL_HW; mib[1] = HW_NCPU; len = sizeof(count); scres = sysctl(mib, 2, &count, &len, NULL, 0); if((0 == scres) && (count > 0)) { #line 367 "dk3cores.ctr" back = (size_t)count; found = DK3_CORES_SRC_SYSTEM; } } else { #line 371 "dk3cores.ctr" back = (size_t)count; found = DK3_CORES_SRC_SYSTEM; } #endif #if !DK3_ON_WINDOWS if((DK3_CORES_SRC_NONE == found)) { #line 377 "dk3cores.ctr" back = dk3cores_from_proc_cpuinfo(&found); } #endif if(back < 1) { #line 381 "dk3cores.ctr" back = 1; } if (NULL != src) { *src = found; } #line 385 "dk3cores.ctr" return back; } size_t dk3cores_max_threads(dk3_app_t *app, int *src) { dkChar line[128]; /* Result buffer for preferences .*/ unsigned long ul; /* Result variable for sscanf(). */ size_t back = 0; size_t cores = 0; /* Number of cores found. */ size_t x; /* Result variable for sscanf(). */ int found = DK3_CORES_SRC_NONE; /* Information source. */ #line 400 "dk3cores.ctr" /* Derive number of threads from number of cores. */ cores = back = dk3cores_get_num(&found); if(back > 2) { back = back - 1; } /* Check /threads/max preference, attempt to use it. */ if(app) { if(dk3app_get_pref(app,dkT("/threads/max"),line,DK3_SIZEOF(line,dkChar))) { #if VERSION_BEFORE_20140716 if(1 == dk3sf_sscanf3(line, dkT("%lu"), &ul)) #else if (0 != dk3ma_ul_from_string(&ul, line, NULL)) #endif { x = (size_t)ul; if(x > back) { dk3app_log_i1(app, DK3_LL_DEBUG, 365); } found = DK3_CORES_SRC_PREFERENCE; back = x; } else { if(0 == dk3str_cmp(dkT("cores"), line)) { back = cores; } } } } /* Apply corrections if no value was found. */ if(back < 1) { back = 1; } if (NULL != src) { *src = found; } #line 439 "dk3cores.ctr" return back; }