From 437a4b1b5f34de15273d8b339cafe39528c28b0a Mon Sep 17 00:00:00 2001 From: "Mark A. Grondona" Date: Fri, 4 Aug 2017 15:24:36 -0700 Subject: [PATCH] modules/cron: avoid rounding in timespec_to_double Avoid implicit rounding in timespec_to_double in both cron.c and task.c. For the cron task timestamps, rename the local function round_timespec_to_double() to be honest about what we're doing, and expand the comment to explain why. For other cron timestamps, just drop the rounding for now. If it an inconvenience in the future (unlikely), the rounding can be copied from task.c as an example. Resolves #1131 --- src/modules/cron/cron.c | 9 +-------- src/modules/cron/task.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/modules/cron/cron.c b/src/modules/cron/cron.c index 7622da2e3e89..977c200cb0cb 100644 --- a/src/modules/cron/cron.c +++ b/src/modules/cron/cron.c @@ -85,18 +85,11 @@ void *cron_entry_type_data (cron_entry_t *e) return e->data; } -static double timespec_to_double (struct timespec *tm) -{ - double s = tm->tv_sec; - double ns = tm->tv_nsec/1.0e9 + .5e-9; // round 1/2 epsilon - return (s + ns); -} - double get_timestamp (void) { struct timespec tm; clock_gettime (CLOCK_REALTIME, &tm); - return timespec_to_double (&tm); + return ((double) tm.tv_sec + (tm.tv_nsec/1.0e9)); } static void timeout_cb (flux_t *h, cron_task_t *t, void *arg) diff --git a/src/modules/cron/task.c b/src/modules/cron/task.c index 4b034bf81fa4..3dbc731f0949 100644 --- a/src/modules/cron/task.c +++ b/src/modules/cron/task.c @@ -447,10 +447,15 @@ int cron_task_status (cron_task_t *t) return (t->status); } -static double timespec_to_double (struct timespec *tm) +static double round_timespec_to_double (struct timespec *tm) { double s = tm->tv_sec; - double ns = tm->tv_nsec/1.0e9 + .5e-9; // round 1/2 epsilon + /* Add .5ns (1/2 the minumim possible value change) to avoid + * underflow which represents something like .5 as .499999... + * (we don't care about overflow since we'll truncate fractional + * part to 9 significant digits *at the most* anyway) + */ + double ns = tm->tv_nsec/1.0e9 + .5e-9; return (s + ns); } @@ -480,7 +485,7 @@ static const char * cron_task_state_string (cron_task_t *t) */ static int add_timespec (json_t *o, const char *name, struct timespec *tm) { - json_t *n = json_real (timespec_to_double (tm)); + json_t *n = json_real (round_timespec_to_double (tm)); if (n == NULL) return -1; return json_object_set_new (o, name, n);