I need to get % CPU currently used by my process on macOS. I expect it to be calculated this way, and it works on Windows:
(currentAppTime - lastTrackedAppTime) * 100% / (currentSysTime - lastTrackedSysTime)
lastTracked and current metrics are collected after a time interval.
Total CPU time code:
mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpuinfo, &count);
lastTrackedSysTime = std::accumulate(cpuinfo.cpu_ticks, cpuinfo.cpu_ticks + count, 0ULL);
Process time:
struct proc_taskinfo taskInfo;
proc_pidinfo(getpid(), PROC_PIDTASKINFO, 0, &taskInfo, sizeof(taskInfo));
lastTrackedAppTime = taskInfo.pti_total_user + taskInfo.pti_total_system;
In my code:
static uint64_t lastTrackedAppTime; // already initialized in ctor
static uint64_t lastTrackedSysTime; // already initialized in ctor
void AppMetrics::getCPU() // called every 5 seconds
{
host_cpu_load_info_data_t cpuinfo;
mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
auto hs = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpuinfo, &count);
assert(hs == KERN_SUCCESS);
uint64_t currentSysTime = std::accumulate(cpuinfo.cpu_ticks, cpuinfo.cpu_ticks + count, 0ULL);
uint64_t totalSysDiff = currentSysTime - lastTrackedSysTime;
struct proc_taskinfo taskInfo;
auto ppi = proc_pidinfo(getpid(), PROC_PIDTASKINFO, 0, &taskInfo, sizeof(taskInfo));
assert(ppi == sizeof(taskInfo));
uint64_t currentAppTime = taskInfo.pti_total_user + taskInfo.pti_total_system;
uint64_t totalAppDiff = currentAppTime - lastTrackedAppTime;
metrics.appCPU = totalAppDiff * 100.0 / totalSysDiff; // the value I need
lastTrackedSysTime = currentSysTime;
lastTrackedAppTime = currentAppTime;
}
The problem is the totalAppDiff
is much bigger than totalSysDiff
.
lastTrackedSysTime: 4555257262
currentSysTime: 4555261249
totalSysDiff: 3987
lastTrackedAppTime: 435637867
currentAppTime: 441909402
totalAppDiff: 6271535
How is this possible? What am I doing wrong? Am I taking the right approach at all?