17#include "kmp_wait_release.h"
18#include "kmp_taskdeps.h"
20#include "ompt-specific.h"
32#ifdef KMP_SUPPORT_GRAPH_OUTPUT
33static std::atomic<kmp_int32> kmp_node_id_seed = 0;
36static void __kmp_init_node(kmp_depnode_t *node,
bool on_stack) {
37 node->dn.successors = NULL;
40 for (
int i = 0; i < MAX_MTX_DEPS; ++i)
41 node->dn.mtx_locks[i] = NULL;
42 node->dn.mtx_num_locks = 0;
43 __kmp_init_lock(&node->dn.lock);
48 KMP_ATOMIC_ST_RLX(&node->dn.nrefs, on_stack ? 3 : 2);
49#ifdef KMP_SUPPORT_GRAPH_OUTPUT
50 node->dn.id = KMP_ATOMIC_INC(&kmp_node_id_seed);
52#if USE_ITT_BUILD && USE_ITT_NOTIFY
53 __itt_sync_create(node,
"OMP task dep node", NULL, 0);
57static inline kmp_depnode_t *__kmp_node_ref(kmp_depnode_t *node) {
58 KMP_ATOMIC_ADD(&node->dn.nrefs, 2);
62enum { KMP_DEPHASH_OTHER_SIZE = 97, KMP_DEPHASH_MASTER_SIZE = 997 };
64size_t sizes[] = {997, 2003, 4001, 8191, 16001, 32003, 64007, 131071, 270029};
65const size_t MAX_GEN = 8;
67static inline size_t __kmp_dephash_hash(kmp_intptr_t addr,
size_t hsize) {
70 return ((addr >> 6) ^ (addr >> 2)) % hsize;
73static kmp_dephash_t *__kmp_dephash_extend(kmp_info_t *thread,
74 kmp_dephash_t *current_dephash) {
77 size_t gen = current_dephash->generation + 1;
79 return current_dephash;
80 size_t new_size = sizes[gen];
82 size_t size_to_allocate =
83 new_size *
sizeof(kmp_dephash_entry_t *) +
sizeof(kmp_dephash_t);
86 h = (kmp_dephash_t *)__kmp_fast_allocate(thread, size_to_allocate);
88 h = (kmp_dephash_t *)__kmp_thread_malloc(thread, size_to_allocate);
92 h->nelements = current_dephash->nelements;
93 h->buckets = (kmp_dephash_entry **)(h + 1);
96 h->last_all = current_dephash->last_all;
99 for (
size_t i = 0; i < new_size; i++) {
100 h->buckets[i] = NULL;
104 for (
size_t i = 0; i < current_dephash->size; i++) {
105 kmp_dephash_entry_t *next, *entry;
106 for (entry = current_dephash->buckets[i]; entry; entry = next) {
107 next = entry->next_in_bucket;
110 size_t new_bucket = __kmp_dephash_hash(entry->addr, h->size);
111 entry->next_in_bucket = h->buckets[new_bucket];
112 if (entry->next_in_bucket) {
115 h->buckets[new_bucket] = entry;
121 __kmp_fast_free(thread, current_dephash);
123 __kmp_thread_free(thread, current_dephash);
129static kmp_dephash_t *__kmp_dephash_create(kmp_info_t *thread,
130 kmp_taskdata_t *current_task) {
135 if (current_task->td_flags.tasktype == TASK_IMPLICIT)
136 h_size = KMP_DEPHASH_MASTER_SIZE;
138 h_size = KMP_DEPHASH_OTHER_SIZE;
140 size_t size = h_size *
sizeof(kmp_dephash_entry_t *) +
sizeof(kmp_dephash_t);
143 h = (kmp_dephash_t *)__kmp_fast_allocate(thread, size);
145 h = (kmp_dephash_t *)__kmp_thread_malloc(thread, size);
152 h->buckets = (kmp_dephash_entry **)(h + 1);
155 for (
size_t i = 0; i < h_size; i++)
161static kmp_dephash_entry *__kmp_dephash_find(kmp_info_t *thread,
162 kmp_dephash_t **hash,
164 kmp_dephash_t *h = *hash;
165 if (h->nelements != 0 && h->nconflicts / h->size >= 1) {
166 *hash = __kmp_dephash_extend(thread, h);
169 size_t bucket = __kmp_dephash_hash(addr, h->size);
171 kmp_dephash_entry_t *entry;
172 for (entry = h->buckets[bucket]; entry; entry = entry->next_in_bucket)
173 if (entry->addr == addr)
179 entry = (kmp_dephash_entry_t *)__kmp_fast_allocate(
180 thread,
sizeof(kmp_dephash_entry_t));
182 entry = (kmp_dephash_entry_t *)__kmp_thread_malloc(
183 thread,
sizeof(kmp_dephash_entry_t));
187 entry->last_out = NULL;
189 entry->last_out = __kmp_node_ref(h->last_all);
190 entry->last_set = NULL;
191 entry->prev_set = NULL;
192 entry->last_flag = 0;
193 entry->mtx_lock = NULL;
194 entry->next_in_bucket = h->buckets[bucket];
195 h->buckets[bucket] = entry;
197 if (entry->next_in_bucket)
203static kmp_depnode_list_t *__kmp_add_node(kmp_info_t *thread,
204 kmp_depnode_list_t *list,
205 kmp_depnode_t *node) {
206 kmp_depnode_list_t *new_head;
209 new_head = (kmp_depnode_list_t *)__kmp_fast_allocate(
210 thread,
sizeof(kmp_depnode_list_t));
212 new_head = (kmp_depnode_list_t *)__kmp_thread_malloc(
213 thread,
sizeof(kmp_depnode_list_t));
216 new_head->node = __kmp_node_ref(node);
217 new_head->next = list;
222static inline void __kmp_track_dependence(kmp_int32 gtid, kmp_depnode_t *source,
224 kmp_task_t *sink_task) {
225#ifdef KMP_SUPPORT_GRAPH_OUTPUT
226 kmp_taskdata_t *task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
229 kmp_taskdata_t *task_sink = KMP_TASK_TO_TASKDATA(sink_task);
231 __kmp_printf(
"%d(%s) -> %d(%s)\n", source->dn.id,
232 task_source->td_ident->psource, sink->dn.id,
233 task_sink->td_ident->psource);
235#if OMPT_SUPPORT && OMPT_OPTIONAL
239 if (ompt_enabled.ompt_callback_task_dependence) {
240 kmp_taskdata_t *task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
241 ompt_data_t *sink_data;
243 sink_data = &(KMP_TASK_TO_TASKDATA(sink_task)->ompt_task_info.task_data);
245 sink_data = &__kmp_threads[gtid]->th.ompt_thread_info.task_data;
247 ompt_callbacks.ompt_callback(ompt_callback_task_dependence)(
248 &(task_source->ompt_task_info.task_data), sink_data);
253kmp_base_depnode_t *__kmpc_task_get_depnode(kmp_task_t *task) {
254 kmp_taskdata_t *td = KMP_TASK_TO_TASKDATA(task);
255 return td->td_depnode ? &(td->td_depnode->dn) : NULL;
258kmp_depnode_list_t *__kmpc_task_get_successors(kmp_task_t *task) {
259 kmp_taskdata_t *td = KMP_TASK_TO_TASKDATA(task);
260 return td->td_depnode->dn.successors;
263static inline kmp_int32
264__kmp_depnode_link_successor(kmp_int32 gtid, kmp_info_t *thread,
265 kmp_task_t *task, kmp_depnode_t *node,
266 kmp_depnode_list_t *plist) {
269 kmp_int32 npredecessors = 0;
271 for (kmp_depnode_list_t *p = plist; p; p = p->next) {
272 kmp_depnode_t *dep = p->node;
274 KMP_ACQUIRE_DEPNODE(gtid, dep);
276 if (!dep->dn.successors || dep->dn.successors->node != node) {
277 __kmp_track_dependence(gtid, dep, node, task);
278 dep->dn.successors = __kmp_add_node(thread, dep->dn.successors, node);
279 KA_TRACE(40, (
"__kmp_process_deps: T#%d adding dependence from %p to "
281 gtid, KMP_TASK_TO_TASKDATA(dep->dn.task),
282 KMP_TASK_TO_TASKDATA(task)));
286 KMP_RELEASE_DEPNODE(gtid, dep);
289 return npredecessors;
293static inline kmp_int32 __kmp_depnode_link_successor(kmp_int32 gtid,
296 kmp_depnode_t *source,
297 kmp_depnode_t *sink) {
300 kmp_int32 npredecessors = 0;
303 KMP_ACQUIRE_DEPNODE(gtid, sink);
305 if (!sink->dn.successors || sink->dn.successors->node != source) {
306 __kmp_track_dependence(gtid, sink, source, task);
307 sink->dn.successors = __kmp_add_node(thread, sink->dn.successors, source);
308 KA_TRACE(40, (
"__kmp_process_deps: T#%d adding dependence from %p to "
310 gtid, KMP_TASK_TO_TASKDATA(sink->dn.task),
311 KMP_TASK_TO_TASKDATA(task)));
315 KMP_RELEASE_DEPNODE(gtid, sink);
317 return npredecessors;
320static inline kmp_int32
321__kmp_process_dep_all(kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t *h,
322 bool dep_barrier, kmp_task_t *task) {
323 KA_TRACE(30, (
"__kmp_process_dep_all: T#%d processing dep_all, "
324 "dep_barrier = %d\n",
326 kmp_info_t *thread = __kmp_threads[gtid];
327 kmp_int32 npredecessors = 0;
331 __kmp_depnode_link_successor(gtid, thread, task, node, h->last_all);
332 __kmp_node_deref(thread, h->last_all);
334 h->last_all = __kmp_node_ref(node);
343 for (
size_t i = 0; i < h->size; i++) {
344 kmp_dephash_entry_t *info = h->buckets[i];
347 for (; info; info = info->next_in_bucket) {
349 kmp_depnode_t *last_out = info->last_out;
350 kmp_depnode_list_t *last_set = info->last_set;
351 kmp_depnode_list_t *prev_set = info->prev_set;
354 __kmp_depnode_link_successor(gtid, thread, task, node, last_set);
355 __kmp_depnode_list_free(thread, last_set);
356 __kmp_depnode_list_free(thread, prev_set);
357 info->last_set = NULL;
358 info->prev_set = NULL;
362 __kmp_depnode_link_successor(gtid, thread, task, node, last_out);
364 __kmp_node_deref(thread, last_out);
366 info->last_out = __kmp_node_ref(node);
368 info->last_out = NULL;
372 KA_TRACE(30, (
"__kmp_process_dep_all: T#%d found %d predecessors\n", gtid,
374 return npredecessors;
377template <
bool filter>
378static inline kmp_int32
379__kmp_process_deps(kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t **hash,
380 bool dep_barrier, kmp_int32 ndeps,
381 kmp_depend_info_t *dep_list, kmp_task_t *task) {
382 KA_TRACE(30, (
"__kmp_process_deps<%d>: T#%d processing %d dependences : "
383 "dep_barrier = %d\n",
384 filter, gtid, ndeps, dep_barrier));
386 kmp_info_t *thread = __kmp_threads[gtid];
387 kmp_int32 npredecessors = 0;
388 for (kmp_int32 i = 0; i < ndeps; i++) {
389 const kmp_depend_info_t *dep = &dep_list[i];
391 if (filter && dep->base_addr == 0)
394 kmp_dephash_entry_t *info =
395 __kmp_dephash_find(thread, hash, dep->base_addr);
396 kmp_depnode_t *last_out = info->last_out;
397 kmp_depnode_list_t *last_set = info->last_set;
398 kmp_depnode_list_t *prev_set = info->prev_set;
400 if (dep->flags.out) {
403 __kmp_depnode_link_successor(gtid, thread, task, node, last_set);
404 __kmp_depnode_list_free(thread, last_set);
405 __kmp_depnode_list_free(thread, prev_set);
406 info->last_set = NULL;
407 info->prev_set = NULL;
411 __kmp_depnode_link_successor(gtid, thread, task, node, last_out);
413 __kmp_node_deref(thread, last_out);
415 info->last_out = __kmp_node_ref(node);
420 info->last_out = NULL;
423 if (info->last_flag == 0 || info->last_flag == dep->flag) {
427 __kmp_depnode_link_successor(gtid, thread, task, node, last_out);
430 __kmp_depnode_link_successor(gtid, thread, task, node, prev_set);
433 __kmp_node_deref(thread, last_out);
434 info->last_out = NULL;
435 __kmp_depnode_list_free(thread, prev_set);
436 info->prev_set = NULL;
441 __kmp_depnode_link_successor(gtid, thread, task, node, last_set);
443 __kmp_node_deref(thread, last_out);
444 info->last_out = NULL;
446 __kmp_depnode_list_free(thread, prev_set);
449 info->prev_set = last_set;
451 info->prev_set = NULL;
454 info->last_set = NULL;
459 info->last_flag = dep->flag;
460 info->last_set = __kmp_add_node(thread, info->last_set, node);
463 if (dep->flag == KMP_DEP_MTX) {
464 if (info->mtx_lock == NULL) {
465 info->mtx_lock = (kmp_lock_t *)__kmp_allocate(
sizeof(kmp_lock_t));
466 __kmp_init_lock(info->mtx_lock);
468 KMP_DEBUG_ASSERT(node->dn.mtx_num_locks < MAX_MTX_DEPS);
471 for (m = 0; m < MAX_MTX_DEPS; ++m) {
473 if (node->dn.mtx_locks[m] < info->mtx_lock) {
474 KMP_DEBUG_ASSERT(!node->dn.mtx_locks[node->dn.mtx_num_locks]);
475 for (
int n = node->dn.mtx_num_locks; n > m; --n) {
477 KMP_DEBUG_ASSERT(node->dn.mtx_locks[n - 1] != NULL);
478 node->dn.mtx_locks[n] = node->dn.mtx_locks[n - 1];
480 node->dn.mtx_locks[m] = info->mtx_lock;
484 KMP_DEBUG_ASSERT(m < MAX_MTX_DEPS);
485 node->dn.mtx_num_locks++;
489 KA_TRACE(30, (
"__kmp_process_deps<%d>: T#%d found %d predecessors\n", filter,
490 gtid, npredecessors));
491 return npredecessors;
494#define NO_DEP_BARRIER (false)
495#define DEP_BARRIER (true)
498static bool __kmp_check_deps(kmp_int32 gtid, kmp_depnode_t *node,
499 kmp_task_t *task, kmp_dephash_t **hash,
500 bool dep_barrier, kmp_int32 ndeps,
501 kmp_depend_info_t *dep_list,
502 kmp_int32 ndeps_noalias,
503 kmp_depend_info_t *noalias_dep_list) {
504 int i, n_mtxs = 0, dep_all = 0;
506 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
508 KA_TRACE(20, (
"__kmp_check_deps: T#%d checking dependences for task %p : %d "
509 "possibly aliased dependences, %d non-aliased dependences : "
510 "dep_barrier=%d .\n",
511 gtid, taskdata, ndeps, ndeps_noalias, dep_barrier));
515 for (i = 0; i < ndeps; i++) {
516 if (dep_list[i].base_addr != 0 &&
517 dep_list[i].base_addr != (kmp_intptr_t)KMP_SIZE_T_MAX) {
519 dep_list[i].flag == KMP_DEP_IN || dep_list[i].flag == KMP_DEP_OUT ||
520 dep_list[i].flag == KMP_DEP_INOUT ||
521 dep_list[i].flag == KMP_DEP_MTX || dep_list[i].flag == KMP_DEP_SET);
522 for (
int j = i + 1; j < ndeps; j++) {
523 if (dep_list[i].base_addr == dep_list[j].base_addr) {
524 if (dep_list[i].flag != dep_list[j].flag) {
526 dep_list[i].flag = KMP_DEP_OUT;
528 dep_list[j].base_addr = 0;
531 if (dep_list[i].flag == KMP_DEP_MTX) {
533 if (n_mtxs < MAX_MTX_DEPS && task != NULL) {
536 dep_list[i].flag = KMP_DEP_OUT;
539 }
else if (dep_list[i].flag == KMP_DEP_ALL ||
540 dep_list[i].base_addr == (kmp_intptr_t)KMP_SIZE_T_MAX) {
553 node->dn.npredecessors = -1;
560 npredecessors = __kmp_process_deps<true>(gtid, node, hash, dep_barrier,
561 ndeps, dep_list, task);
562 npredecessors += __kmp_process_deps<false>(
563 gtid, node, hash, dep_barrier, ndeps_noalias, noalias_dep_list, task);
565 npredecessors = __kmp_process_dep_all(gtid, node, *hash, dep_barrier, task);
568 node->dn.task = task;
578 node->dn.npredecessors.fetch_add(npredecessors) + npredecessors;
580 KA_TRACE(20, (
"__kmp_check_deps: T#%d found %d predecessors for task %p \n",
581 gtid, npredecessors, taskdata));
585 return npredecessors > 0 ? true :
false;
605 kmp_task_t *new_task, kmp_int32 ndeps,
606 kmp_depend_info_t *dep_list,
607 kmp_int32 ndeps_noalias,
608 kmp_depend_info_t *noalias_dep_list) {
610 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
611 KA_TRACE(10, (
"__kmpc_omp_task_with_deps(enter): T#%d loc=%p task=%p\n", gtid,
612 loc_ref, new_taskdata));
613 __kmp_assert_valid_gtid(gtid);
614 kmp_info_t *thread = __kmp_threads[gtid];
615 kmp_taskdata_t *current_task = thread->th.th_current_task;
618 if (ompt_enabled.enabled) {
619 if (!current_task->ompt_task_info.frame.enter_frame.ptr)
620 current_task->ompt_task_info.frame.enter_frame.ptr =
621 OMPT_GET_FRAME_ADDRESS(0);
622 if (ompt_enabled.ompt_callback_task_create) {
623 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
624 &(current_task->ompt_task_info.task_data),
625 &(current_task->ompt_task_info.frame),
626 &(new_taskdata->ompt_task_info.task_data),
627 TASK_TYPE_DETAILS_FORMAT(new_taskdata), 1,
628 OMPT_LOAD_OR_GET_RETURN_ADDRESS(gtid));
631 new_taskdata->ompt_task_info.frame.enter_frame.ptr =
632 OMPT_GET_FRAME_ADDRESS(0);
637 if (ndeps + ndeps_noalias > 0 && ompt_enabled.ompt_callback_dependences) {
640 int ompt_ndeps = ndeps + ndeps_noalias;
641 ompt_dependence_t *ompt_deps = (ompt_dependence_t *)KMP_OMPT_DEPS_ALLOC(
642 thread, (ndeps + ndeps_noalias) *
sizeof(ompt_dependence_t));
644 KMP_ASSERT(ompt_deps != NULL);
646 for (i = 0; i < ndeps; i++) {
647 ompt_deps[i].variable.ptr = (
void *)dep_list[i].base_addr;
648 if (dep_list[i].base_addr == (kmp_intptr_t)KMP_SIZE_T_MAX)
649 ompt_deps[i].dependence_type = ompt_dependence_type_out_all_memory;
650 else if (dep_list[i].flags.in && dep_list[i].flags.out)
651 ompt_deps[i].dependence_type = ompt_dependence_type_inout;
652 else if (dep_list[i].flags.out)
653 ompt_deps[i].dependence_type = ompt_dependence_type_out;
654 else if (dep_list[i].flags.in)
655 ompt_deps[i].dependence_type = ompt_dependence_type_in;
656 else if (dep_list[i].flags.mtx)
657 ompt_deps[i].dependence_type = ompt_dependence_type_mutexinoutset;
658 else if (dep_list[i].flags.set)
659 ompt_deps[i].dependence_type = ompt_dependence_type_inoutset;
660 else if (dep_list[i].flags.all)
661 ompt_deps[i].dependence_type = ompt_dependence_type_out_all_memory;
663 for (i = 0; i < ndeps_noalias; i++) {
664 ompt_deps[ndeps + i].variable.ptr = (
void *)noalias_dep_list[i].base_addr;
665 if (noalias_dep_list[i].base_addr == (kmp_intptr_t)KMP_SIZE_T_MAX)
666 ompt_deps[ndeps + i].dependence_type =
667 ompt_dependence_type_out_all_memory;
668 else if (noalias_dep_list[i].flags.in && noalias_dep_list[i].flags.out)
669 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_inout;
670 else if (noalias_dep_list[i].flags.out)
671 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_out;
672 else if (noalias_dep_list[i].flags.in)
673 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_in;
674 else if (noalias_dep_list[i].flags.mtx)
675 ompt_deps[ndeps + i].dependence_type =
676 ompt_dependence_type_mutexinoutset;
677 else if (noalias_dep_list[i].flags.set)
678 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_inoutset;
679 else if (noalias_dep_list[i].flags.all)
680 ompt_deps[ndeps + i].dependence_type =
681 ompt_dependence_type_out_all_memory;
683 ompt_callbacks.ompt_callback(ompt_callback_dependences)(
684 &(new_taskdata->ompt_task_info.task_data), ompt_deps, ompt_ndeps);
687 KMP_OMPT_DEPS_FREE(thread, ompt_deps);
692 bool serial = current_task->td_flags.team_serial ||
693 current_task->td_flags.tasking_ser ||
694 current_task->td_flags.final;
695 kmp_task_team_t *task_team = thread->th.th_task_team;
697 !(task_team && (task_team->tt.tt_found_proxy_tasks ||
698 task_team->tt.tt_hidden_helper_task_encountered));
700 if (!serial && (ndeps > 0 || ndeps_noalias > 0)) {
702 if (current_task->td_dephash == NULL)
703 current_task->td_dephash = __kmp_dephash_create(thread, current_task);
706 kmp_depnode_t *node =
707 (kmp_depnode_t *)__kmp_fast_allocate(thread,
sizeof(kmp_depnode_t));
709 kmp_depnode_t *node =
710 (kmp_depnode_t *)__kmp_thread_malloc(thread,
sizeof(kmp_depnode_t));
713 __kmp_init_node(node,
false);
714 new_taskdata->td_depnode = node;
716 if (__kmp_check_deps(gtid, node, new_task, ¤t_task->td_dephash,
717 NO_DEP_BARRIER, ndeps, dep_list, ndeps_noalias,
719 KA_TRACE(10, (
"__kmpc_omp_task_with_deps(exit): T#%d task had blocking "
721 "loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n",
722 gtid, loc_ref, new_taskdata));
724 if (ompt_enabled.enabled) {
725 current_task->ompt_task_info.frame.enter_frame = ompt_data_none;
728 return TASK_CURRENT_NOT_QUEUED;
731 KA_TRACE(10, (
"__kmpc_omp_task_with_deps(exit): T#%d ignored dependences "
732 "for task (serialized) loc=%p task=%p\n",
733 gtid, loc_ref, new_taskdata));
736 KA_TRACE(10, (
"__kmpc_omp_task_with_deps(exit): T#%d task had no blocking "
738 "loc=%p task=%p, transferring to __kmp_omp_task\n",
739 gtid, loc_ref, new_taskdata));
741 kmp_int32 ret = __kmp_omp_task(gtid, new_task,
true);
743 if (ompt_enabled.enabled) {
744 current_task->ompt_task_info.frame.enter_frame = ompt_data_none;
751void __ompt_taskwait_dep_finish(kmp_taskdata_t *current_task,
752 ompt_data_t *taskwait_task_data) {
753 if (ompt_enabled.ompt_callback_task_schedule) {
754 ompt_callbacks.ompt_callback(ompt_callback_task_schedule)(
755 taskwait_task_data, ompt_taskwait_complete, NULL);
757 current_task->ompt_task_info.frame.enter_frame.ptr = NULL;
758 *taskwait_task_data = ompt_data_none;
774 kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
775 kmp_depend_info_t *noalias_dep_list) {
776 __kmpc_omp_taskwait_deps_51(loc_ref, gtid, ndeps, dep_list, ndeps_noalias,
777 noalias_dep_list,
false);
785void __kmpc_omp_taskwait_deps_51(
ident_t *loc_ref, kmp_int32 gtid,
786 kmp_int32 ndeps, kmp_depend_info_t *dep_list,
787 kmp_int32 ndeps_noalias,
788 kmp_depend_info_t *noalias_dep_list,
789 kmp_int32 has_no_wait) {
790 KA_TRACE(10, (
"__kmpc_omp_taskwait_deps(enter): T#%d loc=%p nowait#%d\n",
791 gtid, loc_ref, has_no_wait));
792 if (ndeps == 0 && ndeps_noalias == 0) {
793 KA_TRACE(10, (
"__kmpc_omp_taskwait_deps(exit): T#%d has no dependences to "
794 "wait upon : loc=%p\n",
798 __kmp_assert_valid_gtid(gtid);
799 kmp_info_t *thread = __kmp_threads[gtid];
800 kmp_taskdata_t *current_task = thread->th.th_current_task;
808 ompt_data_t *taskwait_task_data = &thread->th.ompt_thread_info.task_data;
809 KMP_ASSERT(taskwait_task_data->ptr == NULL);
810 if (ompt_enabled.enabled) {
811 if (!current_task->ompt_task_info.frame.enter_frame.ptr)
812 current_task->ompt_task_info.frame.enter_frame.ptr =
813 OMPT_GET_FRAME_ADDRESS(0);
814 if (ompt_enabled.ompt_callback_task_create) {
815 ompt_callbacks.ompt_callback(ompt_callback_task_create)(
816 &(current_task->ompt_task_info.task_data),
817 &(current_task->ompt_task_info.frame), taskwait_task_data,
818 ompt_task_taskwait | ompt_task_undeferred | ompt_task_mergeable, 1,
819 OMPT_LOAD_OR_GET_RETURN_ADDRESS(gtid));
825 if (ndeps + ndeps_noalias > 0 && ompt_enabled.ompt_callback_dependences) {
828 int ompt_ndeps = ndeps + ndeps_noalias;
829 ompt_dependence_t *ompt_deps = (ompt_dependence_t *)KMP_OMPT_DEPS_ALLOC(
830 thread, (ndeps + ndeps_noalias) *
sizeof(ompt_dependence_t));
832 KMP_ASSERT(ompt_deps != NULL);
834 for (i = 0; i < ndeps; i++) {
835 ompt_deps[i].variable.ptr = (
void *)dep_list[i].base_addr;
836 if (dep_list[i].flags.in && dep_list[i].flags.out)
837 ompt_deps[i].dependence_type = ompt_dependence_type_inout;
838 else if (dep_list[i].flags.out)
839 ompt_deps[i].dependence_type = ompt_dependence_type_out;
840 else if (dep_list[i].flags.in)
841 ompt_deps[i].dependence_type = ompt_dependence_type_in;
842 else if (dep_list[i].flags.mtx)
843 ompt_deps[ndeps + i].dependence_type =
844 ompt_dependence_type_mutexinoutset;
845 else if (dep_list[i].flags.set)
846 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_inoutset;
848 for (i = 0; i < ndeps_noalias; i++) {
849 ompt_deps[ndeps + i].variable.ptr = (
void *)noalias_dep_list[i].base_addr;
850 if (noalias_dep_list[i].flags.in && noalias_dep_list[i].flags.out)
851 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_inout;
852 else if (noalias_dep_list[i].flags.out)
853 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_out;
854 else if (noalias_dep_list[i].flags.in)
855 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_in;
856 else if (noalias_dep_list[i].flags.mtx)
857 ompt_deps[ndeps + i].dependence_type =
858 ompt_dependence_type_mutexinoutset;
859 else if (noalias_dep_list[i].flags.set)
860 ompt_deps[ndeps + i].dependence_type = ompt_dependence_type_inoutset;
862 ompt_callbacks.ompt_callback(ompt_callback_dependences)(
863 taskwait_task_data, ompt_deps, ompt_ndeps);
866 KMP_OMPT_DEPS_FREE(thread, ompt_deps);
875 bool ignore = current_task->td_flags.team_serial ||
876 current_task->td_flags.tasking_ser ||
877 current_task->td_flags.final;
879 ignore && thread->th.th_task_team != NULL &&
880 thread->th.th_task_team->tt.tt_found_proxy_tasks == FALSE &&
881 thread->th.th_task_team->tt.tt_hidden_helper_task_encountered == FALSE;
882 ignore = ignore || current_task->td_dephash == NULL;
885 KA_TRACE(10, (
"__kmpc_omp_taskwait_deps(exit): T#%d has no blocking "
886 "dependences : loc=%p\n",
889 __ompt_taskwait_dep_finish(current_task, taskwait_task_data);
894 kmp_depnode_t node = {0};
895 __kmp_init_node(&node,
true);
897 if (!__kmp_check_deps(gtid, &node, NULL, ¤t_task->td_dephash,
898 DEP_BARRIER, ndeps, dep_list, ndeps_noalias,
900 KA_TRACE(10, (
"__kmpc_omp_taskwait_deps(exit): T#%d has no blocking "
901 "dependences : loc=%p\n",
904 __ompt_taskwait_dep_finish(current_task, taskwait_task_data);
910 while ((nrefs = node.dn.nrefs) > 3) {
911 KMP_DEBUG_ASSERT((nrefs & 1) == 1);
914 KMP_DEBUG_ASSERT(nrefs == 3);
919 int thread_finished = FALSE;
920 kmp_flag_32<false, false> flag(
921 (std::atomic<kmp_uint32> *)&node.dn.npredecessors, 0U);
922 while (node.dn.npredecessors > 0) {
923 flag.execute_tasks(thread, gtid, FALSE,
924 &thread_finished USE_ITT_BUILD_ARG(NULL),
925 __kmp_task_stealing_constraint);
934 while ((nrefs = node.dn.nrefs) > 3) {
935 KMP_DEBUG_ASSERT((nrefs & 1) == 1);
938 KMP_DEBUG_ASSERT(nrefs == 3);
941 __ompt_taskwait_dep_finish(current_task, taskwait_task_data);
943 KA_TRACE(10, (
"__kmpc_omp_taskwait_deps(exit): T#%d finished waiting : loc=%p\
kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list)
void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list)