Skip to content

Revert "darwin: process' running time should not depend on mach ticks" #1643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,8 @@ AC_CHECK_FUNCS([ \
])

if test "$my_htop_platform" = darwin; then
AC_CHECK_FUNCS([mach_timebase_info])

AC_CHECK_FUNCS([host_statistics64], [
AC_CHECK_TYPES([struct vm_statistics64], [], [], [[#include <mach/vm_statistics.h>]])
], [])
Expand Down
4 changes: 2 additions & 2 deletions darwin/DarwinProcess.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,8 @@ void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessTable
const DarwinMachine* dhost = (const DarwinMachine*) proc->super.super.host;

uint64_t total_existing_time_ns = proc->stime + proc->utime;
uint64_t user_time_ns = pti.pti_total_user;
uint64_t system_time_ns = pti.pti_total_system;
uint64_t user_time_ns = Platform_machTicksToNanoseconds(pti.pti_total_user);
uint64_t system_time_ns = Platform_machTicksToNanoseconds(pti.pti_total_system);
uint64_t total_current_time_ns = user_time_ns + system_time_ns;

if (total_existing_time_ns < total_current_time_ns) {
Expand Down
9 changes: 9 additions & 0 deletions darwin/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,14 @@ const MeterClass* const Platform_meterTypes[] = {
NULL
};

static double Platform_nanosecondsPerMachTick = 1.0;

static double Platform_nanosecondsPerSchedulerTick = -1;

static mach_port_t iokit_port; // the mach port used to initiate communication with IOKit

bool Platform_init(void) {
Platform_nanosecondsPerMachTick = Platform_calculateNanosecondsPerMachTick();

// Determine the number of scheduler clock ticks per second
errno = 0;
Expand All @@ -168,6 +171,12 @@ bool Platform_init(void) {
return true;
}

// Converts ticks in the Mach "timebase" to nanoseconds.
// See `mach_timebase_info`, as used to define the `Platform_nanosecondsPerMachTick` constant.
uint64_t Platform_machTicksToNanoseconds(uint64_t mach_ticks) {
return (uint64_t) ((double) mach_ticks * Platform_nanosecondsPerMachTick);
}

// Converts "scheduler ticks" to nanoseconds.
// See `sysconf(_SC_CLK_TCK)`, as used to define the `Platform_nanosecondsPerSchedulerTick` constant.
double Platform_schedulerTicksToNanoseconds(const double scheduler_ticks) {
Expand Down
4 changes: 4 additions & 0 deletions darwin/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ extern const MeterClass* const Platform_meterTypes[];

bool Platform_init(void);

// Converts ticks in the Mach "timebase" to nanoseconds.
// See `mach_timebase_info`, as used to define the `Platform_nanosecondsPerMachTick` constant.
uint64_t Platform_machTicksToNanoseconds(uint64_t mach_ticks);

// Converts "scheduler ticks" to nanoseconds.
// See `sysconf(_SC_CLK_TCK)`, as used to define the `Platform_nanosecondsPerSchedulerTick` constant.
double Platform_schedulerTicksToNanoseconds(const double scheduler_ticks);
Expand Down
27 changes: 10 additions & 17 deletions darwin/PlatformHelpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,14 @@ void Platform_getCPUBrandString(char* cpuBrandString, size_t cpuBrandStringSize)
}
}

// Adapted from https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment
bool Platform_isRunningTranslated(void) {
int ret = 0;
size_t size = sizeof(ret);
errno = 0;
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) {
if (errno == ENOENT)
return false;

fprintf(stderr,
"WARN: Could not determine if this process was running in a translation environment like Rosetta 2.\n"
"Assuming that we're not.\n"
"errno: %i, %s\n", errno, strerror(errno));

return false;
}
return ret;
double Platform_calculateNanosecondsPerMachTick(void) {
// Check if we can determine the timebase used on this system.
// If the API is unavailable assume we get our timebase in nanoseconds.
#ifndef HAVE_MACH_TIMEBASE_INFO
return 1.0;
#else
mach_timebase_info_data_t info;
mach_timebase_info(&info);
return (double)info.numer / (double)info.denom;
#endif
}
4 changes: 4 additions & 0 deletions darwin/PlatformHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,12 @@ int Platform_CompareKernelVersion(KernelVersion v);
// lowerBound <= currentVersion < upperBound
bool Platform_KernelVersionIsBetween(KernelVersion lowerBound, KernelVersion upperBound);

double Platform_calculateNanosecondsPerMachTick(void);

void Platform_getCPUBrandString(char* cpuBrandString, size_t cpuBrandStringSize);

bool Platform_isRunningTranslated(void);

double Platform_calculateNanosecondsPerMachTick(void);

#endif
Loading