public inbox for cygwin-cvs@sourceware.org
help / color / mirror / Atom feed
* [newlib-cygwin/fp-zeuch] Cygwin: initialize FP environment for each applicaiton thread
@ 2019-02-28 14:14 Corinna Vinschen
  0 siblings, 0 replies; only message in thread
From: Corinna Vinschen @ 2019-02-28 14:14 UTC (permalink / raw)
  To: cygwin-cvs

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=76a9cb772b6d8e98dc2fc8ef1ea197e0851e1037

commit 76a9cb772b6d8e98dc2fc8ef1ea197e0851e1037
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Thu Feb 28 15:13:19 2019 +0100

    Cygwin: initialize FP environment for each applicaiton thread
    
    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>

Diff:
---
 winsup/cygwin/dcrt0.cc       |  2 +-
 winsup/cygwin/fenv.cc        | 22 +++++++++++++---------
 winsup/cygwin/include/fenv.h |  2 +-
 winsup/cygwin/miscfuncs.cc   |  3 +++
 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");


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-02-28 14:14 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-28 14:14 [newlib-cygwin/fp-zeuch] Cygwin: initialize FP environment for each applicaiton thread Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).