diff options
Diffstat (limited to 'libgomp/parallel.c')
-rw-r--r-- | libgomp/parallel.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/libgomp/parallel.c b/libgomp/parallel.c index 803e8b7..c7a8c788 100644 --- a/libgomp/parallel.c +++ b/libgomp/parallel.c @@ -123,7 +123,8 @@ void GOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads) { num_threads = gomp_resolve_num_threads (num_threads, 0); - gomp_team_start (fn, data, num_threads, 0, gomp_new_team (num_threads)); + gomp_team_start (fn, data, num_threads, 0, gomp_new_team (num_threads), + NULL); } void @@ -161,14 +162,33 @@ GOMP_parallel_end (void) ialias (GOMP_parallel_end) void -GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads, unsigned int flags) +GOMP_parallel (void (*fn) (void *), void *data, unsigned num_threads, + unsigned int flags) { num_threads = gomp_resolve_num_threads (num_threads, 0); - gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads)); + gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads), + NULL); fn (data); ialias_call (GOMP_parallel_end) (); } +unsigned +GOMP_parallel_reductions (void (*fn) (void *), void *data, + unsigned num_threads, unsigned int flags) +{ + struct gomp_taskgroup *taskgroup; + num_threads = gomp_resolve_num_threads (num_threads, 0); + uintptr_t *rdata = *(uintptr_t **)data; + taskgroup = gomp_parallel_reduction_register (rdata, num_threads); + gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads), + taskgroup); + fn (data); + ialias_call (GOMP_parallel_end) (); + gomp_sem_destroy (&taskgroup->taskgroup_sem); + free (taskgroup); + return num_threads; +} + bool GOMP_cancellation_point (int which) { @@ -185,8 +205,15 @@ GOMP_cancellation_point (int which) } else if (which & GOMP_CANCEL_TASKGROUP) { - if (thr->task->taskgroup && thr->task->taskgroup->cancelled) - return true; + if (thr->task->taskgroup) + { + if (thr->task->taskgroup->cancelled) + return true; + if (thr->task->taskgroup->workshare + && thr->task->taskgroup->prev + && thr->task->taskgroup->prev->cancelled) + return true; + } /* FALLTHRU into the GOMP_CANCEL_PARALLEL case, as #pragma omp cancel parallel also cancels all explicit tasks. */ @@ -218,11 +245,17 @@ GOMP_cancel (int which, bool do_cancel) } else if (which & GOMP_CANCEL_TASKGROUP) { - if (thr->task->taskgroup && !thr->task->taskgroup->cancelled) + if (thr->task->taskgroup) { - gomp_mutex_lock (&team->task_lock); - thr->task->taskgroup->cancelled = true; - gomp_mutex_unlock (&team->task_lock); + struct gomp_taskgroup *taskgroup = thr->task->taskgroup; + if (taskgroup->workshare && taskgroup->prev) + taskgroup = taskgroup->prev; + if (!taskgroup->cancelled) + { + gomp_mutex_lock (&team->task_lock); + taskgroup->cancelled = true; + gomp_mutex_unlock (&team->task_lock); + } } return true; } |