1/* 2 * top - a top users display for Unix 3 * 4 * THIS IS A TEMPLATE FILE FOR A MACHINE DEPENDENT (m_...c) FILE 5 * 6 * SYNOPSIS: one line description of machine this module works with 7 * 8 * DESCRIPTION: 9 * Detailed description of this machine dependent module. 10 * It can be multiple lines, but a blank comment line (one with only an 11 * asterisk) is considered to end it. Place here a complete list of 12 * the machines and OS versions that this module works on. 13 * 14 * LIBS: list of special libraries to include at link step (REMOVE THIS LINE IF NOT NEEDED) 15 * 16 * AUTHOR: your name and <your@internet.address> 17 */ 18 19#include "top.h" 20#include "machine.h" 21 22 23/* 24 * These definitions control the format of the per-process area 25 */ 26 27static char header[] = 28 " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; 29/* 0123456 -- field to fill in starts at header+6 */ 30#define UNAME_START 6 31 32#define Proc_format \ 33 "%5d %-8.8s %3d %4d%6dK %4dK %-5s%4d:%02d %5.2f%% %5.2f%% %.14s" 34 35/* these are for detailing the process states */ 36 37int process_states[?]; 38char *procstatenames[] = { 39 "", " sleeping, ", " ABANDONED, ", " running, ", " starting, ", 40 " zombie, ", " stopped, ", 41 NULL 42}; 43 44/* these are for detailing the cpu states */ 45 46int cpu_states[?]; 47char *cpustatenames[] = { 48 "user", "nice", "system", "idle", 49 NULL 50}; 51 52/* these are for detailing the memory statistics */ 53 54int memory_stats[?]; 55char *memorynames[] = { 56 "K available, ", "K in use, ", "K free, ", "K locked", NULL 57}; 58 59/* useful externals */ 60extern int errno; 61extern char *sys_errlist[]; 62 63long lseek(); 64long time(); 65long percentages(); 66 67machine_init(statics) 68 69struct statics *statics; 70 71{ 72 return(0); 73} 74 75char *format_header(uname_field) 76 77register char *uname_field; 78 79{ 80 register char *ptr; 81 82 ptr = header + UNAME_START; 83 while (*uname_field != '\0') 84 { 85 *ptr++ = *uname_field++; 86 } 87 88 return(header); 89} 90 91get_system_info(si) 92 93struct system_info *si; 94 95{ 96} 97 98static struct handle handle; 99 100caddr_t get_process_info(si, sel, compare) 101 102struct system_info *si; 103struct process_select *sel; 104int (*compare)(); 105 106{ 107 return((caddr_t)&handle); 108} 109 110char fmt[128]; /* static area where result is built */ 111 112/* define what weighted cpu is. */ 113#define weighted_cpu(pct, pp) ((pp)->p_time == 0 ? 0.0 : \ 114 ((pct) / (1.0 - exp((pp)->p_time * logcpu)))) 115 116char *format_next_process(handle, get_userid) 117 118caddr_t handle; 119char *(*get_userid)(); 120 121{ 122 return(fmt); 123} 124 125/* 126 * getkval(offset, ptr, size, refstr) - get a value out of the kernel. 127 * "offset" is the byte offset into the kernel for the desired value, 128 * "ptr" points to a buffer into which the value is retrieved, 129 * "size" is the size of the buffer (and the object to retrieve), 130 * "refstr" is a reference string used when printing error meessages, 131 * if "refstr" starts with a '!', then a failure on read will not 132 * be fatal (this may seem like a silly way to do things, but I 133 * really didn't want the overhead of another argument). 134 * 135 */ 136 137getkval(offset, ptr, size, refstr) 138 139unsigned long offset; 140int *ptr; 141int size; 142char *refstr; 143 144{ 145 if (kvm_read(kd, offset, ptr, size) != size) 146 { 147 if (*refstr == '!') 148 { 149 return(0); 150 } 151 else 152 { 153 fprintf(stderr, "top: kvm_read for %s: %s\n", 154 refstr, sys_errlist[errno]); 155 quit(23); 156 } 157 } 158 return(1); 159} 160 161/* comparison routine for qsort */ 162/* NOTE: this is specific to the BSD proc structure, but it should 163 give you a good place to start. */ 164 165/* 166 * proc_compare - comparison function for "qsort" 167 * Compares the resource consumption of two processes using five 168 * distinct keys. The keys (in descending order of importance) are: 169 * percent cpu, cpu ticks, state, resident set size, total virtual 170 * memory usage. The process states are ordered as follows (from least 171 * to most important): WAIT, zombie, sleep, stop, start, run. The 172 * array declaration below maps a process state index into a number 173 * that reflects this ordering. 174 */ 175 176static unsigned char sorted_state[] = 177{ 178 0, /* not used */ 179 3, /* sleep */ 180 1, /* ABANDONED (WAIT) */ 181 6, /* run */ 182 5, /* start */ 183 2, /* zombie */ 184 4 /* stop */ 185}; 186 187proc_compare(pp1, pp2) 188 189struct proc **pp1; 190struct proc **pp2; 191 192{ 193 register struct proc *p1; 194 register struct proc *p2; 195 register int result; 196 register pctcpu lresult; 197 198 /* remove one level of indirection */ 199 p1 = *pp1; 200 p2 = *pp2; 201 202 /* compare percent cpu (pctcpu) */ 203 if ((lresult = p2->p_pctcpu - p1->p_pctcpu) == 0) 204 { 205 /* use cpticks to break the tie */ 206 if ((result = p2->p_cpticks - p1->p_cpticks) == 0) 207 { 208 /* use process state to break the tie */ 209 if ((result = sorted_state[p2->p_stat] - 210 sorted_state[p1->p_stat]) == 0) 211 { 212 /* use priority to break the tie */ 213 if ((result = p2->p_pri - p1->p_pri) == 0) 214 { 215 /* use resident set size (rssize) to break the tie */ 216 if ((result = p2->p_rssize - p1->p_rssize) == 0) 217 { 218 /* use total memory to break the tie */ 219 result = PROCSIZE(p2) - PROCSIZE(p1); 220 } 221 } 222 } 223 } 224 } 225 else 226 { 227 result = lresult < 0 ? -1 : 1; 228 } 229 230 return(result); 231} 232 233proc_owner(pid) 234 235int pid; 236 237{ 238 /* returns uid of owner of process pid */ 239 return(uid); 240} 241 242