summaryrefslogtreecommitdiffstats
path: root/bin/ps
diff options
context:
space:
mode:
authorgad <gad@FreeBSD.org>2004-03-30 01:45:23 +0000
committergad <gad@FreeBSD.org>2004-03-30 01:45:23 +0000
commitec3d9baab51d4d8f816833f1bb99e83f5494939c (patch)
treef7f749f18392113e82728db8618c65bc862e8a34 /bin/ps
parent235cde4aca9550787d8ee19043ccf8472f4843ff (diff)
downloadFreeBSD-src-ec3d9baab51d4d8f816833f1bb99e83f5494939c.zip
FreeBSD-src-ec3d9baab51d4d8f816833f1bb99e83f5494939c.tar.gz
Replace pscomp() with a cleaner version, mostly written by bde (*).
This corrects a problem of lost-precision for `-r' (sort-by-CPU). Also, for sort-by-CPU and sort-by-memory, any processes which have the same value CPU or MEMORY are now sorted by TTY and then (if needed) by pid. (* - I just added the NODEV checks, after doing some testing of my own) Submitted by: bde MFC after: 1 week
Diffstat (limited to 'bin/ps')
-rw-r--r--bin/ps/ps.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/bin/ps/ps.c b/bin/ps/ps.c
index 183c0fe..7db9dce 100644
--- a/bin/ps/ps.c
+++ b/bin/ps/ps.c
@@ -1024,20 +1024,49 @@ saveuser(KINFO *ki)
static int
pscomp(const void *a, const void *b)
{
- int i;
-#define VSIZE(k) ((k)->ki_p->ki_dsize + (k)->ki_p->ki_ssize + \
- (k)->ki_p->ki_tsize)
-
- if (sortby == SORTCPU)
- return (getpcpu((const KINFO *)b) - getpcpu((const KINFO *)a));
- if (sortby == SORTMEM)
- return (VSIZE((const KINFO *)b) - VSIZE((const KINFO *)a));
- i = (int)((const KINFO *)a)->ki_p->ki_tdev -
- (int)((const KINFO *)b)->ki_p->ki_tdev;
- if (i == 0)
- i = ((const KINFO *)a)->ki_p->ki_pid -
- ((const KINFO *)b)->ki_p->ki_pid;
- return (i);
+ const KINFO *ka, *kb;
+ double cpua, cpub;
+ segsz_t sizea, sizeb;
+
+ ka = a;
+ kb = b;
+ /* SORTCPU and SORTMEM are sorted in descending order. */
+ if (sortby == SORTCPU) {
+ cpua = getpcpu(ka);
+ cpub = getpcpu(kb);
+ if (cpua < cpub)
+ return (1);
+ if (cpua > cpub)
+ return (-1);
+ }
+ if (sortby == SORTMEM) {
+ sizea = ka->ki_p->ki_tsize + ka->ki_p->ki_dsize +
+ ka->ki_p->ki_ssize;
+ sizeb = kb->ki_p->ki_tsize + kb->ki_p->ki_dsize +
+ kb->ki_p->ki_ssize;
+ if (sizea < sizeb)
+ return (1);
+ if (sizea > sizeb)
+ return (-1);
+ }
+ /*
+ * TTY's are sorted in ascending order, except that all NODEV
+ * processes come before all processes with a device.
+ */
+ if (ka->ki_p->ki_tdev == NODEV && kb->ki_p->ki_tdev != NODEV)
+ return (-1);
+ if (ka->ki_p->ki_tdev != NODEV && kb->ki_p->ki_tdev == NODEV)
+ return (1);
+ if (ka->ki_p->ki_tdev < kb->ki_p->ki_tdev)
+ return (-1);
+ if (ka->ki_p->ki_tdev > kb->ki_p->ki_tdev)
+ return (1);
+ /* PID's are sorted in ascending order. */
+ if (ka->ki_p->ki_pid < kb->ki_p->ki_pid)
+ return (-1);
+ if (ka->ki_p->ki_pid > kb->ki_p->ki_pid)
+ return (1);
+ return (0);
}
/*
OpenPOWER on IntegriCloud