[Openmp-commits] [openmp] r294214 - Fix a race in shutdown when tasking is used.
Andrey Churbanov via Openmp-commits
openmp-commits at lists.llvm.org
Mon Feb 6 10:53:32 PST 2017
Author: achurbanov
Date: Mon Feb 6 12:53:32 2017
New Revision: 294214
URL: http://llvm.org/viewvc/llvm-project?rev=294214&view=rev
Log:
Fix a race in shutdown when tasking is used.
Patch by Terry Wilmarth.
Differential Revision: https://reviews.llvm.org/D28377
Modified:
openmp/trunk/runtime/src/kmp.h
openmp/trunk/runtime/src/kmp_runtime.cpp
openmp/trunk/runtime/src/kmp_tasking.cpp
openmp/trunk/runtime/src/kmp_wait_release.h
Modified: openmp/trunk/runtime/src/kmp.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp.h?rev=294214&r1=294213&r2=294214&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp.h (original)
+++ openmp/trunk/runtime/src/kmp.h Mon Feb 6 12:53:32 2017
@@ -1625,6 +1625,9 @@ typedef struct kmp_disp {
#define KMP_BARRIER_SWITCH_TO_OWN_FLAG 3 // Special state; tells worker to shift from parent to own b_go
#define KMP_BARRIER_SWITCHING 4 // Special state; worker resets appropriate flag on wake-up
+#define KMP_NOT_SAFE_TO_REAP 0 // Thread th_reap_state: not safe to reap (tasking)
+#define KMP_SAFE_TO_REAP 1 // Thread th_reap_state: safe to reap (not tasking)
+
enum barrier_type {
bs_plain_barrier = 0, /* 0, All non-fork/join barriers (except reduction barriers if enabled) */
bs_forkjoin_barrier, /* 1, All fork/join (parallel region) barriers */
@@ -2301,6 +2304,8 @@ typedef struct KMP_ALIGN_CACHE kmp_base_
kmp_uint8 * th_task_state_memo_stack; // Stack holding memos of th_task_state at nested levels
kmp_uint32 th_task_state_top; // Top element of th_task_state_memo_stack
kmp_uint32 th_task_state_stack_sz; // Size of th_task_state_memo_stack
+ kmp_uint32 th_reap_state; // Non-zero indicates thread is not
+ // tasking, thus safe to reap
/*
* More stuff for keeping track of active/sleeping threads
Modified: openmp/trunk/runtime/src/kmp_runtime.cpp
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_runtime.cpp?rev=294214&r1=294213&r2=294214&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_runtime.cpp (original)
+++ openmp/trunk/runtime/src/kmp_runtime.cpp Mon Feb 6 12:53:32 2017
@@ -4004,6 +4004,12 @@ __kmp_initialize_info( kmp_info_t *this_
this_thr->th.th_info.ds.ds_tid = tid;
this_thr->th.th_set_nproc = 0;
+ if (__kmp_tasking_mode != tskm_immediate_exec)
+ // When tasking is possible, threads are not safe to reap until they are
+ // done tasking; this will be set when tasking code is exited in wait
+ this_thr->th.th_reap_state = KMP_NOT_SAFE_TO_REAP;
+ else // no tasking --> always safe to reap
+ this_thr->th.th_reap_state = KMP_SAFE_TO_REAP;
#if OMP_40_ENABLED
this_thr->th.th_set_proc_bind = proc_bind_default;
# if KMP_AFFINITY_SUPPORTED
@@ -5255,7 +5261,25 @@ __kmp_free_team( kmp_root_t *root, kmp_t
/* if we are non-hot team, release our threads */
if( ! use_hot_team ) {
- if ( __kmp_tasking_mode != tskm_immediate_exec ) {
+ if (__kmp_tasking_mode != tskm_immediate_exec) {
+ // Wait for threads to reach reapable state
+ for (f = 1; f < team->t.t_nproc; ++f) {
+ KMP_DEBUG_ASSERT(team->t.t_threads[f]);
+ volatile kmp_uint32 *state = &team->t.t_threads[f]->th.th_reap_state;
+ while (*state != KMP_SAFE_TO_REAP) {
+#if KMP_OS_WINDOWS
+ // On Windows a thread can be killed at any time, check this
+ DWORD ecode;
+ if (__kmp_is_thread_alive(team->t.t_threads[f], &ecode))
+ KMP_CPU_PAUSE();
+ else
+ *state = KMP_SAFE_TO_REAP; // reset the flag for dead thread
+#else
+ KMP_CPU_PAUSE();
+#endif
+ }
+ }
+
// Delete task teams
int tt_idx;
for (tt_idx=0; tt_idx<2; ++tt_idx) {
@@ -5841,6 +5865,7 @@ __kmp_internal_end(void)
kmp_info_t * thread = (kmp_info_t *) __kmp_thread_pool;
__kmp_thread_pool = thread->th.th_next_pool;
// Reap it.
+ KMP_DEBUG_ASSERT(thread->th.th_reap_state == KMP_SAFE_TO_REAP);
thread->th.th_next_pool = NULL;
thread->th.th_in_pool = FALSE;
__kmp_reap_thread( thread, 0 );
Modified: openmp/trunk/runtime/src/kmp_tasking.cpp
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_tasking.cpp?rev=294214&r1=294213&r2=294214&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_tasking.cpp (original)
+++ openmp/trunk/runtime/src/kmp_tasking.cpp Mon Feb 6 12:53:32 2017
@@ -1884,6 +1884,7 @@ static inline int __kmp_execute_tasks_te
KA_TRACE(15, ("__kmp_execute_tasks_template(enter): T#%d final_spin=%d *thread_finished=%d\n",
gtid, final_spin, *thread_finished) );
+ thread->th.th_reap_state = KMP_NOT_SAFE_TO_REAP;
threads_data = (kmp_thread_data_t *)TCR_PTR(task_team -> tt.tt_threads_data);
KMP_DEBUG_ASSERT( threads_data != NULL );
Modified: openmp/trunk/runtime/src/kmp_wait_release.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_wait_release.h?rev=294214&r1=294213&r2=294214&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_wait_release.h (original)
+++ openmp/trunk/runtime/src/kmp_wait_release.h Mon Feb 6 12:53:32 2017
@@ -196,11 +196,16 @@ __kmp_wait_template(kmp_info_t *this_thr
if (KMP_TASKING_ENABLED(task_team))
flag->execute_tasks(this_thr, th_gtid, final_spin, &tasks_completed
USE_ITT_BUILD_ARG(itt_sync_obj), 0);
+ else
+ this_thr->th.th_reap_state = KMP_SAFE_TO_REAP;
}
else {
KMP_DEBUG_ASSERT(!KMP_MASTER_TID(this_thr->th.th_info.ds.ds_tid));
this_thr->th.th_task_team = NULL;
+ this_thr->th.th_reap_state = KMP_SAFE_TO_REAP;
}
+ } else {
+ this_thr->th.th_reap_state = KMP_SAFE_TO_REAP;
} // if
} // if
@@ -273,6 +278,10 @@ __kmp_wait_template(kmp_info_t *this_thr
__kmp_abort_thread();
break;
}
+ else if (__kmp_tasking_mode != tskm_immediate_exec
+ && this_thr->th.th_reap_state == KMP_SAFE_TO_REAP) {
+ this_thr->th.th_reap_state = KMP_NOT_SAFE_TO_REAP;
+ }
// TODO: If thread is done with work and times out, disband/free
}
More information about the Openmp-commits
mailing list