From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 85779 invoked by alias); 28 Feb 2019 14:14:08 -0000 Mailing-List: contact cygwin-cvs-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cygwin-cvs-owner@cygwin.com Received: (qmail 84340 invoked by uid 9078); 28 Feb 2019 14:14:07 -0000 Date: Thu, 28 Feb 2019 14:14:00 -0000 Message-ID: <20190228141407.84336.qmail@sourceware.org> Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/fp-zeuch] Cygwin: initialize FP environment for each applicaiton thread X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/fp-zeuch X-Git-Oldrev: 90232fa641692f1bf8ba100af00714f448cc7527 X-Git-Newrev: 76a9cb772b6d8e98dc2fc8ef1ea197e0851e1037 X-SW-Source: 2019-q1/txt/msg00199.txt.bz2 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=76a9cb772b6d8e98dc2fc8ef1ea197e0851e1037 commit 76a9cb772b6d8e98dc2fc8ef1ea197e0851e1037 Author: Corinna Vinschen 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 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 #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");