📄 m_sunos4mp.c
字号:
register struct page *pp; register int cnt; register int inuse; register int free; register int locked; /* bop thru the array counting page types */ pp = physpage; inuse = free = locked = 0; for (cnt = count; --cnt >= 0; pp++) { if (pp->p_free) free++; else if (pp->p_lock || pp->p_keepcnt > 0) locked++; else inuse++; } /* convert memory stats to Kbytes */ memory_stats[0] = pagetok(inuse + free); memory_stats[1] = pagetok(inuse); memory_stats[2] = pagetok(free); memory_stats[3] = pagetok(locked); } /* set arrays and strings */ si->cpustates = cpu_states; si->memory = memory_stats;}static struct handle handle;caddr_t get_process_info(si, sel, compare)struct system_info *si;struct process_select *sel;int (*compare)();{ register int i; register int total_procs; register int active_procs; register struct proc **prefp; register struct proc *pp; /* these are copied out of sel for speed */ int show_idle; int show_system; int show_uid; int show_command; /* read all the proc structures in one fell swoop */ (void) getkval(proc, (int *)pbase, bytes, "proc array"); /* get a pointer to the states summary array */ si->procstates = process_states; /* set up flags which define what we are going to select */ show_idle = sel->idle; show_system = sel->system; show_uid = sel->uid != -1; show_command = sel->command != NULL; /* count up process states and get pointers to interesting procs */ total_procs = 0; active_procs = 0; bzero((char *)process_states, sizeof(process_states)); prefp = pref; for (pp = pbase, i = 0; i < nproc; pp++, i++) { /* * Place pointers to each valid proc structure in pref[]. * Process slots that are actually in use have a non-zero * status field. Processes with SSYS set are system * processes---these get ignored unless show_sysprocs is set. */ if (pp->p_stat != 0 && (show_system || ((pp->p_flag & SSYS) == 0))) { total_procs++; process_states[pp->p_stat]++; if ((pp->p_stat != SZOMB) && (show_idle || (pp->p_pctcpu != 0) || (pp->p_stat == SRUN)) && (!show_uid || pp->p_uid == (uid_t)sel->uid)) { *prefp++ = pp; active_procs++; } } } /* if requested, sort the "interesting" processes */ if (compare != NULL) { qsort((char *)pref, active_procs, sizeof(struct proc *), compare); } /* 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 */char *format_next_process(handle, get_userid)caddr_t handle;char *(*get_userid)();{ register struct proc *pp; register long cputime; 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>"); cputime = 0; } 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"); } } cputime = u.u_ru.ru_utime.tv_sec + u.u_ru.ru_stime.tv_sec; } /* calculate the base for cpu percentages */ pct = pctdouble(pp->p_pctcpu); /* * If there is more than one cpu then add the processor number to * the "run/" string. Note that this will only show up if the * process is in the run state. Also note: when they * start making Suns with more than 9 processors this will break * since the string will then be more than 5 characters. */ if (IS_MP) { state_abbrev[SRUN][4] = (pp->p_cpuid & 0xf) + '0'; } /* 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(cputime), 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;{ register struct user *lu; lu = kvm_getu(kd, p); if (lu == NULL) { return(-1); } else { *u = *lu; 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) {#ifdef i386 if (nlst->n_value == 0)#else if (nlst->n_type == 0)#endif { /* 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 (kvm_read(kd, offset, ptr, size) != size) { if (*refstr == '!') { return(0); } else { fprintf(stderr, "top: kvm_read for %s: %s\n", refstr, sys_errlist[errno]); quit(23); /*NOTREACHED*/ } } 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 : lresult < 0 ? -1 : 0) == 0)#define ORDERKEY_CPTICKS if ((result = p2->p_cpticks - p1->p_cpticks) == 0)#define ORDERKEY_STATE if ((result = 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 ac; register struct proc **prefp; register struct proc *pp; prefp = pref; ac = pref_len; while (--ac >= 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 + -