mirror of https://github.com/xzeldon/htop.git
Merge branch 'fix-macOS-time-calculations' of amomchilov/htop
This commit is contained in:
commit
fa48c484cc
|
@ -269,6 +269,20 @@ ERROR_A:
|
||||||
Process_updateCmdline(proc, k->kp_proc.p_comm, 0, strlen(k->kp_proc.p_comm));
|
Process_updateCmdline(proc, k->kp_proc.p_comm, 0, strlen(k->kp_proc.p_comm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts ticks in the Mach "timebase" to nanoseconds.
|
||||||
|
// See `mach_timebase_info`, as used to define the `Platform_timebaseToNS` constant.
|
||||||
|
static uint64_t machTicksToNanoseconds(uint64_t schedulerTicks) {
|
||||||
|
double nanoseconds_per_mach_tick = Platform_timebaseToNS;
|
||||||
|
return (uint64_t) (nanoseconds_per_mach_tick * (double) schedulerTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts nanoseconds to hundreths of a second (centiseconds) as needed by the "time" field of the Process struct.
|
||||||
|
static long long int nanosecondsToCentiseconds(uint64_t nanoseconds) {
|
||||||
|
const uint64_t centiseconds_per_second = 100;
|
||||||
|
const uint64_t nanoseconds_per_second = 1e9;
|
||||||
|
return nanoseconds / nanoseconds_per_second * centiseconds_per_second;
|
||||||
|
}
|
||||||
|
|
||||||
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists) {
|
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists) {
|
||||||
DarwinProcess* dp = (DarwinProcess*)proc;
|
DarwinProcess* dp = (DarwinProcess*)proc;
|
||||||
|
|
||||||
|
@ -330,21 +344,25 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
|
||||||
proc->updated = true;
|
proc->updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double time_interval) {
|
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double timeIntervalNS) {
|
||||||
struct proc_taskinfo pti;
|
struct proc_taskinfo pti;
|
||||||
|
|
||||||
if (sizeof(pti) == proc_pidinfo(proc->super.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
|
if (sizeof(pti) == proc_pidinfo(proc->super.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
|
||||||
uint64_t total_existing_time = proc->stime + proc->utime;
|
uint64_t total_existing_time_ns = proc->stime + proc->utime;
|
||||||
uint64_t total_current_time = pti.pti_total_system + pti.pti_total_user;
|
|
||||||
|
|
||||||
if (total_existing_time && 1E-6 < time_interval) {
|
uint64_t user_time_ns = machTicksToNanoseconds(pti.pti_total_user);
|
||||||
uint64_t total_time_diff = total_current_time - total_existing_time;
|
uint64_t system_time_ns = machTicksToNanoseconds(pti.pti_total_system);
|
||||||
proc->super.percent_cpu = ((double)total_time_diff / time_interval) * 100.0;
|
|
||||||
|
uint64_t total_current_time_ns = user_time_ns + system_time_ns;
|
||||||
|
|
||||||
|
if (total_existing_time_ns && 1E-6 < timeIntervalNS) {
|
||||||
|
uint64_t total_time_diff_ns = total_current_time_ns - total_existing_time_ns;
|
||||||
|
proc->super.percent_cpu = ((double)total_time_diff_ns / timeIntervalNS) * 100.0;
|
||||||
} else {
|
} else {
|
||||||
proc->super.percent_cpu = 0.0;
|
proc->super.percent_cpu = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->super.time = total_current_time / 10000000;
|
proc->super.time = nanosecondsToCentiseconds(total_current_time_ns);
|
||||||
proc->super.nlwp = pti.pti_threadnum;
|
proc->super.nlwp = pti.pti_threadnum;
|
||||||
proc->super.m_virt = pti.pti_virtual_size / ONE_K;
|
proc->super.m_virt = pti.pti_virtual_size / ONE_K;
|
||||||
proc->super.m_resident = pti.pti_resident_size / ONE_K;
|
proc->super.m_resident = pti.pti_resident_size / ONE_K;
|
||||||
|
@ -352,8 +370,8 @@ void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList*
|
||||||
proc->super.percent_mem = (double)pti.pti_resident_size * 100.0
|
proc->super.percent_mem = (double)pti.pti_resident_size * 100.0
|
||||||
/ (double)dpl->host_info.max_mem;
|
/ (double)dpl->host_info.max_mem;
|
||||||
|
|
||||||
proc->stime = pti.pti_total_system;
|
proc->stime = system_time_ns;
|
||||||
proc->utime = pti.pti_total_user;
|
proc->utime = user_time_ns;
|
||||||
|
|
||||||
dpl->super.kernelThreads += 0; /*pti.pti_threads_system;*/
|
dpl->super.kernelThreads += 0; /*pti.pti_threads_system;*/
|
||||||
dpl->super.userlandThreads += pti.pti_threadnum; /*pti.pti_threads_user;*/
|
dpl->super.userlandThreads += pti.pti_threadnum; /*pti.pti_threads_user;*/
|
||||||
|
|
|
@ -31,7 +31,7 @@ void Process_delete(Object* cast);
|
||||||
|
|
||||||
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists);
|
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists);
|
||||||
|
|
||||||
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double time_interval);
|
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double timeIntervalNS);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan threads for process state information.
|
* Scan threads for process state information.
|
||||||
|
|
|
@ -160,9 +160,11 @@ void ProcessList_delete(ProcessList* this) {
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static double ticksToNanoseconds(const double ticks) {
|
// Converts "scheduler ticks" to nanoseconds.
|
||||||
|
// See `sysconf(_SC_CLK_TCK)`, as used to define the `Platform_clockTicksPerSec` constant.
|
||||||
|
static double schedulerTicksToNanoseconds(const double ticks) {
|
||||||
const double nanos_per_sec = 1e9;
|
const double nanos_per_sec = 1e9;
|
||||||
return (ticks / Platform_timebaseToNS) * (nanos_per_sec / (double) Platform_clockTicksPerSec);
|
return ticks * (nanos_per_sec / (double) Platform_clockTicksPerSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
|
@ -192,7 +194,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const double time_interval = ticksToNanoseconds(dpl->global_diff) / (double) dpl->super.activeCPUs;
|
const double time_interval_ns = schedulerTicksToNanoseconds(dpl->global_diff) / (double) dpl->super.activeCPUs;
|
||||||
|
|
||||||
/* Clear the thread counts */
|
/* Clear the thread counts */
|
||||||
super->kernelThreads = 0;
|
super->kernelThreads = 0;
|
||||||
|
@ -213,7 +215,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
proc = (DarwinProcess*)ProcessList_getProcess(super, ps[i].kp_proc.p_pid, &preExisting, DarwinProcess_new);
|
proc = (DarwinProcess*)ProcessList_getProcess(super, ps[i].kp_proc.p_pid, &preExisting, DarwinProcess_new);
|
||||||
|
|
||||||
DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], preExisting);
|
DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], preExisting);
|
||||||
DarwinProcess_setFromLibprocPidinfo(proc, dpl, time_interval);
|
DarwinProcess_setFromLibprocPidinfo(proc, dpl, time_interval_ns);
|
||||||
|
|
||||||
if (proc->super.st_uid != ps[i].kp_eproc.e_ucred.cr_uid) {
|
if (proc->super.st_uid != ps[i].kp_eproc.e_ucred.cr_uid) {
|
||||||
proc->super.st_uid = ps[i].kp_eproc.e_ucred.cr_uid;
|
proc->super.st_uid = ps[i].kp_eproc.e_ucred.cr_uid;
|
||||||
|
|
Loading…
Reference in New Issue