Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / top / dist / machine / m_sco5.c
blobe36cd04e2e28fc3bea7677d24184d8c0ae9d9b7b
1 /*
2 * Copyright (c) 1984 through 2008, William LeFebvre
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
16 * * Neither the name of William LeFebvre nor the names of other
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * top - a top users display for Unix
36 * SYNOPSIS: SCO UNIX OpenServer5
38 * DESCRIPTION:
39 * This is the machine-dependent module for SCO OpenServer5.
40 * Originally written for BSD4.3 system by Christos Zoulas.
41 * Modified to m_sco.c (3.2v4.2) by Gregory Shilin <shilin@onyx.co.il>
42 * Modified to m_sco5.c (3.2v5.*) by Mike Hopkirk <hops@sco.com>
43 * Works for:
44 * SCO UNIX 3.2v5.*
46 * CFLAGS: -DHAVE_GETOPT -DORDER
48 * AUTHOR: Mike Hopkirk (hops@sco.com)
49 * hops 10-Jul-98 - added sort fields
50 * 17-Jul-98 - add philiph's chopped cmd string support
51 * (define NO_COMMAND_ARGS to enable )
52 * 09-Dec-98 - provide RSS calculation
53 * 15-Mar-2000 - Fix broken lines and cleanup sysinfo access w macros
56 #include <sys/types.h>
57 #include <sys/param.h>
59 #include <stdio.h>
60 #include <unistd.h>
61 #include <fcntl.h>
62 #include <nlist.h>
63 #include <math.h>
64 #include <signal.h>
65 #include <string.h>
67 #include <sys/dir.h>
68 #include <sys/immu.h>
69 #include <sys/region.h>
70 #include <sys/proc.h>
71 #include <sys/user.h>
72 #include <sys/sysinfo.h>
73 #include <sys/systm.h>
74 #include <sys/sysmacros.h>
75 #include <sys/var.h>
76 #include <sys/sysi86.h>
78 #include "top.h"
79 #include "machine.h"
80 #include "utils.h"
81 #include "loadavg.h"
84 typedef unsigned long ulong;
85 typedef unsigned int uint;
86 typedef unsigned short ushort;
88 typedef unsigned char uchar;
90 #define VMUNIX "/unix"
91 #define KMEM "/dev/kmem"
92 #define MEM "/dev/mem"
94 #define SI_ACTIVE(p) p->p_active
95 #define SI_TOTAL(p) p->p_total
97 /* get_process_info passes back a handle. This is what it looks like: */
98 struct handle {
99 struct proc **next_proc; /* points to next valid proc pointer */
100 int remaining; /* number of pointers remaining */
103 /* define what weighted cpu is */
104 #define weighted_cpu(pct, pp) ((pp)->p_time == 0 ? 0.0 : \
105 ((pct) / (1.0 - exp((pp)->p_time * logcpu))))
107 #define bytetok(bytes) ((bytes) >> 10)
109 /* what we consider to be process size: */
110 #define PROCSIZE(up) bytetok(ctob((up)->u_tsize + (up)->u_dsize+(up)->u_ssize))
112 /* definitions for indices in the nlist array */
113 #define X_V 0 /* System configuration information */
114 #define X_PROC 1 /* process tables */
115 #define X_FREEMEM 2 /* current free memory */
116 #define X_AVAILRMEM 3 /* available resident (not swappable) mem in pages
118 #define X_AVAILSMEM 4 /* available swappable memory in pages */
119 #define X_MAXMEM 5 /* maximum available free memory in clicks */
120 #define X_PHYSMEM 6 /* physical memory in clicks */
121 #define X_NSWAP 7 /* size of swap space in blocks */
122 #define X_HZ 8 /* ticks/second of the clock */
123 #define X_MPID 9 /* last process id */
124 #define X_SYSINFO 10 /* system information (cpu states) */
125 #define X_CUR_CPU 11
127 static struct nlist nlst[] = {
128 { "v" }, /* 0 */
129 { "proc" }, /* 1 */
130 { "freemem" }, /* 2 */
131 { "availrmem" }, /* 3 */
132 { "availsmem" }, /* 4 */
133 { "maxmem" }, /* 5 */
134 { "physmem" }, /* 6 */
135 { "nswap" }, /* 7 */
136 { "Hz" }, /* 8 */
137 { "mpid" }, /* 9 */
138 { "sysinfo" }, /* 10 */
139 { "cur_cpu" }, /* 11 */
140 { NULL }
144 * These definitions control the format of the per-process area
147 static char header[] =
148 " PID X PRI NICE SIZE RES STATE TIME COMMAND";
149 /* 0123456 -- field to fill in starts at header+6 */
150 #define UNAME_START 6
152 #define Proc_format \
153 "%5d %-8.8s %3d %4d %5s %5dK %-5s %6s %.28s"
155 static int kmem, mem;
157 static double logcpu;
159 /* these are retrieved from the kernel in _init */
160 static int Hz;
161 static struct var v;
162 static ulong proca;
163 static load_avg cur_cpu;
165 /* these are for detailing the process states */
166 int process_states[8];
167 char *procstatenames[] = {
168 "", " sleeping, ", " running, ", " zombie, ", " stopped, ",
169 " created, ", " onproc, ", " xswapped, ",
170 NULL
173 /* process state names for the "STATE" column of the display */
174 char *state_abbrev[] = {
175 "", "sleep", "run", "zomb", "stop", "create", "onpr", "swap"
178 /* these are for calculating cpu state percentages */
179 #define CPUSTATES 5 /* definition from struct sysinfo */
180 static time_t cp_time[CPUSTATES];
181 static time_t cp_old[CPUSTATES];
182 static time_t cp_diff[CPUSTATES];
184 /* these are for detailing the cpu states */
185 int cpu_states[CPUSTATES];
186 char *cpustatenames[] = {
187 "idle", "user", "system", "wait", "sxbrk",
188 NULL
191 /* these are for detailing the memory statistics */
192 unsigned long memory_stats[6];
193 char *memorynames[] = {
194 "K phys, ", "K max, ", "K free, ", "K lck, ", "K unlck, ",
195 "K swap,", NULL
198 /* these are for keeping track of the proc array */
199 static int bytes;
200 static int pref_len;
201 static struct proc *pbase;
202 static struct proc **pref;
204 /* forward definitions for comparison functions */
205 int proc_compare();
206 int compare_cpu();
207 int compare_size();
208 int compare_time();
210 int (*proc_compares[])() = {
211 proc_compare, /* state, pri, time, size */
212 compare_cpu, /* cpu, time, state, pri, size */
213 compare_size, /* size, cpu, time, state pri */
214 compare_time, /* time, cpu, state, pri, size */
215 /* compare_res, /* res, cpu, time, state pri */
216 NULL };
218 /* these are names given to allowed sorting orders -- first is default */
219 char *ordernames[]={"state", "cpu", "size", "time", NULL}; /*hops*/
221 /* useful externals */
222 extern int errno;
223 extern char *sys_errlist[];
225 long time();
226 long percentages();
229 machine_init(struct statics *statics)
232 ulong ptr;
234 if ((kmem = open(KMEM, O_RDONLY)) == -1) {
235 perror(KMEM);
236 return -1;
238 if ((mem = open(MEM, O_RDONLY)) == -1) {
239 perror(MEM);
240 return -1;
243 /* get the list of symbols we want to access in the kernel */
244 if (nlist(VMUNIX, nlst) == -1) {
245 fprintf(stderr, "top: nlist failed\n");
246 return -1;
248 /* make sure they were all found */
249 /*ZZ
250 if (check_nlist(nlst) > 0)
251 return -1;
254 proca = nlst[X_PROC].n_value;
256 /* get the symbol values out of kmem */
257 (void) getkval(nlst[X_CUR_CPU].n_value, (int *)(&cur_cpu), sizeof(cur_cpu),
258 nlst[X_CUR_CPU].n_name);
259 (void) getkval(nlst[X_HZ].n_value, (int *)(&Hz), sizeof(Hz),
260 nlst[X_HZ].n_name);
261 (void) getkval(nlst[X_V].n_value, (int *)(&v), sizeof(v),
262 nlst[X_V].n_name);
264 /* this is used in calculating WCPU -- calculate it ahead of time */
265 logcpu = log(fabs(loaddouble(cur_cpu)));
267 /* allocate space for proc structure array and array of pointers */
268 bytes = v.v_proc * sizeof(struct proc);
269 pbase = (struct proc *)malloc(bytes);
270 pref = (struct proc **)malloc(v.v_proc * sizeof(struct proc *));
271 if (pbase == (struct proc *)NULL || pref == (struct proc **)NULL) {
272 fprintf(stderr, "top: cannot allocate sufficient memory\n");
273 return -1;
276 /* fill in the statics information */
277 statics->procstate_names = procstatenames;
278 statics->cpustate_names = cpustatenames;
279 statics->memory_names = memorynames;
280 statics->order_names = ordernames ; /* hops */
282 return 0;
285 char *
286 format_header(register char *uname_field)
289 register char *ptr;
291 ptr = header + UNAME_START;
292 while (*uname_field != '\0')
294 *ptr++ = *uname_field++;
297 return(header);
301 /* philiph - get run ave fm /dev/table info */
302 static int
303 tab_avenrun(double runave[])
305 FILE *fp = fopen("/dev/table/avenrun", "r");
306 int i;
308 for (i=0; i<3; i++)
309 runave[i] = -1.0;
311 if (fp==NULL)
312 return -1;
313 else
315 short rawave[3];
317 if (fread(rawave, sizeof(short), 3, fp) !=3 )
319 fclose(fp);
320 return -1;
322 else
324 int i;
326 for (i=0; i<3; i++)
327 runave[i] = (double) (rawave[i] / 256.0);
329 fclose(fp);
330 return 0;
335 struct pregion *
336 get_pregion(void *ptr)
338 static struct pregion preg;
339 long addr = (long)ptr;
341 (void) getkval(addr , (struct pregion *)(&preg),
342 sizeof(struct pregion), "pregion" );
343 return &preg;
346 struct region *
347 get_region(void *ptr)
349 static struct region reg;
350 long addr = (long)ptr;
352 (void) getkval( addr , (struct region *)(&reg),
353 sizeof(struct region), "region" );
354 return &reg;
357 static unsigned char shareable[RT_VM86 + 1]; /* 1 if shareable */
360 * sum private referenced pages,
361 * treat shared pages depending on value of TREAT_SHARABLE_PAGES macro
362 * undefined : ignore (don't account for - default)
363 * 1: divide among # of references
364 * 2: accumulate as if private
366 /* #define TREAT_SHAREABLE_PAGES 1 */
367 static long
368 proc_residentsize(struct proc *pp)
370 struct pregion *prp;
371 struct region *rp;
372 long rtot = 0;
373 long stot = 0;
374 long s1tot = 0;
376 /* init shareable region array */
377 if (shareable[RT_STEXT] == 0 )
378 shareable[RT_STEXT] = shareable[RT_SHMEM] = shareable[RT_MAPFILE] = 1
381 prp = pp->p_region;
383 if ( prp == 0)
384 return 0;
386 for( ; prp && (prp = get_pregion((void *)(prp))) &&
387 prp->p_reg && (rp = get_region((void*)(prp->p_reg)));
388 prp = prp->p_next)
390 if (shareable[rp->r_type] ) /* account for shared pgs separately
393 stot += (rp->r_nvalid / rp->r_refcnt);
394 s1tot += rp->r_nvalid;
396 else
397 rtot += rp->r_nvalid;
400 #if defined(TREAT_SHAREABLE_PAGES) && TREAT_SHAREABLE_PAGES == 1
401 rtot += stot; /* accumulate and spread over users */
402 #endif
404 #if defined(TREAT_SHAREABLE_PAGES) && TREAT_SHAREABLE_PAGES == 1
405 rtot += s1tot; /* accumulate as if private */
406 #endif
408 return rtot * NBPP/1024; ;
411 void
412 get_system_info(struct system_info *si)
415 long total;
417 /* get process id of the last process */
418 (void) getkval(nlst[X_MPID].n_value, &(si->last_pid),
419 sizeof(si->last_pid),
420 nlst[X_MPID].n_name);
421 /* get the cp_time array */
422 (void) getkval(nlst[X_SYSINFO].n_value, (int *)cp_time, sizeof(cp_time),
423 nlst[X_SYSINFO].n_name);
425 /* convert cp_time counts to persentages */
426 total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff);
428 /* sum memory statistics */
429 (void) getkval(nlst[X_PHYSMEM].n_value, &memory_stats[0],
430 sizeof(memory_stats[0]), nlst[X_PHYSMEM].n_name);
431 (void) getkval(nlst[X_MAXMEM].n_value, &memory_stats[1],
432 sizeof(memory_stats[1]), nlst[X_MAXMEM].n_name);
433 (void) getkval(nlst[X_FREEMEM].n_value, &memory_stats[2],
434 sizeof(memory_stats[2]), nlst[X_FREEMEM].n_name);
435 (void) getkval(nlst[X_AVAILRMEM].n_value, &memory_stats[3],
436 sizeof(memory_stats[3]), nlst[X_AVAILRMEM].n_name);
437 (void) getkval(nlst[X_AVAILSMEM].n_value, &memory_stats[4],
438 sizeof(memory_stats[4]), nlst[X_AVAILSMEM].n_name);
439 (void) getkval(nlst[X_NSWAP].n_value, &memory_stats[5],
440 sizeof(memory_stats[5]), nlst[X_NSWAP].n_name);
441 memory_stats[0] = bytetok(ctob(memory_stats[0])); /* clicks -> bytes
443 memory_stats[1] = bytetok(ctob(memory_stats[1])); /* clicks -> bytes
445 memory_stats[2] = bytetok(ctob(memory_stats[2])); /* clicks -> bytes
447 memory_stats[3] = bytetok(memory_stats[3] * NBPP); /* # bytes per page
449 memory_stats[4] = bytetok(memory_stats[4] * NBPP); /* # bytes per page
451 memory_stats[5] = bytetok(memory_stats[5] * NBPSCTR);/* # bytes per sector
454 /* set arrays and strings */
455 /* Note: we keep memory_stats as an unsigned long to avoid sign
456 extension problems when shifting in bytetok. But the module
457 interface requires an array of signed longs. So we just cast
458 the pointer here and hope for the best. --wnl
460 si->cpustates = cpu_states;
461 si->memory = (long *)memory_stats;
463 tab_avenrun(si->load_avg); /* philiph */
466 static struct handle handle;
468 caddr_t
469 get_process_info(struct system_info *si,
470 struct process_select *sel,
471 int idx)
474 register int i;
475 register int total_procs;
476 register int active_procs;
477 register struct proc **prefp;
478 register struct proc *pp;
480 /* set up flags of what we are going to select */
481 /* these are copied out of sel for simplicity */
482 int show_idle = sel->idle;
483 int show_system = sel->system;
484 int show_uid = sel->uid != -1;
485 int show_command = sel->command != NULL;
487 /* read all the proc structures in one fell swoop */
488 (void) getkval(proca, (int *)pbase, bytes, "proc array");
490 /* get a pointer to the states summary array */
491 si->procstates = process_states;
493 /* count up process states and get pointers to interesting procs */
494 total_procs = active_procs = 0;
495 memset((char *)process_states, 0, sizeof(process_states));
496 prefp = pref;
497 for (pp = pbase, i = 0; i < v.v_proc; pp++, i++) {
499 * Place pointers to each valid proc structure in pref[].
500 * Process slots that are actually in use have a non-zero
501 * status field. Processes with SSYS set are system processes --
502 * these are ignored unless show_system is set.
504 if (pp->p_stat && (show_system || ((pp->p_flag & SSYS) == 0))) {
505 total_procs++;
506 process_states[pp->p_stat]++;
507 if ((pp->p_stat != SZOMB) &&
508 (show_idle || (pp->p_stat == SRUN) || (pp->p_stat == SONPROC)) &&
509 (!show_uid || pp->p_uid == (ushort)sel->uid)) {
510 *prefp++ = pp;
511 active_procs++;
516 /* if requested, sort the "interesting" processes */
517 qsort((char *)pref, active_procs, sizeof(struct proc *), proc_compares[idx]);
519 /* remember active and total counts */
520 SI_TOTAL(si) = total_procs;
521 SI_ACTIVE(si) = pref_len = active_procs;
523 /* pass back a handle */
524 handle.next_proc = pref;
525 handle.remaining = active_procs;
526 return((caddr_t)&handle);
529 char fmt[128]; /* static area where result is built */
531 char *
532 format_next_process(caddr_t handle, char *(*get_userid)())
535 register struct proc *pp;
536 register time_t cputime;
537 register double pct;
538 int where;
539 struct user u;
540 struct handle *hp;
541 char command[29];
542 char * process;
543 char * process2;
545 /* find and remember the next proc structure */
546 hp = (struct handle *)handle;
547 pp = *(hp->next_proc++);
548 hp->remaining--;
550 /* get the process's user struct and set cputime */
551 if ((where = sysi86(RDUBLK, pp->p_pid, &u, sizeof(struct user))) != -1)
552 where = (pp->p_flag & SLOAD) ? 0 : 1;
553 if (where == -1) {
554 strcpy(command, "<swapped>");
555 cputime = 0;
556 } else {
557 /* set u_comm for system processes */
558 if (u.u_comm[0] == '\0') {
559 if (pp->p_pid == 0)
560 strcpy(command, "Swapper");
561 else if (pp->p_pid == 2)
562 strcpy(command, "Pager");
563 else if (pp->p_pid == 3)
564 strcpy(command, "Sync'er");
565 } else if (where == 1) {
566 /* print swapped processes as <pname> */
567 register char *s1;
569 u.u_psargs[28 - 3] = '\0';
570 strcpy(command, "<");
571 strcat(command, strtok(u.u_psargs, " "));
572 strcat(command, ">");
573 while (s1 = (char *)strtok(NULL, " "))
574 strcat(command, s1);
575 } else {
576 sprintf(command, "%s", u.u_psargs);
578 cputime = u.u_utime + u.u_stime;
579 /* cputime = pp->p_utime + pp->p_stime; */
581 /* calculate the base for cpu percentages */
582 pct = pctdouble(pp->p_cpu);
585 * psargs gives the absolute path of the process... strip it to only the
586 * command - [Changes by D. Currie & M. Muldner Aitt NS Canada]
588 process = printable(command);
589 #if NO_COMMAND_ARGS
590 strtok(process," ");
591 #endif
592 process2 = strrchr(process,'/');
593 if(process2)
595 process = process2;
596 process++;
600 /* format this entry */
601 sprintf(fmt,
602 Proc_format,
603 pp->p_pid,
604 (*get_userid)(pp->p_uid),
605 pp->p_pri - PZERO,
606 pp->p_nice - NZERO,
607 format_k(PROCSIZE(&u)), /* same as pp->p_size * 4 */
608 proc_residentsize(pp),
609 state_abbrev[pp->p_stat],
610 format_time(cputime / Hz),
611 printable(process) );
613 return(fmt);
617 * Checks the nlist to see if any symbols were not found.
618 * For every symbol that was not found, a one-line message
619 * is printed to stderr. The routine returns the number of
620 * symbols NOT founded.
623 int check_nlist(register struct nlist *nlst)
626 register int i = 0;
628 while (nlst->n_name) {
629 if (nlst->n_type == 0) {
630 fprintf(stderr, "kernel: no symbol named `%s'\n", nlst->n_name);
631 i++;
633 nlst++;
635 return i;
639 * getkval(offset, ptr, size, refstr) - get a value out of the kernel.
640 * "offset" is the byte offset into the kernel for the desired value,
641 * "ptr" points to a buffer into which the value is retrieved,
642 * "size" is the size of the buffer (and the object to retrieve),
643 * "refstr" is a reference string used when printing error meessages,
644 * if "refstr" starts with a '!', then a failure on read will not
645 * be fatal (this may seem like a silly way to do things, but I
646 * really didn't want the overhead of another argument).
651 getkval(unsigned long offset, int *ptr, int size, char *refstr)
654 if (lseek(kmem, (long)offset, SEEK_SET) == -1) {
655 if (*refstr == '!')
656 refstr++;
657 fprintf(stderr, "%s: lseek to %s: %s\n", KMEM,
658 refstr, errmsg(errno));
659 quit(23);
661 if (read(kmem, (char *)ptr, size) == -1) {
662 if (*refstr == '!')
663 return 0;
664 fprintf(stderr, "%s: reading %s: %s\n", KMEM,
665 refstr, errmsg(errno));
666 quit(23);
668 return(1);
671 /* comparison routine for qsort */
672 /* NOTE: this is specific to the BSD proc structure, but it should
673 give you a good place to start. */
676 * proc_compare - comparison function for "qsort"
677 * Compares the resource consumption of two processes using five
678 * distinct keys. The keys (in descending order of importance) are:
679 * percent cpu, cpu ticks, state, resident set size, total virtual
680 * memory usage. The process states are ordered as follows (from least
681 * to most important): WAIT, zombie, sleep, stop, start, run. The
682 * array declaration below maps a process state index into a number
683 * that reflects this ordering.
686 static unsigned char sorted_state[] =
688 0, /* not used */
689 5, /* sleep */
690 6, /* run */
691 2, /* zombie */
692 4, /* stop */
693 1, /* start */
694 7, /* onpr */
695 3, /* swap */
699 proc_compare(struct proc **pp1, struct proc **pp2)
702 register struct proc *p1;
703 register struct proc *p2;
704 register int result;
705 register ulong lresult;
707 /* remove one level of indirection */
708 p1 = *pp1;
709 p2 = *pp2;
711 /* use process state to break the tie */
712 if ((result = sorted_state[p2->p_stat] -
713 sorted_state[p1->p_stat]) == 0)
715 /* use priority to break the tie */
716 if ((result = p2->p_pri - p1->p_pri) == 0)
718 /* use time to break the tie */
719 if ((result = (p2->p_utime + p2->p_stime) -
720 (p1->p_utime + p1->p_stime)) == 0)
722 /* use resident set size (rssize) to break the tie */
723 if ((result = p2->p_size - p1->p_size) == 0)
725 result = 0;
731 return(result);
734 /* returns uid of owner of process pid */
736 proc_owner(int pid)
739 register int cnt;
740 register struct proc **prefp;
741 register struct proc *pp;
743 prefp = pref;
744 cnt = pref_len;
745 while (--cnt >= 0) {
746 if ((pp = *prefp++)->p_pid == (short)pid)
747 return ((int)pp->p_uid);
749 return(-1);
752 #if 0
753 int setpriority(int dummy, int who, int nicewal)
755 errno = 1;
756 return -1;
758 #endif
760 /* sigblock is not POSIX conformant */
761 sigset_t sigblock (sigset_t mask)
763 sigset_t oset;
765 sigemptyset(&oset);
766 sigprocmask(SIG_BLOCK, &mask, &oset);
767 return oset;
770 /* sigsetmask is not POSIX conformant */
771 sigsetmask(sigset_t mask)
773 sigset_t oset;
775 sigemptyset(&oset);
776 sigprocmask(SIG_SETMASK, &mask, &oset);
777 return oset;
781 /* ---------------- hops - comparison/ordering support ---------------- */
783 #define ORDERKEY_PCTCPU if (dresult = pctdouble(p2->p_cpu) - pctdouble(p1->p_cpu),\
784 (result = dresult > 0.0 ? 1 : dresult < 0.0 ? -1 : 0) == 0)
785 #define ORDERKEY_MEMSIZE if ((result = (p2->p_size - p1->p_size)) == 0)
786 #define ORDERKEY_CPTIME if ((result = (long)(p2->p_utime + p2->p_stime) -\
787 (long)(p1->p_utime + p1->p_stime)) == 0)
789 #define ORDERKEY_STATE if ((result = (sorted_state[p2->p_stat] - \
790 sorted_state[p1->p_stat])) == 0)
791 #define ORDERKEY_PRIO if ((result = p2->p_pri - p1->p_pri) == 0)
795 compare_cpu ( struct proc **pp1, struct proc **pp2)
797 register struct proc *p1;
798 register struct proc *p2;
799 register int result;
800 double dresult;
802 /* remove one level of indirection */
803 p1 = *pp1;
804 p2 = *pp2;
806 ORDERKEY_PCTCPU
807 ORDERKEY_CPTIME
808 ORDERKEY_STATE
809 ORDERKEY_PRIO
810 ORDERKEY_MEMSIZE
813 return (result);
818 /* compare_size - the comparison function for sorting by process size */
820 compare_size ( struct proc **pp1, struct proc **pp2)
822 register struct proc *p1;
823 register struct proc *p2;
824 register int result;
825 double dresult;
827 /* remove one level of indirection */
828 p1 = *pp1;
829 p2 = *pp2;
832 ORDERKEY_MEMSIZE
833 ORDERKEY_PCTCPU
834 ORDERKEY_CPTIME
835 ORDERKEY_STATE
836 ORDERKEY_PRIO
839 return (result);
842 /* compare_res - the comparison function for sorting by resident set size */
843 /* TODO: add shadow proc struct updating usr + sys times and RSS for use
844 * in comparison rtns, implement compare_res rtn as per compare_size()
847 /* compare_time - the comparison function for sorting by total cpu time */
848 /* This is giving wrong results since its using the proc structure vals not
849 * the u struct vals we display above
850 * TODO: add shadow proc struct updating usr + sys times and RSS for use
851 * in comparison rtns
854 compare_time ( struct proc **pp1, struct proc **pp2)
856 register struct proc *p1;
857 register struct proc *p2;
858 register int result;
859 double dresult;
861 /* remove one level of indirection */
862 p1 = *pp1;
863 p2 = *pp2;
865 ORDERKEY_CPTIME
866 ORDERKEY_PCTCPU
867 ORDERKEY_STATE
868 ORDERKEY_PRIO
869 ORDERKEY_MEMSIZE
872 return (result);