Skip site navigation (1)Skip section navigation (2)
Date:      31 May 1998 19:55:28 +0900
From:      Takanori Saneto <sanewo@ba2.so-net.ne.jp>
To:        current@FreeBSD.ORG
Subject:   Re: top -osize
Message-ID:  <87n2byso9r.fsf@sanewo.ba2.so-net.ne.jp>
In-Reply-To: Dan Nelson's message of "Thu, 28 May 1998 21:20:02 -0500"
References:  <19980528211849.A10559@rtfm.net> <19980528212002.A11468@emsphone.com>

next in thread | previous in thread | raw e-mail | index | archive | help
In article <19980528212002.A11468@emsphone.com>,
	Dan Nelson <dnelson@emsphone.com> writes:
>> Is there a real reason for it not being able to do this or is
>> something just mildly broken?

>The only reason is that no one's wanted to write the sort routines. 
>Out of the 40 platforms supported by top 3.5b7, only 5 (aix32, aix41,
>sunos4, sunos5, and untrix4) even implemented -o.

Here's a patch to make sorting option work for -current, which is
based on Solaris' machine.c. I've been using this patched version of
top since it was in ports tree.
-- 
さねを <URL:mailto:sanewo@ba2.so-net.ne.jp>

Index: usr.bin/top/Makefile
===================================================================
RCS file: /sd0/FreeBSD/cvs/src/usr.bin/top/Makefile,v
retrieving revision 1.4
diff -u -r1.4 Makefile
--- Makefile	1997/07/21 16:06:00	1.4
+++ Makefile	1997/07/31 16:59:17
@@ -5,6 +5,8 @@
 
 CFLAGS+= -DHAVE_GETOPT -I${.CURDIR} -I${TOPDIR}
 
+CFLAGS+= -DORDER
+
 #
 # The table size should be a prime number approximately twice as
 # large as the number of lines in /etc/passwd.  The default number
Index: usr.bin/top/machine.c
===================================================================
RCS file: /sd0/FreeBSD/cvs/src/usr.bin/top/machine.c,v
retrieving revision 1.10
diff -u -r1.10 machine.c
--- machine.c	1998/05/28 09:29:48	1.10
+++ machine.c	1998/05/28 17:27:52
@@ -13,6 +13,8 @@
  *
  * LIBS: -lkvm
  *
+ * CFLAGS: -DHAVE_GETOPT -DORDER
+ *
  * AUTHOR:  Christos Zoulas <christos@ee.cornell.edu>
  *          Steven Wallace  <swallace@freebsd.org>
  *          Wolfram Schneider <wosch@FreeBSD.org>
@@ -167,7 +169,6 @@
 static long lastpid;
 static unsigned long cnt_offset;
 static unsigned long bufspace_offset;
-static long cnt;
 
 /* these are for calculating cpu state percentages */
 
@@ -206,6 +207,22 @@
     NULL
 };
 
+/* these are names given to allowed sorting orders -- first is default */
+char *ordernames[] = 
+{"cpu", "size", "res", "time", NULL};
+
+/* forward definitions for comparison functions */
+int compare_cpu();
+int compare_size();
+int compare_res();
+int compare_time();
+
+int (*proc_compares[])() = {
+    compare_cpu,
+    compare_size,
+    compare_res,
+    compare_time,
+    NULL };
 
 /* these are for keeping track of the proc array */
 
@@ -311,6 +328,7 @@
     statics->cpustate_names = cpustatenames;
     statics->memory_names = memorynames;
     statics->swap_names = swapnames;
+    statics->order_names = ordernames;
 
     /* all done! */
     return(0);
@@ -321,13 +339,12 @@
 register char *uname_field;
 
 {
-    register char *ptr;
     static char Header[128];
 
     snprintf(Header, sizeof(Header), smpmode ? smp_header : up_header,
 	     namelength, namelength, uname_field);
 
     cmdlength = 80 - strlen(Header) + 6;
 
     return Header;
 }
@@ -691,20 +708,37 @@
     }
     return(1);
 }
-    
-/* 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
- *  	that reflects this ordering.
+ * 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 (dresult = pctdouble(PP(p2, p_pctcpu)) - pctdouble(PP(p1, p_pctcpu)),\
+			     (result = dresult > 0.0 ? 1 : dresult < 0.0 ? -1 : 0) == 0)
+#define ORDERKEY_CPTICKS if ((result = PP(p2, p_runtime) - PP(p1, p_runtime)) == 0)
+#define ORDERKEY_STATE   if ((result = (long) (sorted_state[(unsigned char)PP(p2, p_stat)] - \
+			       sorted_state[(unsigned char)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 */
+
 static unsigned char sorted_state[] =
 {
     0,	/* not used		*/
@@ -716,8 +750,10 @@
     4	/* stop			*/
 };
  
+/* compare_cpu - the comparison function for sorting by cpu percentage */
+
 int
-proc_compare(pp1, pp2)
+compare_cpu(pp1, pp2)
 
 struct proc **pp1;
 struct proc **pp2;
@@ -726,39 +762,106 @@
     register struct kinfo_proc *p1;
     register struct kinfo_proc *p2;
     register int result;
-    register pctcpu lresult;
+    double dresult;
 
     /* 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 lifetime CPU usage to break the tie */
-	if ((result = PP(p2, p_runtime) - PP(p1, p_runtime)) == 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_PCTCPU
+    ORDERKEY_CPTICKS
+    ORDERKEY_STATE
+    ORDERKEY_PRIO
+    ORDERKEY_RSSIZE
+    ORDERKEY_MEM
+    ;
+
+    return(result);
+}
+
+/* compare_size - the comparison function for sorting by total memory usage */
+
+int
+compare_size(pp1, pp2)
+
+struct proc **pp1;
+struct proc **pp2;
+
+{
+    register struct kinfo_proc *p1;
+    register struct kinfo_proc *p2;
+    register int result;
+    double dresult;
+
+    /* 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_res - the comparison function for sorting by resident set size */
+
+int
+compare_res(pp1, pp2)
+
+struct proc **pp1;
+struct proc **pp2;
+
+{
+    register struct kinfo_proc *p1;
+    register struct kinfo_proc *p2;
+    register int result;
+    double dresult;
+
+    /* 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_time - the comparison function for sorting by total cpu time */
+
+int
+compare_time(pp1, pp2)
+
+struct proc **pp1;
+struct proc **pp2;
+
+{
+    register struct kinfo_proc *p1;
+    register struct kinfo_proc *p2;
+    register int result;
+    double dresult;
+
+    /* 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);
 }

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?87n2byso9r.fsf>