From 174d885649d5cc45a77e93f928ca735617d531cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 7 Oct 2022 16:52:52 +0800 Subject: [PATCH] CpuUsage: add support for Windows --- CMakeLists.txt | 2 +- src/detection/cpuUsage/cpuUsage.h | 5 ++- src/detection/cpuUsage/cpuUsage_apple.c | 6 ++-- src/detection/cpuUsage/cpuUsage_linux.c | 7 ++-- src/detection/cpuUsage/cpuUsage_windows.c | 20 +++++++++++ src/modules/cpuUsage.c | 41 +++++++++++++++++------ 6 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 src/detection/cpuUsage/cpuUsage_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a4bec5c4..bb027e73d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -324,6 +324,7 @@ if(WIN_MSYS) src/detection/os/os_windows.cpp src/detection/processes/processes_windows.cpp src/detection/disk/disk_windows.cpp + src/detection/cpuUsage/cpuUsage_windows.c src/util/windows/wmi.cpp # Shared @@ -334,7 +335,6 @@ if(WIN_MSYS) src/detection/media/media_linux.c src/detection/font/font_linux.c src/detection/memory/memory_linux.c - src/detection/cpuUsage/cpuUsage_linux.c src/detection/temps/temps_linux.c ) endif() diff --git a/src/detection/cpuUsage/cpuUsage.h b/src/detection/cpuUsage/cpuUsage.h index cddd1866b..131fb77f2 100644 --- a/src/detection/cpuUsage/cpuUsage.h +++ b/src/detection/cpuUsage/cpuUsage.h @@ -3,6 +3,9 @@ #ifndef FF_INCLUDED_detection_cpu_cpuUsage #define FF_INCLUDED_detection_cpu_cpuUsage -const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll); +#include + +// We need to use uint64_t because sizeof(long) == 4 on Windows +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll); #endif diff --git a/src/detection/cpuUsage/cpuUsage_apple.c b/src/detection/cpuUsage/cpuUsage_apple.c index e170a7ceb..38a6b4865 100644 --- a/src/detection/cpuUsage/cpuUsage_apple.c +++ b/src/detection/cpuUsage/cpuUsage_apple.c @@ -4,7 +4,7 @@ #include #include -const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll) +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) { natural_t numCPUs = 0U; processor_info_array_t cpuInfo; @@ -21,8 +21,8 @@ const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll) + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_SYSTEM] + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_NICE]; integer_t total = inUse + cpuInfo[CPU_STATE_MAX * i + CPU_STATE_IDLE]; - *inUseAll += inUse; - *totalAll += total; + *inUseAll += (uint64_t)inUse; + *totalAll += (uint64_t)total; } return NULL; } diff --git a/src/detection/cpuUsage/cpuUsage_linux.c b/src/detection/cpuUsage/cpuUsage_linux.c index c3e9b37aa..8667fd526 100644 --- a/src/detection/cpuUsage/cpuUsage_linux.c +++ b/src/detection/cpuUsage/cpuUsage_linux.c @@ -2,16 +2,17 @@ #include "cpuUsage.h" #include +#include -const char* ffGetCpuUsageInfo(long* inUseAll, long* totalAll) +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) { - long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; + uint64_t user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0; FILE* procStat = fopen("/proc/stat", "r"); if(procStat == NULL) return "fopen(\"""/proc/stat\", \"r\") == NULL"; - if (fscanf(procStat, "cpu%ld%ld%ld%ld%ld%ld%ld", &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) + if (fscanf(procStat, "cpu%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64 "%" PRIu64, &user, &nice, &system, &idle, &iowait, &irq, &softirq) < 0) { fclose(procStat); return "fscanf() failed"; diff --git a/src/detection/cpuUsage/cpuUsage_windows.c b/src/detection/cpuUsage/cpuUsage_windows.c new file mode 100644 index 000000000..1aa9ba3f6 --- /dev/null +++ b/src/detection/cpuUsage/cpuUsage_windows.c @@ -0,0 +1,20 @@ +#include "fastfetch.h" +#include "cpuUsage.h" + +#define WIN32_LEAN_AND_MEAN 1 +#include + +static inline uint64_t fileTimeToUint64(const FILETIME* ft) { + return (((uint64_t)ft->dwHighDateTime) << 32) | ((uint64_t)ft->dwLowDateTime); +} + +const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll) +{ + FILETIME idleTime, kernelTime, userTime; + if(GetSystemTimes(&idleTime, &kernelTime, &userTime) == 0) + return "GetSystemTimes() failed"; + + *inUseAll = fileTimeToUint64(&userTime) + fileTimeToUint64(&kernelTime); + *totalAll = *inUseAll + fileTimeToUint64(&idleTime); + return NULL; +} diff --git a/src/modules/cpuUsage.c b/src/modules/cpuUsage.c index a41735c82..501072f7b 100644 --- a/src/modules/cpuUsage.c +++ b/src/modules/cpuUsage.c @@ -1,20 +1,39 @@ #include "fastfetch.h" #include "common/printing.h" #include "detection/cpuUsage/cpuUsage.h" -#include -#include + +#if defined(_WIN32) || defined(__CYGWIN__) + #include + #include +#else + #include + #include +#endif #define FF_CPU_USAGE_MODULE_NAME "CPU Usage" #define FF_CPU_USAGE_NUM_FORMAT_ARGS 1 -time_t getTimeInMs() +static inline uint64_t getTimeInMs() { - struct timeval timeNow; - gettimeofday(&timeNow, NULL); - return (timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000); + #if defined(_WIN32) || defined(__CYGWIN__) + return GetTickCount64(); + #else + struct timeval timeNow; + gettimeofday(&timeNow, NULL); + return (uint64_t)((timeNow.tv_sec * 1000) + (timeNow.tv_usec / 1000)); + #endif } -static long inUseAll1, totalAll1, startTime; +static inline void sleepInMs(uint32_t msec) +{ + #if defined(_WIN32) || defined(__CYGWIN__) + SleepEx(msec, TRUE); + #else + nanosleep(&(struct timespec){ msec / 1000, (msec % 1000) * 1000000 }, NULL); + #endif +} + +static uint64_t inUseAll1, totalAll1, startTime; void ffPrepareCPUUsage() { @@ -30,16 +49,16 @@ void ffPrintCPUUsage(FFinstance* instance) error = ffGetCpuUsageInfo(&inUseAll1, &totalAll1); if(error) goto error; - nanosleep(&(struct timespec){ 1, 0 }, NULL); + sleepInMs(1000); } else { - time_t duration = getTimeInMs() - startTime; + uint64_t duration = getTimeInMs() - startTime; if(duration < 1000) - nanosleep(&(struct timespec){ 0, (1000 - duration) * 1000000L }, NULL); + sleepInMs(1000 - (uint32_t) duration); } - long inUseAll2, totalAll2; + uint64_t inUseAll2, totalAll2; error = ffGetCpuUsageInfo(&inUseAll2, &totalAll2); if(error)