📄 m_irixsgi.c
字号:
if (pp->pr_pri <= NDPHIMIN) /* real time? */ sprintf(prio_str, "+%d", pp->pr_pri); else if (pp->pr_pri <= NDPNORMMIN) /* normal interactive */ sprintf(prio_str, "%d", pp->pr_pri); else /* batch: low prio */ sprintf(prio_str, "b%d", pp->pr_pri); } else { /* copied from Kostadis's code */ if (strcmp(pp->pr_clname, "RT") == 0) /* real time */ sprintf(prio_str, "+%d", pp->pr_pri); else if (strcmp(pp->pr_clname, "DL") == 0) /* unsupported ? */ sprintf(prio_str, "d%d", pp->pr_pri); else if (strcmp(pp->pr_clname, "GN") == 0) sprintf(prio_str, "g%d", pp->pr_pri); else if (strcmp(pp->pr_clname, "GB") == 0) sprintf(prio_str, "p%d", pp->pr_pri); else if (strcmp(pp->pr_clname, "WL") == 0) /* weightless */ return "w"; else if (strcmp(pp->pr_clname, "BC") == 0) return "bc"; /* batch critical */ else if (strcmp(pp->pr_clname, "B") == 0) return "b"; /* batch */ else sprintf(prio_str, "%d", pp->pr_pri); } return prio_str;}static doubleclip_percent(double pct){ if (pct < 0) { return 0.0; } else if (pct >= 100) { return 99.99; } return pct;}char *format_next_process(handle, get_userid) caddr_t handle; char *(*get_userid)();{ struct prpsinfo *pp; struct handle *hp; long cputime; /* find and remember the next proc structure */ hp = (struct handle *) handle; pp = *(hp->next_proc++); hp->remaining--; /* get the process cpu usage since startup */ cputime = pp->pr_time.tv_sec; /* format this entry */ sprintf(fmt, Proc_format, pp->pr_pid, pp->pr_pgrp, (*get_userid) (pp->pr_uid), format_prio(pp), format_k(pagetok(pp->pr_size)), format_k(pagetok(pp->pr_rssize)), format_state(pp), format_time(cputime), clip_percent(weighted_cpu(pp)), clip_percent(percent_cpu(pp)), pp->pr_fname); /* return the result */ return (fmt);}/* * getkval(offset, ptr, size, refstr) - get a value out of the kernel. * "offset" is the byte offset into the kernel for the desired value, * "ptr" points to a buffer into which the value is retrieved, * "size" is the size of the buffer (and the object to retrieve), * "refstr" is a reference string used when printing error meessages, * if "refstr" starts with a '!', then a failure on read will not * be fatal (this may seem like a silly way to do things, but I * really didn't want the overhead of another argument). * */intgetkval(offset, ptr, size, refstr) unsigned long offset; int *ptr; int size; char *refstr;{ if (lseek(kmem, (long) offset, SEEK_SET) == -1) { if (*refstr == '!') refstr++; (void) fprintf(stderr, "%s: %s: lseek to %s: %s\n", myname, KMEM, refstr, strerror(errno)); exit(0); } if (read(kmem, (char *) ptr, size) == -1) { if (*refstr == '!') return (0); else { (void) fprintf(stderr, "%s: %s: reading %s: %s\n", myname, KMEM, refstr, strerror(errno)); exit(0); } } return (1);}/* * compare_K - comparison functions for "qsort" * Compares the resource consumption of two processes using five * distinct keys. The keys are: * percent cpu, cpu ticks, state, resident set size, total virtual * memory usage. The process states are ordered as follows (from least * to most important): WAIT, zombie, sleep, stop, idle, run. * Different comparison functions are used for different orderings. *//* these are names given to allowed sorting orders -- first is default */char *ordernames[] = { /* * Aliases for user convenience/friendliness: * mem == size * rss == res */ "cpu", "size", "mem", "res", "rss", "time", "state", "command", "prio", NULL};/* forward definitions for comparison functions */int compare_cpu(struct prpsinfo **pp1, struct prpsinfo **pp2);int compare_size(struct prpsinfo **pp1, struct prpsinfo **pp2);int compare_res(struct prpsinfo **pp1, struct prpsinfo **pp2);int compare_time(struct prpsinfo **pp1, struct prpsinfo **pp2);int compare_state(struct prpsinfo **pp1, struct prpsinfo **pp2);int compare_cmd(struct prpsinfo **pp1, struct prpsinfo **pp2);int compare_prio(struct prpsinfo **pp1, struct prpsinfo **pp2);int (*proc_compares[])() = { compare_cpu, compare_size, compare_size, compare_res, compare_res, compare_time, compare_state, compare_cmd, compare_prio, NULL};/* * The possible comparison expressions. These are defined in such a way * that they can be merely listed in the source code to define the actual * desired ordering. */#define ORDERKEY_PCTCPU \ if (dresult = percent_cpu(p2) - percent_cpu(p1),\ (result = dresult > 0.0 ? 1 : dresult < 0.0 ? -1 : 0) == 0)#define ORDERKEY_CPTICKS \ if ((result = p2->pr_time.tv_sec - p1->pr_time.tv_sec) == 0)#define ORDERKEY_STATE if ((result = proc_state(p2) - proc_state(p1)) == 0)#define ORDERKEY_PRIO if ((result = p2->pr_oldpri - p1->pr_oldpri) == 0)#define ORDERKEY_RSSIZE if ((result = p2->pr_rssize - p1->pr_rssize) == 0)#define ORDERKEY_MEM if ((result = (p2->pr_size - p1->pr_size)) == 0)#define ORDERKEY_CMD if ((result = strcmp(p1->pr_fname,p2->pr_fname)) == 0)int compare_cpu(struct prpsinfo **pp1, struct prpsinfo **pp2){ struct prpsinfo *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* * order by various keys, resorting to the next one * whenever there's a tie in comparisons */ ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return (result);}int compare_size(struct prpsinfo **pp1, struct prpsinfo **pp2){ struct prpsinfo *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* * order by various keys, resorting to the next one * whenever there's a tie in comparisons */ ORDERKEY_MEM ORDERKEY_RSSIZE ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return (result);}int compare_res(struct prpsinfo **pp1, struct prpsinfo **pp2){ struct prpsinfo *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* * order by various keys, resorting to the next one * whenever there's a tie in comparisons */ ORDERKEY_RSSIZE ORDERKEY_MEM ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return (result);}int compare_time(struct prpsinfo **pp1, struct prpsinfo **pp2){ struct prpsinfo *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* * order by various keys, resorting to the next one * whenever there's a tie in comparisons */ ORDERKEY_CPTICKS ORDERKEY_RSSIZE ORDERKEY_MEM ORDERKEY_PCTCPU ORDERKEY_STATE ORDERKEY_PRIO ; return (result);}int compare_cmd(struct prpsinfo **pp1, struct prpsinfo **pp2){ struct prpsinfo *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* * order by various keys, resorting to the next one * whenever there's a tie in comparisons */ ORDERKEY_CMD ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_RSSIZE ; return (result);}int compare_state(struct prpsinfo **pp1, struct prpsinfo **pp2){ struct prpsinfo *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* * order by various keys, resorting to the next one * whenever there's a tie in comparisons */ ORDERKEY_STATE ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_RSSIZE ; return (result);}int compare_prio(struct prpsinfo **pp1, struct prpsinfo **pp2){ struct prpsinfo *p1, *p2; int result; double dresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; /* * order by various keys, resorting to the next one * whenever there's a tie in comparisons */ ORDERKEY_PRIO ORDERKEY_PCTCPU ; return (result);}/* return the owner of the specified process. */uid_tproc_owner(pid) pid_t pid;{ register struct prpsinfo *p; int i; for (i = 0, p = pbase; i < nproc; i++, p++) if (p->pr_pid == pid) return (p->pr_uid); return (-1);}#ifdef DO_MAPSIZEstatic voidsize(int fd, struct prpsinfo *ps){ prmap_sgi_arg_t maparg; struct prmap_sgi maps[256]; int nmaps; double sz; int i; maparg.pr_vaddr = (caddr_t) maps; maparg.pr_size = sizeof maps; if ((nmaps = ioctl(fd, PIOCMAP_SGI, &maparg)) == -1) { /* XXX - this will be confusing */ return; } for (i = 0, sz = 0; i < nmaps; ++i) { sz += (double) maps[i].pr_wsize / MA_WSIZE_FRAC; } ps->pr_rssize = (long) sz;}#endif/* get process table */voidgetptable(struct prpsinfo *baseptr){ struct prpsinfo *currproc; /* ptr to current proc struct */ int i, numprocs; struct dirent *direntp; struct oldproc *op, *endbase; static struct timeval lasttime, thistime; static double timediff, alpha, beta; /* measure time between last call to getptable and current call */ gettimeofday (&thistime, NULL); /* * To avoid divides, we keep times in nanoseconds. This is * scaled by 1e7 rather than 1e9 so that when we divide we * get percent. */ timediff = ((double) thistime.tv_sec * 1.0e7 - (double) lasttime.tv_sec * 1.0e7) + ((double) thistime.tv_usec * 10 - (double) lasttime.tv_usec * 10); /* * Under extreme load conditions, sca has experienced * an assert(timediff > 0) failure here. His guess is that * sometimes timed resets the time backwards and gettimeofday * returns a lower number on a later call. * To be on the safe side I fix it here by setting timediff * to some arbitrary small value (in nanoseconds). */ if (timediff <= 0.0) timediff = 100.0; lasttime = thistime; /* prepare for next round */ /* * constants for exponential decaying average. * avg = alpha * new + beta * avg * The goal is 50% decay in 30 sec. However if the sample period * is greater than 30 sec, there's not a lot we can do. */ if (timediff < 30.0e7) { alpha = 0.5 * (timediff / 15.0e7); beta = 1.0 - alpha; } else { alpha = 0.5; beta = 0.5; } assert(alpha >= 0); assert(alpha <= 1); assert(beta >= 0); assert(beta <= 1); endbase = oldbase + oldprocs; currproc = baseptr; for (numprocs = 0, rewinddir(procdir); direntp = readdir(procdir);) { int fd; if ((fd = open(direntp->d_name, O_RDONLY)) < 0) continue; currproc = baseptr + numprocs; if (ioctl(fd, PIOCPSINFO, currproc) < 0) { (void) close(fd); continue; } /* * SVR4 doesn't keep track of CPU% in the kernel, * so we have to do our own. * See if we've heard of this process before. * If so, compute % based on CPU since last time. */ op = oldbase + HASH (currproc->pr_pid); for (;;) { if (op->oldpid == -1) /* not there */ break; if (op->oldpid == currproc->pr_pid) { /* found old data */ percent_cpu(currproc) = ((currproc->pr_time.tv_sec * 1.0e9 + currproc->pr_time.tv_nsec) - op->oldtime) / timediff; weighted_cpu(currproc) = op->oldpct * beta + percent_cpu(currproc) * alpha; break; } op++; /* try next entry in hash table */ if (op == endbase) /* table wrap around */ op = oldbase; } /* Otherwise, it's new, so use all of its CPU time */ if (op->oldpid == -1) { if (lasttime.tv_sec) { percent_cpu(currproc) = (currproc->pr_time.tv_sec * 1.0e9 + currproc->pr_time.tv_nsec) / timediff; weighted_cpu(currproc) = percent_cpu(currproc); } else { /* first screen -- no difference is possible */ percent_cpu(currproc) = 0.0; weighted_cpu(currproc) = 0.0; } }#ifdef DO_MAPSIZE size(fd, currproc);#endif numprocs++; (void) close(fd); /* * Bug: in case process count grew so dramatically * as to exceed to table size. We give up on a full scan. * the chances of this to happen are extremely slim due to * the big factor we're using. getting nproc from nlist * is not worth the headache. realloc wouldn't work either * because we have pointers to the proc table so we cannot * move it around. */ if (numprocs >= ptable_size) { fprintf(stderr, "preallocated proc table size (%d) exceeded, " "skipping some processes\n", ptable_size); break; } } nproc = numprocs; /* * Save current CPU time for next time around * For the moment recreate the hash table each time, as the code * is easier that way. */ oldprocs = 2 * nproc; endbase = oldbase + oldprocs; for (op = oldbase; op < endbase; op++) op->oldpid = -1; for (i = 0, currproc = baseptr; i < nproc; i++, currproc++) { /* find an empty spot */ op = oldbase + HASH (currproc->pr_pid); for (;;) { if (op->oldpid == -1) break; op++; if (op == endbase) op = oldbase; } op->oldpid = currproc->pr_pid; op->oldtime = (currproc->pr_time.tv_sec * 1.0e9 + currproc->pr_time.tv_nsec); op->oldpct = weighted_cpu(currproc); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -