summaryrefslogtreecommitdiffstats
path: root/openmp
diff options
context:
space:
mode:
authorJonathan Peyton <jonathan.l.peyton@intel.com>2015-11-09 16:31:51 +0000
committerJonathan Peyton <jonathan.l.peyton@intel.com>2015-11-09 16:31:51 +0000
commit3f5dfc256204b4f4825fbfbfc7c9f985f4e78422 (patch)
tree8c13565dbd9a8fde21497ec15dfc6341b2a25073 /openmp
parentb0b83c8b0cb020425fe5cfbc892d170cec696caa (diff)
downloadbcm5719-llvm-3f5dfc256204b4f4825fbfbfc7c9f985f4e78422.tar.gz
bcm5719-llvm-3f5dfc256204b4f4825fbfbfc7c9f985f4e78422.zip
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
Diffstat (limited to 'openmp')
-rw-r--r--openmp/runtime/src/kmp_tasking.c1
-rw-r--r--openmp/runtime/src/kmp_wait_release.h3
-rw-r--r--openmp/runtime/src/z_Linux_util.c5
-rw-r--r--openmp/runtime/src/z_Windows_NT_util.c5
4 files changed, 10 insertions, 4 deletions
diff --git a/openmp/runtime/src/kmp_tasking.c b/openmp/runtime/src/kmp_tasking.c
index 1334111bf96..54664ff0dd2 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 31beccd90a6..92db155eb5a 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<kmp_uint32> {
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<kmp_uint64> {
@@ -458,6 +459,7 @@ class kmp_flag_64 : public kmp_basic_flag<kmp_uint64> {
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 dd290936756..890ec5cfaaf 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 61ed2ce897e..db7965a562a 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 );
OpenPOWER on IntegriCloud