diff options
Diffstat (limited to 'libgomp/sections.c')
-rw-r--r-- | libgomp/sections.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/libgomp/sections.c b/libgomp/sections.c index 65b53b4..3449e00 100644 --- a/libgomp/sections.c +++ b/libgomp/sections.c @@ -26,8 +26,11 @@ /* This file handles the SECTIONS construct. */ #include "libgomp.h" +#include <string.h> +ialias_redirect (GOMP_taskgroup_reduction_register) + /* Initialize the given work share construct from the given arguments. */ static inline void @@ -72,7 +75,7 @@ GOMP_sections_start (unsigned count) struct gomp_thread *thr = gomp_thread (); long s, e, ret; - if (gomp_work_share_start (false)) + if (gomp_work_share_start (0)) { gomp_sections_init (thr->ts.work_share, count); gomp_work_share_init_done (); @@ -95,6 +98,66 @@ GOMP_sections_start (unsigned count) return ret; } +unsigned +GOMP_sections2_start (unsigned count, uintptr_t *reductions, void **mem) +{ + struct gomp_thread *thr = gomp_thread (); + long s, e, ret; + + if (reductions) + gomp_workshare_taskgroup_start (); + if (gomp_work_share_start (0)) + { + gomp_sections_init (thr->ts.work_share, count); + if (reductions) + { + GOMP_taskgroup_reduction_register (reductions); + thr->task->taskgroup->workshare = true; + thr->ts.work_share->task_reductions = reductions; + } + if (mem) + { + uintptr_t size = (uintptr_t) *mem; + if (size > (sizeof (struct gomp_work_share) + - offsetof (struct gomp_work_share, + inline_ordered_team_ids))) + thr->ts.work_share->ordered_team_ids + = gomp_malloc_cleared (size); + else + memset (thr->ts.work_share->ordered_team_ids, '\0', size); + *mem = (void *) thr->ts.work_share->ordered_team_ids; + } + gomp_work_share_init_done (); + } + else + { + if (reductions) + { + uintptr_t *first_reductions = thr->ts.work_share->task_reductions; + gomp_workshare_task_reduction_register (reductions, + first_reductions); + } + if (mem) + *mem = (void *) thr->ts.work_share->ordered_team_ids; + } + +#ifdef HAVE_SYNC_BUILTINS + if (gomp_iter_dynamic_next (&s, &e)) + ret = s; + else + ret = 0; +#else + gomp_mutex_lock (&thr->ts.work_share->lock); + if (gomp_iter_dynamic_next_locked (&s, &e)) + ret = s; + else + ret = 0; + gomp_mutex_unlock (&thr->ts.work_share->lock); +#endif + + return ret; +} + /* This routine is called when the thread completes processing of the section currently assigned to it. If the work-share construct is bound directly to a parallel construct, then the construct may have @@ -140,7 +203,7 @@ GOMP_parallel_sections_start (void (*fn) (void *), void *data, num_threads = gomp_resolve_num_threads (num_threads, count); team = gomp_new_team (num_threads); gomp_sections_init (&team->work_shares[0], count); - gomp_team_start (fn, data, num_threads, 0, team); + gomp_team_start (fn, data, num_threads, 0, team, NULL); } ialias_redirect (GOMP_parallel_end) @@ -154,7 +217,7 @@ GOMP_parallel_sections (void (*fn) (void *), void *data, num_threads = gomp_resolve_num_threads (num_threads, count); team = gomp_new_team (num_threads); gomp_sections_init (&team->work_shares[0], count); - gomp_team_start (fn, data, num_threads, flags, team); + gomp_team_start (fn, data, num_threads, flags, team, NULL); fn (data); GOMP_parallel_end (); } |