From 7cc9de9929630fd74c055c66d9da1c3d29e54d05 Mon Sep 17 00:00:00 2001
From: Moe Jette <jette1@llnl.gov>
Date: Wed, 30 Mar 2011 15:32:50 +0000
Subject: [PATCH] Replace comparision of qos_ptr->usage_thres == X with
 fizzy_equal(qos_ptr->usage_thres, X). This deals with imprecision in storage
 for a double, especially with respect to un/pack across machine
 architectures.

---
 src/common/assoc_mgr.c                                      | 2 +-
 src/common/macros.h                                         | 6 ++++++
 .../accounting_storage/mysql/accounting_storage_mysql.h     | 1 +
 src/plugins/accounting_storage/mysql/as_mysql_qos.c         | 4 ++--
 src/slurmctld/job_mgr.c                                     | 2 +-
 src/slurmctld/node_scheduler.c                              | 2 +-
 6 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/common/assoc_mgr.c b/src/common/assoc_mgr.c
index 58eb7b7b55d..f127f2e826c 100644
--- a/src/common/assoc_mgr.c
+++ b/src/common/assoc_mgr.c
@@ -2950,7 +2950,7 @@ extern int assoc_mgr_update_qos(slurmdb_update_object_t *update)
 				rec->usage_factor =
 					object->usage_factor;
 
-			if (object->usage_thres != (double)NO_VAL)
+			if (!fuzzy_equal(object->usage_thres, NO_VAL))
 				rec->usage_thres = object->usage_thres;
 
 			if (update_jobs && update_qos_notify) {
diff --git a/src/common/macros.h b/src/common/macros.h
index 8d392dc6da8..e6e13c0ce64 100644
--- a/src/common/macros.h
+++ b/src/common/macros.h
@@ -265,4 +265,10 @@ typedef enum {false, true} bool;
 #  define strndup(src,size) strdup(src)
 #endif
 
+/* There are places where we put NO_VAL or INFINITE into a float or double
+ * Use fuzzy_equal below to test for those values rather than an comparision
+ * which could fail due to rounding errors. */
+#define FUZZY_EPSILON 0.00001
+#define fuzzy_equal(v1, v2) ((((v1)-(v2)) > -FUZZY_EPSILON) && (((v1)-(v2)) < FUZZY_EPSILON))
+
 #endif /* !_MACROS_H */
diff --git a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.h b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.h
index 7fa0340a590..09019c8724f 100644
--- a/src/plugins/accounting_storage/mysql/accounting_storage_mysql.h
+++ b/src/plugins/accounting_storage/mysql/accounting_storage_mysql.h
@@ -60,6 +60,7 @@
 #define	debug5			slurm_debug5
 
 #include "src/common/assoc_mgr.h"
+#include "src/common/macros.h"
 #include "src/common/slurmdbd_defs.h"
 #include "src/common/slurm_auth.h"
 #include "src/common/uid.h"
diff --git a/src/plugins/accounting_storage/mysql/as_mysql_qos.c b/src/plugins/accounting_storage/mysql/as_mysql_qos.c
index 330846c5b4b..9e05a57caba 100644
--- a/src/plugins/accounting_storage/mysql/as_mysql_qos.c
+++ b/src/plugins/accounting_storage/mysql/as_mysql_qos.c
@@ -362,11 +362,11 @@ static int _setup_qos_limits(slurmdb_qos_rec_t *qos,
 		xstrfmtcat(*extra, ", usage_factor=%f", qos->usage_factor);
 	}
 
-	if (qos->usage_thres == (double)INFINITE) {
+	if (fuzzy_equal(qos->usage_thres, INFINITE)) {
 		xstrcat(*cols, ", usage_thres");
 		xstrcat(*vals, ", NULL");
 		xstrcat(*extra, ", usage_thres=NULL");
-	} else if ((qos->usage_thres != (double)NO_VAL)
+	} else if (!fuzzy_equal(qos->usage_thres, NO_VAL)
 		   && (qos->usage_thres >= 0)) {
 		xstrcat(*cols, ", usage_thres");
 		xstrfmtcat(*vals, ", %f", qos->usage_thres);
diff --git a/src/slurmctld/job_mgr.c b/src/slurmctld/job_mgr.c
index 6319de8ac8e..eb9f9c7d4fa 100644
--- a/src/slurmctld/job_mgr.c
+++ b/src/slurmctld/job_mgr.c
@@ -3839,7 +3839,7 @@ static int _job_create(job_desc_msg_t * job_desc, int allocate, int will_run,
 		fail_reason = WAIT_PART_TIME_LIMIT;
 	} else if (qos_ptr && assoc_ptr &&
 		   (qos_ptr->flags & QOS_FLAG_ENFORCE_USAGE_THRES) &&
-		   (qos_ptr->usage_thres != (double)NO_VAL)) {
+		   (!fuzzy_equal(qos_ptr->usage_thres, NO_VAL))) {
 		if (!job_ptr->prio_factors)
 			job_ptr->prio_factors =
 				xmalloc(sizeof(priority_factors_object_t));
diff --git a/src/slurmctld/node_scheduler.c b/src/slurmctld/node_scheduler.c
index ca12566b8a8..0ff26bf7081 100644
--- a/src/slurmctld/node_scheduler.c
+++ b/src/slurmctld/node_scheduler.c
@@ -1175,7 +1175,7 @@ extern int select_nodes(struct job_record *job_ptr, bool test_only,
 		fail_reason = WAIT_PART_NODE_LIMIT;
 	else if (qos_ptr && assoc_ptr &&
 		 (qos_ptr->flags & QOS_FLAG_ENFORCE_USAGE_THRES) &&
-		 (qos_ptr->usage_thres != (double)NO_VAL)) {
+		 (!fuzzy_equal(qos_ptr->usage_thres, NO_VAL))) {
 		if (!job_ptr->prio_factors)
 			job_ptr->prio_factors =
 				xmalloc(sizeof(priority_factors_object_t));
-- 
GitLab