winpthreads: Call `_fpreset()` for new threads This is necessary for math functions taking `long double` arguments to work reliably, as by default, new threads have their x87 precision set to 53 bits. Note the x87 control word can't be set in the TLS callback. It gets overwritten before the thread procedure begins execution. There is NO workaround for the win32 thread model, other than requiring users to call `_fpreset()` themselves. Reference: https://sourceforge.net/p/mingw-w64/mailman/message/37084134/ Signed-off-by: Liu Hao <lh_mouse@126.com>
diff --git a/mingw-w64-libraries/winpthreads/src/thread.c b/mingw-w64-libraries/winpthreads/src/thread.c index 8afa90f..a9f286b 100644 --- a/mingw-w64-libraries/winpthreads/src/thread.c +++ b/mingw-w64-libraries/winpthreads/src/thread.c
@@ -1475,6 +1475,8 @@ return 0; } +void _fpreset (void); + #if defined(__i386__) /* Align ESP on 16-byte boundaries. */ # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2) @@ -1487,6 +1489,8 @@ unsigned rslt = 0; struct _pthread_v *tv = (struct _pthread_v *)args; + _fpreset(); + pthread_mutex_lock (&mtx_pthr_locked); pthread_mutex_lock (&tv->p_clock); _pthread_once_raw(&_pthread_tls_once, pthread_tls_init);