#ifndef FATICA_H #define FATICA_H // API // unit = 100-nanosecond starting from somewhen unsigned long long fatica_time_process(void); void fatica_cpu_meter(float *value, unsigned long long start, unsigned long long end, uint32_t sample_count, float sample_rate); // Implementation #if defined(_WIN32) || defined(__CYGWIN__) # include static ULONGLONG filetime_to_ull(const FILETIME* ft) { return (((ULONGLONG)ft->dwHighDateTime) << 32) + ft->dwLowDateTime; } unsigned long long fatica_time_process(void) { FILETIME creationTime, exitTime, kernelTime, userTime; const DWORD threadId = GetCurrentThreadId(); const HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, threadId); if (!GetThreadTimes(hThread, &creationTime, &exitTime, &kernelTime, &userTime)) return 0ull; CloseHandle(hThread); return (unsigned long long) (filetime_to_ull(&kernelTime) + filetime_to_ull(&userTime)); } #elif defined(__linux__) # ifndef _XOPEN_SOURCE # if __STDC_VERSION__ >= 199901L # define _XOPEN_SOURCE 600 # else # define _XOPEN_SOURCE 500 # endif # endif # include # include unsigned long long fatica_time_process(void) { struct timespec ts; if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) return 0ull; return (unsigned long long) (ts.tv_sec * 1e7 + ts.tv_nsec / 1e2); } #elif defined(__APPLE__) # include # include # include unsigned long long fatica_time_process(void) { thread_t thread = mach_thread_self(); thread_basic_info_data_t info; mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; if (thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &count) != KERN_SUCCESS) return 0ull; return (info.user_time.seconds + info.system_time.seconds) * 1000 + (info.user_time.microseconds + info.system_time.microseconds) / 1000; } #else # error "System not supported" #endif void fatica_cpu_meter(float *value, unsigned long long start, unsigned long long end, uint32_t sample_count, float sample_rate) { const unsigned long long processTime100n = end - start; const double processTimeMs = ((double) processTime100n) * 1.0e-4; *value = *value * 0.99f + ((float) (processTimeMs * sample_count / (sample_rate * 1000))) * 0.01f; } #endif // FATICA_H