Index: openmp/trunk/runtime/src/kmp_tasking.c =================================================================== --- openmp/trunk/runtime/src/kmp_tasking.c +++ openmp/trunk/runtime/src/kmp_tasking.c @@ -39,6 +39,7 @@ 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; Index: openmp/trunk/runtime/src/kmp_wait_release.h =================================================================== --- openmp/trunk/runtime/src/kmp_wait_release.h +++ openmp/trunk/runtime/src/kmp_wait_release.h @@ -438,6 +438,7 @@ 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 @@ 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 @@ } kmp_uint8 *get_stolen() { return NULL; } enum barrier_type get_bt() { return bt; } + flag_type get_ptr_type() { return flag_oncore; } }; Index: openmp/trunk/runtime/src/z_Linux_util.c =================================================================== --- openmp/trunk/runtime/src/z_Linux_util.c +++ openmp/trunk/runtime/src/z_Linux_util.c @@ -1837,11 +1837,12 @@ 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 ); Index: openmp/trunk/runtime/src/z_Windows_NT_util.c =================================================================== --- openmp/trunk/runtime/src/z_Windows_NT_util.c +++ openmp/trunk/runtime/src/z_Windows_NT_util.c @@ -455,11 +455,12 @@ __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 );