$NetBSD: patch-af,v 1.1 1999/12/08 16:18:49 agc Exp $

--- machine/m_netbsd10.c	Fri Jan 26 06:27:18 1996
+++ machine/m_netbsd10.c	Sat Oct  4 03:27:03 1997
@@ -3,3 +3,3 @@
  *
- * SYNOPSIS:  For a NetBSD-1.0 (4.4BSD) system
+ * SYNOPSIS:  For a NetBSD-1.0 through NetBSD-1.2.1 system
  *	      Note process resident sizes could be wrong, but ps shows
@@ -9,5 +9,5 @@
  * 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
- * .
+ * Based on the FreeBSD 2.0 version by Steven Wallace && 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
@@ -15,2 +15,5 @@
  *	NetBSD-1.0
+ *	NetBSD-1.1 
+ *	NetBSD-1.2
+ *	NetBSD-1.2.1
  *
@@ -18,3 +21,3 @@
  *
- * CFLAGS: -DHAVE_GETOPT
+ * CFLAGS: -DHAVE_GETOPT -DORDER
  *
@@ -24,2 +27,4 @@
  *	    Arne Helme <arne@acm.org>
+ *	    Luke Mewburn <lukem@netbsd.org>
+ *
  *
@@ -30,4 +35,4 @@
 
-#define LASTPID      /**/  /* use last pid, compiler depended */
-/* #define LASTPID_FIXED /**/ 
+/* #define LASTPID      */  /* use last pid, compiler depended */
+/* #define LASTPID_FIXED */ 
 #define VM_REAL      /**/  /* use the same values as vmstat -s */
@@ -53,2 +58,11 @@
 
+#include "os.h"
+
+#include <err.h>
+#include <kvm.h>
+#include <math.h>
+#include <nlist.h>
+#include <stdio.h>
+#include <unistd.h>
+
 #ifdef USE_SWAP
@@ -87,3 +101,4 @@
 /* what we consider to be process size: */
-#define PROCSIZE(pp) (VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize))
+#define PROCSIZE(pp) \
+	(VP((pp), vm_tsize) + VP((pp), vm_dsize) + VP((pp), vm_ssize))
 
@@ -171,3 +186,3 @@
 {
-    "", "start", "run\0\0\0", "sleep", "stop", "zomb", "WAIT"
+    "", "start", "run\0\0\0", "sleep", "stop", "zomb"
 };
@@ -196,3 +211,2 @@
 static unsigned long cnt_offset;
-static long cnt;
 #endif
@@ -239,2 +253,33 @@
 
+
+/* 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 */
@@ -260,8 +305,6 @@
 machine_init(statics)
-
-struct statics *statics;
-
+    struct statics *statics;
 {
-    register int i = 0;
-    register int pagesize;
+    int i = 0;
+    int pagesize;
 
@@ -293,6 +336,2 @@
 
-#if (defined DEBUG)
-    fprintf(stderr, "Hertz: %d\n", hz); 
-#endif
-
     (void) getkval(nlst[X_CCPU].n_value,   (int *)(&ccpu),	sizeof(ccpu),
@@ -333,2 +372,3 @@
     statics->memory_names = memorynames;
+    statics->order_names = ordernames;
 
@@ -338,8 +378,7 @@
 
-char *format_header(uname_field)
-
-register char *uname_field;
-
+char *
+format_header(uname_field)
+    char *uname_field;
 {
-    register char *ptr;
+    char *ptr;
 
@@ -360,8 +399,5 @@
 get_system_info(si)
-
-struct system_info *si;
-
+    struct system_info *si;
 {
     long total;
-    load_avg avenrun[3];
 
@@ -370,31 +406,13 @@
 		   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),
-		   "!");
+    (void) getkval(lastpid_offset, (int *)(&lastpid), sizeof(lastpid), "!");
 #endif
 
-    /* convert load averages to doubles */
-    {
-	register int i;
-	register double *infoloadp;
-	load_avg *avenrunp;
+    if (getloadavg(si->load_avg, NUM_AVERAGES) < 0) {
+	int i;
 
-#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++);
-	}
+	warn("can't getloadavg");
+	for (i = 0; i < NUM_AVERAGES; i++)
+	    si->load_avg[i] = 0.0;
     }
@@ -426,4 +444,4 @@
 	memory_stats[7] = pagetok(total.t_free);
-    }
-#else
+
+#else /* !VM_REAL */
 	struct vmmeter sum;
@@ -455,5 +473,5 @@
         /* swap_delay++; XXX Arne */
-#else
+#else /* !USE_SWAP */
         memory_stats[4] = 0;
-#endif
+#endif /* !USE_SWAP */
 
@@ -461,4 +479,5 @@
 	memory_stats[7] = -1;
+#endif /* !VM_REAL */
     }
-#endif
+
     /* set arrays and strings */
@@ -480,14 +498,13 @@
 
-caddr_t get_process_info(si, sel, compare)
-
-struct system_info *si;
-struct process_select *sel;
-int (*compare)();
-
+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;
+    int i;
+    int total_procs;
+    int active_procs;
+    struct kinfo_proc **prefp;
+    struct kinfo_proc *pp;
 
@@ -564,11 +581,10 @@
 
-char *format_next_process(handle, get_userid)
-
-caddr_t handle;
-char *(*get_userid)();
-
+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 kinfo_proc *pp;
+    long cputime;
+    double pct;
     struct handle *hp;
@@ -633,8 +649,7 @@
 
-static int check_nlist(nlst)
-
-register struct nlist *nlst;
-
+static int
+check_nlist(nlst)
+    struct nlist *nlst;
 {
-    register int i;
+    int i;
 
@@ -672,9 +687,8 @@
 
-static int getkval(offset, ptr, size, refstr)
-
-unsigned long offset;
-int *ptr;
-int size;
-char *refstr;
-
+static int
+getkval(offset, ptr, size, refstr)
+    unsigned long offset;
+    int *ptr;
+    int size;
+    char *refstr;
 {
@@ -696,12 +710,13 @@
     
-/* comparison routine for qsort */
+/* comparison routines 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
+ * 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.
@@ -709,24 +724,79 @@
 
-static unsigned char sorted_state[] =
-{
-    0,	/* not used		*/
-    3,	/* sleep		*/
-    1,	/* ABANDONED (WAIT)	*/
-    6,	/* run			*/
-    5,	/* start		*/
-    2,	/* zombie		*/
-    4	/* stop			*/
+/*
+ * 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
-proc_compare(pp1, pp2)
+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;
 
-struct proc **pp1;
-struct 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;
 {
-    register struct kinfo_proc *p1;
-    register struct kinfo_proc *p2;
-    register int result;
-    register pctcpu lresult;
+    struct kinfo_proc *p1;
+    struct kinfo_proc *p2;
+    int result;
+    pctcpu lresult;
 
@@ -736,31 +806,115 @@
 
-    /* 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;
-    }
+    ORDERKEY_PRIO
+    ORDERKEY_PCTCPU
+    ORDERKEY_CPTICKS
+    ORDERKEY_STATE
+    ORDERKEY_RSSIZE
+    ORDERKEY_MEM
+    ;
 
-    return(result);
+    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);
 }
@@ -778,10 +932,9 @@
 
-int proc_owner(pid)
-
-int pid;
-
+int
+proc_owner(pid)
+    int pid;
 {
-    register int cnt;
-    register struct kinfo_proc **prefp;
-    register struct kinfo_proc *pp;
+    int cnt;
+    struct kinfo_proc **prefp;
+    struct kinfo_proc *pp;
 
@@ -832,2 +985,3 @@
 
+	l = 0;
 	KGET(VM_NSWAP, nswap);
@@ -938,4 +1092,2 @@
 
-
-#endif
-
+#endif /* USE_SWAP */
