From bce2da1f9a34e9520c4cbb8d2a585188793ee3e0 Mon Sep 17 00:00:00 2001 From: albert <> Date: Tue, 28 May 2002 04:18:55 +0000 Subject: [PATCH] 64-bit time for Linux 2.5.xx --- pgrep.c | 2 +- proc/readproc.c | 16 ++++-- proc/readproc.h | 9 +-- proc/sysinfo.c | 14 ++--- proc/sysinfo.h | 2 +- ps/display.c | 2 +- ps/output.c | 142 ++++++++++++++++++++++-------------------------- w.c | 6 +- 8 files changed, 93 insertions(+), 100 deletions(-) diff --git a/pgrep.c b/pgrep.c index 7c0a2526..0e18bce5 100644 --- a/pgrep.c +++ b/pgrep.c @@ -473,7 +473,7 @@ select_procs () { PROCTAB *ptp; proc_t task; - long newest_start_time = 0; + unsigned long long newest_start_time = 0; pid_t newest_pid = 0; int matches = 0; int size = 32; diff --git a/proc/readproc.c b/proc/readproc.c index 5a14b4d2..4f05e965 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -164,9 +164,11 @@ static void stat2proc(char* S, proc_t* P) { num = sscanf(tmp + 2, /* skip space after ')' too */ "%c " "%d %d %d %d %d " - "%lu %lu %lu %lu %lu %lu %lu " - "%ld %ld %ld %ld %ld %ld " - "%lu %lu " + "%lu %lu %lu %lu %lu " + "%Lu %Lu %Lu %Lu " /* utime stime cutime cstime */ + "%ld %ld %ld %ld " + "%Lu " /* start_time */ + "%lu " "%ld " "%lu %lu %lu %lu %lu %lu " "%*s %*s %*s %*s " /* discard, no RT signals & Linux 2.1 used hex */ @@ -174,9 +176,11 @@ static void stat2proc(char* S, proc_t* P) { "%d %d", &P->state, &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid, - &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt, &P->utime, &P->stime, - &P->cutime, &P->cstime, &P->priority, &P->nice, &P->timeout, &P->it_real_value, - &P->start_time, &P->vsize, + &P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt, + &P->utime, &P->stime, &P->cutime, &P->cstime, + &P->priority, &P->nice, &P->timeout, &P->it_real_value, + &P->start_time, + &P->vsize, &P->rss, &P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack, &P->kstk_esp, &P->kstk_eip, /* P->signal, P->blocked, P->sigignore, P->sigcatch, */ /* can't use */ diff --git a/proc/readproc.h b/proc/readproc.h index 81195944..da43a120 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -44,9 +44,13 @@ typedef struct proc_s { sigignore, /* mask of ignored signals */ sigcatch; /* mask of caught signals */ #endif - long + unsigned long long cutime, /* cumulative utime of process and reaped children */ cstime, /* cumulative stime of process and reaped children */ + utime, /* user-mode CPU time accumulated by process */ + stime, /* kernel-mode CPU time accumulated by process */ + start_time; /* start time of process -- seconds since 1-1-70 */ + long priority, /* kernel scheduling priority */ timeout, /* ? */ nice, /* standard unix nice level of process */ @@ -78,14 +82,11 @@ typedef struct proc_s { cmaj_flt, /* cumulative maj_flt of process and child processes */ nswap, /* ? */ cnswap, /* cumulative nswap ? */ - utime, /* user-mode CPU time accumulated by process */ - stime, /* kernel-mode CPU time accumulated by process */ start_code, /* address of beginning of code segment */ end_code, /* address of end of code segment */ start_stack, /* address of the bottom of stack for the process */ kstk_esp, /* kernel stack pointer */ kstk_eip, /* kernel instruction pointer */ - start_time, /* start time of process -- seconds since 1-1-70 */ wchan; /* address of kernel wait channel proc is sleeping in */ struct proc_s *l, /* ptrs for building arbitrary linked structs */ *r; /* (i.e. singly/doubly-linked lists and trees */ diff --git a/proc/sysinfo.c b/proc/sysinfo.c index 74a8821d..d485f80a 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -115,12 +115,12 @@ int uptime(double *uptime_secs, double *idle_secs) { * used with a kernel that doesn't support the ELF note. On some other * architectures there may be a system call or sysctl() that will work. */ -unsigned long Hertz; +unsigned long long Hertz; static void init_Hertz_value(void) __attribute__((constructor)); static void init_Hertz_value(void){ - unsigned long user_j, nice_j, sys_j, other_j; /* jiffies (clock ticks) */ + unsigned long long user_j, nice_j, sys_j, other_j; /* jiffies (clock ticks) */ double up_1, up_2, seconds; - unsigned long jiffies, h; + unsigned long long jiffies, h; char *savelocale; smp_num_cpus = sysconf(_SC_NPROCESSORS_CONF); @@ -134,11 +134,11 @@ static void init_Hertz_value(void){ sscanf(buf, "cpu %lu %lu %lu %lu", &user_j, &nice_j, &sys_j, &other_j); FILE_TO_BUF(UPTIME_FILE,uptime_fd); sscanf(buf, "%lf", &up_2); /* uptime(&up_2, NULL); */ - } while((long)( (up_2-up_1)*1000.0/up_1 )); /* want under 0.1% error */ + } while((long long)( (up_2-up_1)*1000.0/up_1 )); /* want under 0.1% error */ setlocale(LC_NUMERIC, savelocale); jiffies = user_j + nice_j + sys_j + other_j; seconds = (up_1 + up_2) / 2; - h = (unsigned long)( (double)jiffies/seconds/smp_num_cpus ); + h = (unsigned long long)( (double)jiffies/seconds/smp_num_cpus ); /* actual values used by 2.4 kernels: 32 64 100 128 1000 1024 1200 */ switch(h){ case 9 ... 11 : Hertz = 10; break; /* S/390 (sometimes) */ @@ -158,7 +158,7 @@ static void init_Hertz_value(void){ case 1180 ... 1220 : Hertz = 1200; break; /* Alpha */ default: #ifdef HZ - Hertz = (unsigned long)HZ; /* */ + Hertz = (unsigned long long)HZ; /* */ #else /* If 32-bit or big-endian (not Alpha or ia64), assume HZ is 100. */ Hertz = (sizeof(long)==sizeof(int) || htons(999)==999) ? 100UL : 1024UL; @@ -176,7 +176,7 @@ static void init_Hertz_value(void){ #ifndef NAN #define NAN (-0.0) #endif -#define JT unsigned long +#define JT unsigned long long void four_cpu_numbers(double *uret, double *nret, double *sret, double *iret){ double tmp_u, tmp_n, tmp_s, tmp_i; double scale; /* scale values to % */ diff --git a/proc/sysinfo.h b/proc/sysinfo.h index 320220dc..c4af4f46 100644 --- a/proc/sysinfo.h +++ b/proc/sysinfo.h @@ -1,7 +1,7 @@ #ifndef SYSINFO_H #define SYSINFO_H -extern unsigned long Hertz; /* clock tick frequency */ +extern unsigned long long Hertz; /* clock tick frequency */ extern long smp_num_cpus; /* number of CPUs */ #define JT double diff --git a/ps/display.c b/ps/display.c index 38b1382d..1ad27b83 100644 --- a/ps/display.c +++ b/ps/display.c @@ -191,7 +191,7 @@ static void fill_pcpu(proc_t *buf){ total_time = buf->utime + buf->stime; if(include_dead_children) total_time += (buf->cutime + buf->cstime); - seconds = (seconds_since_boot - ((unsigned long)buf->start_time) / Hertz); + seconds = seconds_since_boot - buf->start_time / Hertz; if(seconds) pcpu = (total_time * 1000ULL / Hertz) / seconds; buf->pcpu = (pcpu > 999) ? 999 : pcpu; } diff --git a/ps/output.c b/ps/output.c index 152ad641..ad416724 100644 --- a/ps/output.c +++ b/ps/output.c @@ -376,13 +376,10 @@ static int pr_fname(void){ /* elapsed wall clock time, [[dd-]hh:]mm:ss format (not same as "time") */ static int pr_etime(void){ - unsigned t, dd,hh,mm,ss; + unsigned long long t; + unsigned dd,hh,mm,ss; char *cp = outbuf; - t = ( - ((unsigned long)seconds_since_boot) - - ((unsigned long)pp->start_time) - / Hertz - ); + t = seconds_since_boot - pp->start_time / Hertz; ss = t%60; t /= 60; mm = t%60; @@ -401,48 +398,39 @@ static int pr_nice(void){ /* "Processor utilisation for scheduling." --- we use %cpu w/o fraction */ static int pr_c(void){ - unsigned long total_time; /* jiffies used by this process */ - unsigned long pcpu = 0; /* scaled %cpu, 999 means 99.9% */ - unsigned long seconds; /* seconds of process life */ + unsigned long long total_time; /* jiffies used by this process */ + unsigned pcpu = 0; /* scaled %cpu, 999 means 99.9% */ + unsigned long long seconds; /* seconds of process life */ total_time = pp->utime + pp->stime; if(include_dead_children) total_time += (pp->cutime + pp->cstime); - seconds = - seconds_since_boot - ((unsigned long)pp->start_time) / Hertz - ; - /* Use 100ULL (not 100) to avoid 32-bit overflow. */ + seconds = seconds_since_boot - pp->start_time / Hertz; if(seconds) pcpu = (total_time * 100ULL / Hertz) / seconds; - if (pcpu > 99) pcpu = 99; - return snprintf(outbuf, COLWID, "%2u", (unsigned)pcpu); + if (pcpu > 99U) pcpu = 99U; + return snprintf(outbuf, COLWID, "%2u", pcpu); } /* normal %CPU in ##.# format. */ static int pr_pcpu(void){ - unsigned long total_time; /* jiffies used by this process */ - unsigned long pcpu = 0; /* scaled %cpu, 999 means 99.9% */ - unsigned long seconds; /* seconds of process life */ + unsigned long long total_time; /* jiffies used by this process */ + unsigned pcpu = 0; /* scaled %cpu, 999 means 99.9% */ + unsigned long long seconds; /* seconds of process life */ total_time = pp->utime + pp->stime; if(include_dead_children) total_time += (pp->cutime + pp->cstime); - seconds = - seconds_since_boot - ((unsigned long)pp->start_time) / Hertz - ; - /* Use 1000ULL (not 1000) to avoid 32-bit overflow. */ + seconds = seconds_since_boot - pp->start_time / Hertz; if(seconds) pcpu = (total_time * 1000ULL / Hertz) / seconds; - if (pcpu > 999) pcpu = 999; - return snprintf(outbuf, COLWID, "%2u.%u", (unsigned)(pcpu/10), (unsigned)(pcpu%10)); + if (pcpu > 999U) pcpu = 999U; + return snprintf(outbuf, COLWID, "%2u.%u", pcpu/10U, pcpu%10U); } /* this is a "per-mill" format, like %cpu with no decimal point */ static int pr_cp(void){ - unsigned long total_time; /* jiffies used by this process */ - unsigned long pcpu = 0; /* scaled %cpu, 999 means 99.9% */ - unsigned long seconds; /* seconds of process life */ + unsigned long long total_time; /* jiffies used by this process */ + unsigned pcpu = 0; /* scaled %cpu, 999 means 99.9% */ + unsigned long long seconds; /* seconds of process life */ total_time = pp->utime + pp->stime; if(include_dead_children) total_time += (pp->cutime + pp->cstime); - seconds = - seconds_since_boot - ((unsigned long)pp->start_time) / Hertz - ; - /* Use 1000ULL (not 1000) to avoid 32-bit overflow. */ + seconds = seconds_since_boot - pp->start_time / Hertz ; if(seconds) pcpu = (total_time * 1000ULL / Hertz) / seconds; - if (pcpu > 999) pcpu = 999; - return snprintf(outbuf, COLWID, "%3u", (unsigned)pcpu); + if (pcpu > 999U) pcpu = 999U; + return snprintf(outbuf, COLWID, "%3u", pcpu); } static int pr_pgid(void){ @@ -458,17 +446,10 @@ static int pr_ppid(void){ /* cumulative CPU time, [dd-]hh:mm:ss format (not same as "etime") */ static int pr_time(void){ - unsigned t, dd,hh,mm,ss; + unsigned long long t; + unsigned dd,hh,mm,ss; int c; - t = (unsigned)( - ( - (unsigned long)(pp->utime) - + - (unsigned long)(pp->stime) - ) - / - (unsigned long)Hertz - ); + t = (pp->utime + pp->stime) / Hertz; ss = t%60; t /= 60; mm = t%60; @@ -500,9 +481,13 @@ static int pr_vsz(void){ */ static int pr_ruser(void){ - if(user_is_number || (strlen(pp->ruser)>max_rightward)) - return snprintf(outbuf, COLWID, "%d", pp->ruid); - return snprintf(outbuf, COLWID, "%s", pp->ruser); + int width = COLWID; + + if(user_is_number) + return snprintf(outbuf, COLWID, "%d", pp->ruid); + if (strlen(pp->ruser)>max_rightward) + width = max_rightward; + return snprintf(outbuf, width, "%s", pp->ruser); } static int pr_egroup(void){ if(strlen(pp->egroup)>max_rightward) return snprintf(outbuf, COLWID, "%d", pp->egid); @@ -513,8 +498,12 @@ static int pr_rgroup(void){ return snprintf(outbuf, COLWID, "%s", pp->rgroup); } static int pr_euser(void){ - if(user_is_number || (strlen(pp->euser)>max_rightward)) return snprintf(outbuf, COLWID, "%d", pp->euid); - return snprintf(outbuf, COLWID, "%s", pp->euser); + int width = COLWID; + if(user_is_number) + return snprintf(outbuf, COLWID, "%d", pp->euid); + if (strlen(pp->euser)>max_rightward) + width = max_rightward; + return snprintf(outbuf, width, "%s", pp->euser); } /********* maybe standard (Unix98 only defines the header) **********/ @@ -630,26 +619,27 @@ static int pr_eip(void){ } /* This function helps print old-style time formats */ -static int old_time_helper(char *dst, unsigned long t, unsigned long rel) { +static int old_time_helper(char *dst, unsigned long long t, unsigned long long rel) { if(!t) return snprintf(dst, COLWID, " -"); - if((long)t == -1) return snprintf(dst, COLWID, " xx"); - if((long)(t-=rel) < 0) t=0; - if(t>9999) return snprintf(dst, COLWID, "%5lu", t/100); - else return snprintf(dst, COLWID, "%2lu.%02lu", t/100, t%100); + if(t == ~0ULL) return snprintf(dst, COLWID, " xx"); + if((long long)(t-=rel) < 0) t=0ULL; + if(t>9999ULL) return snprintf(dst, COLWID, "%5Lu", t/100ULL); + else return snprintf(dst, COLWID, "%2lu.%02lu", (unsigned)t/100U, (unsigned)t%100U); } static int pr_bsdtime(void){ - unsigned long t; + unsigned long long t; + unsigned u; t = pp->utime + pp->stime; if(include_dead_children) t += (pp->cutime + pp->cstime); - t /= Hertz; - return snprintf(outbuf, COLWID, "%3ld:%02d", t/60, (int)(t%60)); + u = t / Hertz; + return snprintf(outbuf, COLWID, "%3u:%02u", u/60U, u%60U); } static int pr_bsdstart(void){ time_t start; time_t seconds_ago; - start = time_of_boot + pp->start_time/Hertz; + start = time_of_boot + pp->start_time / Hertz; seconds_ago = seconds_since_1970 - start; if(seconds_ago < 0) seconds_ago=0; if(seconds_ago > 3600*24) strcpy(outbuf, ctime(&start)+4); @@ -663,7 +653,7 @@ static int pr_timeout(void){ } static int pr_alarm(void){ - return old_time_helper(outbuf, pp->it_real_value, 0); + return old_time_helper(outbuf, pp->it_real_value, 0ULL); } /* HP-UX puts this in pages and uses "vsz" for kB */ @@ -769,11 +759,7 @@ static int pr_pmem(void){ static int pr_lstart(void){ time_t t; - t = ( - ((unsigned long)time_of_boot) - + ((unsigned long)pp->start_time) - / Hertz - ); + t = time_of_boot + pp->start_time / Hertz; return snprintf(outbuf, COLWID, "%24.24s", ctime(&t)); } @@ -796,11 +782,7 @@ static int pr_stime(void){ our_time = localtime(&seconds_since_1970); /* not reentrant */ tm_year = our_time->tm_year; tm_yday = our_time->tm_yday; - t = (time_t)( - ((unsigned long)time_of_boot) - + ((unsigned long)pp->start_time) - / Hertz - ); + t = time_of_boot + pp->start_time / Hertz; proc_time = localtime(&t); /* not reentrant, this corrupts our_time */ fmt = "%H:%M"; /* 03:02 23:59 */ if(tm_yday != proc_time->tm_yday) fmt = "%b%d"; /* Jun06 Aug27 */ @@ -811,11 +793,7 @@ static int pr_stime(void){ static int pr_start(void){ time_t t; char *str; - t = ( - ((unsigned long)time_of_boot) - + ((unsigned long)pp->start_time) - / Hertz - ); + t = time_of_boot + pp->start_time / Hertz; str = ctime(&t); if(str[8]==' ') str[8]='0'; if(str[11]==' ') str[11]='0'; @@ -891,12 +869,22 @@ static int pr_sgroup(void){ return snprintf(outbuf, COLWID, "%s", pp->sgroup); } static int pr_fuser(void){ - if(user_is_number || (strlen(pp->fuser)>max_rightward)) return snprintf(outbuf, COLWID, "%d", pp->fuid); - return snprintf(outbuf, COLWID, "%s", pp->fuser); + int width = COLWID; + + if(user_is_number) + return snprintf(outbuf, COLWID, "%d", pp->fuid); + if (strlen(pp->fuser)>max_rightward) + width = max_rightward; + return snprintf(outbuf, width, "%s", pp->fuser); } static int pr_suser(void){ - if(user_is_number || (strlen(pp->suser)>max_rightward)) return snprintf(outbuf, COLWID, "%d", pp->suid); - return snprintf(outbuf, COLWID, "%s", pp->suser); + int width = COLWID; + + if(user_is_number) + return snprintf(outbuf, COLWID, "%d", pp->suid); + if (strlen(pp->suser)>max_rightward) + width = max_rightward; + return snprintf(outbuf, width, "%s", pp->suser); } diff --git a/w.c b/w.c index 1ec26136..17c5fe0a 100644 --- a/w.c +++ b/w.c @@ -128,7 +128,7 @@ static void print_logintime(time_t logt, FILE* fout) { * for the "best" process to report as "(w)hat" the user for that login * session is doing currently. This the essential core of 'w'. */ -static proc_t *getproc(utmp_t *u, char *tty, int *jcpu, int *found_utpid) { +static proc_t *getproc(utmp_t *u, char *tty, unsigned long long *jcpu, int *found_utpid) { int line; proc_t **p, *best = NULL, *secondbest = NULL; unsigned uid = ~0U; @@ -168,7 +168,7 @@ static proc_t *getproc(utmp_t *u, char *tty, int *jcpu, int *found_utpid) { /***** showinfo */ static void showinfo(utmp_t *u, int formtype, int maxcmd, int from) { - int jcpu, ut_pid_found; + unsigned long long jcpu, ut_pid_found; unsigned i; char uname[USERSZ + 1] = "", tty[5 + sizeof u->ut_line + 1] = "/dev/"; @@ -201,7 +201,7 @@ static void showinfo(utmp_t *u, int formtype, int maxcmd, int from) { print_time_ival7(idletime(tty), 0, stdout); print_time_ival7(jcpu/Hertz, (jcpu%Hertz)*(100./Hertz), stdout); if (best) { - int pcpu = best->utime + best->stime; + unsigned long long pcpu = best->utime + best->stime; print_time_ival7(pcpu/Hertz, (pcpu%Hertz)*(100./Hertz), stdout); } else printf(" ? ");