aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/z_Windows_NT_util.cpp
diff options
context:
space:
mode:
authorAndrey Churbanov <Andrey.Churbanov@intel.com>2019-05-16 17:52:53 +0000
committerAndrey Churbanov <Andrey.Churbanov@intel.com>2019-05-16 17:52:53 +0000
commitba56714719294ad7aa15a1351c201e642445e2ab (patch)
treef41aa105ca07416199aa3f533efccb1792023ec0 /runtime/src/z_Windows_NT_util.cpp
parent9a0d0f00e90c4f9e0cbd281ab5578db28fafdfcb (diff)
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
Diffstat (limited to 'runtime/src/z_Windows_NT_util.cpp')
-rw-r--r--runtime/src/z_Windows_NT_util.cpp22
1 files changed, 16 insertions, 6 deletions
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);
}
}