summaryrefslogtreecommitdiffstats
path: root/linux/LinuxProcess.c
diff options
context:
space:
mode:
authorExplorer09 <explorer09@gmail.com>2023-07-29 16:24:12 +0800
committerBenBE <BenBE@geshi.org>2023-08-18 12:52:28 +0200
commitb416433fbe7ccf935ad4e268396aa423143c2318 (patch)
tree55a38c76f4f0091ed6b06d7369706bd2f1f6f61e /linux/LinuxProcess.c
parentc6fd64fce8502a4e557711abe9fee394763ac52c (diff)
Replace isnan() with better comparisons (isgreater(), etc.)
The standard isnan() function is defined to never throw FP exceptions even when the argument is a "signaling" NaN. This makes isnan() more expensive than (x != x) expression unless the compiler flag '-fno-signaling-nans' is given. Introduce functions isNaN(), isNonnegative(), isPositive(), sumPositiveValues() and compareRealNumbers(), and replace isnan() in htop's codebase with the new functions. These functions utilize isgreater() and isgreaterequal() comparisons, which do not throw FP exceptions on "quiet" NaNs, which htop uses extensively. With isnan() removed, there is no need to suppress the warning '-Wno-c11-extensions' in FreeBSD. Remove the code from 'configure.ac'. Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Diffstat (limited to 'linux/LinuxProcess.c')
-rw-r--r--linux/LinuxProcess.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c
index b815c5b5..0a88644c 100644
--- a/linux/LinuxProcess.c
+++ b/linux/LinuxProcess.c
@@ -192,6 +192,19 @@ bool LinuxProcess_changeAutogroupPriorityBy(Process* this, Arg delta) {
return success;
}
+static double LinuxProcess_totalIORate(const LinuxProcess* lp) {
+ double totalRate = NAN;
+ if (isNonnegative(lp->io_rate_read_bps)) {
+ totalRate = lp->io_rate_read_bps;
+ if (isNonnegative(lp->io_rate_write_bps)) {
+ totalRate += lp->io_rate_write_bps;
+ }
+ } else if (isNonnegative(lp->io_rate_write_bps)) {
+ totalRate = lp->io_rate_write_bps;
+ }
+ return totalRate;
+}
+
static void LinuxProcess_writeField(const Process* this, RichString* str, ProcessField field) {
const LinuxProcess* lp = (const LinuxProcess*) this;
const LinuxMachine* lhost = (const LinuxMachine*) this->host;
@@ -230,19 +243,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
case CNCLWB: Process_printBytes(str, lp->io_cancelled_write_bytes, coloring); return;
case IO_READ_RATE: Process_printRate(str, lp->io_rate_read_bps, coloring); return;
case IO_WRITE_RATE: Process_printRate(str, lp->io_rate_write_bps, coloring); return;
- case IO_RATE: {
- double totalRate;
- if (!isnan(lp->io_rate_read_bps) && !isnan(lp->io_rate_write_bps))
- totalRate = lp->io_rate_read_bps + lp->io_rate_write_bps;
- else if (!isnan(lp->io_rate_read_bps))
- totalRate = lp->io_rate_read_bps;
- else if (!isnan(lp->io_rate_write_bps))
- totalRate = lp->io_rate_write_bps;
- else
- totalRate = NAN;
- Process_printRate(str, totalRate, coloring);
- return;
- }
+ case IO_RATE: Process_printRate(str, LinuxProcess_totalIORate(lp), coloring); return;
#ifdef HAVE_OPENVZ
case CTID: xSnprintf(buffer, n, "%-8s ", lp->ctid ? lp->ctid : ""); break;
case VPID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, lp->vpid); break;
@@ -309,11 +310,14 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
RichString_appendAscii(str, attr, buffer);
}
-static double adjustNaN(double num) {
- if (isnan(num))
- return -0.0005;
-
- return num;
+/* Compares floating point values for ordering data entries. In this function,
+ NaN is considered "less than" any other floating point value (regardless of
+ sign), and two NaNs are considered "equal" regardless of payload. */
+static int compareRealNumbers(double a, double b) {
+ int result = isgreater(a, b) - isgreater(b, a);
+ if (result)
+ return result;
+ return !isNaN(a) - !isNaN(b);
}
static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) {
@@ -358,11 +362,11 @@ static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, Proce
case CNCLWB:
return SPACESHIP_NUMBER(p1->io_cancelled_write_bytes, p2->io_cancelled_write_bytes);
case IO_READ_RATE:
- return SPACESHIP_NUMBER(adjustNaN(p1->io_rate_read_bps), adjustNaN(p2->io_rate_read_bps));
+ return compareRealNumbers(p1->io_rate_read_bps, p2->io_rate_read_bps);
case IO_WRITE_RATE:
- return SPACESHIP_NUMBER(adjustNaN(p1->io_rate_write_bps), adjustNaN(p2->io_rate_write_bps));
+ return compareRealNumbers(p1->io_rate_write_bps, p2->io_rate_write_bps);
case IO_RATE:
- return SPACESHIP_NUMBER(adjustNaN(p1->io_rate_read_bps) + adjustNaN(p1->io_rate_write_bps), adjustNaN(p2->io_rate_read_bps) + adjustNaN(p2->io_rate_write_bps));
+ return compareRealNumbers(LinuxProcess_totalIORate(p1), LinuxProcess_totalIORate(p2));
#ifdef HAVE_OPENVZ
case CTID:
return SPACESHIP_NULLSTR(p1->ctid, p2->ctid);

© 2014-2024 Faster IT GmbH | imprint | privacy policy