6 //===----------------------------------------------------------------------===//
8 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9 // See https://llvm.org/LICENSE.txt for license information.
10 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12 //===----------------------------------------------------------------------===//
15 #ifndef KMP_TASKDEPS_H
16 #define KMP_TASKDEPS_H
20 #define KMP_ACQUIRE_DEPNODE(gtid, n) __kmp_acquire_lock(&(n)->dn.lock, (gtid))
21 #define KMP_RELEASE_DEPNODE(gtid, n) __kmp_release_lock(&(n)->dn.lock, (gtid))
23 static inline void __kmp_node_deref(kmp_info_t
*thread
, kmp_depnode_t
*node
) {
27 kmp_int32 n
= KMP_ATOMIC_DEC(&node
->dn
.nrefs
) - 1;
29 KMP_ASSERT(node
->dn
.nrefs
== 0);
31 __kmp_fast_free(thread
, node
);
33 __kmp_thread_free(thread
, node
);
38 static inline void __kmp_depnode_list_free(kmp_info_t
*thread
,
39 kmp_depnode_list
*list
) {
40 kmp_depnode_list
*next
;
42 for (; list
; list
= next
) {
45 __kmp_node_deref(thread
, list
->node
);
47 __kmp_fast_free(thread
, list
);
49 __kmp_thread_free(thread
, list
);
54 static inline void __kmp_dephash_free_entries(kmp_info_t
*thread
,
56 for (size_t i
= 0; i
< h
->size
; i
++) {
58 kmp_dephash_entry_t
*next
;
59 for (kmp_dephash_entry_t
*entry
= h
->buckets
[i
]; entry
; entry
= next
) {
60 next
= entry
->next_in_bucket
;
61 __kmp_depnode_list_free(thread
, entry
->last_ins
);
62 __kmp_depnode_list_free(thread
, entry
->last_mtxs
);
63 __kmp_node_deref(thread
, entry
->last_out
);
64 if (entry
->mtx_lock
) {
65 __kmp_destroy_lock(entry
->mtx_lock
);
66 __kmp_free(entry
->mtx_lock
);
69 __kmp_fast_free(thread
, entry
);
71 __kmp_thread_free(thread
, entry
);
79 static inline void __kmp_dephash_free(kmp_info_t
*thread
, kmp_dephash_t
*h
) {
80 __kmp_dephash_free_entries(thread
, h
);
82 __kmp_fast_free(thread
, h
);
84 __kmp_thread_free(thread
, h
);
88 static inline void __kmp_release_deps(kmp_int32 gtid
, kmp_taskdata_t
*task
) {
89 kmp_info_t
*thread
= __kmp_threads
[gtid
];
90 kmp_depnode_t
*node
= task
->td_depnode
;
92 if (task
->td_dephash
) {
94 40, ("__kmp_release_deps: T#%d freeing dependencies hash of task %p.\n",
96 __kmp_dephash_free(thread
, task
->td_dephash
);
97 task
->td_dephash
= NULL
;
103 KA_TRACE(20, ("__kmp_release_deps: T#%d notifying successors of task %p.\n",
106 KMP_ACQUIRE_DEPNODE(gtid
, node
);
108 NULL
; // mark this task as finished, so no new dependencies are generated
109 KMP_RELEASE_DEPNODE(gtid
, node
);
111 kmp_depnode_list_t
*next
;
112 for (kmp_depnode_list_t
*p
= node
->dn
.successors
; p
; p
= next
) {
113 kmp_depnode_t
*successor
= p
->node
;
114 kmp_int32 npredecessors
= KMP_ATOMIC_DEC(&successor
->dn
.npredecessors
) - 1;
116 // successor task can be NULL for wait_depends or because deps are still
118 if (npredecessors
== 0) {
120 if (successor
->dn
.task
) {
121 KA_TRACE(20, ("__kmp_release_deps: T#%d successor %p of %p scheduled "
123 gtid
, successor
->dn
.task
, task
));
124 __kmp_omp_task(gtid
, successor
->dn
.task
, false);
129 __kmp_node_deref(thread
, p
->node
);
131 __kmp_fast_free(thread
, p
);
133 __kmp_thread_free(thread
, p
);
137 __kmp_node_deref(thread
, node
);
141 ("__kmp_release_deps: T#%d all successors of %p notified of completion\n",
145 #endif // KMP_TASKDEPS_H