From owner-freebsd-current Sun May 31 07:13:58 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id HAA26525 for freebsd-current-outgoing; Sun, 31 May 1998 07:13:58 -0700 (PDT) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from sanewo.ba2.so-net.ne.jp (root@p84b44a.sng2.ap.so-net.ne.jp [210.132.180.74]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id HAA26518 for ; Sun, 31 May 1998 07:13:44 -0700 (PDT) (envelope-from sanewo@ba2.so-net.ne.jp) Received: (from sanewo@localhost) by sanewo.ba2.so-net.ne.jp (8.8.8/8.7.3) id TAA02504; Sun, 31 May 1998 19:55:29 +0900 (JST) To: current@FreeBSD.ORG Subject: Re: top -osize References: <19980528211849.A10559@rtfm.net> <19980528212002.A11468@emsphone.com> From: Takanori Saneto In-Reply-To: Dan Nelson's message of "Thu, 28 May 1998 21:20:02 -0500" X-Emacs: Emacs 20.2, MULE 3.0 (MOMIJINOGA) MIME-Version: 1.0 (generated by SEMI 1.4.5 - "Tomari") Content-Type: text/plain; charset=ISO-2022-JP Date: 31 May 1998 19:55:28 +0900 Message-ID: <87n2byso9r.fsf@sanewo.ba2.so-net.ne.jp> Lines: 295 X-Mailer: Semi-gnus 6.3.1 (based on Gnus 5.6.9; for SEMI 1.4) Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG In article <19980528212002.A11468@emsphone.com>, Dan Nelson 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. -- さねを 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 * Steven Wallace * Wolfram Schneider @@ -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