diff options
author | agc <agc@pkgsrc.org> | 1997-10-03 11:45:34 +0000 |
---|---|---|
committer | agc <agc@pkgsrc.org> | 1997-10-03 11:45:34 +0000 |
commit | cb6d273fca8b0315b66fdcd48d1c45cb061b7126 (patch) | |
tree | 158fe517dcca252d5135fc346e826b8d9facb520 /sysutils/top | |
parent | c3113873abe0725ec75ceb628c97de993b24da6f (diff) | |
download | pkgsrc-cb6d273fca8b0315b66fdcd48d1c45cb061b7126.tar.gz |
Luke Mewburn's NetBSD 1.2G module for top. As posted to current-users:
> Message-ID: <199706170751.RAA00046@shara.off.connect.com.au>
> From: Luke Mewburn <lukem@connect.com.au>
> Date: Tue, 17 Jun 1997 17:51:49 +1000
Subsequent patch by Christos Zoulas, also posted to current-users:
> Message-Id: <199706172224.SAA00740@ramoth.nyc.deshaw.com>
> From: christos@deshaw.com (Christos Zoulas)
> Date: Tue, 17 Jun 1997 18:24:22 -0400
Diffstat (limited to 'sysutils/top')
-rw-r--r-- | sysutils/top/patches/patch-aa | 1876 | ||||
-rw-r--r-- | sysutils/top/patches/patch-ab | 129 |
2 files changed, 2005 insertions, 0 deletions
diff --git a/sysutils/top/patches/patch-aa b/sysutils/top/patches/patch-aa new file mode 100644 index 00000000000..9b903b87c40 --- /dev/null +++ b/sysutils/top/patches/patch-aa @@ -0,0 +1,1876 @@ +Return-Path: <current-users-owner-agc=amdahl.com@NetBSD.ORG> +Received: by juno.ccc.amdahl.com (/\==/\ Smail #25.1) + id <m0we38A-0000SaC@juno.ccc.amdahl.com>; Tue, 17 Jun 97 11:37 PDT +Received: from vega.oes.amdahl.com by orpheus.amdahl.com with smtp + (Smail3.1.29.1 #3) id m0we38J-0004u0C; Tue, 17 Jun 97 11:37 PDT +Received: from minerva.amdahl.com by vega.oes.amdahl.com with SMTP + (OES Smail-3.1.29.1) id m0we38I-000B1FC; Tue, 17 Jun 97 11:37 PDT +Received: from orpheus.amdahl.com by minerva.amdahl.com with smtp + (Smail3.1.29.1 #5) id m0we38H-0002AQC; Tue, 17 Jun 97 11:37 PDT +Received: from mail.NetBSD.ORG by orpheus.amdahl.com with smtp + (Smail3.1.29.1 #3) id m0we38F-0004tyC; Tue, 17 Jun 97 11:37 PDT +Received: (qmail 27809 invoked by uid 605); 17 Jun 1997 18:25:18 -0000 +Received: (qmail 27786 invoked by uid 1032); 17 Jun 1997 18:25:13 -0000 +Received: (qmail 28031 invoked from network); 17 Jun 1997 07:53:22 -0000 +Received: from shara.off.connect.com.au (192.94.41.9) + by homeworld.cygnus.com with SMTP; 17 Jun 1997 07:53:22 -0000 +Received: from connect.com.au (lukem@localhost) by shara.off.connect.com.au with ESMTP id RAA00046 + (8.8.5/IDA-1.6 for <current-users@netbsd.org>); Tue, 17 Jun 1997 17:51:49 +1000 (EST) +Message-ID: <199706170751.RAA00046@shara.off.connect.com.au> +From: Luke Mewburn <lukem@connect.com.au> +Reply-to: lukem@connect.com.au +To: current-users@netbsd.org +Subject: top 3.5b5 patches for -current and not so -current +Date: Tue, 17 Jun 1997 17:51:49 +1000 +Sender: current-users-owner@NetBSD.ORG +Precedence: list +Delivered-To: current-users@NetBSD.ORG + + +Here's a patch to top3.5-beta5 that does the following: + * fixes up a minor bug in the configure script. + * adds process ordering (sorting on cpu, pri, res, size, + state, or time) + * removes attempted support for LASTPID - it didn't work, + and in any case, it's a security issue. + * adds a new module for netbsd 1.3 (and netbsd1.2G) - + m_netbsd13.c, which supports the new swap code. + +You can get the source from: + ftp://ftp.groupsys.com/pub/top/top-3.5beta5.tar.gz + +[agc - I've modified the filenames below so that the patches +work within the packages system] + +Here's the diff: + +*** Configure Sat Dec 21 02:52:30 1996 +--- Configure Tue Apr 22 19:19:34 1997 +*************** +*** 346,352 **** + + EOF + set t_mode = 4711 +- set mode = 4711 + else if (-e /dev/kmem) then + $ls /dev/kmem >/tmp/$$.b + grep '^....r..r..' /tmp/$$.b >&/dev/null +--- 346,351 ---- +*** commands.c Wed Aug 28 00:13:57 1996 +--- commands.c Tue Apr 22 19:19:34 1997 +*************** +*** 23,30 **** +--- 23,33 ---- + #include <sys/time.h> + #include <sys/resource.h> + ++ #include "top.h" ++ #include "top.local.h" + #include "sigdesc.h" /* generated automatically */ + #include "boolean.h" ++ #include "machine.h" + #include "utils.h" + + extern int errno; +*************** +*** 42,49 **** + * either 'h' or '?'. + */ + +! show_help() +! + { + printf("Top version %s, %s\n", version_string(), copyright); + fputs("\n\n\ +--- 45,52 ---- + * either 'h' or '?'. + */ + +! show_help(statics) +! struct statics *statics; + { + printf("Top version %s, %s\n", version_string(), copyright); + fputs("\n\n\ +*************** +*** 72,79 **** + k - kill processes; send a signal to a list of processes\n\ + n or # - change number of processes to display\n", stdout); + #ifdef ORDER +! fputs("\ +! o - specify sort order (size, res, cpu, time)\n", stdout); + #endif + fputs("\ + r - renice a process\n\ +--- 75,89 ---- + k - kill processes; send a signal to a list of processes\n\ + n or # - change number of processes to display\n", stdout); + #ifdef ORDER +! { +! int i; +! +! fputs("\ +! o - specify sort order (", stdout); +! for (i = 0; statics->order_names[i] != NULL; i++) +! printf("%s%s", i == 0 ? "" : ", ", statics->order_names[i]); +! puts(")"); +! } + #endif + fputs("\ + r - renice a process\n\ +*** machine/m_netbsd10.c Fri Jan 26 16:27:18 1996 +--- machine/m_netbsd10.c Tue Jun 17 16:57:08 1997 +*************** +*** 1,49 **** + /* + * top - a top users display for Unix + * +! * SYNOPSIS: For a NetBSD-1.0 (4.4BSD) system + * Note process resident sizes could be wrong, but ps shows + * zero for them too.. + * + * DESCRIPTION: + * Originally written for BSD4.4 system by Christos Zoulas. +! * Based on the FreeBSD 2.0 version by Steven Wallace && Wolfram Schneider +! * NetBSD-1.0 port by Arne Helme +! * . +! * This is the machine-dependent module for NetBSD-1.0 + * Works for: + * NetBSD-1.0 + * + * LIBS: -lkvm + * +! * CFLAGS: -DHAVE_GETOPT + * +- * AUTHOR: Christos Zoulas <christos@ee.cornell.edu> +- * Steven Wallace <swallace@freebsd.org> +- * Wolfram Schneider <wosch@cs.tu-berlin.de> +- * Arne Helme <arne@acm.org> + * + * $Id: patch-aa,v 1.1 1997/10/03 11:45:34 agc Exp $ + */ + + +! +! #define LASTPID /**/ /* use last pid, compiler depended */ +! /* #define LASTPID_FIXED /**/ + #define VM_REAL /**/ /* use the same values as vmstat -s */ + #define USE_SWAP /**/ /* use swap usage (pstat -s), + need to much cpu time */ +- /* #define DEBUG 1 /**/ + + #include <sys/types.h> + #include <sys/signal.h> + #include <sys/param.h> +- +- #include "os.h" +- #include <stdio.h> +- #include <nlist.h> +- #include <math.h> +- #include <kvm.h> + #include <sys/errno.h> + #include <sys/sysctl.h> + #include <sys/dir.h> +--- 1,46 ---- + /* + * top - a top users display for Unix + * +! * SYNOPSIS: For a NetBSD-1.0 through NetBSD-1.2.1 system + * Note process resident sizes could be wrong, but ps shows + * zero for them too.. + * + * DESCRIPTION: + * Originally written for BSD4.4 system by Christos Zoulas. +! * Based on the FreeBSD 2.0 version by Steven Wallace and Wolfram Schneider. +! * NetBSD-1.0 port by Arne Helme. Process ordering added by Luke Mewburn. +! * +! * This is the machine-dependent module for NetBSD-1.0 and later + * Works for: + * NetBSD-1.0 ++ * NetBSD-1.1 ++ * NetBSD-1.2 ++ * NetBSD-1.2.1 + * + * LIBS: -lkvm + * +! * CFLAGS: -DHAVE_GETOPT -DORDER +! * +! * AUTHORS: Christos Zoulas <christos@ee.cornell.edu> +! * Steven Wallace <swallace@freebsd.org> +! * Wolfram Schneider <wosch@cs.tu-berlin.de> +! * Arne Helme <arne@acm.org> +! * Luke Mewburn <lukem@netbsd.org> + * + * + * $Id: patch-aa,v 1.1 1997/10/03 11:45:34 agc Exp $ + */ + + +! /* #define LASTPID */ /* use last pid, compiler depended */ +! /* #define LASTPID_FIXED */ + #define VM_REAL /**/ /* use the same values as vmstat -s */ + #define USE_SWAP /**/ /* use swap usage (pstat -s), + need to much cpu time */ + + #include <sys/types.h> + #include <sys/signal.h> + #include <sys/param.h> + #include <sys/errno.h> + #include <sys/sysctl.h> + #include <sys/dir.h> +*************** +*** 51,56 **** +--- 48,61 ---- + #include <sys/file.h> + #include <sys/time.h> + ++ #include "os.h" ++ #include <err.h> ++ #include <kvm.h> ++ #include <math.h> ++ #include <nlist.h> ++ #include <stdio.h> ++ #include <unistd.h> ++ + #ifdef USE_SWAP + #include <stdlib.h> + #include <sys/map.h> +*************** +*** 85,91 **** + ((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu)))) + + /* what we consider to be process size: */ +! #define PROCSIZE(pp) (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) + + /* definitions for indices in the nlist array */ + +--- 90,97 ---- + ((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu)))) + + /* what we consider to be process size: */ +! #define PROCSIZE(pp) \ +! (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) + + /* definitions for indices in the nlist array */ + +*************** +*** 169,175 **** + + char *state_abbrev[] = + { +! "", "start", "run\0\0\0", "sleep", "stop", "zomb", "WAIT" + }; + + +--- 175,181 ---- + + char *state_abbrev[] = + { +! "", "start", "run\0\0\0", "sleep", "stop", "zomb" + }; + + +*************** +*** 194,200 **** + #endif + #ifdef VM_REAL + static unsigned long cnt_offset; +- static long cnt; + #endif + /* these are for calculating cpu state percentages */ + +--- 200,205 ---- +*************** +*** 237,242 **** +--- 242,278 ---- + #endif + }; + ++ ++ /* these are names given to allowed sorting orders -- first is default */ ++ char *ordernames[] = { ++ "cpu", ++ "pri", ++ "res", ++ "size", ++ "state", ++ "time", ++ NULL ++ }; ++ ++ /* forward definitions for comparison functions */ ++ int compare_cpu(); ++ int compare_prio(); ++ int compare_res(); ++ int compare_size(); ++ int compare_state(); ++ int compare_time(); ++ ++ int (*proc_compares[])() = { ++ compare_cpu, ++ compare_prio, ++ compare_res, ++ compare_size, ++ compare_state, ++ compare_time, ++ NULL ++ }; ++ ++ + /* these are for keeping track of the proc array */ + + static int nproc; +*************** +*** 258,269 **** + + int + machine_init(statics) +! +! struct statics *statics; +! + { +! register int i = 0; +! register int pagesize; + + if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) + return -1; +--- 294,303 ---- + + int + machine_init(statics) +! struct statics *statics; + { +! int i = 0; +! int pagesize; + + if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) + return -1; +*************** +*** 291,300 **** + } + + +- #if (defined DEBUG) +- fprintf(stderr, "Hertz: %d\n", hz); +- #endif +- + (void) getkval(nlst[X_CCPU].n_value, (int *)(&ccpu), sizeof(ccpu), + nlst[X_CCPU].n_name); + +--- 325,330 ---- +*************** +*** 331,347 **** + statics->procstate_names = procstatenames; + statics->cpustate_names = cpustatenames; + statics->memory_names = memorynames; + + /* all done! */ + return(0); + } + +! char *format_header(uname_field) +! +! register char *uname_field; +! + { +! register char *ptr; + + ptr = header + UNAME_START; + while (*uname_field != '\0') +--- 361,377 ---- + statics->procstate_names = procstatenames; + statics->cpustate_names = cpustatenames; + statics->memory_names = memorynames; ++ statics->order_names = ordernames; + + /* all done! */ + return(0); + } + +! char * +! format_header(uname_field) +! char *uname_field; + { +! char *ptr; + + ptr = header + UNAME_START; + while (*uname_field != '\0') +*************** +*** 358,402 **** + + void + get_system_info(si) +! +! struct system_info *si; +! + { + long total; +- load_avg avenrun[3]; + + /* get the cp_time array */ + (void) getkval(cp_time_offset, (int *)cp_time, sizeof(cp_time), + nlst[X_CP_TIME].n_name); +- (void) getkval(avenrun_offset, (int *)avenrun, sizeof(avenrun), +- nlst[X_AVENRUN].n_name); + + #ifdef LASTPID +! (void) getkval(lastpid_offset, (int *)(&lastpid), sizeof(lastpid), +! "!"); + #endif + +! /* convert load averages to doubles */ +! { +! register int i; +! register double *infoloadp; +! load_avg *avenrunp; +! +! #ifdef notyet +! struct loadavg sysload; +! int size; +! getkerninfo(KINFO_LOADAVG, &sysload, &size, 0); +! #endif + +! infoloadp = si->load_avg; +! avenrunp = avenrun; +! for (i = 0; i < 3; i++) +! { +! #ifdef notyet +! *infoloadp++ = ((double) sysload.ldavg[i]) / sysload.fscale; +! #endif +! *infoloadp++ = loaddouble(*avenrunp++); +! } + } + + /* convert cp_time counts to percentages */ +--- 388,411 ---- + + void + get_system_info(si) +! struct system_info *si; + { + long total; + + /* get the cp_time array */ + (void) getkval(cp_time_offset, (int *)cp_time, sizeof(cp_time), + nlst[X_CP_TIME].n_name); + + #ifdef LASTPID +! (void) getkval(lastpid_offset, (int *)(&lastpid), sizeof(lastpid), "!"); + #endif + +! if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) { +! int i; + +! warn("can't getloadavg"); +! for (i = 0; i < NUM_AVERAGES; i++) +! si->load_avg[i] = 0.0; + } + + /* convert cp_time counts to percentages */ +*************** +*** 424,431 **** + memory_stats[5] = pagetok(total.t_vm); + memory_stats[6] = -1; + memory_stats[7] = pagetok(total.t_free); +! } +! #else + struct vmmeter sum; + static unsigned int swap_delay = 0; + +--- 433,440 ---- + memory_stats[5] = pagetok(total.t_vm); + memory_stats[6] = -1; + memory_stats[7] = pagetok(total.t_free); +! +! #else /* !VM_REAL */ + struct vmmeter sum; + static unsigned int swap_delay = 0; + +*************** +*** 453,466 **** + memory_stats[4] = swapmode(); + } + /* swap_delay++; XXX Arne */ +! #else + memory_stats[4] = 0; +! #endif + + + memory_stats[7] = -1; + } +! #endif + /* set arrays and strings */ + si->cpustates = cpu_states; + si->memory = memory_stats; +--- 462,476 ---- + memory_stats[4] = swapmode(); + } + /* swap_delay++; XXX Arne */ +! #else /* !USE_SWAP */ + memory_stats[4] = 0; +! #endif /* !USE_SWAP */ + + + memory_stats[7] = -1; ++ #endif /* !VM_REAL */ + } +! + /* set arrays and strings */ + si->cpustates = cpu_states; + si->memory = memory_stats; +*************** +*** 473,495 **** + #else + si->last_pid = -1; + #endif +- + } + + 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 kinfo_proc **prefp; +! register struct kinfo_proc *pp; + + /* these are copied out of sel for speed */ + int show_idle; +--- 483,503 ---- + #else + si->last_pid = -1; + #endif + } + + static struct handle handle; + +! caddr_t +! get_process_info(si, sel, compare) +! struct system_info *si; +! struct process_select *sel; +! int (*compare)(); + { +! int i; +! int total_procs; +! int active_procs; +! struct kinfo_proc **prefp; +! struct kinfo_proc *pp; + + /* these are copied out of sel for speed */ + int show_idle; +*************** +*** 562,576 **** + + char fmt[128]; /* static area where result is built */ + +! char *format_next_process(handle, get_userid) +! +! caddr_t handle; +! char *(*get_userid)(); +! + { +! register struct kinfo_proc *pp; +! register long cputime; +! register double pct; + struct handle *hp; + + /* find and remember the next proc structure */ +--- 570,583 ---- + + char fmt[128]; /* static area where result is built */ + +! char * +! format_next_process(handle, get_userid) +! caddr_t handle; +! char *(*get_userid)(); + { +! struct kinfo_proc *pp; +! long cputime; +! double pct; + struct handle *hp; + + /* find and remember the next proc structure */ +*************** +*** 631,642 **** + * number of symbols NOT found. + */ + +! static 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 */ +--- 638,648 ---- + * number of symbols NOT found. + */ + +! static int +! check_nlist(nlst) +! struct nlist *nlst; + { +! 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 */ +*************** +*** 670,682 **** + * + */ + +! static int getkval(offset, ptr, size, refstr) +! +! unsigned long offset; +! int *ptr; +! int size; +! char *refstr; +! + { + if (kvm_read(kd, offset, (char *) ptr, size) != size) + { +--- 676,687 ---- + * + */ + +! static int +! getkval(offset, ptr, size, refstr) +! unsigned long offset; +! int *ptr; +! int size; +! char *refstr; + { + if (kvm_read(kd, offset, (char *) ptr, size) != size) + { +*************** +*** 694,768 **** + return(1); + } + +! /* comparison routine for qsort */ + + /* +! * proc_compare - comparison function for "qsort" +! * Compares the resource consumption of two processes using five +! * distinct keys. The keys (in descending order of importance) are: +! * percent cpu, cpu ticks, 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. + */ + +! static unsigned char sorted_state[] = +! { +! 0, /* not used */ +! 3, /* sleep */ +! 1, /* ABANDONED (WAIT) */ +! 6, /* run */ +! 5, /* start */ +! 2, /* zombie */ +! 4 /* stop */ + }; +! + int +! proc_compare(pp1, pp2) + +! struct proc **pp1; +! struct proc **pp2; + + { +! register struct kinfo_proc *p1; +! register struct kinfo_proc *p2; +! register int result; +! register pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + +! /* compare percent cpu (pctcpu) */ +! if ((lresult = PP(p2, p_pctcpu) - PP(p1, p_pctcpu)) == 0) +! { +! /* use cpticks to break the tie */ +! if ((result = PP(p2, p_cpticks) - PP(p1, p_cpticks)) == 0) +! { +! /* use process state to break the tie */ +! if ((result = sorted_state[(unsigned char) PP(p2, p_stat)] - +! sorted_state[(unsigned char) PP(p1, p_stat)]) == 0) +! { +! /* use priority to break the tie */ +! if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) +! { +! /* use resident set size (rssize) to break the tie */ +! if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) +! { +! /* use total memory to break the tie */ +! result = PROCSIZE(p2) - PROCSIZE(p1); +! } +! } +! } +! } +! } +! else +! { +! result = lresult < 0 ? -1 : 1; +! } + +! return(result); + } + + +--- 699,913 ---- + 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 = PP(p2, p_pctcpu) - PP(p1, p_pctcpu),\ +! (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) +! +! #define ORDERKEY_CPTICKS \ +! if (lresult = PP(p2, p_rtime).tv_sec - PP(p1, p_rtime).tv_sec,\ +! (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) +! +! #define ORDERKEY_STATE \ +! if ((result = sorted_state[(int)PP(p2, p_stat)] - \ +! sorted_state[(int)PP(p1, p_stat)] ) == 0) +! +! #define ORDERKEY_PRIO \ +! if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) +! +! #define ORDERKEY_RSSIZE \ +! if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) +! +! #define ORDERKEY_MEM \ +! if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0) +! +! /* +! * Now the array that maps process state to a weight. +! * The order of the elements should match those in state_abbrev[] +! */ +! +! static int sorted_state[] = { +! 0, /* (not used) ? */ +! 4, /* "start" SIDL */ +! 5, /* "run" SRUN */ +! 2, /* "sleep" SSLEEP */ +! 3, /* "stop" SSTOP */ +! 1, /* "zomb" SZOMB */ + }; +! +! /* compare_cpu - the comparison function for sorting by cpu percentage */ +! + int +! compare_cpu(pp1, pp2) +! struct proc **pp1, **pp2; +! { +! struct kinfo_proc *p1; +! struct kinfo_proc *p2; +! int result; +! pctcpu lresult; + +! /* remove one level of indirection */ +! p1 = *(struct kinfo_proc **) pp1; +! p2 = *(struct kinfo_proc **) pp2; +! +! ORDERKEY_PCTCPU +! ORDERKEY_CPTICKS +! ORDERKEY_STATE +! ORDERKEY_PRIO +! ORDERKEY_RSSIZE +! ORDERKEY_MEM +! ; +! +! return (result); +! } + ++ /* compare_prio - the comparison function for sorting by process priority */ ++ ++ int ++ compare_prio(pp1, pp2) ++ struct proc **pp1, **pp2; + { +! struct kinfo_proc *p1; +! struct kinfo_proc *p2; +! int result; +! pctcpu lresult; + + /* remove one level of indirection */ + p1 = *(struct kinfo_proc **) pp1; + p2 = *(struct kinfo_proc **) pp2; + +! ORDERKEY_PRIO +! ORDERKEY_PCTCPU +! ORDERKEY_CPTICKS +! ORDERKEY_STATE +! ORDERKEY_RSSIZE +! ORDERKEY_MEM +! ; +! +! return (result); +! } +! +! /* compare_res - the comparison function for sorting by resident set size */ +! +! int +! compare_res(pp1, pp2) +! struct proc **pp1, **pp2; +! { +! struct kinfo_proc *p1; +! struct kinfo_proc *p2; +! int result; +! pctcpu lresult; +! +! /* remove one level of indirection */ +! p1 = *(struct kinfo_proc **) pp1; +! p2 = *(struct kinfo_proc **) pp2; + +! ORDERKEY_RSSIZE +! ORDERKEY_MEM +! ORDERKEY_PCTCPU +! ORDERKEY_CPTICKS +! ORDERKEY_STATE +! ORDERKEY_PRIO +! ; +! +! return (result); +! } +! +! /* compare_size - the comparison function for sorting by total memory usage */ +! +! int +! compare_size(pp1, pp2) +! struct proc **pp1, **pp2; +! { +! struct kinfo_proc *p1; +! struct kinfo_proc *p2; +! int result; +! pctcpu lresult; +! +! /* remove one level of indirection */ +! p1 = *(struct kinfo_proc **) pp1; +! p2 = *(struct kinfo_proc **) pp2; +! +! ORDERKEY_MEM +! ORDERKEY_RSSIZE +! ORDERKEY_PCTCPU +! ORDERKEY_CPTICKS +! ORDERKEY_STATE +! ORDERKEY_PRIO +! ; +! +! return (result); +! } +! +! /* compare_state - the comparison function for sorting by process state */ +! +! int +! compare_state(pp1, pp2) +! struct proc **pp1, **pp2; +! { +! struct kinfo_proc *p1; +! struct kinfo_proc *p2; +! int result; +! pctcpu lresult; +! +! /* remove one level of indirection */ +! p1 = *(struct kinfo_proc **) pp1; +! p2 = *(struct kinfo_proc **) pp2; +! +! ORDERKEY_STATE +! ORDERKEY_PCTCPU +! ORDERKEY_CPTICKS +! ORDERKEY_PRIO +! ORDERKEY_RSSIZE +! ORDERKEY_MEM +! ; +! +! return (result); +! } +! +! /* compare_time - the comparison function for sorting by total cpu time */ +! +! int +! compare_time(pp1, pp2) +! struct proc **pp1, **pp2; +! { +! struct kinfo_proc *p1; +! struct kinfo_proc *p2; +! int result; +! pctcpu lresult; +! +! /* remove one level of indirection */ +! p1 = *(struct kinfo_proc **) pp1; +! p2 = *(struct kinfo_proc **) pp2; +! +! ORDERKEY_CPTICKS +! ORDERKEY_PCTCPU +! ORDERKEY_STATE +! ORDERKEY_PRIO +! ORDERKEY_MEM +! ORDERKEY_RSSIZE +! ; +! +! return (result); + } + + +*************** +*** 776,789 **** + * and "renice" commands. + */ + +! int proc_owner(pid) +! +! int pid; +! + { +! register int cnt; +! register struct kinfo_proc **prefp; +! register struct kinfo_proc *pp; + + prefp = pref; + cnt = pref_len; +--- 921,933 ---- + * and "renice" commands. + */ + +! int +! proc_owner(pid) +! int pid; + { +! int cnt; +! struct kinfo_proc **prefp; +! struct kinfo_proc *pp; + + prefp = pref; + cnt = pref_len; +*************** +*** 830,835 **** +--- 974,980 ---- + struct map *swapmap, *kswapmap; + struct mapent *mp, *freemp; + ++ l = 0; + KGET(VM_NSWAP, nswap); + KGET(VM_NSWDEV, nswdev); + KGET(VM_DMMAX, dmmax); +*************** +*** 936,941 **** + return (int)(((double)used / (double)avail * 100.0) + 0.5); + } + +! +! #endif +! +--- 1081,1084 ---- + return (int)(((double)used / (double)avail * 100.0) + 0.5); + } + +! #endif /* USE_SWAP */ +*** /dev/null Thu Jan 1 10:00:00 1970 +--- machine/m_netbsd13.c Tue Jun 17 17:41:07 1997 +*************** +*** 0 **** +--- 1,841 ---- ++ /* ++ * top - a top users display for Unix ++ * ++ * SYNOPSIS: For a NetBSD-1.3 (or later) system ++ * ++ * DESCRIPTION: ++ * Originally written for BSD4.4 system by Christos Zoulas. ++ * Based on the FreeBSD 2.0 version by Steven Wallace and Wolfram Schneider. ++ * NetBSD-1.0 port by Arne Helme. Process ordering by Luke Mewburn. ++ * NetBSD-1.3 port by Luke Mewburn, based on code by Matthew Green. ++ * ++ * This is the machine-dependent module for NetBSD-1.3 and later ++ * Works for: ++ * NetBSD-1.3 ++ * ++ * LIBS: -lkvm ++ * ++ * CFLAGS: -DHAVE_GETOPT -DORDER ++ * ++ * AUTHORS: Christos Zoulas <christos@ee.cornell.edu> ++ * Steven Wallace <swallace@freebsd.org> ++ * Wolfram Schneider <wosch@cs.tu-berlin.de> ++ * Arne Helme <arne@acm.org> ++ * Luke Mewburn <lukem@netbsd.org> ++ * Matthew Green <mrg@eterna.com.au> ++ * ++ * ++ * $Id: patch-aa,v 1.1 1997/10/03 11:45:34 agc Exp $ ++ */ ++ ++ #include <sys/types.h> ++ #include <sys/signal.h> ++ #include <sys/param.h> ++ #include <sys/stat.h> ++ #include <sys/errno.h> ++ #include <sys/sysctl.h> ++ #include <sys/dir.h> ++ #include <sys/dkstat.h> ++ #include <sys/file.h> ++ #include <sys/time.h> ++ ++ #include <vm/vm_swap.h> ++ ++ #include "os.h" ++ #include <err.h> ++ #include <errno.h> ++ #include <kvm.h> ++ #include <math.h> ++ #include <nlist.h> ++ #include <stdio.h> ++ #include <stdlib.h> ++ #include <string.h> ++ #include <unistd.h> ++ ++ static int check_nlist __P((struct nlist *)); ++ static int getkval __P((unsigned long, int *, int, char *)); ++ extern char* printable __P((char *)); ++ ++ #include "top.h" ++ #include "machine.h" ++ #include "utils.h" ++ ++ ++ /* get_process_info passes back a handle. This is what it looks like: */ ++ ++ struct handle ++ { ++ struct kinfo_proc **next_proc; /* points to next valid proc pointer */ ++ int remaining; /* number of pointers remaining */ ++ }; ++ ++ /* declarations for load_avg */ ++ #include "loadavg.h" ++ ++ #define PP(pp, field) ((pp)->kp_proc . field) ++ #define EP(pp, field) ((pp)->kp_eproc . field) ++ #define VP(pp, field) ((pp)->kp_eproc.e_vm . field) ++ ++ /* define what weighted cpu is. */ ++ #define weighted_cpu(pct, pp) (PP((pp), p_swtime) == 0 ? 0.0 : \ ++ ((pct) / (1.0 - exp(PP((pp), p_swtime) * logcpu)))) ++ ++ /* what we consider to be process size: */ ++ #define PROCSIZE(pp) \ ++ (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize)) ++ ++ /* definitions for indices in the nlist array */ ++ ++ ++ static struct nlist nlst[] = { ++ #define X_CCPU 0 ++ { "_ccpu" }, /* 0 */ ++ #define X_CP_TIME 1 ++ { "_cp_time" }, /* 1 */ ++ #define X_HZ 2 ++ { "_hz" }, /* 2 */ ++ #define X_STATHZ 3 ++ { "_stathz" }, /* 3 */ ++ #define X_AVENRUN 4 ++ { "_averunnable" }, /* 4 */ ++ #define X_CNT 5 ++ { "_cnt" }, ++ ++ { 0 } ++ }; ++ ++ /* ++ * These definitions control the format of the per-process area ++ */ ++ ++ static char header[] = ++ " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; ++ /* 0123456 -- field to fill in starts at header+6 */ ++ #define UNAME_START 6 ++ ++ #define Proc_format \ ++ "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" ++ ++ ++ /* process state names for the "STATE" column of the display */ ++ /* the extra nulls in the string "run" are for adding a slash and ++ the processor number when needed */ ++ ++ char *state_abbrev[] = ++ { ++ "", "start", "run\0\0\0", "sleep", "stop", "zomb" ++ }; ++ ++ ++ static kvm_t *kd; ++ ++ /* values that we stash away in _init and use in later routines */ ++ ++ static double logcpu; ++ ++ /* these are retrieved from the kernel in _init */ ++ ++ static long hz; ++ static load_avg ccpu; ++ ++ /* these are offsets obtained via nlist and used in the get_ functions */ ++ ++ static unsigned long cp_time_offset; ++ static unsigned long avenrun_offset; ++ static unsigned long cnt_offset; ++ /* these are for calculating cpu state percentages */ ++ ++ static long cp_time[CPUSTATES]; ++ static long cp_old[CPUSTATES]; ++ static long cp_diff[CPUSTATES]; ++ ++ /* these are for detailing the process states */ ++ ++ int process_states[7]; ++ char *procstatenames[] = { ++ "", " starting, ", " running, ", " sleeping, ", " stopped, ", ++ " zombie, ", " ABANDONED, ", ++ NULL ++ }; ++ ++ /* these are for detailing the cpu states */ ++ ++ int cpu_states[CPUSTATES]; ++ char *cpustatenames[] = { ++ "user", "nice", "system", "interrupt", "idle", NULL ++ }; ++ ++ /* these are for detailing the memory statistics */ ++ ++ int memory_stats[7]; ++ char *memorynames[] = { ++ "K Act ", "K Inact ", "K Wired ", "K Free ", ++ "K Swap ", "K Swap free ", ++ NULL ++ }; ++ ++ ++ /* these are names given to allowed sorting orders -- first is default */ ++ char *ordernames[] = { ++ "cpu", ++ "pri", ++ "res", ++ "size", ++ "state", ++ "time", ++ NULL ++ }; ++ ++ /* forward definitions for comparison functions */ ++ int compare_cpu(); ++ int compare_prio(); ++ int compare_res(); ++ int compare_size(); ++ int compare_state(); ++ int compare_time(); ++ ++ int (*proc_compares[])() = { ++ compare_cpu, ++ compare_prio, ++ compare_res, ++ compare_size, ++ compare_state, ++ compare_time, ++ NULL ++ }; ++ ++ ++ /* these are for keeping track of the proc array */ ++ ++ static int nproc; ++ static int onproc = -1; ++ static int pref_len; ++ static struct kinfo_proc *pbase; ++ static struct kinfo_proc **pref; ++ ++ /* these are for getting the memory statistics */ ++ ++ static int pageshift; /* log base 2 of the pagesize */ ++ ++ /* define pagetok in terms of pageshift */ ++ ++ #define pagetok(size) ((size) << pageshift) ++ ++ /* useful externals */ ++ long percentages(); ++ ++ int ++ machine_init(statics) ++ struct statics *statics; ++ { ++ int i = 0; ++ int pagesize; ++ ++ if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) ++ return -1; ++ ++ ++ /* get the list of symbols we want to access in the kernel */ ++ (void) kvm_nlist(kd, nlst); ++ if (nlst[0].n_type == 0) ++ { ++ fprintf(stderr, "top: nlist failed\n"); ++ return(-1); ++ } ++ ++ /* make sure they were all found */ ++ if (i > 0 && check_nlist(nlst) > 0) ++ { ++ return(-1); ++ } ++ ++ /* get the symbol values out of kmem */ ++ (void) getkval(nlst[X_STATHZ].n_value, (int *)(&hz), sizeof(hz), "!"); ++ if (!hz) { ++ (void) getkval(nlst[X_HZ].n_value, (int *)(&hz), sizeof(hz), ++ nlst[X_HZ].n_name); ++ } ++ ++ ++ (void) getkval(nlst[X_CCPU].n_value, (int *)(&ccpu), sizeof(ccpu), ++ nlst[X_CCPU].n_name); ++ ++ /* stash away certain offsets for later use */ ++ cp_time_offset = nlst[X_CP_TIME].n_value; ++ avenrun_offset = nlst[X_AVENRUN].n_value; ++ cnt_offset = nlst[X_CNT].n_value; ++ ++ /* this is used in calculating WCPU -- calculate it ahead of time */ ++ logcpu = log(loaddouble(ccpu)); ++ ++ pbase = NULL; ++ pref = NULL; ++ nproc = 0; ++ onproc = -1; ++ /* get the page size with "getpagesize" and calculate pageshift from it */ ++ pagesize = getpagesize(); ++ pageshift = 0; ++ while (pagesize > 1) ++ { ++ pageshift++; ++ pagesize >>= 1; ++ } ++ ++ /* we only need the amount of log(2)1024 for our conversion */ ++ pageshift -= LOG1024; ++ ++ /* fill in the statics information */ ++ statics->procstate_names = procstatenames; ++ statics->cpustate_names = cpustatenames; ++ statics->memory_names = memorynames; ++ statics->order_names = ordernames; ++ ++ /* all done! */ ++ return(0); ++ } ++ ++ char * ++ format_header(uname_field) ++ char *uname_field; ++ { ++ char *ptr; ++ ++ ptr = header + UNAME_START; ++ while (*uname_field != '\0') ++ { ++ *ptr++ = *uname_field++; ++ } ++ ++ return(header); ++ } ++ ++ void ++ get_system_info(si) ++ struct system_info *si; ++ { ++ long total; ++ struct vmmeter sum; ++ struct swapent *sep; ++ int totalsize, size, totalinuse, inuse, ncounted; ++ int rnswap, nswap; ++ ++ /* get the cp_time array */ ++ (void) getkval(cp_time_offset, (int *)cp_time, sizeof(cp_time), ++ nlst[X_CP_TIME].n_name); ++ ++ if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) { ++ int i; ++ ++ warn("can't getloadavg"); ++ for (i = 0; i < NUM_AVERAGES; i++) ++ si->load_avg[i] = 0.0; ++ } ++ ++ /* convert cp_time counts to percentages */ ++ total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); ++ ++ /* sum memory statistics */ ++ ++ (void) getkval(cnt_offset, (int *)(&sum), sizeof(sum), "_cnt"); ++ ++ /* convert memory stats to Kbytes */ ++ memory_stats[0] = pagetok(sum.v_active_count); ++ memory_stats[1] = pagetok(sum.v_inactive_count); ++ memory_stats[2] = pagetok(sum.v_wire_count); ++ memory_stats[3] = pagetok(sum.v_free_count); ++ ++ memory_stats[4] = memory_stats[5] = 0; ++ ++ sep = NULL; ++ do { ++ nswap = swapctl(SWAP_NSWAP, 0, 0); ++ if (nswap < 1) ++ break; ++ sep = (struct swapent *)malloc(nswap * sizeof(*sep)); ++ if (sep == NULL) ++ break; ++ rnswap = swapctl(SWAP_STATS, (void *)sep, nswap); ++ if (nswap != rnswap) ++ break; ++ ++ totalsize = totalinuse = ncounted = 0; ++ for (; rnswap-- > 0; sep++) { ++ ncounted++; ++ size = sep->se_nblks; ++ inuse = sep->se_inuse; ++ totalsize += size; ++ totalinuse += inuse; ++ } ++ memory_stats[4] = dbtob(totalinuse) / 1024; ++ memory_stats[5] = dbtob(totalsize) / 1024 - memory_stats[4]; ++ } while (0); ++ if (sep) ++ free(sep); ++ ++ memory_stats[6] = -1; ++ ++ /* set arrays and strings */ ++ si->cpustates = cpu_states; ++ si->memory = memory_stats; ++ si->last_pid = -1; ++ } ++ ++ static struct handle handle; ++ ++ caddr_t ++ get_process_info(si, sel, compare) ++ struct system_info *si; ++ struct process_select *sel; ++ int (*compare)(); ++ { ++ int i; ++ int total_procs; ++ int active_procs; ++ struct kinfo_proc **prefp; ++ struct kinfo_proc *pp; ++ ++ /* these are copied out of sel for speed */ ++ int show_idle; ++ int show_system; ++ int show_uid; ++ int show_command; ++ ++ ++ pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc); ++ if (nproc > onproc) ++ pref = (struct kinfo_proc **) realloc(pref, sizeof(struct kinfo_proc *) ++ * (onproc = nproc)); ++ if (pref == NULL || pbase == NULL) { ++ (void) fprintf(stderr, "top: Out of memory.\n"); ++ quit(23); ++ } ++ /* 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; ++ memset((char *)process_states, 0, 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 P_SYSTEM set are system ++ * processes---these get ignored unless show_sysprocs is set. ++ */ ++ if (PP(pp, p_stat) != 0 && ++ (show_system || ((PP(pp, p_flag) & P_SYSTEM) == 0))) ++ { ++ total_procs++; ++ process_states[(unsigned char) PP(pp, p_stat)]++; ++ if ((PP(pp, p_stat) != SZOMB) && ++ (show_idle || (PP(pp, p_pctcpu) != 0) || ++ (PP(pp, p_stat) == SRUN)) && ++ (!show_uid || EP(pp, e_pcred.p_ruid) == (uid_t)sel->uid)) ++ { ++ *prefp++ = pp; ++ active_procs++; ++ } ++ } ++ } ++ ++ /* if requested, sort the "interesting" processes */ ++ if (compare != NULL) ++ { ++ qsort((char *)pref, active_procs, sizeof(struct kinfo_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[128]; /* static area where result is built */ ++ ++ char * ++ format_next_process(handle, get_userid) ++ caddr_t handle; ++ char *(*get_userid)(); ++ { ++ struct kinfo_proc *pp; ++ long cputime; ++ double pct; ++ 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 ((PP(pp, p_flag) & P_INMEM) == 0) { ++ /* ++ * Print swapped processes as <pname> ++ */ ++ char *comm = PP(pp, p_comm); ++ #define COMSIZ sizeof(PP(pp, p_comm)) ++ char buf[COMSIZ]; ++ (void) strncpy(buf, comm, COMSIZ); ++ comm[0] = '<'; ++ (void) strncpy(&comm[1], buf, COMSIZ - 2); ++ comm[COMSIZ - 2] = '\0'; ++ (void) strncat(comm, ">", COMSIZ - 1); ++ comm[COMSIZ - 1] = '\0'; ++ } ++ ++ #if 0 ++ /* This does not produce the correct results */ ++ cputime = PP(pp, p_uticks) + PP(pp, p_sticks) + PP(pp, p_iticks); ++ #endif ++ cputime = PP(pp, p_rtime).tv_sec; /* This does not count interrupts */ ++ ++ /* calculate the base for cpu percentages */ ++ pct = pctdouble(PP(pp, p_pctcpu)); ++ ++ #define Proc_format \ ++ "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" ++ ++ /* format this entry */ ++ sprintf(fmt, ++ Proc_format, ++ PP(pp, p_pid), ++ (*get_userid)(EP(pp, e_pcred.p_ruid)), ++ PP(pp, p_priority) - PZERO, ++ PP(pp, p_nice) - NZERO, ++ format_k(pagetok(PROCSIZE(pp))), ++ format_k(pagetok(VP(pp, vm_rssize))), ++ state_abbrev[(unsigned char) PP(pp, p_stat)], ++ format_time(cputime), ++ 10000.0 * weighted_cpu(pct, pp) / hz, ++ 10000.0 * pct / hz, ++ printable(PP(pp, p_comm))); ++ ++ /* return the result */ ++ return(fmt); ++ } ++ ++ ++ /* ++ * 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. ++ */ ++ ++ static int ++ check_nlist(nlst) ++ struct nlist *nlst; ++ { ++ 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 */ ++ (void) 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). ++ * ++ */ ++ ++ static int ++ getkval(offset, ptr, size, refstr) ++ unsigned long offset; ++ int *ptr; ++ int size; ++ char *refstr; ++ { ++ if (kvm_read(kd, offset, (char *) ptr, size) != size) ++ { ++ if (*refstr == '!') ++ { ++ return(0); ++ } ++ else ++ { ++ fprintf(stderr, "top: kvm_read for %s: %s\n", ++ refstr, strerror(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 = PP(p2, p_pctcpu) - PP(p1, p_pctcpu),\ ++ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) ++ ++ #define ORDERKEY_CPTICKS \ ++ if (lresult = PP(p2, p_rtime).tv_sec - PP(p1, p_rtime).tv_sec,\ ++ (result = lresult > 0 ? 1 : lresult < 0 ? -1 : 0) == 0) ++ ++ #define ORDERKEY_STATE \ ++ if ((result = sorted_state[(int)PP(p2, p_stat)] - \ ++ sorted_state[(int)PP(p1, p_stat)] ) == 0) ++ ++ #define ORDERKEY_PRIO \ ++ if ((result = PP(p2, p_priority) - PP(p1, p_priority)) == 0) ++ ++ #define ORDERKEY_RSSIZE \ ++ if ((result = VP(p2, vm_rssize) - VP(p1, vm_rssize)) == 0) ++ ++ #define ORDERKEY_MEM \ ++ if ((result = (PROCSIZE(p2) - PROCSIZE(p1))) == 0) ++ ++ /* ++ * Now the array that maps process state to a weight. ++ * The order of the elements should match those in state_abbrev[] ++ */ ++ ++ static int sorted_state[] = { ++ 0, /* (not used) ? */ ++ 4, /* "start" SIDL */ ++ 5, /* "run" SRUN */ ++ 2, /* "sleep" SSLEEP */ ++ 3, /* "stop" SSTOP */ ++ 1, /* "zomb" SZOMB */ ++ }; ++ ++ /* compare_cpu - the comparison function for sorting by cpu percentage */ ++ ++ int ++ compare_cpu(pp1, pp2) ++ struct proc **pp1, **pp2; ++ { ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; ++ ++ return (result); ++ } ++ ++ /* compare_prio - the comparison function for sorting by process priority */ ++ ++ int ++ compare_prio(pp1, pp2) ++ struct proc **pp1, **pp2; ++ { ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_PRIO ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; ++ ++ return (result); ++ } ++ ++ /* compare_res - the comparison function for sorting by resident set size */ ++ ++ int ++ compare_res(pp1, pp2) ++ struct proc **pp1, **pp2; ++ { ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ; ++ ++ return (result); ++ } ++ ++ /* compare_size - the comparison function for sorting by total memory usage */ ++ ++ int ++ compare_size(pp1, pp2) ++ struct proc **pp1, **pp2; ++ { ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_MEM ++ ORDERKEY_RSSIZE ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ; ++ ++ return (result); ++ } ++ ++ /* compare_state - the comparison function for sorting by process state */ ++ ++ int ++ compare_state(pp1, pp2) ++ struct proc **pp1, **pp2; ++ { ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_STATE ++ ORDERKEY_PCTCPU ++ ORDERKEY_CPTICKS ++ ORDERKEY_PRIO ++ ORDERKEY_RSSIZE ++ ORDERKEY_MEM ++ ; ++ ++ return (result); ++ } ++ ++ /* compare_time - the comparison function for sorting by total cpu time */ ++ ++ int ++ compare_time(pp1, pp2) ++ struct proc **pp1, **pp2; ++ { ++ struct kinfo_proc *p1; ++ struct kinfo_proc *p2; ++ int result; ++ pctcpu lresult; ++ ++ /* remove one level of indirection */ ++ p1 = *(struct kinfo_proc **) pp1; ++ p2 = *(struct kinfo_proc **) pp2; ++ ++ ORDERKEY_CPTICKS ++ ORDERKEY_PCTCPU ++ ORDERKEY_STATE ++ ORDERKEY_PRIO ++ ORDERKEY_MEM ++ ORDERKEY_RSSIZE ++ ; ++ ++ 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; ++ { ++ int cnt; ++ struct kinfo_proc **prefp; ++ struct kinfo_proc *pp; ++ ++ prefp = pref; ++ cnt = pref_len; ++ while (--cnt >= 0) ++ { ++ pp = *prefp++; ++ if (PP(pp, p_pid) == (pid_t)pid) ++ { ++ return((int)EP(pp, e_pcred.p_ruid)); ++ } ++ } ++ return(-1); ++ } +*** top.c Fri Sep 13 05:50:53 1996 +--- top.c Tue Apr 22 19:19:34 1997 +*************** +*** 714,720 **** + case CMD_help2: + reset_display(); + clear(); +! show_help(); + standout("Hit any key to continue: "); + fflush(stdout); + (void) read(0, &ch, 1); +--- 714,720 ---- + case CMD_help2: + reset_display(); + clear(); +! show_help(&statics); + standout("Hit any key to continue: "); + fflush(stdout); + (void) read(0, &ch, 1); +*** utils.c Wed Sep 11 06:15:14 1996 +--- utils.c Tue Apr 22 19:19:34 1997 +*************** +*** 16,21 **** +--- 16,23 ---- + #include "top.h" + #include "os.h" + ++ #include <errno.h> ++ + int atoiwi(str) + + char *str; diff --git a/sysutils/top/patches/patch-ab b/sysutils/top/patches/patch-ab new file mode 100644 index 00000000000..e55538feec3 --- /dev/null +++ b/sysutils/top/patches/patch-ab @@ -0,0 +1,129 @@ +Return-Path: <current-users-owner-agc=amdahl.com@NetBSD.ORG> +Received: by juno.ccc.amdahl.com (/\==/\ Smail #25.1) + id <m0we6gi-0000SSC@juno.ccc.amdahl.com>; Tue, 17 Jun 97 15:25 PDT +Received: from vega.oes.amdahl.com by orpheus.amdahl.com with smtp + (Smail3.1.29.1 #3) id m0we6gp-0004iwC; Tue, 17 Jun 97 15:25 PDT +Received: from minerva.amdahl.com by vega.oes.amdahl.com with SMTP + (OES Smail-3.1.29.1) id m0we6gp-000B0rC; Tue, 17 Jun 97 15:25 PDT +Received: from orpheus.amdahl.com by minerva.amdahl.com with smtp + (Smail3.1.29.1 #5) id m0we6gn-0002AWC; Tue, 17 Jun 97 15:25 PDT +Received: from mail.NetBSD.ORG by orpheus.amdahl.com with smtp + (Smail3.1.29.1 #3) id m0we6gn-0004iwC; Tue, 17 Jun 97 15:25 PDT +Received: (qmail 1595 invoked by uid 605); 17 Jun 1997 22:25:30 -0000 +Received: (qmail 1589 invoked from network); 17 Jun 1997 22:25:26 -0000 +Received: from ramoth.nyc.deshaw.com (root@149.77.15.102) + by homeworld.cygnus.com with SMTP; 17 Jun 1997 22:25:26 -0000 +Received: (from christos@localhost) + by ramoth.nyc.deshaw.com (8.8.5/8.7.Alpha.4/1.34.kim) id SAA00740 + for current-users@netbsd.org; Tue, 17 Jun 1997 18:24:22 -0400 (EDT) +Message-Id: <199706172224.SAA00740@ramoth.nyc.deshaw.com> +From: christos@deshaw.com (Christos Zoulas) +Date: Tue, 17 Jun 1997 18:24:22 -0400 +Organization: D. E. Shaw & Co. +X-Address: Tower 45, 120 West 45th St., 39th Floor, New York, N.Y. 10036 +X-Phone: (212) 478 0000 +X-Fax: (212) 478 0101 +X-Face: %jL.CVv-*"-d?@xSu)#i[QzHK3,c?Qx,G.u#bZ;O'qSg"$LmB})v;&A"6r&;#2NRahSRwYl + D9Y8"L97FX^O7oBy?'hA6-1AQA`L(c[yqZySfl/t&4;gHT1|X\ElkgxMV<G<Wl4Bw[Y^/8]X@>NUjM + /A)InAN\hPuhymGG{1&&ay2c"[4z_*Gb?{gbnv5+?terjcRFl`(^3vO-^Mw%\Cfk`p{@!a3&/NR#*p + <c]7@{DT)R_*g4#M@G98-f$hN#J<pnDfR:xx<ph,7HcR3TeE|G~&}*>fH0rostE1 +X-Mailer: Mail User's Shell (7.2.6 beta(2)+dynamic 2/29/96) +To: current-users@netbsd.org +Subject: patch for the top patch +Sender: current-users-owner@NetBSD.ORG +Precedence: list +Delivered-To: current-users@NetBSD.ORG + + +I liked more the wait proc patch... This is to be applied after Luke's patch. + +christos + +[agc - I've modified the filename below so that it works in the packages +system] + +*** machine/m_netbsd13.c.orig Tue Jun 17 18:16:57 1997 +--- machine/m_netbsd13.c Tue Jun 17 18:12:02 1997 +*************** +*** 109,120 **** + */ + + static char header[] = +! " PID X PRI NICE SIZE RES STATE TIME WCPU CPU COMMAND"; + /* 0123456 -- field to fill in starts at header+6 */ + #define UNAME_START 6 + + #define Proc_format \ +! "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" + + + /* process state names for the "STATE" column of the display */ +--- 109,120 ---- + */ + + static char header[] = +! " PID X PRI NICE SIZE RES STATE WAIT TIME CPU COMMAND"; + /* 0123456 -- field to fill in starts at header+6 */ + #define UNAME_START 6 + + #define Proc_format \ +! "%5d %-8.8s %3d %4d %5s %5s %-5s %-6.6s %6s %5.2f%% %.14s" + + + /* process state names for the "STATE" column of the display */ +*************** +*** 474,479 **** +--- 474,480 ---- + long cputime; + double pct; + struct handle *hp; ++ char *p_wait, waddr[32]; + + /* find and remember the next proc structure */ + hp = (struct handle *)handle; +*************** +*** 506,513 **** + /* calculate the base for cpu percentages */ + pct = pctdouble(PP(pp, p_pctcpu)); + +! #define Proc_format \ +! "%5d %-8.8s %3d %4d%7s %5s %-5s%7s %5.2f%% %5.2f%% %.14s" + + /* format this entry */ + sprintf(fmt, +--- 507,522 ---- + /* calculate the base for cpu percentages */ + pct = pctdouble(PP(pp, p_pctcpu)); + +! if (PP(pp, p_wchan)) +! if (PP(pp, p_wmesg)) +! p_wait = EP(pp, e_wmesg); +! else { +! sprintf(waddr, "%x", +! (unsigned long)(PP(pp, p_wchan)) & ~KERNBASE); +! p_wait = waddr; +! } +! else +! p_wait = "-"; + + /* format this entry */ + sprintf(fmt, +*************** +*** 519,526 **** + format_k(pagetok(PROCSIZE(pp))), + format_k(pagetok(VP(pp, vm_rssize))), + state_abbrev[(unsigned char) PP(pp, p_stat)], + format_time(cputime), +- 10000.0 * weighted_cpu(pct, pp) / hz, + 10000.0 * pct / hz, + printable(PP(pp, p_comm))); + +--- 528,535 ---- + format_k(pagetok(PROCSIZE(pp))), + format_k(pagetok(VP(pp, vm_rssize))), + state_abbrev[(unsigned char) PP(pp, p_stat)], ++ p_wait, + format_time(cputime), + 10000.0 * pct / hz, + printable(PP(pp, p_comm))); + |