Skip to content

Commit

Permalink
Compare all percentage fields with compareRealNumbers()
Browse files Browse the repository at this point in the history
The SPACESHIP_NUMBER() macro does not work well with floating point
values that are possible to be NaNs. Change the compare logic of all
percentage fields of Process entries to use compareRealNumbers().

Signed-off-by: Kang-Che Sung <[email protected]>
  • Loading branch information
Explorer09 committed Aug 16, 2023
1 parent 1673b5a commit 7958197
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ int Process_compareByKey_Base(const Process* p1, const Process* p2, ProcessField
switch (key) {
case PERCENT_CPU:
case PERCENT_NORM_CPU:
return SPACESHIP_NUMBER(p1->percent_cpu, p2->percent_cpu);
return compareRealNumbers(p1->percent_cpu, p2->percent_cpu);
case PERCENT_MEM:
return SPACESHIP_NUMBER(p1->m_resident, p2->m_resident);
case COMM:
Expand Down
11 changes: 11 additions & 0 deletions XUtils.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ in the source distribution for its full text.
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
Expand Down Expand Up @@ -339,6 +340,16 @@ ssize_t full_write(int fd, const void* buf, size_t count) {
return written;
}

/* 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. */
int compareRealNumbers(double a, double b) {
int result = isgreater(a, b) - isgreater(b, a);
if (result)
return result;
return !isNaN(a) - !isNaN(b);
}

/* Computes the sum of all positive floating point values in an array.
NaN values in the array are skipped. The returned sum will always be
nonnegative. */
Expand Down
5 changes: 5 additions & 0 deletions XUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ ssize_t xReadfileat(openat_arg_t dirfd, const char* pathname, void* buffer, size
ATTR_ACCESS3_R(2, 3)
ssize_t full_write(int fd, const void* buf, size_t count);

/* 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. */
int compareRealNumbers(double a, double b);

/* Computes the sum of all positive floating point values in an array.
NaN values in the array are skipped. The returned sum will always be
nonnegative. */
Expand Down
16 changes: 3 additions & 13 deletions linux/LinuxProcess.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,6 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
RichString_appendAscii(str, attr, buffer);
}

/* 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) {
const LinuxProcess* p1 = (const LinuxProcess*)v1;
const LinuxProcess* p2 = (const LinuxProcess*)v2;
Expand Down Expand Up @@ -385,11 +375,11 @@ static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, Proce
return SPACESHIP_NUMBER(p1->oom, p2->oom);
#ifdef HAVE_DELAYACCT
case PERCENT_CPU_DELAY:
return SPACESHIP_NUMBER(p1->cpu_delay_percent, p2->cpu_delay_percent);
return compareRealNumbers(p1->cpu_delay_percent, p2->cpu_delay_percent);
case PERCENT_IO_DELAY:
return SPACESHIP_NUMBER(p1->blkio_delay_percent, p2->blkio_delay_percent);
return compareRealNumbers(p1->blkio_delay_percent, p2->blkio_delay_percent);
case PERCENT_SWAP_DELAY:
return SPACESHIP_NUMBER(p1->swapin_delay_percent, p2->swapin_delay_percent);
return compareRealNumbers(p1->swapin_delay_percent, p2->swapin_delay_percent);
#endif
case IO_PRIORITY:
return SPACESHIP_NUMBER(LinuxProcess_effectiveIOPriority(p1), LinuxProcess_effectiveIOPriority(p2));
Expand Down
4 changes: 2 additions & 2 deletions pcp/PCPDynamicColumn.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,9 @@ int PCPDynamicColumn_compareByKey(const PCPProcess* p1, const PCPProcess* p2, Pr
case PM_TYPE_U64:
return SPACESHIP_NUMBER(atom2.ull, atom1.ull);
case PM_TYPE_FLOAT:
return SPACESHIP_NUMBER(atom2.f, atom1.f);
return compareRealNumbers(atom2.f, atom1.f);
case PM_TYPE_DOUBLE:
return SPACESHIP_NUMBER(atom2.d, atom1.d);
return compareRealNumbers(atom2.d, atom1.d);
default:
break;
}
Expand Down
16 changes: 3 additions & 13 deletions pcp/PCPProcess.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,16 +199,6 @@ static void PCPProcess_writeField(const Process* this, RichString* str, ProcessF
RichString_appendWide(str, attr, buffer);
}

/* 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 PCPProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) {
const PCPProcess* p1 = (const PCPProcess*)v1;
const PCPProcess* p2 = (const PCPProcess*)v2;
Expand Down Expand Up @@ -263,11 +253,11 @@ static int PCPProcess_compareByKey(const Process* v1, const Process* v2, Process
case OOM:
return SPACESHIP_NUMBER(p1->oom, p2->oom);
case PERCENT_CPU_DELAY:
return SPACESHIP_NUMBER(p1->cpu_delay_percent, p2->cpu_delay_percent);
return compareRealNumbers(p1->cpu_delay_percent, p2->cpu_delay_percent);
case PERCENT_IO_DELAY:
return SPACESHIP_NUMBER(p1->blkio_delay_percent, p2->blkio_delay_percent);
return compareRealNumbers(p1->blkio_delay_percent, p2->blkio_delay_percent);
case PERCENT_SWAP_DELAY:
return SPACESHIP_NUMBER(p1->swapin_delay_percent, p2->swapin_delay_percent);
return compareRealNumbers(p1->swapin_delay_percent, p2->swapin_delay_percent);
case CTXT:
return SPACESHIP_NUMBER(p1->ctxt_diff, p2->ctxt_diff);
case SECATTR:
Expand Down

0 comments on commit 7958197

Please sign in to comment.