Skip to content

Commit 3f5dfc2

Browse files
committedNov 9, 2015
Fixes to wait-loop code
1) Add get_ptr_type() method to all wait flag types. 2) Flag in sleep_loc may change type by the time the resume is called from __kmp_null_resume_wrapper. We use get_ptr_type to obtain the real type and compare it to the casted object received. If they don't match, we know the flag has changed (already resumed and replaced by another flag). If they match, it doesn't hurt to go ahead and resume it. Differential Revision: http://reviews.llvm.org/D14458 llvm-svn: 252487
1 parent b0b83c8 commit 3f5dfc2

File tree

4 files changed

+10
-4
lines changed

4 files changed

+10
-4
lines changed
 

‎openmp/runtime/src/kmp_tasking.c

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ static void __kmp_bottom_half_finish_proxy( kmp_int32 gtid, kmp_task_t * ptask )
3939

4040
static inline void __kmp_null_resume_wrapper(int gtid, volatile void *flag) {
4141
if (!flag) return;
42+
// Attempt to wake up a thread: examine its type and call appropriate template
4243
switch (((kmp_flag_64 *)flag)->get_type()) {
4344
case flag32: __kmp_resume_32(gtid, NULL); break;
4445
case flag64: __kmp_resume_64(gtid, NULL); break;

‎openmp/runtime/src/kmp_wait_release.h

+3
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ class kmp_flag_32 : public kmp_basic_flag<kmp_uint32> {
438438
USE_ITT_BUILD_ARG(itt_sync_obj));
439439
}
440440
void release() { __kmp_release_template(this); }
441+
flag_type get_ptr_type() { return flag32; }
441442
};
442443

443444
class kmp_flag_64 : public kmp_basic_flag<kmp_uint64> {
@@ -458,6 +459,7 @@ class kmp_flag_64 : public kmp_basic_flag<kmp_uint64> {
458459
USE_ITT_BUILD_ARG(itt_sync_obj));
459460
}
460461
void release() { __kmp_release_template(this); }
462+
flag_type get_ptr_type() { return flag64; }
461463
};
462464

463465
// Hierarchical 64-bit on-core barrier instantiation
@@ -551,6 +553,7 @@ class kmp_flag_oncore : public kmp_flag<kmp_uint64> {
551553
}
552554
kmp_uint8 *get_stolen() { return NULL; }
553555
enum barrier_type get_bt() { return bt; }
556+
flag_type get_ptr_type() { return flag_oncore; }
554557
};
555558

556559

‎openmp/runtime/src/z_Linux_util.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -1837,11 +1837,12 @@ static inline void __kmp_resume_template( int target_gtid, C *flag )
18371837
status = pthread_mutex_lock( &th->th.th_suspend_mx.m_mutex );
18381838
KMP_CHECK_SYSFAIL( "pthread_mutex_lock", status );
18391839

1840-
if (!flag) {
1840+
if (!flag) { // coming from __kmp_null_resume_wrapper
18411841
flag = (C *)th->th.th_sleep_loc;
18421842
}
18431843

1844-
if (!flag) {
1844+
// First, check if the flag is null or its type has changed. If so, someone else woke it up.
1845+
if (!flag || flag->get_type() != flag->get_ptr_type()) { // get_ptr_type simply shows what flag was cast to
18451846
KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag(%p)\n",
18461847
gtid, target_gtid, NULL ) );
18471848
status = pthread_mutex_unlock( &th->th.th_suspend_mx.m_mutex );

‎openmp/runtime/src/z_Windows_NT_util.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -455,11 +455,12 @@ static inline void __kmp_resume_template( int target_gtid, C *flag )
455455
__kmp_suspend_initialize_thread( th );
456456
__kmp_win32_mutex_lock( &th->th.th_suspend_mx );
457457

458-
if (!flag) {
458+
if (!flag) { // coming from __kmp_null_resume_wrapper
459459
flag = (C *)th->th.th_sleep_loc;
460460
}
461461

462-
if (!flag) {
462+
// First, check if the flag is null or its type has changed. If so, someone else woke it up.
463+
if (!flag || flag->get_type() != flag->get_ptr_type()) { // get_ptr_type simply shows what flag was cast to
463464
KF_TRACE( 5, ( "__kmp_resume_template: T#%d exiting, thread T#%d already awake: flag's loc(%p)\n",
464465
gtid, target_gtid, NULL ) );
465466
__kmp_win32_mutex_unlock( &th->th.th_suspend_mx );

0 commit comments

Comments
 (0)
Please sign in to comment.