mirror of https://github.com/xzeldon/htop.git
Merge branch 'smalinux-CtrTime'
This commit is contained in:
commit
f3a37f9ef3
|
@ -20,9 +20,10 @@ static const int ClockMeter_attributes[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ClockMeter_updateValues(Meter* this) {
|
static void ClockMeter_updateValues(Meter* this) {
|
||||||
time_t t = time(NULL);
|
const ProcessList* pl = this->pl;
|
||||||
|
|
||||||
struct tm result;
|
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;
|
this->values[0] = lt->tm_hour * 60 + lt->tm_min;
|
||||||
strftime(this->txtBuffer, sizeof(this->txtBuffer), "%H:%M:%S", lt);
|
strftime(this->txtBuffer, sizeof(this->txtBuffer), "%H:%M:%S", lt);
|
||||||
}
|
}
|
||||||
|
|
34
Compat.c
34
Compat.c
|
@ -11,18 +11,12 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h> // IWYU pragma: keep
|
#include <fcntl.h> // IWYU pragma: keep
|
||||||
#include <time.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h> // IWYU pragma: keep
|
#include <sys/types.h> // IWYU pragma: keep
|
||||||
|
|
||||||
#include "XUtils.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,
|
int Compat_faccessat(int dirfd,
|
||||||
const char* pathname,
|
const char* pathname,
|
||||||
|
@ -123,31 +117,3 @@ ssize_t Compat_readlinkat(int dirfd,
|
||||||
|
|
||||||
#endif
|
#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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
2
Compat.h
2
Compat.h
|
@ -56,6 +56,4 @@ ssize_t Compat_readlinkat(int dirfd,
|
||||||
char* buf,
|
char* buf,
|
||||||
size_t bufsize);
|
size_t bufsize);
|
||||||
|
|
||||||
int Compat_clock_monotonic_gettime(struct timespec *tp);
|
|
||||||
|
|
||||||
#endif /* HEADER_Compat */
|
#endif /* HEADER_Compat */
|
||||||
|
|
|
@ -20,9 +20,10 @@ static const int DateMeter_attributes[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void DateMeter_updateValues(Meter* this) {
|
static void DateMeter_updateValues(Meter* this) {
|
||||||
time_t t = time(NULL);
|
const ProcessList* pl = this->pl;
|
||||||
|
|
||||||
struct tm result;
|
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;
|
this->values[0] = lt->tm_yday;
|
||||||
int year = lt->tm_year + 1900;
|
int year = lt->tm_year + 1900;
|
||||||
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
|
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
|
||||||
|
|
|
@ -20,9 +20,10 @@ static const int DateTimeMeter_attributes[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void DateTimeMeter_updateValues(Meter* this) {
|
static void DateTimeMeter_updateValues(Meter* this) {
|
||||||
time_t t = time(NULL);
|
const ProcessList* pl = this->pl;
|
||||||
|
|
||||||
struct tm result;
|
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;
|
int year = lt->tm_year + 1900;
|
||||||
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
|
if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
|
||||||
this->total = 366;
|
this->total = 366;
|
||||||
|
|
|
@ -31,12 +31,10 @@ static uint32_t cached_write_diff;
|
||||||
static double cached_utilisation_diff;
|
static double cached_utilisation_diff;
|
||||||
|
|
||||||
static void DiskIOMeter_updateValues(Meter* this) {
|
static void DiskIOMeter_updateValues(Meter* this) {
|
||||||
static uint64_t cached_last_update;
|
const ProcessList* pl = this->pl;
|
||||||
|
|
||||||
struct timeval tv;
|
static uint64_t cached_last_update;
|
||||||
gettimeofday(&tv, NULL);
|
uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update;
|
||||||
uint64_t timeInMilliSeconds = (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000;
|
|
||||||
uint64_t passedTimeInMs = timeInMilliSeconds - cached_last_update;
|
|
||||||
|
|
||||||
/* update only every 500ms */
|
/* update only every 500ms */
|
||||||
if (passedTimeInMs > 500) {
|
if (passedTimeInMs > 500) {
|
||||||
|
@ -45,7 +43,7 @@ static void DiskIOMeter_updateValues(Meter* this) {
|
||||||
static uint64_t cached_msTimeSpend_total;
|
static uint64_t cached_msTimeSpend_total;
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
|
|
||||||
cached_last_update = timeInMilliSeconds;
|
cached_last_update = pl->realtimeMs;
|
||||||
|
|
||||||
DiskIOData data;
|
DiskIOData data;
|
||||||
|
|
||||||
|
|
14
Makefile.am
14
Makefile.am
|
@ -134,6 +134,7 @@ myhtopheaders = \
|
||||||
# -----
|
# -----
|
||||||
|
|
||||||
linux_platform_headers = \
|
linux_platform_headers = \
|
||||||
|
generic/gettime.h \
|
||||||
generic/hostname.h \
|
generic/hostname.h \
|
||||||
generic/uname.h \
|
generic/uname.h \
|
||||||
linux/HugePageMeter.h \
|
linux/HugePageMeter.h \
|
||||||
|
@ -154,6 +155,7 @@ linux_platform_headers = \
|
||||||
zfs/ZfsCompressedArcMeter.h
|
zfs/ZfsCompressedArcMeter.h
|
||||||
|
|
||||||
linux_platform_sources = \
|
linux_platform_sources = \
|
||||||
|
generic/gettime.c \
|
||||||
generic/hostname.c \
|
generic/hostname.c \
|
||||||
generic/uname.c \
|
generic/uname.c \
|
||||||
linux/HugePageMeter.c \
|
linux/HugePageMeter.c \
|
||||||
|
@ -184,6 +186,7 @@ freebsd_platform_headers = \
|
||||||
freebsd/FreeBSDProcess.h \
|
freebsd/FreeBSDProcess.h \
|
||||||
freebsd/Platform.h \
|
freebsd/Platform.h \
|
||||||
freebsd/ProcessField.h \
|
freebsd/ProcessField.h \
|
||||||
|
generic/gettime.h \
|
||||||
generic/hostname.h \
|
generic/hostname.h \
|
||||||
generic/openzfs_sysctl.h \
|
generic/openzfs_sysctl.h \
|
||||||
generic/uname.h \
|
generic/uname.h \
|
||||||
|
@ -195,6 +198,7 @@ freebsd_platform_sources = \
|
||||||
freebsd/Platform.c \
|
freebsd/Platform.c \
|
||||||
freebsd/FreeBSDProcessList.c \
|
freebsd/FreeBSDProcessList.c \
|
||||||
freebsd/FreeBSDProcess.c \
|
freebsd/FreeBSDProcess.c \
|
||||||
|
generic/gettime.c \
|
||||||
generic/hostname.c \
|
generic/hostname.c \
|
||||||
generic/openzfs_sysctl.c \
|
generic/openzfs_sysctl.c \
|
||||||
generic/uname.c \
|
generic/uname.c \
|
||||||
|
@ -215,6 +219,7 @@ dragonflybsd_platform_headers = \
|
||||||
dragonflybsd/DragonFlyBSDProcess.h \
|
dragonflybsd/DragonFlyBSDProcess.h \
|
||||||
dragonflybsd/Platform.h \
|
dragonflybsd/Platform.h \
|
||||||
dragonflybsd/ProcessField.h \
|
dragonflybsd/ProcessField.h \
|
||||||
|
generic/gettime.h \
|
||||||
generic/hostname.h \
|
generic/hostname.h \
|
||||||
generic/uname.h
|
generic/uname.h
|
||||||
|
|
||||||
|
@ -222,6 +227,7 @@ dragonflybsd_platform_sources = \
|
||||||
dragonflybsd/DragonFlyBSDProcessList.c \
|
dragonflybsd/DragonFlyBSDProcessList.c \
|
||||||
dragonflybsd/DragonFlyBSDProcess.c \
|
dragonflybsd/DragonFlyBSDProcess.c \
|
||||||
dragonflybsd/Platform.c \
|
dragonflybsd/Platform.c \
|
||||||
|
generic/gettime.c \
|
||||||
generic/hostname.c \
|
generic/hostname.c \
|
||||||
generic/uname.c
|
generic/uname.c
|
||||||
|
|
||||||
|
@ -235,6 +241,7 @@ endif
|
||||||
# -------
|
# -------
|
||||||
|
|
||||||
openbsd_platform_headers = \
|
openbsd_platform_headers = \
|
||||||
|
generic/gettime.h \
|
||||||
generic/hostname.h \
|
generic/hostname.h \
|
||||||
generic/uname.h \
|
generic/uname.h \
|
||||||
openbsd/OpenBSDProcessList.h \
|
openbsd/OpenBSDProcessList.h \
|
||||||
|
@ -243,6 +250,7 @@ openbsd_platform_headers = \
|
||||||
openbsd/ProcessField.h
|
openbsd/ProcessField.h
|
||||||
|
|
||||||
openbsd_platform_sources = \
|
openbsd_platform_sources = \
|
||||||
|
generic/gettime.c \
|
||||||
generic/hostname.c \
|
generic/hostname.c \
|
||||||
generic/uname.c \
|
generic/uname.c \
|
||||||
openbsd/OpenBSDProcessList.c \
|
openbsd/OpenBSDProcessList.c \
|
||||||
|
@ -263,6 +271,7 @@ darwin_platform_headers = \
|
||||||
darwin/DarwinProcessList.h \
|
darwin/DarwinProcessList.h \
|
||||||
darwin/Platform.h \
|
darwin/Platform.h \
|
||||||
darwin/ProcessField.h \
|
darwin/ProcessField.h \
|
||||||
|
generic/gettime.h \
|
||||||
generic/hostname.h \
|
generic/hostname.h \
|
||||||
generic/openzfs_sysctl.h \
|
generic/openzfs_sysctl.h \
|
||||||
generic/uname.h \
|
generic/uname.h \
|
||||||
|
@ -274,6 +283,7 @@ darwin_platform_sources = \
|
||||||
darwin/Platform.c \
|
darwin/Platform.c \
|
||||||
darwin/DarwinProcess.c \
|
darwin/DarwinProcess.c \
|
||||||
darwin/DarwinProcessList.c \
|
darwin/DarwinProcessList.c \
|
||||||
|
generic/gettime.c \
|
||||||
generic/hostname.c \
|
generic/hostname.c \
|
||||||
generic/openzfs_sysctl.c \
|
generic/openzfs_sysctl.c \
|
||||||
generic/uname.c \
|
generic/uname.c \
|
||||||
|
@ -291,6 +301,7 @@ endif
|
||||||
# -------
|
# -------
|
||||||
|
|
||||||
solaris_platform_headers = \
|
solaris_platform_headers = \
|
||||||
|
generic/gettime.h \
|
||||||
generic/hostname.h \
|
generic/hostname.h \
|
||||||
generic/uname.h \
|
generic/uname.h \
|
||||||
solaris/ProcessField.h \
|
solaris/ProcessField.h \
|
||||||
|
@ -302,6 +313,7 @@ solaris_platform_headers = \
|
||||||
zfs/ZfsCompressedArcMeter.h
|
zfs/ZfsCompressedArcMeter.h
|
||||||
|
|
||||||
solaris_platform_sources = \
|
solaris_platform_sources = \
|
||||||
|
generic/gettime.c \
|
||||||
generic/hostname.c \
|
generic/hostname.c \
|
||||||
generic/uname.c \
|
generic/uname.c \
|
||||||
solaris/Platform.c \
|
solaris/Platform.c \
|
||||||
|
@ -320,12 +332,14 @@ endif
|
||||||
# -----------
|
# -----------
|
||||||
|
|
||||||
unsupported_platform_headers = \
|
unsupported_platform_headers = \
|
||||||
|
generic/gettime.h \
|
||||||
unsupported/Platform.h \
|
unsupported/Platform.h \
|
||||||
unsupported/ProcessField.h \
|
unsupported/ProcessField.h \
|
||||||
unsupported/UnsupportedProcess.h \
|
unsupported/UnsupportedProcess.h \
|
||||||
unsupported/UnsupportedProcessList.h
|
unsupported/UnsupportedProcessList.h
|
||||||
|
|
||||||
unsupported_platform_sources = \
|
unsupported_platform_sources = \
|
||||||
|
generic/gettime.c \
|
||||||
unsupported/Platform.c \
|
unsupported/Platform.c \
|
||||||
unsupported/UnsupportedProcess.c \
|
unsupported/UnsupportedProcess.c \
|
||||||
unsupported/UnsupportedProcessList.c
|
unsupported/UnsupportedProcessList.c
|
||||||
|
|
8
Meter.c
8
Meter.c
|
@ -18,6 +18,7 @@ in the source distribution for its full text.
|
||||||
#include "CRT.h"
|
#include "CRT.h"
|
||||||
#include "Macros.h"
|
#include "Macros.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
#include "Platform.h"
|
||||||
#include "ProvideCurses.h"
|
#include "ProvideCurses.h"
|
||||||
#include "RichString.h"
|
#include "RichString.h"
|
||||||
#include "Settings.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) {
|
static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
|
||||||
|
const ProcessList* pl = this->pl;
|
||||||
|
|
||||||
if (!this->drawData) {
|
if (!this->drawData) {
|
||||||
this->drawData = xCalloc(1, sizeof(GraphData));
|
this->drawData = xCalloc(1, sizeof(GraphData));
|
||||||
|
@ -312,12 +314,10 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
|
||||||
x += captionLen;
|
x += captionLen;
|
||||||
w -= captionLen;
|
w -= captionLen;
|
||||||
|
|
||||||
struct timeval now;
|
if (!timercmp(&pl->realtime, &(data->time), <)) {
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if (!timercmp(&now, &(data->time), <)) {
|
|
||||||
int globalDelay = this->pl->settings->delay;
|
int globalDelay = this->pl->settings->delay;
|
||||||
struct timeval delay = { .tv_sec = globalDelay / 10, .tv_usec = (globalDelay - ((globalDelay / 10) * 10)) * 100000 };
|
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++)
|
for (int i = 0; i < nValues - 1; i++)
|
||||||
data->values[i] = data->values[i + 1];
|
data->values[i] = data->values[i + 1];
|
||||||
|
|
|
@ -25,12 +25,10 @@ static uint32_t cached_txb_diff;
|
||||||
static uint32_t cached_txp_diff;
|
static uint32_t cached_txp_diff;
|
||||||
|
|
||||||
static void NetworkIOMeter_updateValues(Meter* this) {
|
static void NetworkIOMeter_updateValues(Meter* this) {
|
||||||
|
const ProcessList* pl = this->pl;
|
||||||
static uint64_t cached_last_update = 0;
|
static uint64_t cached_last_update = 0;
|
||||||
|
|
||||||
struct timeval tv;
|
uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update;
|
||||||
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;
|
|
||||||
|
|
||||||
/* update only every 500ms */
|
/* update only every 500ms */
|
||||||
if (passedTimeInMs > 500) {
|
if (passedTimeInMs > 500) {
|
||||||
|
@ -40,7 +38,7 @@ static void NetworkIOMeter_updateValues(Meter* this) {
|
||||||
static uint64_t cached_txp_total;
|
static uint64_t cached_txp_total;
|
||||||
uint64_t diff;
|
uint64_t diff;
|
||||||
|
|
||||||
cached_last_update = timeInMilliSeconds;
|
cached_last_update = pl->realtimeMs;
|
||||||
|
|
||||||
NetworkIOData data;
|
NetworkIOData data;
|
||||||
hasData = Platform_getNetworkIO(&data);
|
hasData = Platform_getNetworkIO(&data);
|
||||||
|
|
|
@ -467,14 +467,14 @@ void Process_toggleTag(Process* this) {
|
||||||
|
|
||||||
bool Process_isNew(const Process* this) {
|
bool Process_isNew(const Process* this) {
|
||||||
assert(this->processList);
|
assert(this->processList);
|
||||||
if (this->processList->scanTs >= this->seenTs) {
|
if (this->processList->monotonicMs >= this->seenStampMs) {
|
||||||
return this->processList->scanTs - this->seenTs <= 1000 * this->processList->settings->highlightDelaySecs;
|
return this->processList->monotonicMs - this->seenStampMs <= 1000 * (uint64_t)this->processList->settings->highlightDelaySecs;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process_isTomb(const Process* this) {
|
bool Process_isTomb(const Process* this) {
|
||||||
return this->tombTs > 0;
|
return this->tombStampMs > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Process_setPriority(Process* this, int priority) {
|
bool Process_setPriority(Process* this, int priority) {
|
||||||
|
|
|
@ -174,8 +174,8 @@ typedef struct Process_ {
|
||||||
/*
|
/*
|
||||||
* Internal time counts for showing new and exited processes.
|
* Internal time counts for showing new and exited processes.
|
||||||
*/
|
*/
|
||||||
time_t seenTs;
|
uint64_t seenStampMs;
|
||||||
time_t tombTs;
|
uint64_t tombStampMs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal state for tree-mode.
|
* Internal state for tree-mode.
|
||||||
|
|
|
@ -10,11 +10,12 @@ in the source distribution for its full text.
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include "Compat.h"
|
|
||||||
#include "CRT.h"
|
#include "CRT.h"
|
||||||
#include "Hashtable.h"
|
#include "Hashtable.h"
|
||||||
#include "Macros.h"
|
#include "Macros.h"
|
||||||
|
#include "Platform.h"
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, Users
|
||||||
// set later by platform-specific code
|
// set later by platform-specific code
|
||||||
this->cpuCount = 0;
|
this->cpuCount = 0;
|
||||||
|
|
||||||
this->scanTs = 0;
|
this->monotonicMs = 0;
|
||||||
|
|
||||||
#ifdef HAVE_LIBHWLOC
|
#ifdef HAVE_LIBHWLOC
|
||||||
this->topologyOk = false;
|
this->topologyOk = false;
|
||||||
|
@ -131,7 +132,7 @@ void ProcessList_add(ProcessList* this, Process* p) {
|
||||||
p->processList = this;
|
p->processList = this;
|
||||||
|
|
||||||
// highlighting processes found in first scan by first scan marked "far in the past"
|
// 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);
|
Vector_add(this->processes, p);
|
||||||
Hashtable_put(this->processTable, p->pid, 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) {
|
void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate) {
|
if (pauseProcessUpdate) {
|
||||||
ProcessList_goThroughEntries(this, true);
|
ProcessList_goThroughEntries(this, true);
|
||||||
|
@ -604,31 +603,29 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) {
|
||||||
this->runningTasks = 0;
|
this->runningTasks = 0;
|
||||||
|
|
||||||
|
|
||||||
// set scanTs
|
// set scan timestamp
|
||||||
static bool firstScanDone = false;
|
static bool firstScanDone = false;
|
||||||
if (!firstScanDone) {
|
if (firstScanDone) {
|
||||||
this->scanTs = 0;
|
Platform_gettime_monotonic(&this->monotonicMs);
|
||||||
|
} else {
|
||||||
|
this->monotonicMs = 0;
|
||||||
firstScanDone = true;
|
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);
|
ProcessList_goThroughEntries(this, false);
|
||||||
|
|
||||||
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
|
||||||
Process* p = (Process*) Vector_get(this->processes, i);
|
Process* p = (Process*) Vector_get(this->processes, i);
|
||||||
if (p->tombTs > 0) {
|
if (p->tombStampMs > 0) {
|
||||||
// remove tombed process
|
// remove tombed process
|
||||||
if (this->scanTs >= p->tombTs) {
|
if (this->monotonicMs >= p->tombStampMs) {
|
||||||
ProcessList_remove(this, p);
|
ProcessList_remove(this, p);
|
||||||
}
|
}
|
||||||
} else if (p->updated == false) {
|
} else if (p->updated == false) {
|
||||||
// process no longer exists
|
// process no longer exists
|
||||||
if (this->settings->highlightChanges && p->wasShown) {
|
if (this->settings->highlightChanges && p->wasShown) {
|
||||||
// mark tombed
|
// mark tombed
|
||||||
p->tombTs = this->scanTs + 1000 * this->settings->highlightDelaySecs;
|
p->tombStampMs = this->monotonicMs + 1000 * this->settings->highlightDelaySecs;
|
||||||
} else {
|
} else {
|
||||||
// immediately remove
|
// immediately remove
|
||||||
ProcessList_remove(this, p);
|
ProcessList_remove(this, p);
|
||||||
|
|
|
@ -48,6 +48,10 @@ typedef struct ProcessList_ {
|
||||||
Hashtable* displayTreeSet;
|
Hashtable* displayTreeSet;
|
||||||
Hashtable* draftingTreeSet;
|
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;
|
Panel* panel;
|
||||||
int following;
|
int following;
|
||||||
uid_t userId;
|
uid_t userId;
|
||||||
|
@ -76,8 +80,6 @@ typedef struct ProcessList_ {
|
||||||
memory_t cachedSwap;
|
memory_t cachedSwap;
|
||||||
|
|
||||||
unsigned int cpuCount;
|
unsigned int cpuCount;
|
||||||
|
|
||||||
time_t scanTs;
|
|
||||||
} ProcessList;
|
} ProcessList;
|
||||||
|
|
||||||
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId);
|
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId);
|
||||||
|
|
|
@ -15,6 +15,7 @@ in the source distribution for its full text.
|
||||||
#include "CRT.h"
|
#include "CRT.h"
|
||||||
#include "FunctionBar.h"
|
#include "FunctionBar.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
#include "Platform.h"
|
||||||
#include "ProcessList.h"
|
#include "ProcessList.h"
|
||||||
#include "ProvideCurses.h"
|
#include "ProvideCurses.h"
|
||||||
#include "XUtils.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) {
|
static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTimeout, bool* redraw, bool* rescan, bool* timedOut) {
|
||||||
ProcessList* pl = this->header->pl;
|
ProcessList* pl = this->header->pl;
|
||||||
|
|
||||||
struct timeval tv;
|
Platform_gettime_realtime(&pl->realtime, &pl->realtimeMs);
|
||||||
gettimeofday(&tv, NULL);
|
double newTime = ((double)pl->realtime.tv_sec * 10) + ((double)pl->realtime.tv_usec / 100000);
|
||||||
double newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000);
|
|
||||||
|
|
||||||
*timedOut = (newTime - *oldTime > this->settings->delay);
|
*timedOut = (newTime - *oldTime > this->settings->delay);
|
||||||
*rescan |= *timedOut;
|
*rescan |= *timedOut;
|
||||||
|
|
|
@ -37,6 +37,10 @@ in the source distribution for its full text.
|
||||||
#include "zfs/ZfsArcMeter.h"
|
#include "zfs/ZfsArcMeter.h"
|
||||||
#include "zfs/ZfsCompressedArcMeter.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
|
#ifdef HAVE_MACH_MACH_TIME_H
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -405,3 +409,23 @@ void Platform_getBattery(double* percent, ACPresence* isOnAC) {
|
||||||
CFRelease(list);
|
CFRelease(list);
|
||||||
CFRelease(power_sources);
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ in the source distribution for its full text.
|
||||||
#include "NetworkIOMeter.h"
|
#include "NetworkIOMeter.h"
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
|
#include "generic/gettime.h"
|
||||||
#include "generic/hostname.h"
|
#include "generic/hostname.h"
|
||||||
#include "generic/uname.h"
|
#include "generic/uname.h"
|
||||||
|
|
||||||
|
@ -85,4 +86,10 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
|
||||||
return false;
|
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
|
#endif
|
||||||
|
|
|
@ -17,6 +17,7 @@ in the source distribution for its full text.
|
||||||
#include "NetworkIOMeter.h"
|
#include "NetworkIOMeter.h"
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
|
#include "generic/gettime.h"
|
||||||
#include "generic/hostname.h"
|
#include "generic/hostname.h"
|
||||||
#include "generic/uname.h"
|
#include "generic/uname.h"
|
||||||
|
|
||||||
|
@ -75,4 +76,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
|
||||||
return false;
|
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
|
#endif
|
||||||
|
|
|
@ -18,6 +18,7 @@ in the source distribution for its full text.
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
|
#include "generic/gettime.h"
|
||||||
#include "generic/hostname.h"
|
#include "generic/hostname.h"
|
||||||
#include "generic/uname.h"
|
#include "generic/uname.h"
|
||||||
|
|
||||||
|
@ -80,4 +81,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
|
||||||
return false;
|
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
|
#endif
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
|
@ -1989,10 +1989,6 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
unsigned long long now = tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL;
|
|
||||||
|
|
||||||
/* PROCDIR is an absolute path */
|
/* PROCDIR is an absolute path */
|
||||||
assert(PROCDIR[0] == '/');
|
assert(PROCDIR[0] == '/');
|
||||||
#ifdef HAVE_OPENAT
|
#ifdef HAVE_OPENAT
|
||||||
|
@ -2001,5 +1997,5 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
openat_arg_t rootFd = "";
|
openat_arg_t rootFd = "";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LinuxProcessList_recurseProcTree(this, rootFd, PROCDIR, NULL, period, now);
|
LinuxProcessList_recurseProcTree(this, rootFd, PROCDIR, NULL, period, super->realtimeMs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ in the source distribution for its full text.
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
|
#include "generic/gettime.h"
|
||||||
#include "generic/hostname.h"
|
#include "generic/hostname.h"
|
||||||
#include "generic/uname.h"
|
#include "generic/uname.h"
|
||||||
|
|
||||||
|
@ -93,4 +94,12 @@ void Platform_longOptionsUsage(const char* name);
|
||||||
|
|
||||||
bool Platform_getLongOption(int opt, int argc, char** argv);
|
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
|
#endif
|
||||||
|
|
|
@ -19,6 +19,7 @@ in the source distribution for its full text.
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
|
#include "generic/gettime.h"
|
||||||
#include "generic/hostname.h"
|
#include "generic/hostname.h"
|
||||||
#include "generic/uname.h"
|
#include "generic/uname.h"
|
||||||
|
|
||||||
|
@ -78,4 +79,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
|
||||||
return false;
|
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
|
#endif
|
||||||
|
|
|
@ -26,6 +26,7 @@ in the source distribution for its full text.
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
|
|
||||||
|
#include "generic/gettime.h"
|
||||||
#include "generic/hostname.h"
|
#include "generic/hostname.h"
|
||||||
#include "generic/uname.h"
|
#include "generic/uname.h"
|
||||||
|
|
||||||
|
@ -101,4 +102,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
|
||||||
return false;
|
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
|
#endif
|
||||||
|
|
|
@ -15,6 +15,7 @@ in the source distribution for its full text.
|
||||||
#include "ProcessLocksScreen.h"
|
#include "ProcessLocksScreen.h"
|
||||||
#include "SignalsPanel.h"
|
#include "SignalsPanel.h"
|
||||||
#include "UnsupportedProcess.h"
|
#include "UnsupportedProcess.h"
|
||||||
|
#include "generic/gettime.h"
|
||||||
|
|
||||||
|
|
||||||
extern const SignalItem Platform_signals[];
|
extern const SignalItem Platform_signals[];
|
||||||
|
@ -69,4 +70,12 @@ static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int a
|
||||||
return false;
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue