Hi Arnd,
On Mon, Dec 01, 2025 at 08:45:00AM +0100, Arnd Bergmann wrote:
On Sun, Nov 30, 2025, at 11:58, Willy Tarreau wrote:
On Sat, Nov 22, 2025 at 05:59:15PM +0100, Thomas Weißschuh wrote:
struct timespec {
- __kernel_old_time_t tv_sec;
- long tv_nsec;
- time_t tv_sec;
- int64_t tv_nsec;
}; #define _STRUCT_TIMESPEC +/* Never use with system calls */ struct timeval {
- __kernel_old_time_t tv_sec;
- __kernel_suseconds_t tv_usec;
- time_t tv_sec;
- int64_t tv_usec;
};
It seems to me that glibc continues to make the effort of using a long for tv_usec and tv_nsec. At least I'm seeing how that can make a difference for application code given that these fields are constantly multiplied or divided, forcing them to 64-bit when we know they'll never be larger than 1 billion is extra burden for the application. Another reason might be that the definition really changed from long to suseconds_t in timeval a while ago, it's possible that it's used as a long in various APIs (or even just printf formats).
IMHO it would be cleaner to keep it as a long here, or do you have a particular reason for wanting int64_t (which BTW already forced a cast in sys_gettimeofday()) ?
As far as I can tell, it's the other way round for suseconds_t, which in glibc is defined as
#if __TIMESIZE == 64 && __WORDSIZE == 32 # define __TIME_T_TYPE __SQUAD_TYPE # define __SUSECONDS_T_TYPE __SQUAD_TYPE #else # define __TIME_T_TYPE __SLONGWORD_TYPE # define __SUSECONDS_T_TYPE __SLONGWORD_TYPE #endif
so this one is explicitly the same width as tv_sec, which has all the issues you listed, but avoids the need for padding.
Ah we seem to just have checked different versions then, as in mine there was still some extra padding left depending on the endianness :-)
As far as I remember, the one reason for having a 'long tv_nsec' with complex padding in glibc and musl is that this is actually required by both Unix[1] and C11/C11 [2] standards.
That's what I found as well and was my initial compatibility concern (e.g. referencing &tv->tv_nsec as a long).
C23 has updated the definition and does allow int64_t tv_nsec.
So it purposely breaks existing apps or does it apply only to those compiled with -mstd=c23 ?
I think it makes sense for nolibc to just follow the kernel's definition here.
Given the very narrow range of existing code that can be impacted, I'm fine, but in general I try to remain extremely cautious about portability: as a general rule, ifdefs needed to address possible incompatibilities, if any, should rather be in the libc code itself and not in the user application. I just ran a quick check and don't have code using &tv_usec nor &tv_nsec so here the risk remains quite low.
Thanks, Willy