Sometimes I want to see certain programs with least amount of memory,
so this diff implements `o -field' to sort in reverse order.
The logic is straight forward:
1. merge common code from argument and command loops into new setorder()
2. introduce global state `rev_order' (set in the helper)
3. move identical code to set up process objects from compare_*()
functions into SETORDER macro using global boolean
compare_*() are used by qsort(3). To sort in reverse, the macro simply
swaps the objects used by the ORDERKEY_* macros. That is it inverts the
comparison from `p1 > p2' into `p2 > p1' respectively `p1 < p2'.
Works fine for all available fields on amd64, no behaviour change for
"normal" order.
Feedback? Objections?
Index: display.c
===
RCS file: /cvs/src/usr.bin/top/display.c,v
retrieving revision 1.57
diff -u -p -r1.57 display.c
--- display.c 17 Nov 2018 23:10:08 - 1.57
+++ display.c 24 Nov 2018 14:09:38 -
@@ -817,7 +817,8 @@ show_help(void)
"I | i- toggle the display of idle processes\n"
"k [-sig] pid - send signal `-sig' to process `pid'\n"
"n|# count- show `count' processes\n"
- "o field - specify sort order (size, res, cpu, time, pri, pid,
command)\n"
+ "o [-]field - specify sort order (size, res, cpu, time, pri, pid,
command)\n"
+ " (o -field sorts in reverse)\n"
"P pid- highlight process `pid' (P+ switches highlighting
off)\n"
"p pid- display process by `pid' (p+ selects all
processes)\n"
"q- quit\n"
Index: machine.c
===
RCS file: /cvs/src/usr.bin/top/machine.c,v
retrieving revision 1.95
diff -u -p -r1.95 machine.c
--- machine.c 17 Nov 2018 23:10:08 - 1.95
+++ machine.c 24 Nov 2018 14:47:32 -
@@ -602,6 +602,8 @@ static unsigned char sorted_state[] =
1 /* zombie*/
};
+extern int rev_order;
+
/*
* proc_compares - comparison functions for "qsort"
*/
@@ -631,6 +633,17 @@ static unsigned char sorted_state[] =
#define ORDERKEY_CMD \
if ((result = strcmp(p1->p_comm, p2->p_comm)) == 0)
+/* remove one level of indirection and set sort order */
+#define SETORDER do { \
+ if (rev_order) { \
+ p1 = *(struct kinfo_proc **) pp2; \
+ p2 = *(struct kinfo_proc **) pp1; \
+ } else { \
+ p1 = *(struct kinfo_proc **) pp1; \
+ p2 = *(struct kinfo_proc **) pp2; \
+ } \
+ } while (0)
+
/* compare_cpu - the comparison function for sorting by cpu percentage */
static int
compare_cpu(const void *v1, const void *v2)
@@ -640,9 +653,7 @@ compare_cpu(const void *v1, const void *
struct kinfo_proc *p1, *p2;
int result;
- /* remove one level of indirection */
- p1 = *(struct kinfo_proc **) pp1;
- p2 = *(struct kinfo_proc **) pp2;
+ SETORDER;
ORDERKEY_PCTCPU
ORDERKEY_CPUTIME
@@ -663,9 +674,7 @@ compare_size(const void *v1, const void
struct kinfo_proc *p1, *p2;
int result;
- /* remove one level of indirection */
- p1 = *(struct kinfo_proc **) pp1;
- p2 = *(struct kinfo_proc **) pp2;
+ SETORDER;
ORDERKEY_MEM
ORDERKEY_RSSIZE
@@ -686,9 +695,7 @@ compare_res(const void *v1, const void *
struct kinfo_proc *p1, *p2;
int result;
- /* remove one level of indirection */
- p1 = *(struct kinfo_proc **) pp1;
- p2 = *(struct kinfo_proc **) pp2;
+ SETORDER;
ORDERKEY_RSSIZE
ORDERKEY_MEM
@@ -709,9 +716,7 @@ compare_time(const void *v1, const void
struct kinfo_proc *p1, *p2;
int result;
- /* remove one level of indirection */
- p1 = *(struct kinfo_proc **) pp1;
- p2 = *(struct kinfo_proc **) pp2;
+ SETORDER;
ORDERKEY_CPUTIME
ORDERKEY_PCTCPU
@@ -732,9 +737,7 @@ compare_prio(const void *v1, const void
struct kinfo_proc *p1, *p2;
int result;
- /* remove one level of indirection */
- p1 = *(struct kinfo_proc **) pp1;
- p2 = *(struct kinfo_proc **) pp2;
+ SETORDER;
ORDERKEY_PRIO
ORDERKEY_PCTCPU
@@ -754,9 +757,7 @@ compare_pid(const void *v1, const void *
struct kinfo_proc *p1, *p2;
int result;
- /* remove one level of indirection */
- p1 = *(struct kinfo_proc **) pp1;
- p2 = *(struct kinfo_proc **) pp2;
+ SETORDER;
ORDERKEY_PID
ORDERKEY_PCTCPU
@@ -777,9 +778,7 @@ compare_cmd(const void *v1, const void *
struct kinfo_proc *p1, *p2;
int result;
- /* remove one level of indirection */
- p1 = *(struct kinfo_proc **) pp1;
- p2 =