top: protect against distortion when system time reset
If a system's time is adjusted backwards, then elapsed time could appear as negative. This yielded a negative %CPU value. Alternately if zeros were suppressed ('0') the result was a blank %CPU column. In both cases that distortion would last for one display cycle or until a user forced a display refresh via some keyboard input. The original recommendation was trading gettimeofday() for clock_gettime() using CLOCK_MONOTONIC. But on some systems that might not be possible, forcing the use of CLOCK_REALTIME instead. Not only would that complicate the build system, but it may leave us with minus %CPU. Another approach was to ensure that elapsed time could never be negative. Of course, this produced distortion of %CPU values but it would be proportionally correct. This wasn't dissimilar to a distortion already present should the time be adjusted forward or backward within any 'remaining' top delay intervals. These aberrations would be avoided with clock_gettime & CLOCK_MONOTONIC, but that is a less than ideal solution as noted above. This final solution, which originated down under, will simply rely on the /proc/uptime seconds, which will be immune to *any* tampering with the system clock. Thus, we now have a fix for the distortion we didn't know we suffered plus a negative %CPU that began this odyssey. Thanks to: sk.alvin.x@gmail.com, for the original effort jcapik@redhat.com, for a heads up on CLOCK_MONOTONIC csmall-procps@enc.com.au, for the best suggestion of all Reference(s): . original post/patch http://www.freelists.org/post/procps/PATCH-top-use-clock-gettime-instead-of-gettimeofday . heads up on CLOCK_MONOTONIC http://www.freelists.org/post/procps/PATCH-top-use-clock-gettime-instead-of-gettimeofday,2 . the final solution http://www.freelists.org/post/procps/PATCH-top-use-clock-gettime-instead-of-gettimeofday,11 Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
0b3f63456a
commit
22e6582974
13
top/top.c
13
top/top.c
@ -2518,17 +2518,14 @@ static void procs_hlp (proc_t *this) {
|
|||||||
HST_t *h;
|
HST_t *h;
|
||||||
|
|
||||||
if (!this) {
|
if (!this) {
|
||||||
static struct timeval oldtimev;
|
static double uptime_sav;
|
||||||
struct timeval timev;
|
double uptime_cur;
|
||||||
struct timezone timez;
|
|
||||||
float et;
|
float et;
|
||||||
void *v;
|
void *v;
|
||||||
|
|
||||||
gettimeofday(&timev, &timez);
|
uptime(&uptime_cur, NULL);
|
||||||
et = (timev.tv_sec - oldtimev.tv_sec)
|
et = uptime_cur - uptime_sav;
|
||||||
+ (float)(timev.tv_usec - oldtimev.tv_usec) / 1000000.0;
|
uptime_sav = uptime_cur;
|
||||||
oldtimev.tv_sec = timev.tv_sec;
|
|
||||||
oldtimev.tv_usec = timev.tv_usec;
|
|
||||||
|
|
||||||
// if in Solaris mode, adjust our scaling for all cpus
|
// if in Solaris mode, adjust our scaling for all cpus
|
||||||
Frame_etscale = 100.0f / ((float)Hertz * (float)et * (Rc.mode_irixps ? 1 : smp_num_cpus));
|
Frame_etscale = 100.0f / ((float)Hertz * (float)et * (Rc.mode_irixps ? 1 : smp_num_cpus));
|
||||||
|
Loading…
Reference in New Issue
Block a user