124139Sjoerg/* 224139Sjoerg * top - a top users display for Unix 324139Sjoerg * 424139Sjoerg * THIS IS A TEMPLATE FILE FOR A MACHINE DEPENDENT (m_...c) FILE 524139Sjoerg * 624139Sjoerg * SYNOPSIS: one line description of machine this module works with 724139Sjoerg * 824139Sjoerg * DESCRIPTION: 924139Sjoerg * Detailed description of this machine dependent module. 1024139Sjoerg * It can be multiple lines, but a blank comment line (one with only an 1124139Sjoerg * asterisk) is considered to end it. Place here a complete list of 1224139Sjoerg * the machines and OS versions that this module works on. 1324139Sjoerg * 1424139Sjoerg * LIBS: list of special libraries to include at link step (REMOVE THIS LINE IF NOT NEEDED) 1524139Sjoerg * 1624139Sjoerg * AUTHOR: your name and <your@internet.address> 1724139Sjoerg */ 1824139Sjoerg 1924139Sjoerg#include "top.h" 2024139Sjoerg#include "machine.h" 2124139Sjoerg 2224139Sjoerg 2324139Sjoerg/* 2424139Sjoerg * These definitions control the format of the per-process area 2524139Sjoerg */ 2624139Sjoerg 2724139Sjoergstatic char header[] = 2824139Sjoerg " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; 2924139Sjoerg/* 0123456 -- field to fill in starts at header+6 */ 3024139Sjoerg#define UNAME_START 6 3124139Sjoerg 3224139Sjoerg#define Proc_format \ 3324139Sjoerg "%5d %-8.8s %3d %4d%6dK %4dK %-5s%4d:%02d %5.2f%% %5.2f%% %.14s" 3424139Sjoerg 3524139Sjoerg/* these are for detailing the process states */ 3624139Sjoerg 3724139Sjoergint process_states[?]; 3824139Sjoergchar *procstatenames[] = { 3924139Sjoerg "", " sleeping, ", " ABANDONED, ", " running, ", " starting, ", 4024139Sjoerg " zombie, ", " stopped, ", 4124139Sjoerg NULL 4224139Sjoerg}; 4324139Sjoerg 4424139Sjoerg/* these are for detailing the cpu states */ 4524139Sjoerg 4624139Sjoergint cpu_states[?]; 4724139Sjoergchar *cpustatenames[] = { 4824139Sjoerg "user", "nice", "system", "idle", 4924139Sjoerg NULL 5024139Sjoerg}; 5124139Sjoerg 5224139Sjoerg/* these are for detailing the memory statistics */ 5324139Sjoerg 5424139Sjoergint memory_stats[?]; 5524139Sjoergchar *memorynames[] = { 5624139Sjoerg "K available, ", "K in use, ", "K free, ", "K locked", NULL 5724139Sjoerg}; 5824139Sjoerg 5924139Sjoerg/* useful externals */ 6024139Sjoergextern int errno; 6124139Sjoergextern char *sys_errlist[]; 6224139Sjoerg 6324139Sjoerglong lseek(); 6424139Sjoerglong time(); 6524139Sjoerglong percentages(); 6624139Sjoerg 6724139Sjoergmachine_init(statics) 6824139Sjoerg 6924139Sjoergstruct statics *statics; 7024139Sjoerg 7124139Sjoerg{ 7224139Sjoerg return(0); 7324139Sjoerg} 7424139Sjoerg 7524139Sjoergchar *format_header(uname_field) 7624139Sjoerg 7724139Sjoergregister char *uname_field; 7824139Sjoerg 7924139Sjoerg{ 8024139Sjoerg register char *ptr; 8124139Sjoerg 8224139Sjoerg ptr = header + UNAME_START; 8324139Sjoerg while (*uname_field != '\0') 8424139Sjoerg { 8524139Sjoerg *ptr++ = *uname_field++; 8624139Sjoerg } 8724139Sjoerg 8824139Sjoerg return(header); 8924139Sjoerg} 9024139Sjoerg 9124139Sjoergget_system_info(si) 9224139Sjoerg 9324139Sjoergstruct system_info *si; 9424139Sjoerg 9524139Sjoerg{ 9624139Sjoerg} 9724139Sjoerg 9824139Sjoergstatic struct handle handle; 9924139Sjoerg 10024139Sjoergcaddr_t get_process_info(si, sel, compare) 10124139Sjoerg 10224139Sjoergstruct system_info *si; 10324139Sjoergstruct process_select *sel; 10424139Sjoergint (*compare)(); 10524139Sjoerg 10624139Sjoerg{ 10724139Sjoerg return((caddr_t)&handle); 10824139Sjoerg} 10924139Sjoerg 11024139Sjoergchar fmt[128]; /* static area where result is built */ 11124139Sjoerg 11224139Sjoerg/* define what weighted cpu is. */ 11324139Sjoerg#define weighted_cpu(pct, pp) ((pp)->p_time == 0 ? 0.0 : \ 11424139Sjoerg ((pct) / (1.0 - exp((pp)->p_time * logcpu)))) 11524139Sjoerg 11624139Sjoergchar *format_next_process(handle, get_userid) 11724139Sjoerg 11824139Sjoergcaddr_t handle; 11924139Sjoergchar *(*get_userid)(); 12024139Sjoerg 12124139Sjoerg{ 12224139Sjoerg return(fmt); 12324139Sjoerg} 12424139Sjoerg 12524139Sjoerg/* 12624139Sjoerg * getkval(offset, ptr, size, refstr) - get a value out of the kernel. 12724139Sjoerg * "offset" is the byte offset into the kernel for the desired value, 12824139Sjoerg * "ptr" points to a buffer into which the value is retrieved, 12924139Sjoerg * "size" is the size of the buffer (and the object to retrieve), 13024139Sjoerg * "refstr" is a reference string used when printing error meessages, 13124139Sjoerg * if "refstr" starts with a '!', then a failure on read will not 13224139Sjoerg * be fatal (this may seem like a silly way to do things, but I 13324139Sjoerg * really didn't want the overhead of another argument). 13424139Sjoerg * 13524139Sjoerg */ 13624139Sjoerg 13724139Sjoerggetkval(offset, ptr, size, refstr) 13824139Sjoerg 13924139Sjoergunsigned long offset; 14024139Sjoergint *ptr; 14124139Sjoergint size; 14224139Sjoergchar *refstr; 14324139Sjoerg 14424139Sjoerg{ 14524139Sjoerg if (kvm_read(kd, offset, ptr, size) != size) 14624139Sjoerg { 14724139Sjoerg if (*refstr == '!') 14824139Sjoerg { 14924139Sjoerg return(0); 15024139Sjoerg } 15124139Sjoerg else 15224139Sjoerg { 15324139Sjoerg fprintf(stderr, "top: kvm_read for %s: %s\n", 15424139Sjoerg refstr, sys_errlist[errno]); 15524139Sjoerg quit(23); 15624139Sjoerg } 15724139Sjoerg } 15824139Sjoerg return(1); 15924139Sjoerg} 16024139Sjoerg 16124139Sjoerg/* comparison routine for qsort */ 16224139Sjoerg/* NOTE: this is specific to the BSD proc structure, but it should 16324139Sjoerg give you a good place to start. */ 16424139Sjoerg 16524139Sjoerg/* 16624139Sjoerg * proc_compare - comparison function for "qsort" 16724139Sjoerg * Compares the resource consumption of two processes using five 16824139Sjoerg * distinct keys. The keys (in descending order of importance) are: 16924139Sjoerg * percent cpu, cpu ticks, state, resident set size, total virtual 17024139Sjoerg * memory usage. The process states are ordered as follows (from least 17124139Sjoerg * to most important): WAIT, zombie, sleep, stop, start, run. The 17224139Sjoerg * array declaration below maps a process state index into a number 17324139Sjoerg * that reflects this ordering. 17424139Sjoerg */ 17524139Sjoerg 17624139Sjoergstatic unsigned char sorted_state[] = 17724139Sjoerg{ 17824139Sjoerg 0, /* not used */ 17924139Sjoerg 3, /* sleep */ 18024139Sjoerg 1, /* ABANDONED (WAIT) */ 18124139Sjoerg 6, /* run */ 18224139Sjoerg 5, /* start */ 18324139Sjoerg 2, /* zombie */ 18424139Sjoerg 4 /* stop */ 18524139Sjoerg}; 18624139Sjoerg 18724139Sjoergproc_compare(pp1, pp2) 18824139Sjoerg 18924139Sjoergstruct proc **pp1; 19024139Sjoergstruct proc **pp2; 19124139Sjoerg 19224139Sjoerg{ 19324139Sjoerg register struct proc *p1; 19424139Sjoerg register struct proc *p2; 19524139Sjoerg register int result; 19624139Sjoerg register pctcpu lresult; 19724139Sjoerg 19824139Sjoerg /* remove one level of indirection */ 19924139Sjoerg p1 = *pp1; 20024139Sjoerg p2 = *pp2; 20124139Sjoerg 20224139Sjoerg /* compare percent cpu (pctcpu) */ 20324139Sjoerg if ((lresult = p2->p_pctcpu - p1->p_pctcpu) == 0) 20424139Sjoerg { 20524139Sjoerg /* use cpticks to break the tie */ 20624139Sjoerg if ((result = p2->p_cpticks - p1->p_cpticks) == 0) 20724139Sjoerg { 20824139Sjoerg /* use process state to break the tie */ 20924139Sjoerg if ((result = sorted_state[p2->p_stat] - 21024139Sjoerg sorted_state[p1->p_stat]) == 0) 21124139Sjoerg { 21224139Sjoerg /* use priority to break the tie */ 21324139Sjoerg if ((result = p2->p_pri - p1->p_pri) == 0) 21424139Sjoerg { 21524139Sjoerg /* use resident set size (rssize) to break the tie */ 21624139Sjoerg if ((result = p2->p_rssize - p1->p_rssize) == 0) 21724139Sjoerg { 21824139Sjoerg /* use total memory to break the tie */ 21924139Sjoerg result = PROCSIZE(p2) - PROCSIZE(p1); 22024139Sjoerg } 22124139Sjoerg } 22224139Sjoerg } 22324139Sjoerg } 22424139Sjoerg } 22524139Sjoerg else 22624139Sjoerg { 22724139Sjoerg result = lresult < 0 ? -1 : 1; 22824139Sjoerg } 22924139Sjoerg 23024139Sjoerg return(result); 23124139Sjoerg} 23224139Sjoerg 23324139Sjoergproc_owner(pid) 23424139Sjoerg 23524139Sjoergint pid; 23624139Sjoerg 23724139Sjoerg{ 23824139Sjoerg /* returns uid of owner of process pid */ 23924139Sjoerg return(uid); 24024139Sjoerg} 24124139Sjoerg 242