📄 m_mtxinu.c
字号:
/* remember active and total counts */ si->p_total = total_procs; si->p_active = pref_len = active_procs; /* pass back a handle */ handle.next_proc = pref; handle.remaining = active_procs; return((caddr_t)&handle);}char fmt[MAX_COLS]; /* static area where result is built *//* define what weighted cpu is. */#define weighted_cpu(pct, pp) ((pp)->p_time == 0 ? 0.0 : \ ((pct) / (1.0 - exp((pp)->p_time * logcpu))))char *format_next_process(handle, get_userid)caddr_t handle;char *(*get_userid)();{ register struct proc *pp; register double pct; struct user u; struct handle *hp; /* find and remember the next proc structure */ hp = (struct handle *)handle; pp = *(hp->next_proc++); hp->remaining--; /* get the process's user struct and set cputime */ if (getu(pp, &u) == -1) { (void) strcpy(u.u_comm, "<swapped>"); } else { /* set u_comm for system processes */ if (u.u_comm[0] == '\0') { if (pp->p_pid == 0) { (void) strcpy(u.u_comm, "Swapper"); } else if (pp->p_pid == 2) { (void) strcpy(u.u_comm, "Pager"); } } } /* calculate the base for cpu percentages */ pct = pctdouble(pp->p_pctcpu); /* format this entry */ sprintf(fmt, Proc_format, pp->p_pid, (*get_userid)(pp->p_uid), pp->p_pri - PZERO, pp->p_nice - NZERO, format_k(pagetok(PROCSIZE(pp))), format_k(pagetok(pp->p_rssize)), state_abbrev[pp->p_stat], format_time(PROCTIME(pp)), 100.0 * weighted_cpu(pct, pp), 100.0 * pct, printable(u.u_comm)); /* return the result */ return(fmt);}/* * getu(p, u) - get the user structure for the process whose proc structure * is pointed to by p. The user structure is put in the buffer pointed * to by u. Return 0 if successful, -1 on failure (such as the process * being swapped out). */getu(p, u)register struct proc *p;struct user *u;{ struct pte uptes[UPAGES]; register caddr_t upage; register struct pte *pte; register nbytes, n; /* * Check if the process is currently loaded or swapped out. The way we * get the u area is totally different for the two cases. For this * application, we just don't bother if the process is swapped out. */ if ((p->p_flag & SLOAD) == 0) { return(-1); } /* * Process is currently in memory, we hope! */ if (!getkval((unsigned long)p->p_addr, (int *)uptes, sizeof(uptes), "!p->p_addr")) { /* we can't seem to get to it, so pretend it's swapped out */ return(-1); } upage = (caddr_t)u; pte = uptes; for (nbytes = sizeof(struct user); nbytes > 0; nbytes -= NBPG) { (void) lseek(mem, (long)(pte++->pg_pfnum * NBPG), 0); n = MIN(nbytes, NBPG); if (read(mem, upage, n) != n) { /* we can't seem to get to it, so pretend it's swapped out */ return(-1); } upage += n; } return(0);}/* * check_nlist(nlst) - checks the nlist to see if any symbols were not * found. For every symbol that was not found, a one-line * message is printed to stderr. The routine returns the * number of symbols NOT found. */int check_nlist(nlst)register struct nlist *nlst;{ register int i; /* check to see if we got ALL the symbols we requested */ /* this will write one line to stderr for every symbol not found */ i = 0; while (nlst->n_name != NULL) { if (nlst->n_type == 0) { /* this one wasn't found */ fprintf(stderr, "kernel: no symbol named `%s'\n", nlst->n_name); i = 1; } nlst++; } return(i);}/* * 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). * */getkval(offset, ptr, size, refstr)unsigned long offset;int *ptr;int size;char *refstr;{ if (lseek(kmem, (long)offset, 0) == -1) { if (*refstr == '!') { refstr++; } fprintf(stderr, "%s: lseek to %s: %s\n", KMEM, refstr, sys_errlist[errno]); quit(22); } if (read(kmem, (char *)ptr, size) == -1) { if (*refstr == '!') { /* we lost the race with the kernel, process isn't in memory */ return(0); } else { fprintf(stderr, "%s: reading %s: %s\n", KMEM, refstr, sys_errlist[errno]); quit(23); } } return(1);}/* comparison routines for qsort *//* * There are currently four possible comparison routines. main selects * one of these by indexing in to the array proc_compares. * * Possible keys are defined as macros below. Currently these keys are * defined: percent cpu, cpu ticks, process state, resident set size, * total virtual memory usage. The process states are ordered as follows * (from least to most important): WAIT, zombie, sleep, stop, start, run. * The array declaration below maps a process state index into a number * that reflects this ordering. *//* First, the possible comparison keys. 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 (lresult = p2->p_pctcpu - p1->p_pctcpu,\ (result = lresult < 0 ? -1 : 1) == 0)#define ORDERKEY_CPTICKS if ((result = PROCTIME(p2) - PROCTIME(p1)) == 0)#define ORDERKEY_STATE if ((result = (long) (sorted_state[p2->p_stat] - \ sorted_state[p1->p_stat])) == 0)#define ORDERKEY_PRIO if ((result = p2->p_pri - p1->p_pri) == 0)#define ORDERKEY_RSSIZE if ((result = p2->p_rssize - p1->p_rssize) == 0)#define ORDERKEY_MEM if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0)/* Now the array that maps process state to a weight */static unsigned char sorted_state[] ={ 0, /* not used */ 3, /* sleep */ 1, /* ABANDONED (WAIT) */ 6, /* run */ 5, /* start */ 2, /* zombie */ 4 /* stop */};/* compare_cpu - the comparison function for sorting by cpu percentage */compare_cpu(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return(result);}/* compare_size - the comparison function for sorting by total memory usage */compare_size(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_MEM ORDERKEY_RSSIZE ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return(result);}/* compare_res - the comparison function for sorting by resident set size */compare_res(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_RSSIZE ORDERKEY_MEM ORDERKEY_PCTCPU ORDERKEY_CPTICKS ORDERKEY_STATE ORDERKEY_PRIO ; return(result);}/* compare_time - the comparison function for sorting by total cpu time */compare_time(pp1, pp2)struct proc **pp1;struct proc **pp2;{ register struct proc *p1; register struct proc *p2; register int result; register pctcpu lresult; /* remove one level of indirection */ p1 = *pp1; p2 = *pp2; ORDERKEY_CPTICKS ORDERKEY_PCTCPU ORDERKEY_STATE ORDERKEY_PRIO ORDERKEY_RSSIZE ORDERKEY_MEM ; return(result);}/* * proc_owner(pid) - returns the uid that owns process "pid", or -1 if * the process does not exist. * It is EXTREMLY IMPORTANT that this function work correctly. * If top runs setuid root (as in SVR4), then this function * is the only thing that stands in the way of a serious * security problem. It validates requests for the "kill" * and "renice" commands. */int proc_owner(pid)int pid;{ register int cnt; register struct proc **prefp; register struct proc *pp; prefp = pref; cnt = pref_len; while (--cnt >= 0) { if ((pp = *prefp++)->p_pid == (pid_t)pid) { return((int)pp->p_uid); } } return(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -