aboutsummaryrefslogtreecommitdiff
path: root/libgomp/work.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgomp/work.c')
-rw-r--r--libgomp/work.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/libgomp/work.c b/libgomp/work.c
index 5912427..9c5a327 100644
--- a/libgomp/work.c
+++ b/libgomp/work.c
@@ -221,7 +221,10 @@ gomp_work_share_end (void)
if (gomp_barrier_last_thread (bstate))
{
if (__builtin_expect (thr->ts.last_work_share != NULL, 1))
- free_work_share (team, thr->ts.last_work_share);
+ {
+ team->work_shares_to_free = thr->ts.work_share;
+ free_work_share (team, thr->ts.last_work_share);
+ }
}
gomp_team_barrier_wait_end (&team->barrier, bstate);
@@ -229,6 +232,32 @@ gomp_work_share_end (void)
}
/* The current thread is done with its current work sharing construct.
+ This version implies a cancellable barrier at the end of the work-share. */
+
+bool
+gomp_work_share_end_cancel (void)
+{
+ struct gomp_thread *thr = gomp_thread ();
+ struct gomp_team *team = thr->ts.team;
+ gomp_barrier_state_t bstate;
+
+ /* Cancellable work sharing constructs cannot be orphaned. */
+ bstate = gomp_barrier_wait_cancel_start (&team->barrier);
+
+ if (gomp_barrier_last_thread (bstate))
+ {
+ if (__builtin_expect (thr->ts.last_work_share != NULL, 1))
+ {
+ team->work_shares_to_free = thr->ts.work_share;
+ free_work_share (team, thr->ts.last_work_share);
+ }
+ }
+ thr->ts.last_work_share = NULL;
+
+ return gomp_team_barrier_wait_cancel_end (&team->barrier, bstate);
+}
+
+/* The current thread is done with its current work sharing construct.
This version does NOT imply a barrier at the end of the work-share. */
void
@@ -259,6 +288,9 @@ gomp_work_share_end_nowait (void)
#endif
if (completed == team->nthreads)
- free_work_share (team, thr->ts.last_work_share);
+ {
+ team->work_shares_to_free = thr->ts.work_share;
+ free_work_share (team, thr->ts.last_work_share);
+ }
thr->ts.last_work_share = NULL;
}