summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Scott <nathans@redhat.com>2021-03-30 15:55:48 +1100
committerSohaib <sohaib.amhmd@gmail.com>2021-04-05 23:41:07 +0200
commit356488aa53e8c0bedeb7641685d931c8900098c5 (patch)
treec09f2df8264cc4075b72a55409ae261c021cda55
parent421bdeec603b4fb1a4edec0e802c437fbe47fca0 (diff)
Request the realtime and monotonic clock times once per sample
Refactor the sample time code to make one call to gettimeofday (aka the realtime clock in clock_gettime, when available) and one to the monotonic clock. Stores each in more appropriately named ProcessList fields for ready access when needed. Every platform gets the opportunity to provide their own clock code, and the existing Mac OS X specific code is moved below darwin instead of in Compat. A couple of leftover time(2) calls are converted to use these ProcessList fields as well, instead of yet again sampling the system clock. Related to https://github.com/htop-dev/htop/pull/574
-rw-r--r--ClockMeter.c2
-rw-r--r--Compat.c34
-rw-r--r--Compat.h2
-rw-r--r--DateMeter.c2
-rw-r--r--DateTimeMeter.c5
-rw-r--r--DiskIOMeter.c4
-rw-r--r--Makefile.am14
-rw-r--r--Meter.c4
-rw-r--r--NetworkIOMeter.c4
-rw-r--r--Process.c6
-rw-r--r--Process.h4
-rw-r--r--ProcessList.c27
-rw-r--r--ProcessList.h7
-rw-r--r--ScreenManager.c6
-rw-r--r--darwin/Platform.c24
-rw-r--r--darwin/Platform.h7
-rw-r--r--dragonflybsd/Platform.h9
-rw-r--r--freebsd/Platform.h9
-rw-r--r--generic/gettime.c57
-rw-r--r--generic/gettime.h19
-rw-r--r--linux/LinuxProcessList.c10
-rw-r--r--linux/Platform.h9
-rw-r--r--openbsd/Platform.h9
-rw-r--r--solaris/Platform.h9
-rw-r--r--unsupported/Platform.h9
25 files changed, 210 insertions, 82 deletions
diff --git a/ClockMeter.c b/ClockMeter.c
index de47bdcb..f8a447e9 100644
--- a/ClockMeter.c
+++ b/ClockMeter.c
@@ -23,7 +23,7 @@ static void ClockMeter_updateValues(Meter* this) {
const ProcessList* pl = this->pl;
struct tm result;
- const struct tm* lt = localtime_r(&pl->timestamp.tv_sec, &result);
+ const struct tm* lt = localtime_r(&pl->realtime.tv_sec, &result);
this->values[0] = lt->tm_hour * 60 + lt->tm_min;
strftime(this->txtBuffer, sizeof(this->txtBuffer), "%H:%M:%S", lt);
}
diff --git a/Compat.c b/Compat.c
index 55be1b1d..43d02ec7 100644
--- a/Compat.c
+++ b/Compat.c
@@ -11,18 +11,12 @@ in the source distribution for its full text.
#include <errno.h>
#include <fcntl.h> // IWYU pragma: keep
-#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h> // IWYU pragma: keep
#include "XUtils.h" // IWYU pragma: keep
-#ifdef HAVE_HOST_GET_CLOCK_SERVICE
-#include <mach/clock.h>
-#include <mach/mach.h>
-#endif
-
int Compat_faccessat(int dirfd,
const char* pathname,
@@ -123,31 +117,3 @@ ssize_t Compat_readlinkat(int dirfd,
#endif
}
-
-int Compat_clock_monotonic_gettime(struct timespec *tp) {
-
-#if defined(HAVE_CLOCK_GETTIME)
-
- return clock_gettime(CLOCK_MONOTONIC, tp);
-
-#elif defined(HAVE_HOST_GET_CLOCK_SERVICE)
-
- clock_serv_t cclock;
- mach_timespec_t mts;
-
- host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
- clock_get_time(cclock, &mts);
- mach_port_deallocate(mach_task_self(), cclock);
-
- tp->tv_sec = mts.tv_sec;
- tp->tv_nsec = mts.tv_nsec;
-
- return 0;
-
-#else
-
-#error No Compat_clock_monotonic_gettime() implementation!
-
-#endif
-
-}
diff --git a/Compat.h b/Compat.h
index 95947351..94c2ee2f 100644
--- a/Compat.h
+++ b/Compat.h
@@ -56,6 +56,4 @@ ssize_t Compat_readlinkat(int dirfd,
char* buf,
size_t bufsize);
-int Compat_clock_monotonic_gettime(struct timespec *tp);
-
#endif /* HEADER_Compat */
diff --git a/DateMeter.c b/DateMeter.c
index e7fe1a67..520e516a 100644
--- a/DateMeter.c
+++ b/DateMeter.c
@@ -23,7 +23,7 @@ static void DateMeter_updateValues(Meter* this) {
const ProcessList* pl = this->pl;
struct tm result;
- const struct tm* lt = localtime_r(&pl->timestamp.tv_sec, &result);
+ const struct tm* lt = localtime_r(&pl->realtime.tv_sec, &result);
this->values[0] = lt->tm_yday;
int year = lt->tm_year + 1900;
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
diff --git a/DateTimeMeter.c b/DateTimeMeter.c
index 3fb515b5..588b9fbe 100644
--- a/DateTimeMeter.c
+++ b/DateTimeMeter.c
@@ -20,9 +20,10 @@ static const int DateTimeMeter_attributes[] = {
};
static void DateTimeMeter_updateValues(Meter* this) {
- time_t t = time(NULL);
+ const ProcessList* pl = this->pl;
+
struct tm result;
- const struct tm* lt = localtime_r(&t, &result);
+ const struct tm* lt = localtime_r(&pl->realtime.tv_sec, &result);
int year = lt->tm_year + 1900;
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
this->total = 366;
diff --git a/DiskIOMeter.c b/DiskIOMeter.c
index c1b35690..dd2e3c46 100644
--- a/DiskIOMeter.c
+++ b/DiskIOMeter.c
@@ -34,7 +34,7 @@ static void DiskIOMeter_updateValues(Meter* this) {
const ProcessList* pl = this->pl;
static uint64_t cached_last_update;
- uint64_t passedTimeInMs = pl->timestampMs - cached_last_update;
+ uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update;
/* update only every 500ms */
if (passedTimeInMs > 500) {
@@ -43,7 +43,7 @@ static void DiskIOMeter_updateValues(Meter* this) {
static uint64_t cached_msTimeSpend_total;
uint64_t diff;
- cached_last_update = pl->timestampMs;
+ cached_last_update = pl->realtimeMs;
DiskIOData data;
diff --git a/Makefile.am b/Makefile.am
index f587eeb0..f9b9a7d4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -134,6 +134,7 @@ myhtopheaders = \
# -----
linux_platform_headers = \
+ generic/gettime.h \
generic/hostname.h \
generic/uname.h \
linux/HugePageMeter.h \
@@ -154,6 +155,7 @@ linux_platform_headers = \
zfs/ZfsCompressedArcMeter.h
linux_platform_sources = \
+ generic/gettime.c \
generic/hostname.c \
generic/uname.c \
linux/HugePageMeter.c \
@@ -184,6 +186,7 @@ freebsd_platform_headers = \
freebsd/FreeBSDProcess.h \
freebsd/Platform.h \
freebsd/ProcessField.h \
+ generic/gettime.h \
generic/hostname.h \
generic/openzfs_sysctl.h \
generic/uname.h \
@@ -195,6 +198,7 @@ freebsd_platform_sources = \
freebsd/Platform.c \
freebsd/FreeBSDProcessList.c \
freebsd/FreeBSDProcess.c \
+ generic/gettime.c \
generic/hostname.c \
generic/openzfs_sysctl.c \
generic/uname.c \
@@ -215,6 +219,7 @@ dragonflybsd_platform_headers = \
dragonflybsd/DragonFlyBSDProcess.h \
dragonflybsd/Platform.h \
dragonflybsd/ProcessField.h \
+ generic/gettime.h \
generic/hostname.h \
generic/uname.h
@@ -222,6 +227,7 @@ dragonflybsd_platform_sources = \
dragonflybsd/DragonFlyBSDProcessList.c \
dragonflybsd/DragonFlyBSDProcess.c \
dragonflybsd/Platform.c \
+ generic/gettime.c \
generic/hostname.c \
generic/uname.c
@@ -235,6 +241,7 @@ endif
# -------
openbsd_platform_headers = \
+ generic/gettime.h \
generic/hostname.h \
generic/uname.h \
openbsd/OpenBSDProcessList.h \
@@ -243,6 +250,7 @@ openbsd_platform_headers = \
openbsd/ProcessField.h
openbsd_platform_sources = \
+ generic/gettime.c \
generic/hostname.c \
generic/uname.c \
openbsd/OpenBSDProcessList.c \
@@ -263,6 +271,7 @@ darwin_platform_headers = \
darwin/DarwinProcessList.h \
darwin/Platform.h \
darwin/ProcessField.h \
+ generic/gettime.h \
generic/hostname.h \
generic/openzfs_sysctl.h \
generic/uname.h \
@@ -274,6 +283,7 @@ darwin_platform_sources = \
darwin/Platform.c \
darwin/DarwinProcess.c \
darwin/DarwinProcessList.c \
+ generic/gettime.c \
generic/hostname.c \
generic/openzfs_sysctl.c \
generic/uname.c \
@@ -291,6 +301,7 @@ endif
# -------
solaris_platform_headers = \
+ generic/gettime.h \
generic/hostname.h \
generic/uname.h \
solaris/ProcessField.h \
@@ -302,6 +313,7 @@ solaris_platform_headers = \
zfs/ZfsCompressedArcMeter.h
solaris_platform_sources = \
+ generic/gettime.c \
generic/hostname.c \
generic/uname.c \
solaris/Platform.c \
@@ -320,12 +332,14 @@ endif
# -----------
unsupported_platform_headers = \
+ generic/gettime.h \
unsupported/Platform.h \
unsupported/ProcessField.h \
unsupported/UnsupportedProcess.h \
unsupported/UnsupportedProcessList.h
unsupported_platform_sources = \
+ generic/gettime.c \
unsupported/Platform.c \
unsupported/UnsupportedProcess.c \
unsupported/UnsupportedProcessList.c
diff --git a/Meter.c b/Meter.c
index b60b6933..13df763a 100644
--- a/Meter.c
+++ b/Meter.c
@@ -314,10 +314,10 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
x += captionLen;
w -= captionLen;
- if (!timercmp(&pl->timestamp, &(data->time), <)) {
+ if (!timercmp(&pl->realtime, &(data->time), <)) {
int globalDelay = this->pl->settings->delay;
struct timeval delay = { .tv_sec = globalDelay / 10, .tv_usec = (globalDelay - ((globalDelay / 10) * 10)) * 100000 };
- timeradd(&pl->timestamp, &delay, &(data->time));
+ timeradd(&pl->realtime, &delay, &(data->time));
for (int i = 0; i < nValues - 1; i++)
data->values[i] = data->values[i + 1];
diff --git a/NetworkIOMeter.c b/NetworkIOMeter.c
index bfcb3c0e..84fc12db 100644
--- a/NetworkIOMeter.c
+++ b/NetworkIOMeter.c
@@ -28,7 +28,7 @@ static void NetworkIOMeter_updateValues(Meter* this) {
const ProcessList* pl = this->pl;
static uint64_t cached_last_update = 0;
- uint64_t passedTimeInMs = pl->timestampMs - cached_last_update;
+ uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update;
/* update only every 500ms */
if (passedTimeInMs > 500) {
@@ -38,7 +38,7 @@ static void NetworkIOMeter_updateValues(Meter* this) {
static uint64_t cached_txp_total;
uint64_t diff;
- cached_last_update = pl->timestampMs;
+ cached_last_update = pl->realtimeMs;
NetworkIOData data;
hasData = Platform_getNetworkIO(&data);
diff --git a/Process.c b/Process.c
index b67ad445..6eecddfc 100644
--- a/Process.c
+++ b/Process.c
@@ -467,14 +467,14 @@ void Process_toggleTag(Process* this) {
bool Process_isNew(const Process* this) {
assert(this->processList);
- if (this->processList->scanTs >= this->seenTs) {
- return this->processList->scanTs - this->seenTs <= 1000 * this->processList->settings->highlightDelaySecs;
+ if (this->processList->monotonicMs >= this->seenStampMs) {
+ return this->processList->monotonicMs - this->seenStampMs <= 1000 * (uint64_t)this->processList->settings->highlightDelaySecs;
}
return false;
}
bool Process_isTomb(const Process* this) {
- return this->tombTs > 0;
+ return this->tombStampMs > 0;
}
bool Process_setPriority(Process* this, int priority) {
diff --git a/Process.h b/Process.h
index e9c42622..72197963 100644
--- a/Process.h
+++ b/Process.h
@@ -174,8 +174,8 @@ typedef struct Process_ {
/*
* Internal time counts for showing new and exited processes.
*/
- time_t seenTs;
- time_t tombTs;
+ uint64_t seenStampMs;
+ uint64_t tombStampMs;
/*
* Internal state for tree-mode.
diff --git a/ProcessList.c b/ProcessList.c
index cd8ebd8a..6bc15611 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -10,11 +10,12 @@ in the source distribution for its full text.
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/time.h>
-#include "Compat.h"
#include "CRT.h"
#include "Hashtable.h"
#include "Macros.h"
+#include "Platform.h"
#include "Vector.h"
#include "XUtils.h"
@@ -35,7 +36,7 @@ ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, Users
// set later by platform-specific code
this->cpuCount = 0;
- this->scanTs = 0;
+ this->monotonicMs = 0;
#ifdef HAVE_LIBHWLOC
this->topologyOk = false;
@@ -131,7 +132,7 @@ void ProcessList_add(ProcessList* this, Process* p) {
p->processList = this;
// highlighting processes found in first scan by first scan marked "far in the past"
- p->seenTs = this->scanTs;
+ p->seenStampMs = this->monotonicMs;
Vector_add(this->processes, p);
Hashtable_put(this->processTable, p->pid, p);
@@ -582,8 +583,6 @@ Process* ProcessList_getProcess(ProcessList* this, pid_t pid, bool* preExisting,
}
void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
- struct timespec now;
-
// in pause mode only gather global data for meters (CPU/memory/...)
if (pauseProcessUpdate) {
ProcessList_goThroughEntries(this, true);
@@ -604,31 +603,29 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
this->runningTasks = 0;
- // set scanTs
+ // set scan timestamp
static bool firstScanDone = false;
- if (!firstScanDone) {
- this->scanTs = 0;
+ if (firstScanDone) {
+ Platform_gettime_monotonic(&this->monotonicMs);
+ } else {
+ this->monotonicMs = 0;
firstScanDone = true;
- } else if (Compat_clock_monotonic_gettime(&now) == 0) {
- // save time in millisecond, so with a delay in deciseconds
- // there are no irregularities
- this->scanTs = 1000 * now.tv_sec + now.tv_nsec / 1000000;
}
ProcessList_goThroughEntries(this, false);
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
Process* p = (Process*) Vector_get(this->processes, i);
- if (p->tombTs > 0) {
+ if (p->tombStampMs > 0) {
// remove tombed process
- if (this->scanTs >= p->tombTs) {
+ if (this->monotonicMs >= p->tombStampMs) {
ProcessList_remove(this, p);
}
} else if (p->updated == false) {
// process no longer exists
if (this->settings->highlightChanges && p->wasShown) {
// mark tombed
- p->tombTs = this->scanTs + 1000 * this->settings->highlightDelaySecs;
+ p->tombStampMs = this->monotonicMs + 1000 * this->settings->highlightDelaySecs;
} else {
// immediately remove
ProcessList_remove(this, p);
diff --git a/ProcessList.h b/ProcessList.h
index 46944dbd..7d98197d 100644
--- a/ProcessList.h
+++ b/ProcessList.h
@@ -48,8 +48,9 @@ typedef struct ProcessList_ {
Hashtable* displayTreeSet;
Hashtable* draftingTreeSet;
- struct timeval timestamp; /* time of the current sample */
- uint64_t timestampMs; /* current time in milliseconds */
+ struct timeval realtime; /* time of the current sample */
+ uint64_t realtimeMs; /* current time in milliseconds */
+ uint64_t monotonicMs; /* same, but from monotonic clock */
Panel* panel;
int following;
@@ -79,8 +80,6 @@ typedef struct ProcessList_ {
memory_t cachedSwap;
unsigned int cpuCount;
-
- time_t scanTs;
} ProcessList;
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId);
diff --git a/ScreenManager.c b/ScreenManager.c
index 17a76bf3..6e7551fe 100644
--- a/ScreenManager.c
+++ b/ScreenManager.c
@@ -15,6 +15,7 @@ in the source distribution for its full text.
#include "CRT.h"
#include "FunctionBar.h"
#include "Object.h"
+#include "Platform.h"
#include "ProcessList.h"
#include "ProvideCurses.h"
#include "XUtils.h"
@@ -92,9 +93,8 @@ void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) {
static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTimeout, bool* redraw, bool* rescan, bool* timedOut) {
ProcessList* pl = this->header->pl;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- double newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000);
+ Platform_gettime_realtime(&pl->realtime, &pl->realtimeMs);
+ double newTime = ((double)pl->realtime.tv_sec * 10) + ((double)pl->realtime.tv_usec / 100000);
*timedOut = (newTime - *oldTime > this->settings->delay);
*rescan |= *timedOut;
diff --git a/darwin/Platform.c b/darwin/Platform.c
index 3842fddc..ca8df611 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -37,6 +37,10 @@ in the source distribution for its full text.
#include "zfs/ZfsArcMeter.h"
#include "zfs/ZfsCompressedArcMeter.h"
+#ifdef HAVE_HOST_GET_CLOCK_SERVICE
+#include <mach/clock.h>
+#include <mach/mach.h>
+#endif
#ifdef HAVE_MACH_MACH_TIME_H
#include <mach/mach_time.h>
#endif
@@ -405,3 +409,23 @@ void Platform_getBattery(double* percent, ACPresence* isOnAC) {
CFRelease(list);
CFRelease(power_sources);
}
+
+void Platform_gettime_monotonic(uint64_t* msec) {
+
+#ifdef HAVE_HOST_GET_CLOCK_SERVICE
+
+ clock_serv_t cclock;
+ mach_timespec_t mts;
+
+ host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
+ clock_get_time(cclock, &mts);
+ mach_port_deallocate(mach_task_self(), cclock);
+
+ *msec = ((uint64_t)mts.tv_sec * 1000) + ((uint64_t)mts.tv_nsec / 1000000);
+
+#else
+
+ Generic_gettime_monotomic(msec);
+
+#endif
+}
diff --git a/darwin/Platform.h b/darwin/Platform.h
index 7bce9b35..902d27ef 100644
--- a/darwin/Platform.h
+++ b/darwin/Platform.h
@@ -19,6 +19,7 @@ in the source distribution for its full text.
#include "NetworkIOMeter.h"
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+#include "generic/gettime.h"
#include "generic/hostname.h"
#include "generic/uname.h"
@@ -85,4 +86,10 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
return false;
}
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+void Platform_gettime_monotonic(uint64_t* msec);
+
#endif
diff --git a/dragonflybsd/Platform.h b/dragonflybsd/Platform.h
index 993768be..87c124d9 100644
--- a/dragonflybsd/Platform.h
+++ b/dragonflybsd/Platform.h
@@ -17,6 +17,7 @@ in the source distribution for its full text.
#include "NetworkIOMeter.h"
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+#include "generic/gettime.h"
#include "generic/hostname.h"
#include "generic/uname.h"
@@ -75,4 +76,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
return false;
}
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+static inline void Platform_gettime_monotonic(uint64_t* msec) {
+ Generic_gettime_monotonic(msec);
+}
+
#endif
diff --git a/freebsd/Platform.h b/freebsd/Platform.h
index 884b7634..a0ec6abe 100644
--- a/freebsd/Platform.h
+++ b/freebsd/Platform.h
@@ -18,6 +18,7 @@ in the source distribution for its full text.
#include "Process.h"
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+#include "generic/gettime.h"
#include "generic/hostname.h"
#include "generic/uname.h"
@@ -80,4 +81,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
return false;
}
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+static inline void Platform_gettime_monotonic(uint64_t* msec) {
+ Generic_gettime_monotonic(msec);
+}
+
#endif
diff --git a/generic/gettime.c b/generic/gettime.c
new file mode 100644
index 00000000..ef7d2290
--- /dev/null
+++ b/generic/gettime.c
@@ -0,0 +1,57 @@
+/*
+htop - generic/gettime.c
+(C) 2021 htop dev team
+Released under the GNU GPLv2, see the COPYING file
+in the source distribution for its full text.
+*/
+#include "config.h" // IWYU pragma: keep
+
+#include <string.h>
+#include <time.h>
+
+#include "generic/gettime.h"
+
+
+void Generic_gettime_realtime(struct timeval* tvp, uint64_t* msec) {
+
+#if defined(HAVE_CLOCK_GETTIME)
+
+ struct timespec ts;
+ if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
+ tvp->tv_sec = ts.tv_sec;
+ tvp->tv_usec = ts.tv_nsec / 1000;
+ *msec = ((uint64_t)ts.tv_sec * 1000) + ((uint64_t)ts.tv_nsec / 1000000);
+ } else {
+ memset(tvp, 0, sizeof(struct timeval));
+ *msec = 0;
+ }
+
+#else /* lower resolution gettimeofday(2) is always available */
+
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL) == 0) {
+ *tsp = tv; /* struct copy */
+ *msec = ((uint64_t)tv.tv_sec * 1000) + ((uint64_t)tv.tv_usec / 1000);
+ } else {
+ memset(tvp, 0, sizeof(struct timeval));
+ *msec = 0;
+ }
+
+#endif
+}
+
+void Generic_gettime_monotonic(uint64_t* msec) {
+#if defined(HAVE_CLOCK_GETTIME)
+
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+ *msec = ((uint64_t)ts.tv_sec * 1000) + ((uint64_t)ts.tv_nsec / 1000000);
+ else
+ *msec = 0;
+
+#else
+
+# error "No monotonic clock available"
+
+#endif
+}
diff --git a/generic/gettime.h b/generic/gettime.h
new file mode 100644
index 00000000..fab33da1
--- /dev/null
+++ b/generic/gettime.h
@@ -0,0 +1,19 @@
+#ifndef HEADER_gettime
+#define HEADER_gettime
+/*
+htop - generic/gettime.h
+(C) 2021 htop dev team
+Released under the GNU GPLv2, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include <stdint.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+
+void Generic_gettime_realtime(struct timeval* ts, uint64_t* msec);
+
+void Generic_gettime_monotonic(uint64_t* msec);
+
+#endif
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index c6fd205a..0c0fd16c 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -189,13 +189,6 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super, FILE* stream) {
}
}
-static void LinuxProcessList_updateTime(LinuxProcessList* this) {
- ProcessList* pl = &(this->super);
-
- gettimeofday(&pl->timestamp, NULL);
- pl->timestampMs = (uint64_t)&pl->timestamp.tv_sec * 1000 + (uint64_t)pl->timestamp.tv_usec / 1000;
-}
-
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
LinuxProcessList* this = xCalloc(1, sizeof(LinuxProcessList));
ProcessList* pl = &(this->super);
@@ -1975,7 +1968,6 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
LinuxProcessList* this = (LinuxProcessList*) super;
const Settings* settings = super->settings;
- LinuxProcessList_updateTime(this);
LinuxProcessList_scanMemoryInfo(super);
LinuxProcessList_scanHugePages(this);
LinuxProcessList_scanZfsArcstats(this);
@@ -2005,5 +1997,5 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
openat_arg_t rootFd = "";
#endif
- LinuxProcessList_recurseProcTree(this, rootFd, PROCDIR, NULL, period, super->timestampMs);
+ LinuxProcessList_recurseProcTree(this, rootFd, PROCDIR, NULL, period, super->realtimeMs);
}
diff --git a/linux/Platform.h b/linux/Platform.h
index 18d303d1..78a44275 100644
--- a/linux/Platform.h
+++ b/linux/Platform.h
@@ -19,6 +19,7 @@ in the source distribution for its full text.
#include "Process.h"
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+#include "generic/gettime.h"
#include "generic/hostname.h"
#include "generic/uname.h"
@@ -93,4 +94,12 @@ void Platform_longOptionsUsage(const char* name);
bool Platform_getLongOption(int opt, int argc, char** argv);
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+static inline void Platform_gettime_monotonic(uint64_t* msec) {
+ Generic_gettime_monotonic(msec);
+}
+
#endif
diff --git a/openbsd/Platform.h b/openbsd/Platform.h
index f54b0509..18e1a1c0 100644
--- a/openbsd/Platform.h
+++ b/openbsd/Platform.h
@@ -19,6 +19,7 @@ in the source distribution for its full text.
#include "Process.h"
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+#include "generic/gettime.h"
#include "generic/hostname.h"
#include "generic/uname.h"
@@ -78,4 +79,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
return false;
}
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+static inline void Platform_gettime_monotonic(uint64_t* msec) {
+ Generic_gettime_monotonic(msec);
+}
+
#endif
diff --git a/solaris/Platform.h b/solaris/Platform.h
index cca857bc..47fa3727 100644
--- a/solaris/Platform.h
+++ b/solaris/Platform.h
@@ -26,6 +26,7 @@ in the source distribution for its full text.
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+#include "generic/gettime.h"
#include "generic/hostname.h"
#include "generic/uname.h"
@@ -101,4 +102,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
return false;
}
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+static inline void Platform_gettime_monotonic(uint64_t* msec) {
+ Generic_gettime_monotonic(msec);
+}
+
#endif
diff --git a/unsupported/Platform.h b/unsupported/Platform.h
index 2331e278..849a6861 100644
--- a/unsupported/Platform.h
+++ b/unsupported/Platform.h
@@ -15,6 +15,7 @@ in the source distribution for its full text.
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
#include "UnsupportedProcess.h"
+#include "generic/gettime.h"
extern const SignalItem Platform_signals[];
@@ -69,4 +70,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
return false;
}
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+static inline void Platform_gettime_monotonic(uint64_t* msec) {
+ Generic_gettime_monotonic(msec);
+}
+
#endif

© 2014-2024 Faster IT GmbH | imprint | privacy policy