Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Nov 2018 03:19:46 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Eugene Grosbein <eugen@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r341006 - head/sys/netgraph
Message-ID:  <20181128023031.H1503@besplex.bde.org>
In-Reply-To: <201811270405.wAR45cmZ044829@repo.freebsd.org>
References:  <201811270405.wAR45cmZ044829@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 27 Nov 2018, Eugene Grosbein wrote:

> Log:
>  ng_source(4): correction after the change r340617
>
>  tv_usec has "long" type for all architecture in FreeBSD
>  and follows __LP64__. However, this is not true for tv_sec
>  that has "time_t" type.

tv_usec actually has type suseconds_t.  suseconds_t happens to be
long on all arches in FreeBSD (it is declared in an MI header without
any ifdef).  Hard-coding it as long here and elsewhere defeats the
reason for existence of suseconds_t.  The most common hard-coding of
it is probably using %ld format for printing it.

However, the existence of suseconds_t is a historical bug (in POSIX).
This bug was missing in POSIX Issue 4.  tv_usec just had type long
then.  POSIX added suseconds_t and hangecd the type of tv_usec to
suseconds_t in Issue 5, so now almost no one knows the type of tv_usec
and messy ifdefs like the one here (but messier) are needed to parse
and print it portably.  I think suseconds_t came from SysV or XSI.
BSD just used long before it was broken to POSIX spec.  Similar typedefs
and messy ifdefs are unfortunately needed for too many other POSIX
types, but tv_usec is too limited to need the complications.

This bug is still missing for tv_nsec.  I think timespecs were a POSIX
invention in 1988.  POSIX introduced them and intentionally left out
timevals designed timespecs a bit better than timevals since timevals
are too limited and unportable.  Unfortunately, many older APIs like
select() were never updated to the 1980's, so when POSIX started
supporting these in 2001 it had to standardize timevals, so now timevals
are ever further from going away than in 1988.

long for tv_usec and tv_nsec is a smaller historical bug.  BSD carefully
used long for too many integer types as late as 4.4BSD-Lite1, because
very old versions of BSD (2.x?) supported 16-bit ints, and 16-bits is
is often too small, and typedef poisoning wasn't very common in merely
old versions.  Also, support for ABIs was weak.  NetBSD changed many of
these longs to int or int32_t to support alpha and/or ABIs, and Lite2
obtained these changes from somewhere near NetBSD, and FreeBSD obtained
them from Lite2 in 1996.

E.g., pid_t went from long in Lite1 to int32_t in Lite2.  long was far
too large for pid_t and most other types if long is 64 bits or larger,
and using it in structs gives unnecessarily MD ABIs.  In modern POSIX,
int must be at least 32 bits so most types can be plain int, but
historical mistakes and ABIs prevent changing the excessively typedefed
APIs.

So on 64-bit arches, lots of space is wasted not just for 64-bit time_t,
but also for 64-bit longs for tv_[nu]sec.  32-bit tv_[nu]sec wouldn't
on 64-bit arches since the struct would be padded from 96 to 128 bits.
On 32-bit arches with 64-bit time_t, the longs give a natural struct
size of 96i bits, and this might be padded to 128 bits (wasting space),
or left unpadded (giving worse alignment).

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20181128023031.H1503>