diff --git a/openmp/runtime/src/kmp_tasking.c b/openmp/runtime/src/kmp_tasking.c index 1334111bf96b..54664ff0dd27 100644 --- a/openmp/runtime/src/kmp_tasking.c +++ b/openmp/runtime/src/kmp_tasking.c @@ -39,6 +39,7 @@ static void __kmp_bottom_half_finish_proxy( kmp_int32 gtid, kmp_task_t * ptask ) static inline void __kmp_null_resume_wrapper(int gtid, volatile void *flag) { if (!flag) return; + // Attempt to wake up a thread: examine its type and call appropriate template switch (((kmp_flag_64 *)flag)->get_type()) { case flag32: __kmp_resume_32(gtid, NULL); break; case flag64: __kmp_resume_64(gtid, NULL); break; diff --git a/openmp/runtime/src/kmp_wait_release.h b/openmp/runtime/src/kmp_wait_release.h index 31beccd90a65..92db155eb5ac 100644 --- a/openmp/runtime/src/kmp_wait_release.h +++ b/openmp/runtime/src/kmp_wait_release.h @@ -438,6 +438,7 @@ class kmp_flag_32 : public kmp_basic_flag { USE_ITT_BUILD_ARG(itt_sync_obj)); } void release() { __kmp_release_template(this); } + flag_type get_ptr_type() { return flag32; } }; class kmp_flag_64 : public kmp_basic_flag { @@ -458,6 +459,7 @@ class kmp_flag_64 : public kmp_basic_flag { USE_ITT_BUILD_ARG(itt_sync_obj)); } void release() { __kmp_release_template(this); } + flag_type get_ptr_type() { return flag64; } }; // Hierarchical 64-bit on-core barrier instantiation @@ -551,6 +553,7 @@ public: } kmp_uint8 *get_stolen() { return NULL; } enum barrier_type get_bt() { return bt; } + flag_type get_ptr_type() { return flag_oncore; } }; diff --git a/openmp/runtime/src/z_Linux_util.c b/openmp/runtime/src/z_Linux_util.c index dd290936756f..890ec5cfaaf1 100644 --- a/openmp/runtime/src/z_Linux_util.c +++ b/openmp/runtime/src/z_Linux_util.c @@ -1837,11 +1837,12 @@ static inline void __kmp_resume_template( int target_gtid, C *flag ) status = pthread_mutex_lock( &th->th.th_suspend_mx.m_mutex ); KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status ); - if (!flag) { + if (!flag) { // coming from __kmp_null_resume_wrapper flag = (C *)th->th.th_sleep_loc; } - if (!flag) { + // First, check if the flag is null or its type has changed. If so, someone else woke it up. + if (!flag || flag->get_type() != flag->get_ptr_type()) { // get_ptr_type simply shows what flag was cast to KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag(%p)\n", gtid, target_gtid, NULL ) ); status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex ); diff --git a/openmp/runtime/src/z_Windows_NT_util.c b/openmp/runtime/src/z_Windows_NT_util.c index 61ed2ce897e2..db7965a562ae 100644 --- a/openmp/runtime/src/z_Windows_NT_util.c +++ b/openmp/runtime/src/z_Windows_NT_util.c @@ -455,11 +455,12 @@ static inline void __kmp_resume_template( int target_gtid, C *flag ) __kmp_suspend_initialize_thread( th ); __kmp_win32_mutex_lock( &th->th.th_suspend_mx ); - if (!flag) { + if (!flag) { // coming from __kmp_null_resume_wrapper flag = (C *)th->th.th_sleep_loc; } - if (!flag) { + // First, check if the flag is null or its type has changed. If so, someone else woke it up. + if (!flag || flag->get_type() != flag->get_ptr_type()) { // get_ptr_type simply shows what flag was cast to KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag's loc(%p)\n", gtid, target_gtid, NULL ) ); __kmp_win32_mutex_unlock( &th->th.th_suspend_mx );