summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Scott <nathans@redhat.com>2021-04-07 15:19:18 +1000
committerNathan Scott <nathans@redhat.com>2021-04-07 15:19:18 +1000
commitf3a37f9ef33cf5459acf1c5352f9c8104cce8806 (patch)
treec09f2df8264cc4075b72a55409ae261c021cda55
parentf16aa483dd36cfdb39e9d6d4238687178f2981e8 (diff)
parent356488aa53e8c0bedeb7641685d931c8900098c5 (diff)
Merge branch 'smalinux-CtrTime'
-rw-r--r--ClockMeter.c5
-rw-r--r--Compat.c34
-rw-r--r--Compat.h2
-rw-r--r--DateMeter.c5
-rw-r--r--DateTimeMeter.c5
-rw-r--r--DiskIOMeter.c10
-rw-r--r--Makefile.am14
-rw-r--r--Meter.c8
-rw-r--r--NetworkIOMeter.c8
-rw-r--r--Process.c6
-rw-r--r--Process.h4
-rw-r--r--ProcessList.c27
-rw-r--r--ProcessList.h6
-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.c6
-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, 220 insertions, 87 deletions
diff --git a/ClockMeter.c b/ClockMeter.c
index 410c7e8a..f8a447e9 100644
--- a/ClockMeter.c
+++ b/ClockMeter.c
@@ -20,9 +20,10 @@ static const int ClockMeter_attributes[] = {
};
static void ClockMeter_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);
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 ac653b62..520e516a 100644
--- a/DateMeter.c
+++ b/DateMeter.c
@@ -20,9 +20,10 @@ static const int DateMeter_attributes[] = {
};
static void DateMeter_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);
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 dde007ed..dd2e3c46 100644
--- a/DiskIOMeter.c
+++ b/DiskIOMeter.c
@@ -31,12 +31,10 @@ static uint32_t cached_write_diff;
static double cached_utilisation_diff;
static void DiskIOMeter_updateValues(Meter* this) {
- static uint64_t cached_last_update;
+ const ProcessList* pl = this->pl;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- uint64_t timeInMilliSeconds = (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000;
- uint64_t passedTimeInMs = timeInMilliSeconds - cached_last_update;
+ static uint64_t cached_last_update;
+ uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update;
/* update only every 500ms */
if (passedTimeInMs > 500) {
@@ -45,7 +43,7 @@ static void DiskIOMeter_updateValues(Meter* this) {
static uint64_t cached_msTimeSpend_total;
uint64_t diff;
- cached_last_update = timeInMilliSeconds;
+ 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 6aa9f08e..13df763a 100644
--- a/Meter.c
+++ b/Meter.c
@@ -18,6 +18,7 @@ in the source distribution for its full text.
#include "CRT.h"
#include "Macros.h"
#include "Object.h"
+#include "Platform.h"
#include "ProvideCurses.h"
#include "RichString.h"
#include "Settings.h"
@@ -286,6 +287,7 @@ static const char* const GraphMeterMode_dotsAscii[] = {
};
static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
+ const ProcessList* pl = this->pl;
if (!this->drawData) {
this->drawData = xCalloc(1, sizeof(GraphData));
@@ -312,12 +314,10 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
x += captionLen;
w -= captionLen;
- struct timeval now;
- gettimeofday(&now, NULL);
- if (!timercmp(&now, &(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(&now, &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 c0e1b06f..84fc12db 100644
--- a/NetworkIOMeter.c
+++ b/NetworkIOMeter.c
@@ -25,12 +25,10 @@ static uint32_t cached_txb_diff;
static uint32_t cached_txp_diff;
static void NetworkIOMeter_updateValues(Meter* this) {
+ const ProcessList* pl = this->pl;
static uint64_t cached_last_update = 0;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- uint64_t timeInMilliSeconds = (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000;
- uint64_t passedTimeInMs = timeInMilliSeconds - cached_last_update;
+ uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update;
/* update only every 500ms */
if (passedTimeInMs > 500) {
@@ -40,7 +38,7 @@ static void NetworkIOMeter_updateValues(Meter* this) {
static uint64_t cached_txp_total;
uint64_t diff;
- cached_last_update = timeInMilliSeconds;
+ 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 3d9b8ff2..7d98197d 100644
--- a/ProcessList.h
+++ b/ProcessList.h
@@ -48,6 +48,10 @@ typedef struct ProcessList_ {
Hashtable* displayTreeSet;
Hashtable* draftingTreeSet;
+ 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;
uid_t userId;
@@ -76,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 b12a415b..0c0fd16c 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -1989,10 +1989,6 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
return;
}
- struct timeval tv;
- gettimeofday(&tv, NULL);
- unsigned long long now = tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL;
-
/* PROCDIR is an absolute path */
assert(PROCDIR[0] == '/');
#ifdef HAVE_OPENAT
@@ -2001,5 +1997,5 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
openat_arg_t rootFd = "";
#endif
- LinuxProcessList_recurseProcTree(this, rootFd, PROCDIR, NULL, period, now);
+ 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