mirror of https://github.com/xzeldon/htop.git
Unhardcode tick-to-ms conversion
Division by 100000.0 worked because `sysconf(_SC_CLK_TCK)` happened to be 100. By unhardcoding: 1) It becomes more clear what this 100000.0 figure comes from. 2) It protects against bugs in the case `sysconf(_SC_CLK_TCK)` ever changes.
This commit is contained in:
parent
f614b8a19f
commit
67ccd6b909
|
@ -292,23 +292,21 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
|
||||||
proc->updated = true;
|
proc->updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl) {
|
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double time_interval) {
|
||||||
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))) {
|
||||||
if (0 != proc->utime || 0 != proc->stime) {
|
uint64_t total_existing_time = proc->stime + proc->utime;
|
||||||
uint64_t diff = (pti.pti_total_system - proc->stime)
|
uint64_t total_current_time = pti.pti_total_system + pti.pti_total_user;
|
||||||
+ (pti.pti_total_user - proc->utime);
|
|
||||||
|
|
||||||
proc->super.percent_cpu = (double)diff * (double)dpl->super.cpuCount * Platform_timebaseToNS
|
if (total_existing_time && 1e-6 < time_interval) {
|
||||||
/ ((double)dpl->global_diff * 100000.0);
|
uint64_t total_time_diff = total_current_time - total_existing_time;
|
||||||
|
proc->super.percent_cpu = ((double)total_time_diff / time_interval) * 100.0;
|
||||||
// fprintf(stderr, "%f %llu %llu %llu %llu %llu\n", proc->super.percent_cpu,
|
} else {
|
||||||
// proc->stime, proc->utime, pti.pti_total_system, pti.pti_total_user, dpl->global_diff);
|
proc->super.percent_cpu = 0.0;
|
||||||
// exit(7);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proc->super.time = (pti.pti_total_system + pti.pti_total_user) / 10000000;
|
proc->super.time = total_current_time / 10000000;
|
||||||
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;
|
||||||
|
|
|
@ -34,7 +34,7 @@ bool Process_isThread(const Process* this);
|
||||||
|
|
||||||
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);
|
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double time_interval);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan threads for process state information.
|
* Scan threads for process state information.
|
||||||
|
|
|
@ -21,6 +21,7 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include "CRT.h"
|
#include "CRT.h"
|
||||||
#include "DarwinProcess.h"
|
#include "DarwinProcess.h"
|
||||||
|
#include "Platform.h"
|
||||||
#include "ProcessList.h"
|
#include "ProcessList.h"
|
||||||
#include "zfs/openzfs_sysctl.h"
|
#include "zfs/openzfs_sysctl.h"
|
||||||
#include "zfs/ZfsArcStats.h"
|
#include "zfs/ZfsArcStats.h"
|
||||||
|
@ -158,6 +159,11 @@ void ProcessList_delete(ProcessList* this) {
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double ticksToNanoseconds(const double ticks) {
|
||||||
|
const double nanos_per_sec = 1e9;
|
||||||
|
return ticks / (double) Platform_clockTicksPerSec * Platform_timebaseToNS * nanos_per_sec;
|
||||||
|
}
|
||||||
|
|
||||||
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
DarwinProcessList* dpl = (DarwinProcessList*)super;
|
DarwinProcessList* dpl = (DarwinProcessList*)super;
|
||||||
bool preExisting = true;
|
bool preExisting = true;
|
||||||
|
@ -185,6 +191,8 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const double time_interval = ticksToNanoseconds(dpl->global_diff) / (double) dpl->super.cpuCount;
|
||||||
|
|
||||||
/* Clear the thread counts */
|
/* Clear the thread counts */
|
||||||
super->kernelThreads = 0;
|
super->kernelThreads = 0;
|
||||||
super->userlandThreads = 0;
|
super->userlandThreads = 0;
|
||||||
|
@ -204,7 +212,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);
|
DarwinProcess_setFromLibprocPidinfo(proc, dpl, time_interval);
|
||||||
|
|
||||||
// Disabled for High Sierra due to bug in macOS High Sierra
|
// Disabled for High Sierra due to bug in macOS High Sierra
|
||||||
bool isScanThreadSupported = ! ( CompareKernelVersion(17, 0, 0) >= 0 && CompareKernelVersion(17, 5, 0) < 0);
|
bool isScanThreadSupported = ! ( CompareKernelVersion(17, 0, 0) >= 0 && CompareKernelVersion(17, 5, 0) < 0);
|
||||||
|
|
|
@ -10,16 +10,18 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
|
||||||
#include <CoreFoundation/CFString.h>
|
#include <CoreFoundation/CFString.h>
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
#include <IOKit/ps/IOPowerSources.h>
|
#include <IOKit/ps/IOPowerSources.h>
|
||||||
#include <IOKit/ps/IOPSKeys.h>
|
#include <IOKit/ps/IOPSKeys.h>
|
||||||
|
|
||||||
#include "ClockMeter.h"
|
#include "ClockMeter.h"
|
||||||
#include "CPUMeter.h"
|
#include "CPUMeter.h"
|
||||||
|
#include "CRT.h"
|
||||||
#include "DarwinProcessList.h"
|
#include "DarwinProcessList.h"
|
||||||
#include "DateMeter.h"
|
#include "DateMeter.h"
|
||||||
#include "DateTimeMeter.h"
|
#include "DateTimeMeter.h"
|
||||||
|
@ -112,6 +114,8 @@ const MeterClass* const Platform_meterTypes[] = {
|
||||||
|
|
||||||
double Platform_timebaseToNS = 1.0;
|
double Platform_timebaseToNS = 1.0;
|
||||||
|
|
||||||
|
long Platform_clockTicksPerSec = -1;
|
||||||
|
|
||||||
void Platform_init(void) {
|
void Platform_init(void) {
|
||||||
// Check if we can determine the timebase used on this system.
|
// Check if we can determine the timebase used on this system.
|
||||||
// If the API is unavailable assume we get our timebase in nanoseconds.
|
// If the API is unavailable assume we get our timebase in nanoseconds.
|
||||||
|
@ -122,6 +126,14 @@ void Platform_init(void) {
|
||||||
#else
|
#else
|
||||||
Platform_timebaseToNS = 1.0;
|
Platform_timebaseToNS = 1.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Determine the number of clock ticks per second
|
||||||
|
errno = 0;
|
||||||
|
Platform_clockTicksPerSec = sysconf(_SC_CLK_TCK);
|
||||||
|
|
||||||
|
if (errno || Platform_clockTicksPerSec < 1) {
|
||||||
|
CRT_fatalError("Unable to retrieve clock tick rate");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_done(void) {
|
void Platform_done(void) {
|
||||||
|
|
|
@ -24,6 +24,8 @@ extern const ProcessField Platform_defaultFields[];
|
||||||
|
|
||||||
extern double Platform_timebaseToNS;
|
extern double Platform_timebaseToNS;
|
||||||
|
|
||||||
|
extern long Platform_clockTicksPerSec;
|
||||||
|
|
||||||
extern const SignalItem Platform_signals[];
|
extern const SignalItem Platform_signals[];
|
||||||
|
|
||||||
extern const unsigned int Platform_numberOfSignals;
|
extern const unsigned int Platform_numberOfSignals;
|
||||||
|
|
Loading…
Reference in New Issue