64-bit time for Linux 2.5.xx

This commit is contained in:
albert 2002-05-28 04:18:55 +00:00
parent ea1d89ec4f
commit bce2da1f9a
8 changed files with 93 additions and 100 deletions

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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; /* <asm/param.h> */
Hertz = (unsigned long long)HZ; /* <asm/param.h> */
#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 % */

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

6
w.c
View File

@ -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(" ? ");