Date: Thu, 8 May 2014 14:30:51 +1000 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Alan Somers <asomers@freebsd.org> Cc: "svn-src-head@freebsd.org" <svn-src-head@freebsd.org>, "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>, "src-committers@freebsd.org" <src-committers@freebsd.org>, Bruce Evans <brde@optusnet.com.au>, Jilles Tjoelker <jilles@stack.nl> Subject: Re: svn commit: r265472 - head/bin/dd Message-ID: <20140508133943.K1439@besplex.bde.org> In-Reply-To: <CAOtMX2jL=Zxk=WqAKJw%2BfF=HZCCc52fGxZ=JVZXkCoK8%2BJHwag@mail.gmail.com> References: <201405062206.s46M6dxW060155@svn.freebsd.org> <20140507113345.B923@besplex.bde.org> <CAOtMX2h_%2B1G18Nv5JvDE0H7_TZ96p81JotOwhq1Jm-dOOeahPw@mail.gmail.com> <20140507202623.GA14233@stack.nl> <CAOtMX2jL=Zxk=WqAKJw%2BfF=HZCCc52fGxZ=JVZXkCoK8%2BJHwag@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 7 May 2014, Alan Somers wrote: > On Wed, May 7, 2014 at 2:26 PM, Jilles Tjoelker <jilles@stack.nl> wrote: >> The floating point addition starts losing precision after 8388608 >> seconds (slightly more than 97 days, a plausible uptime for a server). >> It is better to subtract the timespecs to avoid this issue. >> >> With microseconds, the precision of a double is sufficient for 272 >> years, so that calculation is probably acceptable. > > Good point. I'll fix it. BTW, FreeBSD does not have a timespecsub, > but I notice that NetBSD does. This seems like a good candidate to > import. > > http://netbsd.gw.com/cgi-bin/man-cgi?timespecsub++NetBSD-current Hrmph. This was intentionally left out in FreeBSD. Floating point works better. Unfortunately, floating point is unavailable in kernels, or was too slow, especially in 1980, so APIs use the not so good timespec and timeval APIs. Not to mention bintimes, sbintimes and struct tm. sbintime or just nanoseconds would be better if floating point is unavailable. struct tm is too bloated to be good for syscalls although not bloated enough to support sub-second times. FreeBSD does have the corresponding design errors for timeval APIs: timeradd(), etc. These are even documented, but in a wrong way as prototypes. They are actually unsafe macros spelled as if they are safe. Some of them could be functions, but timercmp() must be a macro. Design errors in them start with their names (timer* instead of tv*). <sys/time.h> has rather complicated ifdefs to keep these APIs in or out of the kernel. It already has timespecsub(), but limits it to the kernel. The efficiency of these functions is unimportant, and some like timevalsub() are extern functions in the kernel. This helps give the complicated ifdefs and confusing namespaces: - bintime_sub() is kernel inline - bintime_sub() is user inline (undocumented pollution) - bintime_sub() uses an extra underscore - the good name btsub() is not used - timevalsub() is kernel extern - timersub() is user macro (otherBSD compatibility cruft) - the good name tvsub() is not used. timersub() is an especially bad name for an API that handles timevals. timevals were intentionally left out of old versions of POSIX. POSIX invented timespecs instead. The old APIs using timevals couldn't be killed so easily, and POSIX eventually had to standardize them. POSIX also standardized many new timespec APIs. Then, just when the timevals could be killed better, the unnecessary APIs for manipulating them were introduced, though not in POSIX. The non-kernel versions of them have a name that is particularly when there is more than 1 timer struct. - timespecsub() is kernel macro - timespecsub() as user API is intentionally left out - the good name tssub() is not used. Parameter names and orders for these APIs are also inconsistent and mostly bad. In the macro timersub(), the parameters are (tvp, uvp, vvp). You might thing tvp is the target, but it is one of the sources. In the man page "prototype", they are (a, b, res). Slightly better, but now missing a 'p'. But 'p' is not missing in the man page for timerset() or timerclear(). The ordering with the target last is an old convention. bintime functions mostly but not always go the other way. Floating point is easier to use than these functions, except for conversion from floating point back to a timespec or timeval. That takes about 2 statements instead of 1 function call. It's just a bit inelegant to go through floating point when you start with timespecs and have to convert back to timespecs. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140508133943.K1439>