Hi Collin, Let me add some context. A few months ago mingw-w64 added support for POSIX macros _FILE_BITS and _TIME_BITS.
Some winpthreads' functions are using `struct timespec` but they were not handling _TIME_BITS macro. This could result in situations when winpthreads' functions would be compiled with 32-bit time_t but used with 64-bit time_t (with _TIME_BITS=64). This would produce incorrect results. I wrote _TIME_BITS handling for winpthreads. We added explicit 32-bit and 64-bit versions for functions which use `struct timespec` (e.g. nonosleep32 and nanosleep64), previously there was only external nanosleep. In order to avoid breaking existing binaries, we still provide external nanosleep. Keep in mind that while winpthreads is part of mingw runtime, it can be built and used with MSVC. With gcc/clang we could simply use inline assembly to rename the symbols, but this would not work with MSVC. The remaining options were to define macros like ``` #if _TIME_BITS == 64 #define nanosleep nanosleep64 #else #define nanosleep nanosleep32 #endif ``` or using inline wrappers which call explicitly sized version. I choose the latter. You may notice WINPTHREAD_NANOSLEEP_DECL macro in declaration of nanosleep and other functions. When building the library, it defines nanosleep as external function. When header files used by the client code, it defines it as (static, in C) inline wrapper. Since winpthreads' header files define nanosleep as inline function, it prevents gnulib from overriding it. I would like to fix this in winpthreads, I'm just not sure how this can be achieved taking MSVC into account. - Kirill Makurin ________________________________ From: [email protected] <[email protected]> on behalf of Jeffrey Walton <[email protected]> Sent: Sunday, November 16, 2025 12:42 PM To: Collin Funk <[email protected]> Cc: [email protected] <[email protected]>; [email protected] <[email protected]>; Bruno Haible <[email protected]> Subject: Re: nanosleep: Avoid a redefinition on MinGW. On Sat, Nov 15, 2025 at 10:22 PM Collin Funk <[email protected]> wrote: > > Using the reproduction steps Tim shared [1], this patch fixes the > redeclaration on MinGW: > > depbase=`echo nanosleep.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\ > x86_64-w64-mingw32-gcc -DHAVE_CONFIG_H -I. -I.. > -DGNULIB_STRICT_CHECKING=1 -g -O2 -MT nanosleep.o -MD -MP -MF $depbase.Tpo > -c -o nanosleep.o nanosleep.c &&\ > mv -f $depbase.Tpo $depbase.Po > nanosleep.c:97:1: error: redefinition of 'nanosleep' > 97 | nanosleep (const struct timespec *requested_delay, > | ^~~~~~~~~ > In file included from /usr/share/mingw-w64/include/time.h:323, > from ./time.h:54, > from nanosleep.c:23: > /usr/share/mingw-w64/include/pthread_time.h:79:39: note: previous > definition of 'nanosleep' with type 'int(const struct timespec *, struct > timespec *)' > 79 | WINPTHREAD_NANOSLEEP_DECL int __cdecl nanosleep(const struct > timespec *request, struct timespec *remain) > | ^~~~~~~~~ > make[4]: *** [Makefile:2248: nanosleep.o] Error 1 > > I left the cross guess as "no" so the function gets replaced. This is > because MinGW does not use QueryPerformanceCounter, so I assume that > does not work as well for small durations [2]. QueryPerformanceCounter is not monotonically increasing in practice. Time can appear to run backwards if subsequent QueryPerformanceCounter is run on a different core. See <https://stackoverflow.com/questions/27419223/time-running-backwards-with-queryperformancecounter>. > I'm not sure if that is correct and/or if it should be documented. So I > will hold off pushing for review. > > [1] https://savannah.gnu.org/bugs/?67704 > [2] > https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-libraries/winpthreads/src/nanosleep.c Jeff
