From d35f6548e63e5deb4e9a7ac40f517fc10b1dc7b9 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 29 Jul 2017 17:00:23 +0000 Subject: Add inline functions to convert between sbintime_t and decimal time units. Use them in some existing code that is vulnerable to roundoff errors. The existing constant SBT_1NS is a honeypot, luring unsuspecting folks into writing code such as long_timeout_ns*SBT_1NS to generate the argument for a sleep call. The actual value of 1ns in sbt units is ~4.3, leading to a large roundoff error giving a shorter sleep than expected when multiplying by the trucated value of 4 in SBT_1NS. (The evil honeypot aspect becomes clear after you waste a whole day figuring out why your sleeps return early.) --- sys/dev/ow/owc_gpiobus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sys/dev/ow') diff --git a/sys/dev/ow/owc_gpiobus.c b/sys/dev/ow/owc_gpiobus.c index 779f2d0f6945..423dde811b9f 100644 --- a/sys/dev/ow/owc_gpiobus.c +++ b/sys/dev/ow/owc_gpiobus.c @@ -295,10 +295,10 @@ owc_gpiobus_read_data(device_t dev, struct ow_timing *t, int *bit) do { now = sbinuptime(); GETPIN(sc, &sample); - } while ((now - then) / SBT_1US < t->t_rdv + 2 && sample == 0); + } while (sbttous(now - then) < t->t_rdv + 2 && sample == 0); critical_exit(); - if ((now - then) / SBT_1NS < t->t_rdv * 1000) + if (sbttons(now - then) < t->t_rdv * 1000) *bit = 1; else *bit = 0; -- cgit v1.2.3