diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2019-02-28 15:13:19 +0100 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2019-02-28 15:13:19 +0100 |
commit | 76a9cb772b6d8e98dc2fc8ef1ea197e0851e1037 (patch) | |
tree | d7a4705ad9fe9c6589b99cb8900b385f86e5ce31 | |
parent | 90232fa641692f1bf8ba100af00714f448cc7527 (diff) | |
download | newlib-github/fp-zeuch.zip newlib-github/fp-zeuch.tar.gz newlib-github/fp-zeuch.tar.bz2 |
Cygwin: initialize FP environment for each applicaiton threadgithub/fp-zeuchfp-zeuch
Also, initialize FP environment in timerfd thread before calling
RegisterClassW to avoid a spurious STATUS_FLOAT_INEXACT_RESULT
from msvcrt.dll.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/fenv.cc | 22 | ||||
-rw-r--r-- | winsup/cygwin/include/fenv.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/miscfuncs.cc | 3 | ||||
-rw-r--r-- | winsup/cygwin/timerfd.cc | 13 |
5 files changed, 22 insertions, 20 deletions
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 11edcdf..bc7eeb4 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -1079,7 +1079,7 @@ _dll_crt0 () fork_info->alloc_stack (); #endif - _feinitialise (); + _feinitialise (true); _main_tls = &_my_tls; _main_tls->call ((DWORD (*) (void *, void *)) dll_crt0_1, NULL); } diff --git a/winsup/cygwin/fenv.cc b/winsup/cygwin/fenv.cc index 396f98a..a2c8359 100644 --- a/winsup/cygwin/fenv.cc +++ b/winsup/cygwin/fenv.cc @@ -420,7 +420,7 @@ fesetprec (int prec) /* Set up the FPU and SSE environment at the start of execution. */ void -_feinitialise (void) +_feinitialise (bool pre_main) { unsigned int edx, eax; @@ -442,14 +442,18 @@ _feinitialise (void) if (use_sse) __asm__ volatile ("ldmxcsr %0" :: "m" (mxcsr)); - /* Setup unmasked environment, but leave __FE_DENORM masked. */ - feenableexcept (FE_ALL_EXCEPT); - fegetenv (&fe_nomask_env); + if (pre_main) + { + /* Setup unmasked environment, but leave __FE_DENORM masked. */ + feenableexcept (FE_ALL_EXCEPT); + fegetenv (&fe_nomask_env); - /* Restore default exception masking (all masked). */ - fedisableexcept (FE_ALL_EXCEPT); + /* Restore default exception masking (all masked). */ + fedisableexcept (FE_ALL_EXCEPT); - /* Finally cache state as default environment. */ - fegetenv (&fe_dfl_env); + /* Finally cache state as default environment. */ + fegetenv (&fe_dfl_env); + } + else + fedisableexcept (FE_ALL_EXCEPT); } - diff --git a/winsup/cygwin/include/fenv.h b/winsup/cygwin/include/fenv.h index a355c47..3c9b538 100644 --- a/winsup/cygwin/include/fenv.h +++ b/winsup/cygwin/include/fenv.h @@ -168,7 +168,7 @@ extern int fesetprec (int __prec); #ifdef __INSIDE_CYGWIN__ /* This is Cygwin-custom, not from the standard, for use in the Cygwin CRT. */ -extern void _feinitialise (); +extern void _feinitialise (bool); #endif #ifdef __cplusplus diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index b5dfffc..ed32a50 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -16,6 +16,7 @@ details. */ #include "fhandler.h" #include "exception.h" #include "tls_pbuf.h" +#include "fenv.h" int __reg2 check_invalid_virtual_addr (const void *s, unsigned sz) @@ -397,6 +398,8 @@ pthread_wrapper (PVOID arg) wrapper_arg.guardsize -= wincap.page_size (); SetThreadStackGuarantee (&wrapper_arg.guardsize); } + /* FP initialization. */ + _feinitialise (false); /* Initialize new _cygtls. */ _my_tls.init_thread (wrapper_arg.stackbase - CYGTLS_PADSIZE, (DWORD (*)(void*, void*)) wrapper_arg.func); diff --git a/winsup/cygwin/timerfd.cc b/winsup/cygwin/timerfd.cc index 8e4c94e..c4faf30 100644 --- a/winsup/cygwin/timerfd.cc +++ b/winsup/cygwin/timerfd.cc @@ -15,6 +15,7 @@ details. */ #include "cygerrno.h" #include <sys/timerfd.h> #include "timerfd.h" +#include "fenv.h" #define TFD_CANCEL_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET) @@ -32,15 +33,9 @@ timerfd_tracker::create_timechange_window () wclass.lpfnWndProc = DefWindowProcW; wclass.hInstance = user_data->hmodule; wclass.lpszClassName = cname; - /* This sleep is required on Windows 10 64 bit only, and only when running - under strace. One of the child processes inheriting the timerfd - descriptor will get a STATUS_FLOAT_INEXACT_RESULT exception inside of - msvcrt.dll. While this is completely crazy in itself, it's apparently - some timing problem. It occurs in 4 out of 5 runs under strace only. - The sleep is required before calling RegisterClassW. Moving it before - CreateWindowExW does not work. What the heck? */ - if (being_debugged ()) - Sleep (1L); + /* Avoid a potential STATUS_FLOAT_INEXACT_RESULT in msvcrt.dll. + Only observed on x86_64 W10 under strace. */ + _feinitialise (false); atom = RegisterClassW (&wclass); if (!atom) debug_printf ("RegisterClass %E"); |