tibia/templates/common/fatica.h
2024-12-09 11:31:35 +01:00

76 lines
2.3 KiB
C

#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 <windows.h>
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 <time.h>
# include <unistd.h>
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 <unistd.h>
# include <mach/mach.h>
# include <mach/thread_act.h>
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