Merging all the points related to calculating time in one place#574
Merging all the points related to calculating time in one place#574natoscott merged 2 commits intohtop-dev:masterfrom
Conversation
|
@smalinux looks like there's an inconsistency between a header and associated function call (LinuxProcessList_updateCPUcount?) - possibly merge fallout. Its causing CI issues currently. |
|
Also AFAIR there is a timestamp passed around for each update already. Please check if there are any functions that don't currently already use that timestamp for their timing needs. |
a3f
left a comment
There was a problem hiding this comment.
Having to list multiple bullet points is a good indicator a commit should be split up into a number of commits where each message just describes a single issue.
You can still give an overview in the cover-letter (here, PR caption), but the individual commits should focus on the backstory of the changeset at hand.
PR also seems to introduce a regression.
|
|
||
| #if defined(HAVE_CLOCK_GETTIME) | ||
|
|
||
| return clock_gettime(CLOCK_MONOTONIC, tp); |
There was a problem hiding this comment.
This change should be in a separate commit.
| } | ||
|
|
||
| int xClock_gettime (clockid_t __clock_id, struct timespec *__tp) { | ||
| return clock_gettime (__clock_id, __tp); |
There was a problem hiding this comment.
What's the added value of having this wrapper? Also __ prefixed identifiers are reserved for the C implementation and/or denote internal stuff. You could just call it clock_id and tp directly here.
| ssize_t xReadfile(const char* pathname, void* buffer, size_t count); | ||
| ssize_t xReadfileat(openat_arg_t dirfd, const char* pathname, void* buffer, size_t count); | ||
|
|
||
| int xClock_gettime (clockid_t __clock_id, struct timespec *__tp); |
There was a problem hiding this comment.
Seems to me this header has a dependency on clockid_t being defined externally. You should probably #include <time.h> above (provided you keep xClock_gettime).
Nitpick: coding style seems to not use a space before parentheses.
| gettimeofday(&tv, NULL); | ||
|
|
||
| pl->timestamp = tv; | ||
| pl->timestampMs = (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000; |
There was a problem hiding this comment.
Is it worth it to precompute this on every updateTime even if we don't use it? Wouldn't it be better to just store timestamp and compute timestampMs if needed?
There was a problem hiding this comment.
I think it is OK to compute the millisecond value here once every cycle.
| LinuxProcessList_scanMemoryInfo(super); | ||
| LinuxProcessList_scanHugePages(this); | ||
| LinuxProcessList_scanZfsArcstats(this); | ||
| LinuxProcessList_updateCPUcount(this); |
There was a problem hiding this comment.
copy-paste error? Shouldn't this be LinuxProcessList_updateTime?
| struct timeval tv; | ||
| gettimeofday(&tv, NULL); | ||
| unsigned long long now = tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL; | ||
| unsigned long long now = super->timestamp.tv_sec * 1000ULL + super->timestamp.tv_usec / 1000ULL; |
There was a problem hiding this comment.
Given that it's repeated quite a few times, a prerequisite patch adding a tv_to_msec() might be useful.
There was a problem hiding this comment.
It exists in two different places, each one of them has its own calculation, the rest of the duplicate places are removed.
There was a problem hiding this comment.
I can't follow. I still see it here and in LinuxProcessList_updateTime.
There was a problem hiding this comment.
Can't now be replaced by pl->timestampMs?
There was a problem hiding this comment.
If unsigned long long now == uint64_t pl->timestampMs? Yes :) (and I 'think' it-is)
I used |
|
I retreated all 'xClock' related changes, I think it will not affect PCP-related work, so I left clock_gettime(2) as-is at this stage. Also, I retreated from removing |
|
The CI still reports one issue: |
| struct timeval previous; /* time of the previous sample */ | ||
| uint64_t timestampMs; /* current time in milliseconds */ | ||
| uint64_t previousMs; /* previous time in milliseconds */ | ||
| uint64_t intervalMs; /* milliseconds between 2 samples */ |
There was a problem hiding this comment.
The fields previous, previousMs and intervalMs are currently only assigned, but never used.
I suppose they are getting used in future additions?
Also, to please my eyes, please align the comments.
There was a problem hiding this comment.
The fields previous, previousMs and intervalMs are currently only assigned, but never used.
I suppose they are getting used in future additions?
Yes, should I leave them as-is? or remove them for now?
There was a problem hiding this comment.
That's already wrong with the current code flow, as the process update updates some fields for the task counts displayed in the header …
I've opened #587 to ensure this bug fix goes in as a standalone fix, as discussed on IRC.
| gettimeofday(&tv, NULL); | ||
|
|
||
| pl->timestamp = tv; | ||
| pl->timestampMs = (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000; |
There was a problem hiding this comment.
I think it is OK to compute the millisecond value here once every cycle.
| pl->timestampMs = (uint64_t)tv.tv_sec * 1000 + (uint64_t)tv.tv_usec / 1000; | ||
| pl->intervalMs = pl->timestampMs - pl->previousMs; | ||
| pl->previousMs = cached_last_update; | ||
| cached_last_update = pl->timestampMs; |
There was a problem hiding this comment.
Please align all the assignments
| LinuxProcessList_scanMemoryInfo(super); | ||
| LinuxProcessList_scanHugePages(this); | ||
| LinuxProcessList_scanZfsArcstats(this); | ||
| LinuxProcessList_updateTime(this); |
There was a problem hiding this comment.
Maybe insert this function call as first action, so every function can assume the data is up-to-date.
There was a problem hiding this comment.
There's still a separate gettimeofday call in checkRecalculation ScreenManager.c too - isn't that the very first place we could capture the 'current time of sampling' (perhaps via a new routine named like Platform_getCurrentTime?) Then we'd not need a later LinuxProcessList_updateTime call.
There was a problem hiding this comment.
@natoscott Excellent, I can't call Platform_getCurrentTime directly from ScreenManager.c (this causes problems with CI and other OSs)
So, I made ProcessList_getCurrentTime.
I think this's optimal because our time-related variables exist within ProcessList struct (ProcessList.h) and my new function in ProcessList.c. I could call it directly from there also.
There was a problem hiding this comment.
@smalinux I'll send some code through shortly - we should be able to call platform code from ScreenManager.c if we need to. I'll need to reproduce that CI failure though to see the exact issue.
| struct timeval tv; | ||
| gettimeofday(&tv, NULL); | ||
| unsigned long long now = tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL; | ||
| unsigned long long now = super->timestamp.tv_sec * 1000ULL + super->timestamp.tv_usec / 1000ULL; |
There was a problem hiding this comment.
Can't now be replaced by pl->timestampMs?
|
I think we need to reorder the updates in diff --git a/ScreenManager.c b/ScreenManager.c
index c4fbfee..23a635f 100644
--- a/ScreenManager.c
+++ b/ScreenManager.c
@@ -105,13 +105,13 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
if (*rescan) {
*oldTime = newTime;
- // always update header, especially to avoid gaps in graph meters
- Header_updateData(this->header);
ProcessList_scan(pl, this->state->pauseProcessUpdate);
if (!this->state->pauseProcessUpdate && (*sortTimeout == 0 || this->settings->treeView)) {
ProcessList_sort(pl);
*sortTimeout = 1;
}
+ // always update header, especially to avoid gaps in graph meters
+ Header_updateData(this->header);
*redraw = true;
}
if (*redraw) {else the NetworkIO and DiskIO meters do not see the updated timestamps. |
|
That's already wrong with the current code flow, as the process update updates some fields for the task counts displayed in the header … |
We'll need to come back to it later - but for now this PR is looking like a good standalone improvement (independent of the needs with historical reporting via PCP). |
f227e01 to
2c634a5
Compare
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 htop-dev#574
|
@smalinux I've created a branch with a series of updates: https://github.com/natoscott/htop/tree/smalinux-CtrTime Could you review and merge with your branch if it looks OK? This adds code to handle both realtime (gettimeofday) and monotonic clock accesses, with a single realtime clock access at the start of sampling (i.e. in ScreenManager.c). |
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 htop-dev#574
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 htop-dev#574
The end goal is to consolidate all the points in htop that can only work in live-only mode today, so that will be able to inject PCP archive mode and have a chance at it working. The biggest problem we've got at this moment is all the places that are independently asking the kernel to 'give me the time right now'. Each of those needs to be audited and ultimately changed to allow platforms to manage their own idea of time. So, all the calls to gettimeofday(2) and time(2) are potential problems. Ultimately I want to get these down to just one or two. Related to htop-dev#574
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 htop-dev#574
The end goal is to consolidate all the points in htop that can only work in live-only mode today, so that will be able to inject PCP archive mode and have a chance at it working. The biggest problem we've got at this moment is all the places that are independently asking the kernel to 'give me the time right now'. Each of those needs to be audited and ultimately changed to allow platforms to manage their own idea of time. So, all the calls to gettimeofday(2) and time(2) are potential problems. Ultimately I want to get these down to just one or two. Related to htop-dev#574
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 htop-dev#574
BenBE
left a comment
There was a problem hiding this comment.
Mostly LGTM. Not yet happy with the rename of seenTs and tombTs.
| time_t seenTs; | ||
| time_t tombTs; | ||
| uint64_t seenMs; | ||
| uint64_t tombMs; |
There was a problem hiding this comment.
Mainly cos I wanted it clear in my head that these timestamps are in milliseconds, and it follows the convention being established in ProcessList.h - but, let's change it back if its confusing.
There was a problem hiding this comment.
[...] let's change it back if its confusing.
@smalinux are you happy to do the rename? I'm about to go on holidays for a few days. :)
There was a problem hiding this comment.
@BenBE oh, also, time_t is typically a time-in-seconds (since the epoch) - hence the change in type (i.e. that part should stay as-is IMO).
There was a problem hiding this comment.
@smalinux are you happy to do the rename?
@natoscott Yes, certainly, happy holiday :)
There was a problem hiding this comment.
I'm both fine with the type change (that should stay) and also with the Ms marker at the end. It's just a bit unfortunate to drop the mid-part Ts altogether. Maybe seenStampMs/tombStampMs?
BenBE points out that some header meters use values calculated during process scanning - make sure we scan processes first in order that current values are displayed. Related to htop-dev#574
BenBE points out that some header meters use values calculated during process scanning - make sure we scan processes first in order that current values are displayed. Related to #574
BenBE points out that some header meters use values calculated during process scanning - make sure we scan processes first in order that current values are displayed. Related to htop-dev#574
The end goal is to consolidate all the points in htop that can only work in live-only mode today, so that will be able to inject PCP archive mode and have a chance at it working. The biggest problem we've got at this moment is all the places that are independently asking the kernel to 'give me the time right now'. Each of those needs to be audited and ultimately changed to allow platforms to manage their own idea of time. So, all the calls to gettimeofday(2) and time(2) are potential problems. Ultimately I want to get these down to just one or two. Related to htop-dev#574
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 htop-dev#574
The end goal is to consolidate all the points in htop that can only work in live-only mode today, so that will be able to inject PCP archive mode and have a chance at it working. The biggest problem we've got at this moment is all the places that are independently asking the kernel to 'give me the time right now'. Each of those needs to be audited and ultimately changed to allow platforms to manage their own idea of time. So, all the calls to gettimeofday(2) and time(2) are potential problems. Ultimately I want to get these down to just one or two. Related to htop-dev#574
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 htop-dev#574
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 htop-dev#574
The end goal is to consolidate all the points in htop that can only work in live-only mode today, so that will be able to inject PCP archive mode and have a chance at it working. The biggest problem we've got at this moment is all the places that are independently asking the kernel to 'give me the time right now'. Each of those needs to be audited and ultimately changed to allow platforms to manage their own idea of time. So, all the calls to gettimeofday(2) and time(2) are potential problems. Ultimately I want to get these down to just one or two. Related to htop-dev#574
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 htop-dev#574
The end goal is to consolidate all the points in htop that can only work in
live-only mode today, so that will be able to inject PCP archive mode and have
a chance at it working.
The biggest problem we've got at this moment is all the places that are
independently asking the kernel to 'give me the time right now'.
Each of those needs to be audited and ultimately changed to allow platforms to
manage their own idea of time.
So, all the calls to gettimeofday(2) and time(2) are potential problems.
Ultimately I want to get these down to just one or two.