// start of multicore_util.h /* Multicore Utility functions */ #ifndef _MULTICORE_UTIL_H_ #define _MULTICORE_UTIL_H_ /* A wrapper for getting rusage on Linux and MacOS */ /* TODO maybe figure out this for windows */ static inline int getrusage_thread(struct rusage *rusage) { int err = -1; #if defined(__APPLE__) thread_basic_info_data_t info = { 0 }; mach_msg_type_number_t info_count = THREAD_BASIC_INFO_COUNT; kern_return_t kern_err; kern_err = thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)&info, &info_count); if (kern_err == KERN_SUCCESS) { memset(rusage, 0, sizeof(struct rusage)); rusage->ru_utime.tv_sec = info.user_time.seconds; rusage->ru_utime.tv_usec = info.user_time.microseconds; rusage->ru_stime.tv_sec = info.system_time.seconds; rusage->ru_stime.tv_usec = info.system_time.microseconds; err = 0; } else { errno = EINVAL; } #elif defined(__linux__) err = getrusage(RUSAGE_THREAD, rusage); #endif return err; } /* returns the number of logical cores */ static int num_processors() { #if defined(_WIN32) /* https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info */ SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); int ncores = sysinfo.dwNumberOfProcessors; fprintf(stderr, "Found %d cores on your Windows machine\n Is that correct?\n", ncores); return ncores; #elif defined(__APPLE__) int ncores; size_t ncores_size = sizeof(ncores); CHECK_ERRNO(sysctlbyname("hw.logicalcpu", &ncores, &ncores_size, NULL, 0), "sysctlbyname (hw.logicalcpu)"); return ncores; #elif defined(__linux__) return get_nprocs(); #else fprintf(stderr, "operating system not recognised\n"); return -1; #endif } static inline void output_thread_usage(struct worker *worker) { struct rusage usage; CHECK_ERRNO(getrusage_thread(&usage), "getrusage_thread"); struct timeval user_cpu_time = usage.ru_utime; struct timeval sys_cpu_time = usage.ru_stime; fprintf(stderr, "tid: %2d - work time %10llu us - user time: %10llu us - sys: %10llu us\n", worker->tid, (long long unsigned)worker->time_spent_working / 1000, (long long unsigned)(user_cpu_time.tv_sec * 1000000 + user_cpu_time.tv_usec), (long long unsigned)(sys_cpu_time.tv_sec * 1000000 + sys_cpu_time.tv_usec)); } static unsigned int g_seed; // Used to seed the generator. static inline void fast_srand(unsigned int seed) { g_seed = seed; } // Compute a pseudorandom integer. // Output value in range [0, 32767] static inline unsigned int fast_rand(void) { g_seed = (214013*g_seed+2531011); return (g_seed>>16)&0x7FFF; } int64_t min_int64(int64_t x, int64_t y) { return x < y ? x : y; } int64_t max_int64(int64_t x, int64_t y) { return x > y ? x : y; } #endif // end of multicore_util.h