summaryrefslogtreecommitdiffstats
path: root/openmp/runtime/src
diff options
context:
space:
mode:
authorJonas Hahnfeld <Hahnfeld@itc.rwth-aachen.de>2016-08-08 10:08:07 +0000
committerJonas Hahnfeld <Hahnfeld@itc.rwth-aachen.de>2016-08-08 10:08:07 +0000
commit69f8511f8f47c7fab6c8dda663d394b4176f93e5 (patch)
tree08edc65cf1a54fa59516140562f5809953bbbc6b /openmp/runtime/src
parentcae9aeed3934c1f97d8628732bcd58968fe52656 (diff)
downloadbcm5719-llvm-69f8511f8f47c7fab6c8dda663d394b4176f93e5.tar.gz
bcm5719-llvm-69f8511f8f47c7fab6c8dda663d394b4176f93e5.zip
__kmp_free_task: Fix for serial explicit tasks producing proxy tasks
Consider the following code which may be executed by a serial team: int dep; #pragma omp target nowait depend(out: dep) { sleep(1); } #pragma omp task depend(in: dep) { #pragma omp target nowait { sleep(1); } } Here the explicit task may not be freed until the nested proxy task has finished. The current code hasn't considered this and called __kmp_free_task anyway which triggered an assert because of remaining incomplete children: KMP_DEBUG_ASSERT( TCR_4(taskdata->td_incomplete_child_tasks) == 0 ); Differential Revision: https://reviews.llvm.org/D23115 llvm-svn: 277991
Diffstat (limited to 'openmp/runtime/src')
-rw-r--r--openmp/runtime/src/kmp_tasking.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/openmp/runtime/src/kmp_tasking.c b/openmp/runtime/src/kmp_tasking.c
index ce1b63d5cd9..ac9a25f3dde 100644
--- a/openmp/runtime/src/kmp_tasking.c
+++ b/openmp/runtime/src/kmp_tasking.c
@@ -576,15 +576,13 @@ __kmp_free_task( kmp_int32 gtid, kmp_taskdata_t * taskdata, kmp_info_t * thread
static void
__kmp_free_task_and_ancestors( kmp_int32 gtid, kmp_taskdata_t * taskdata, kmp_info_t * thread )
{
- kmp_int32 children = 0;
- kmp_int32 team_or_tasking_serialized = taskdata -> td_flags.team_serial || taskdata -> td_flags.tasking_ser;
-
+ // Proxy tasks must always be allowed to free their parents
+ // because they can be run in background even in serial mode.
+ kmp_int32 task_serial = taskdata->td_flags.task_serial && !taskdata->td_flags.proxy;
KMP_DEBUG_ASSERT( taskdata -> td_flags.tasktype == TASK_EXPLICIT );
- if ( !team_or_tasking_serialized ) {
- children = KMP_TEST_THEN_DEC32( (kmp_int32 *)(& taskdata -> td_allocated_child_tasks) ) - 1;
- KMP_DEBUG_ASSERT( children >= 0 );
- }
+ kmp_int32 children = KMP_TEST_THEN_DEC32( (kmp_int32 *)(& taskdata -> td_allocated_child_tasks) ) - 1;
+ KMP_DEBUG_ASSERT( children >= 0 );
// Now, go up the ancestor tree to see if any ancestors can now be freed.
while ( children == 0 )
@@ -599,16 +597,14 @@ __kmp_free_task_and_ancestors( kmp_int32 gtid, kmp_taskdata_t * taskdata, kmp_in
taskdata = parent_taskdata;
- // Stop checking ancestors at implicit task or if tasking serialized
+ // Stop checking ancestors at implicit task
// instead of walking up ancestor tree to avoid premature deallocation of ancestors.
- if ( team_or_tasking_serialized || taskdata -> td_flags.tasktype == TASK_IMPLICIT )
+ if ( task_serial || taskdata -> td_flags.tasktype == TASK_IMPLICIT )
return;
- if ( !team_or_tasking_serialized ) {
- // Predecrement simulated by "- 1" calculation
- children = KMP_TEST_THEN_DEC32( (kmp_int32 *)(& taskdata -> td_allocated_child_tasks) ) - 1;
- KMP_DEBUG_ASSERT( children >= 0 );
- }
+ // Predecrement simulated by "- 1" calculation
+ children = KMP_TEST_THEN_DEC32( (kmp_int32 *)(& taskdata -> td_allocated_child_tasks) ) - 1;
+ KMP_DEBUG_ASSERT( children >= 0 );
}
KA_TRACE(20, ("__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "
OpenPOWER on IntegriCloud