aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2019-02-28 15:13:19 +0100
committerCorinna Vinschen <corinna@vinschen.de>2019-02-28 15:13:19 +0100
commit76a9cb772b6d8e98dc2fc8ef1ea197e0851e1037 (patch)
treed7a4705ad9fe9c6589b99cb8900b385f86e5ce31
parent90232fa641692f1bf8ba100af00714f448cc7527 (diff)
downloadnewlib-fp-zeuch.zip
newlib-fp-zeuch.tar.gz
newlib-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.cc2
-rw-r--r--winsup/cygwin/fenv.cc22
-rw-r--r--winsup/cygwin/include/fenv.h2
-rw-r--r--winsup/cygwin/miscfuncs.cc3
-rw-r--r--winsup/cygwin/timerfd.cc13
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");