summaryrefslogtreecommitdiffstats
path: root/openmp/runtime/src/kmp_cancel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'openmp/runtime/src/kmp_cancel.cpp')
-rw-r--r--openmp/runtime/src/kmp_cancel.cpp404
1 files changed, 202 insertions, 202 deletions
diff --git a/openmp/runtime/src/kmp_cancel.cpp b/openmp/runtime/src/kmp_cancel.cpp
index 5416049b566..f680d1ac97c 100644
--- a/openmp/runtime/src/kmp_cancel.cpp
+++ b/openmp/runtime/src/kmp_cancel.cpp
@@ -22,76 +22,80 @@
@param gtid Global thread ID of encountering thread
@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
-@return returns true if the cancellation request has been activated and the execution thread
-needs to proceed to the end of the canceled region.
+@return returns true if the cancellation request has been activated and the
+execution thread needs to proceed to the end of the canceled region.
Request cancellation of the binding OpenMP region.
*/
-kmp_int32 __kmpc_cancel(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
- kmp_info_t *this_thr = __kmp_threads [ gtid ];
-
- KC_TRACE( 10, ("__kmpc_cancel: T#%d request %d OMP_CANCELLATION=%d\n", gtid, cncl_kind, __kmp_omp_cancellation) );
-
- KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
- KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
- cncl_kind == cancel_sections || cncl_kind == cancel_taskgroup);
- KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
-
- if (__kmp_omp_cancellation) {
- switch (cncl_kind) {
- case cancel_parallel:
- case cancel_loop:
- case cancel_sections:
- // cancellation requests for parallel and worksharing constructs
- // are handled through the team structure
- {
- kmp_team_t *this_team = this_thr->th.th_team;
- KMP_DEBUG_ASSERT(this_team);
- kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(&(this_team->t.t_cancel_request), cancel_noreq, cncl_kind);
- if (old == cancel_noreq || old == cncl_kind) {
- //printf("__kmpc_cancel: this_team->t.t_cancel_request=%d @ %p\n",
- // this_team->t.t_cancel_request, &(this_team->t.t_cancel_request));
- // we do not have a cancellation request in this team or we do have one
- // that matches the current request -> cancel
- return 1 /* true */;
- }
- break;
- }
- case cancel_taskgroup:
- // cancellation requests for a task group
- // are handled through the taskgroup structure
- {
- kmp_taskdata_t* task;
- kmp_taskgroup_t* taskgroup;
-
- task = this_thr->th.th_current_task;
- KMP_DEBUG_ASSERT( task );
-
- taskgroup = task->td_taskgroup;
- if (taskgroup) {
- kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(&(taskgroup->cancel_request), cancel_noreq, cncl_kind);
- if (old == cancel_noreq || old == cncl_kind) {
- // we do not have a cancellation request in this taskgroup or we do have one
- // that matches the current request -> cancel
- return 1 /* true */;
- }
- }
- else {
- // TODO: what needs to happen here?
- // the specification disallows cancellation w/o taskgroups
- // so we might do anything here, let's abort for now
- KMP_ASSERT( 0 /* false */);
- }
- }
- break;
- default:
- KMP_ASSERT (0 /* false */);
+kmp_int32 __kmpc_cancel(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
+ kmp_info_t *this_thr = __kmp_threads[gtid];
+
+ KC_TRACE(10, ("__kmpc_cancel: T#%d request %d OMP_CANCELLATION=%d\n", gtid,
+ cncl_kind, __kmp_omp_cancellation));
+
+ KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
+ KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
+ cncl_kind == cancel_sections ||
+ cncl_kind == cancel_taskgroup);
+ KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
+
+ if (__kmp_omp_cancellation) {
+ switch (cncl_kind) {
+ case cancel_parallel:
+ case cancel_loop:
+ case cancel_sections:
+ // cancellation requests for parallel and worksharing constructs
+ // are handled through the team structure
+ {
+ kmp_team_t *this_team = this_thr->th.th_team;
+ KMP_DEBUG_ASSERT(this_team);
+ kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(
+ &(this_team->t.t_cancel_request), cancel_noreq, cncl_kind);
+ if (old == cancel_noreq || old == cncl_kind) {
+ // printf("__kmpc_cancel: this_team->t.t_cancel_request=%d @ %p\n",
+ // this_team->t.t_cancel_request,
+ // &(this_team->t.t_cancel_request));
+ // we do not have a cancellation request in this team or we do have
+ // one that matches the current request -> cancel
+ return 1 /* true */;
}
+ break;
+ }
+ case cancel_taskgroup:
+ // cancellation requests for a task group
+ // are handled through the taskgroup structure
+ {
+ kmp_taskdata_t *task;
+ kmp_taskgroup_t *taskgroup;
+
+ task = this_thr->th.th_current_task;
+ KMP_DEBUG_ASSERT(task);
+
+ taskgroup = task->td_taskgroup;
+ if (taskgroup) {
+ kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(
+ &(taskgroup->cancel_request), cancel_noreq, cncl_kind);
+ if (old == cancel_noreq || old == cncl_kind) {
+ // we do not have a cancellation request in this taskgroup or we do
+ // have one that matches the current request -> cancel
+ return 1 /* true */;
+ }
+ } else {
+ // TODO: what needs to happen here?
+ // the specification disallows cancellation w/o taskgroups
+ // so we might do anything here, let's abort for now
+ KMP_ASSERT(0 /* false */);
+ }
+ }
+ break;
+ default:
+ KMP_ASSERT(0 /* false */);
}
+ }
- // ICV OMP_CANCELLATION=false, so we ignored this cancel request
- KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
- return 0 /* false */;
+ // ICV OMP_CANCELLATION=false, so we ignored this cancel request
+ KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
+ return 0 /* false */;
}
/*!
@@ -100,77 +104,77 @@ kmp_int32 __kmpc_cancel(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
@param gtid Global thread ID of encountering thread
@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
-@return returns true if a matching cancellation request has been flagged in the RTL and the
-encountering thread has to cancel..
+@return returns true if a matching cancellation request has been flagged in the
+RTL and the encountering thread has to cancel..
Cancellation point for the encountering thread.
*/
-kmp_int32 __kmpc_cancellationpoint(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
- kmp_info_t *this_thr = __kmp_threads [ gtid ];
-
- KC_TRACE( 10, ("__kmpc_cancellationpoint: T#%d request %d OMP_CANCELLATION=%d\n", gtid, cncl_kind, __kmp_omp_cancellation) );
-
- KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
- KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
- cncl_kind == cancel_sections || cncl_kind == cancel_taskgroup);
- KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
-
- if (__kmp_omp_cancellation) {
- switch (cncl_kind) {
- case cancel_parallel:
- case cancel_loop:
- case cancel_sections:
- // cancellation requests for parallel and worksharing constructs
- // are handled through the team structure
- {
- kmp_team_t *this_team = this_thr->th.th_team;
- KMP_DEBUG_ASSERT(this_team);
- if (this_team->t.t_cancel_request) {
- if (cncl_kind == this_team->t.t_cancel_request) {
- // the request in the team structure matches the type of
- // cancellation point so we can cancel
- return 1 /* true */;
- }
- KMP_ASSERT( 0 /* false */);
- }
- else {
- // we do not have a cancellation request pending, so we just
- // ignore this cancellation point
- return 0;
- }
- break;
- }
- case cancel_taskgroup:
- // cancellation requests for a task group
- // are handled through the taskgroup structure
- {
- kmp_taskdata_t* task;
- kmp_taskgroup_t* taskgroup;
-
- task = this_thr->th.th_current_task;
- KMP_DEBUG_ASSERT( task );
-
- taskgroup = task->td_taskgroup;
- if (taskgroup) {
- // return the current status of cancellation for the
- // taskgroup
- return !!taskgroup->cancel_request;
- }
- else {
- // if a cancellation point is encountered by a task
- // that does not belong to a taskgroup, it is OK
- // to ignore it
- return 0 /* false */;
- }
- }
- default:
- KMP_ASSERT (0 /* false */);
+kmp_int32 __kmpc_cancellationpoint(ident_t *loc_ref, kmp_int32 gtid,
+ kmp_int32 cncl_kind) {
+ kmp_info_t *this_thr = __kmp_threads[gtid];
+
+ KC_TRACE(10,
+ ("__kmpc_cancellationpoint: T#%d request %d OMP_CANCELLATION=%d\n",
+ gtid, cncl_kind, __kmp_omp_cancellation));
+
+ KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
+ KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
+ cncl_kind == cancel_sections ||
+ cncl_kind == cancel_taskgroup);
+ KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
+
+ if (__kmp_omp_cancellation) {
+ switch (cncl_kind) {
+ case cancel_parallel:
+ case cancel_loop:
+ case cancel_sections:
+ // cancellation requests for parallel and worksharing constructs
+ // are handled through the team structure
+ {
+ kmp_team_t *this_team = this_thr->th.th_team;
+ KMP_DEBUG_ASSERT(this_team);
+ if (this_team->t.t_cancel_request) {
+ if (cncl_kind == this_team->t.t_cancel_request) {
+ // the request in the team structure matches the type of
+ // cancellation point so we can cancel
+ return 1 /* true */;
+ }
+ KMP_ASSERT(0 /* false */);
+ } else {
+ // we do not have a cancellation request pending, so we just
+ // ignore this cancellation point
+ return 0;
+ }
+ break;
+ }
+ case cancel_taskgroup:
+ // cancellation requests for a task group
+ // are handled through the taskgroup structure
+ {
+ kmp_taskdata_t *task;
+ kmp_taskgroup_t *taskgroup;
+
+ task = this_thr->th.th_current_task;
+ KMP_DEBUG_ASSERT(task);
+
+ taskgroup = task->td_taskgroup;
+ if (taskgroup) {
+ // return the current status of cancellation for the taskgroup
+ return !!taskgroup->cancel_request;
+ } else {
+ // if a cancellation point is encountered by a task that does not
+ // belong to a taskgroup, it is OK to ignore it
+ return 0 /* false */;
}
+ }
+ default:
+ KMP_ASSERT(0 /* false */);
}
+ }
- // ICV OMP_CANCELLATION=false, so we ignore the cancellation point
- KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
- return 0 /* false */;
+ // ICV OMP_CANCELLATION=false, so we ignore the cancellation point
+ KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
+ return 0 /* false */;
}
/*!
@@ -178,63 +182,61 @@ kmp_int32 __kmpc_cancellationpoint(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 c
@param loc_ref location of the original task directive
@param gtid Global thread ID of encountering thread
-@return returns true if a matching cancellation request has been flagged in the RTL and the
-encountering thread has to cancel..
+@return returns true if a matching cancellation request has been flagged in the
+RTL and the encountering thread has to cancel..
Barrier with cancellation point to send threads from the barrier to the
end of the parallel region. Needs a special code pattern as documented
in the design document for the cancellation feature.
*/
-kmp_int32
-__kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid) {
- int ret = 0 /* false */;
- kmp_info_t *this_thr = __kmp_threads [ gtid ];
- kmp_team_t *this_team = this_thr->th.th_team;
-
- KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
-
- // call into the standard barrier
- __kmpc_barrier(loc, gtid);
-
- // if cancellation is active, check cancellation flag
- if (__kmp_omp_cancellation) {
- // depending on which construct to cancel, check the flag and
- // reset the flag
- switch (this_team->t.t_cancel_request) {
- case cancel_parallel:
- ret = 1;
- // ensure that threads have checked the flag, when
- // leaving the above barrier
- __kmpc_barrier(loc, gtid);
- this_team->t.t_cancel_request = cancel_noreq;
- // the next barrier is the fork/join barrier, which
- // synchronizes the threads leaving here
- break;
- case cancel_loop:
- case cancel_sections:
- ret = 1;
- // ensure that threads have checked the flag, when
- // leaving the above barrier
- __kmpc_barrier(loc, gtid);
- this_team->t.t_cancel_request = cancel_noreq;
- // synchronize the threads again to make sure we
- // do not have any run-away threads that cause a race
- // on the cancellation flag
- __kmpc_barrier(loc, gtid);
- break;
- case cancel_taskgroup:
- // this case should not occur
- KMP_ASSERT (0 /* false */ );
- break;
- case cancel_noreq:
- // do nothing
- break;
- default:
- KMP_ASSERT ( 0 /* false */);
- }
+kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid) {
+ int ret = 0 /* false */;
+ kmp_info_t *this_thr = __kmp_threads[gtid];
+ kmp_team_t *this_team = this_thr->th.th_team;
+
+ KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
+
+ // call into the standard barrier
+ __kmpc_barrier(loc, gtid);
+
+ // if cancellation is active, check cancellation flag
+ if (__kmp_omp_cancellation) {
+ // depending on which construct to cancel, check the flag and
+ // reset the flag
+ switch (this_team->t.t_cancel_request) {
+ case cancel_parallel:
+ ret = 1;
+ // ensure that threads have checked the flag, when
+ // leaving the above barrier
+ __kmpc_barrier(loc, gtid);
+ this_team->t.t_cancel_request = cancel_noreq;
+ // the next barrier is the fork/join barrier, which
+ // synchronizes the threads leaving here
+ break;
+ case cancel_loop:
+ case cancel_sections:
+ ret = 1;
+ // ensure that threads have checked the flag, when
+ // leaving the above barrier
+ __kmpc_barrier(loc, gtid);
+ this_team->t.t_cancel_request = cancel_noreq;
+ // synchronize the threads again to make sure we do not have any run-away
+ // threads that cause a race on the cancellation flag
+ __kmpc_barrier(loc, gtid);
+ break;
+ case cancel_taskgroup:
+ // this case should not occur
+ KMP_ASSERT(0 /* false */);
+ break;
+ case cancel_noreq:
+ // do nothing
+ break;
+ default:
+ KMP_ASSERT(0 /* false */);
}
+ }
- return ret;
+ return ret;
}
/*!
@@ -242,8 +244,8 @@ __kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid) {
@param loc_ref location of the original task directive
@param gtid Global thread ID of encountering thread
-@return returns true if a matching cancellation request has been flagged in the RTL and the
-encountering thread has to cancel..
+@return returns true if a matching cancellation request has been flagged in the
+RTL and the encountering thread has to cancel..
Query function to query the current status of cancellation requests.
Can be used to implement the following pattern:
@@ -254,29 +256,27 @@ if (kmp_get_cancellation_status(kmp_cancel_parallel)) {
}
*/
int __kmp_get_cancellation_status(int cancel_kind) {
- if (__kmp_omp_cancellation) {
- kmp_info_t *this_thr = __kmp_entry_thread();
-
- switch (cancel_kind) {
- case cancel_parallel:
- case cancel_loop:
- case cancel_sections:
- {
- kmp_team_t *this_team = this_thr->th.th_team;
- return this_team->t.t_cancel_request == cancel_kind;
- }
- case cancel_taskgroup:
- {
- kmp_taskdata_t* task;
- kmp_taskgroup_t* taskgroup;
- task = this_thr->th.th_current_task;
- taskgroup = task->td_taskgroup;
- return taskgroup && taskgroup->cancel_request;
- }
- }
+ if (__kmp_omp_cancellation) {
+ kmp_info_t *this_thr = __kmp_entry_thread();
+
+ switch (cancel_kind) {
+ case cancel_parallel:
+ case cancel_loop:
+ case cancel_sections: {
+ kmp_team_t *this_team = this_thr->th.th_team;
+ return this_team->t.t_cancel_request == cancel_kind;
+ }
+ case cancel_taskgroup: {
+ kmp_taskdata_t *task;
+ kmp_taskgroup_t *taskgroup;
+ task = this_thr->th.th_current_task;
+ taskgroup = task->td_taskgroup;
+ return taskgroup && taskgroup->cancel_request;
+ }
}
+ }
- return 0 /* false */;
+ return 0 /* false */;
}
#endif
OpenPOWER on IntegriCloud