From ba56714719294ad7aa15a1351c201e642445e2ab Mon Sep 17 00:00:00 2001 From: Andrey Churbanov Date: Thu, 16 May 2019 17:52:53 +0000 Subject: Fixed second issue reported in https://bugs.llvm.org/show_bug.cgi?id=41584. Added synchronization for possible concurrent initialization of mutexes by multiple threads. The need of synchronization caused by commit r357927 which added the use of mutexes at threads movement to/from common pool (earlier the mutexes were used only at suspend/resume). Patch by Johnny Peyton. Differential Revision: https://reviews.llvm.org/D61995 git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@360919 91177308-0d34-0410-b5e6-96231b3b80d8 --- runtime/src/z_Windows_NT_util.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'runtime/src/z_Windows_NT_util.cpp') diff --git a/runtime/src/z_Windows_NT_util.cpp b/runtime/src/z_Windows_NT_util.cpp index 97d0e79..c503e9c 100644 --- a/runtime/src/z_Windows_NT_util.cpp +++ b/runtime/src/z_Windows_NT_util.cpp @@ -310,22 +310,32 @@ void __kmp_suspend_initialize(void) { /* do nothing */ } void __kmp_suspend_initialize_thread(kmp_info_t *th) { - if (!TCR_4(th->th.th_suspend_init)) { - /* this means we haven't initialized the suspension pthread objects for this - thread in this instance of the process */ + int old_value = KMP_ATOMIC_LD_RLX(&th->th.th_suspend_init); + int new_value = TRUE; + // Return if already initialized + if (old_value == new_value) + return; + // Wait, then return if being initialized + if (old_value == -1 || + !__kmp_atomic_compare_store(&th->th.th_suspend_init, old_value, -1)) { + while (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init) != new_value) { + KMP_CPU_PAUSE(); + } + } else { + // Claim to be the initializer and do initializations __kmp_win32_cond_init(&th->th.th_suspend_cv); __kmp_win32_mutex_init(&th->th.th_suspend_mx); - TCW_4(th->th.th_suspend_init, TRUE); + KMP_ATOMIC_ST_REL(&th->th.th_suspend_init, new_value); } } void __kmp_suspend_uninitialize_thread(kmp_info_t *th) { - if (TCR_4(th->th.th_suspend_init)) { + if (KMP_ATOMIC_LD_ACQ(&th->th.th_suspend_init)) { /* this means we have initialize the suspension pthread objects for this thread in this instance of the process */ __kmp_win32_cond_destroy(&th->th.th_suspend_cv); __kmp_win32_mutex_destroy(&th->th.th_suspend_mx); - TCW_4(th->th.th_suspend_init, FALSE); + KMP_ATOMIC_ST_REL(&th->th.th_suspend_init, FALSE); } } -- cgit v1.2.3