Bug Summary

File:projects/openmp/runtime/src/kmp_tasking.cpp
Warning:line 1430, column 65
The right operand of '-' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name kmp_tasking.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D omp_EXPORTS -I /build/llvm-toolchain-snapshot-7~svn337957/build-llvm/projects/openmp/runtime/src -I /build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src -I /build/llvm-toolchain-snapshot-7~svn337957/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn337957/include -I /build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/i18n -I /build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/include/50 -I /build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/thirdparty/ittnotify -U NDEBUG -D _GNU_SOURCE -D _REENTRANT -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/x86_64-linux-gnu/c++/8 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-comment -Wno-sign-compare -Wno-unused-function -Wno-unused-value -Wno-unused-variable -Wno-switch -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-missing-braces -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn337957/build-llvm/projects/openmp/runtime/src -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fno-rtti -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-07-26-043338-586-1 -x c++ /build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp -faddrsig
1/*
2 * kmp_tasking.cpp -- OpenMP 3.0 tasking support.
3 */
4
5//===----------------------------------------------------------------------===//
6//
7// The LLVM Compiler Infrastructure
8//
9// This file is dual licensed under the MIT and the University of Illinois Open
10// Source Licenses. See LICENSE.txt for details.
11//
12//===----------------------------------------------------------------------===//
13
14#include "kmp.h"
15#include "kmp_i18n.h"
16#include "kmp_itt.h"
17#include "kmp_stats.h"
18#include "kmp_wait_release.h"
19
20#if OMPT_SUPPORT1
21#include "ompt-specific.h"
22#endif
23
24#include "tsan_annotations.h"
25
26/* forward declaration */
27static void __kmp_enable_tasking(kmp_task_team_t *task_team,
28 kmp_info_t *this_thr);
29static void __kmp_alloc_task_deque(kmp_info_t *thread,
30 kmp_thread_data_t *thread_data);
31static int __kmp_realloc_task_threads_data(kmp_info_t *thread,
32 kmp_task_team_t *task_team);
33
34#ifdef OMP_45_ENABLED(50 >= 45)
35static void __kmp_bottom_half_finish_proxy(kmp_int32 gtid, kmp_task_t *ptask);
36#endif
37
38#ifdef BUILD_TIED_TASK_STACK
39
40// __kmp_trace_task_stack: print the tied tasks from the task stack in order
41// from top do bottom
42//
43// gtid: global thread identifier for thread containing stack
44// thread_data: thread data for task team thread containing stack
45// threshold: value above which the trace statement triggers
46// location: string identifying call site of this function (for trace)
47static void __kmp_trace_task_stack(kmp_int32 gtid,
48 kmp_thread_data_t *thread_data,
49 int threshold, char *location) {
50 kmp_task_stack_t *task_stack = &thread_data->td.td_susp_tied_tasks;
51 kmp_taskdata_t **stack_top = task_stack->ts_top;
52 kmp_int32 entries = task_stack->ts_entries;
53 kmp_taskdata_t *tied_task;
54
55 KA_TRACE(if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(start): location = %s, gtid = %d, entries = %d, "
"first_block = %p, stack_top = %p \n", location, gtid, entries
, task_stack->ts_first_block, stack_top); }
56 threshold,if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(start): location = %s, gtid = %d, entries = %d, "
"first_block = %p, stack_top = %p \n", location, gtid, entries
, task_stack->ts_first_block, stack_top); }
57 ("__kmp_trace_task_stack(start): location = %s, gtid = %d, entries = %d, "if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(start): location = %s, gtid = %d, entries = %d, "
"first_block = %p, stack_top = %p \n", location, gtid, entries
, task_stack->ts_first_block, stack_top); }
58 "first_block = %p, stack_top = %p \n",if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(start): location = %s, gtid = %d, entries = %d, "
"first_block = %p, stack_top = %p \n", location, gtid, entries
, task_stack->ts_first_block, stack_top); }
59 location, gtid, entries, task_stack->ts_first_block, stack_top))if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(start): location = %s, gtid = %d, entries = %d, "
"first_block = %p, stack_top = %p \n", location, gtid, entries
, task_stack->ts_first_block, stack_top); }
;
60
61 KMP_DEBUG_ASSERT(stack_top != NULL)((stack_top != __null) ? 0 : __kmp_debug_assert("stack_top != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 61))
;
62 KMP_DEBUG_ASSERT(entries > 0)((entries > 0) ? 0 : __kmp_debug_assert("entries > 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 62))
;
63
64 while (entries != 0) {
65 KMP_DEBUG_ASSERT(stack_top != &task_stack->ts_first_block.sb_block[0])((stack_top != &task_stack->ts_first_block.sb_block[0]
) ? 0 : __kmp_debug_assert("stack_top != &task_stack->ts_first_block.sb_block[0]"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 65))
;
66 // fix up ts_top if we need to pop from previous block
67 if (entries & TASK_STACK_INDEX_MASK == 0) {
68 kmp_stack_block_t *stack_block = (kmp_stack_block_t *)(stack_top);
69
70 stack_block = stack_block->sb_prev;
71 stack_top = &stack_block->sb_block[TASK_STACK_BLOCK_SIZE];
72 }
73
74 // finish bookkeeping
75 stack_top--;
76 entries--;
77
78 tied_task = *stack_top;
79
80 KMP_DEBUG_ASSERT(tied_task != NULL)((tied_task != __null) ? 0 : __kmp_debug_assert("tied_task != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 80))
;
81 KMP_DEBUG_ASSERT(tied_task->td_flags.tasktype == TASK_TIED)((tied_task->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("tied_task->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 81))
;
82
83 KA_TRACE(threshold,if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(%s): gtid=%d, entry=%d, "
"stack_top=%p, tied_task=%p\n", location, gtid, entries, stack_top
, tied_task); }
84 ("__kmp_trace_task_stack(%s): gtid=%d, entry=%d, "if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(%s): gtid=%d, entry=%d, "
"stack_top=%p, tied_task=%p\n", location, gtid, entries, stack_top
, tied_task); }
85 "stack_top=%p, tied_task=%p\n",if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(%s): gtid=%d, entry=%d, "
"stack_top=%p, tied_task=%p\n", location, gtid, entries, stack_top
, tied_task); }
86 location, gtid, entries, stack_top, tied_task))if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(%s): gtid=%d, entry=%d, "
"stack_top=%p, tied_task=%p\n", location, gtid, entries, stack_top
, tied_task); }
;
87 }
88 KMP_DEBUG_ASSERT(stack_top == &task_stack->ts_first_block.sb_block[0])((stack_top == &task_stack->ts_first_block.sb_block[0]
) ? 0 : __kmp_debug_assert("stack_top == &task_stack->ts_first_block.sb_block[0]"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 88))
;
89
90 KA_TRACE(threshold,if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(exit): location = %s, gtid = %d\n"
, location, gtid); }
91 ("__kmp_trace_task_stack(exit): location = %s, gtid = %d\n",if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(exit): location = %s, gtid = %d\n"
, location, gtid); }
92 location, gtid))if (kmp_a_debug >= threshold) { __kmp_debug_printf ("__kmp_trace_task_stack(exit): location = %s, gtid = %d\n"
, location, gtid); }
;
93}
94
95// __kmp_init_task_stack: initialize the task stack for the first time
96// after a thread_data structure is created.
97// It should not be necessary to do this again (assuming the stack works).
98//
99// gtid: global thread identifier of calling thread
100// thread_data: thread data for task team thread containing stack
101static void __kmp_init_task_stack(kmp_int32 gtid,
102 kmp_thread_data_t *thread_data) {
103 kmp_task_stack_t *task_stack = &thread_data->td.td_susp_tied_tasks;
104 kmp_stack_block_t *first_block;
105
106 // set up the first block of the stack
107 first_block = &task_stack->ts_first_block;
108 task_stack->ts_top = (kmp_taskdata_t **)first_block;
109 memset((void *)first_block, '\0',
110 TASK_STACK_BLOCK_SIZE * sizeof(kmp_taskdata_t *));
111
112 // initialize the stack to be empty
113 task_stack->ts_entries = TASK_STACK_EMPTY;
114 first_block->sb_next = NULL__null;
115 first_block->sb_prev = NULL__null;
116}
117
118// __kmp_free_task_stack: free the task stack when thread_data is destroyed.
119//
120// gtid: global thread identifier for calling thread
121// thread_data: thread info for thread containing stack
122static void __kmp_free_task_stack(kmp_int32 gtid,
123 kmp_thread_data_t *thread_data) {
124 kmp_task_stack_t *task_stack = &thread_data->td.td_susp_tied_tasks;
125 kmp_stack_block_t *stack_block = &task_stack->ts_first_block;
126
127 KMP_DEBUG_ASSERT(task_stack->ts_entries == TASK_STACK_EMPTY)((task_stack->ts_entries == TASK_STACK_EMPTY) ? 0 : __kmp_debug_assert
("task_stack->ts_entries == TASK_STACK_EMPTY", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 127))
;
128 // free from the second block of the stack
129 while (stack_block != NULL__null) {
130 kmp_stack_block_t *next_block = (stack_block) ? stack_block->sb_next : NULL__null;
131
132 stack_block->sb_next = NULL__null;
133 stack_block->sb_prev = NULL__null;
134 if (stack_block != &task_stack->ts_first_block) {
135 __kmp_thread_free(thread,___kmp_thread_free((thread), (stack_block), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 136)
136 stack_block)___kmp_thread_free((thread), (stack_block), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 136)
; // free the block, if not the first
137 }
138 stack_block = next_block;
139 }
140 // initialize the stack to be empty
141 task_stack->ts_entries = 0;
142 task_stack->ts_top = NULL__null;
143}
144
145// __kmp_push_task_stack: Push the tied task onto the task stack.
146// Grow the stack if necessary by allocating another block.
147//
148// gtid: global thread identifier for calling thread
149// thread: thread info for thread containing stack
150// tied_task: the task to push on the stack
151static void __kmp_push_task_stack(kmp_int32 gtid, kmp_info_t *thread,
152 kmp_taskdata_t *tied_task) {
153 // GEH - need to consider what to do if tt_threads_data not allocated yet
154 kmp_thread_data_t *thread_data =
155 &thread->th.th_task_team->tt.tt_threads_data[__kmp_tid_from_gtid(gtid)((((gtid) >= 0) ? 0 : __kmp_debug_assert("(gtid) >= 0",
"/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 155)), __kmp_threads[(gtid)]->th.th_info.ds.ds_tid)
];
156 kmp_task_stack_t *task_stack = &thread_data->td.td_susp_tied_tasks;
157
158 if (tied_task->td_flags.team_serial || tied_task->td_flags.tasking_ser) {
159 return; // Don't push anything on stack if team or team tasks are serialized
160 }
161
162 KMP_DEBUG_ASSERT(tied_task->td_flags.tasktype == TASK_TIED)((tied_task->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("tied_task->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 162))
;
163 KMP_DEBUG_ASSERT(task_stack->ts_top != NULL)((task_stack->ts_top != __null) ? 0 : __kmp_debug_assert("task_stack->ts_top != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 163))
;
164
165 KA_TRACE(20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task_stack(enter): GTID: %d; THREAD: %p; TASK: %p\n"
, gtid, thread, tied_task); }
166 ("__kmp_push_task_stack(enter): GTID: %d; THREAD: %p; TASK: %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task_stack(enter): GTID: %d; THREAD: %p; TASK: %p\n"
, gtid, thread, tied_task); }
167 gtid, thread, tied_task))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task_stack(enter): GTID: %d; THREAD: %p; TASK: %p\n"
, gtid, thread, tied_task); }
;
168 // Store entry
169 *(task_stack->ts_top) = tied_task;
170
171 // Do bookkeeping for next push
172 task_stack->ts_top++;
173 task_stack->ts_entries++;
174
175 if (task_stack->ts_entries & TASK_STACK_INDEX_MASK == 0) {
176 // Find beginning of this task block
177 kmp_stack_block_t *stack_block =
178 (kmp_stack_block_t *)(task_stack->ts_top - TASK_STACK_BLOCK_SIZE);
179
180 // Check if we already have a block
181 if (stack_block->sb_next !=
182 NULL__null) { // reset ts_top to beginning of next block
183 task_stack->ts_top = &stack_block->sb_next->sb_block[0];
184 } else { // Alloc new block and link it up
185 kmp_stack_block_t *new_block = (kmp_stack_block_t *)__kmp_thread_calloc(
186 thread, sizeof(kmp_stack_block_t));
187
188 task_stack->ts_top = &new_block->sb_block[0];
189 stack_block->sb_next = new_block;
190 new_block->sb_prev = stack_block;
191 new_block->sb_next = NULL__null;
192
193 KA_TRACE(if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_push_task_stack(): GTID: %d; TASK: %p; Alloc new block: %p\n"
, gtid, tied_task, new_block); }
194 30,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_push_task_stack(): GTID: %d; TASK: %p; Alloc new block: %p\n"
, gtid, tied_task, new_block); }
195 ("__kmp_push_task_stack(): GTID: %d; TASK: %p; Alloc new block: %p\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_push_task_stack(): GTID: %d; TASK: %p; Alloc new block: %p\n"
, gtid, tied_task, new_block); }
196 gtid, tied_task, new_block))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_push_task_stack(): GTID: %d; TASK: %p; Alloc new block: %p\n"
, gtid, tied_task, new_block); }
;
197 }
198 }
199 KA_TRACE(20, ("__kmp_push_task_stack(exit): GTID: %d; TASK: %p\n", gtid,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task_stack(exit): GTID: %d; TASK: %p\n"
, gtid, tied_task); }
200 tied_task))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task_stack(exit): GTID: %d; TASK: %p\n"
, gtid, tied_task); }
;
201}
202
203// __kmp_pop_task_stack: Pop the tied task from the task stack. Don't return
204// the task, just check to make sure it matches the ending task passed in.
205//
206// gtid: global thread identifier for the calling thread
207// thread: thread info structure containing stack
208// tied_task: the task popped off the stack
209// ending_task: the task that is ending (should match popped task)
210static void __kmp_pop_task_stack(kmp_int32 gtid, kmp_info_t *thread,
211 kmp_taskdata_t *ending_task) {
212 // GEH - need to consider what to do if tt_threads_data not allocated yet
213 kmp_thread_data_t *thread_data =
214 &thread->th.th_task_team->tt_threads_data[__kmp_tid_from_gtid(gtid)((((gtid) >= 0) ? 0 : __kmp_debug_assert("(gtid) >= 0",
"/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 214)), __kmp_threads[(gtid)]->th.th_info.ds.ds_tid)
];
215 kmp_task_stack_t *task_stack = &thread_data->td.td_susp_tied_tasks;
216 kmp_taskdata_t *tied_task;
217
218 if (ending_task->td_flags.team_serial || ending_task->td_flags.tasking_ser) {
219 // Don't pop anything from stack if team or team tasks are serialized
220 return;
221 }
222
223 KMP_DEBUG_ASSERT(task_stack->ts_top != NULL)((task_stack->ts_top != __null) ? 0 : __kmp_debug_assert("task_stack->ts_top != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 223))
;
224 KMP_DEBUG_ASSERT(task_stack->ts_entries > 0)((task_stack->ts_entries > 0) ? 0 : __kmp_debug_assert(
"task_stack->ts_entries > 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 224))
;
225
226 KA_TRACE(20, ("__kmp_pop_task_stack(enter): GTID: %d; THREAD: %p\n", gtid,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_pop_task_stack(enter): GTID: %d; THREAD: %p\n"
, gtid, thread); }
227 thread))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_pop_task_stack(enter): GTID: %d; THREAD: %p\n"
, gtid, thread); }
;
228
229 // fix up ts_top if we need to pop from previous block
230 if (task_stack->ts_entries & TASK_STACK_INDEX_MASK == 0) {
231 kmp_stack_block_t *stack_block = (kmp_stack_block_t *)(task_stack->ts_top);
232
233 stack_block = stack_block->sb_prev;
234 task_stack->ts_top = &stack_block->sb_block[TASK_STACK_BLOCK_SIZE];
235 }
236
237 // finish bookkeeping
238 task_stack->ts_top--;
239 task_stack->ts_entries--;
240
241 tied_task = *(task_stack->ts_top);
242
243 KMP_DEBUG_ASSERT(tied_task != NULL)((tied_task != __null) ? 0 : __kmp_debug_assert("tied_task != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 243))
;
244 KMP_DEBUG_ASSERT(tied_task->td_flags.tasktype == TASK_TIED)((tied_task->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("tied_task->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 244))
;
245 KMP_DEBUG_ASSERT(tied_task == ending_task)((tied_task == ending_task) ? 0 : __kmp_debug_assert("tied_task == ending_task"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 245))
; // If we built the stack correctly
246
247 KA_TRACE(20, ("__kmp_pop_task_stack(exit): GTID: %d; TASK: %p\n", gtid,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_pop_task_stack(exit): GTID: %d; TASK: %p\n"
, gtid, tied_task); }
248 tied_task))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_pop_task_stack(exit): GTID: %d; TASK: %p\n"
, gtid, tied_task); }
;
249 return;
250}
251#endif /* BUILD_TIED_TASK_STACK */
252
253// __kmp_push_task: Add a task to the thread's deque
254static kmp_int32 __kmp_push_task(kmp_int32 gtid, kmp_task_t *task) {
255 kmp_info_t *thread = __kmp_threads[gtid];
256 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
257 kmp_task_team_t *task_team = thread->th.th_task_team;
258 kmp_int32 tid = __kmp_tid_from_gtid(gtid)((((gtid) >= 0) ? 0 : __kmp_debug_assert("(gtid) >= 0",
"/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 258)), __kmp_threads[(gtid)]->th.th_info.ds.ds_tid)
;
259 kmp_thread_data_t *thread_data;
260
261 KA_TRACE(20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d trying to push task %p.\n"
, gtid, taskdata); }
262 ("__kmp_push_task: T#%d trying to push task %p.\n", gtid, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d trying to push task %p.\n"
, gtid, taskdata); }
;
263
264 if (taskdata->td_flags.tiedness == TASK_UNTIED0) {
265 // untied task needs to increment counter so that the task structure is not
266 // freed prematurely
267 kmp_int32 counter = 1 + KMP_ATOMIC_INC(&taskdata->td_untied_count)(&taskdata->td_untied_count)->fetch_add(1, std::memory_order_acq_rel
)
;
268 KA_TRACE(if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d untied_count (%d) incremented for task %p\n"
, gtid, counter, taskdata); }
269 20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d untied_count (%d) incremented for task %p\n"
, gtid, counter, taskdata); }
270 ("__kmp_push_task: T#%d untied_count (%d) incremented for task %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d untied_count (%d) incremented for task %p\n"
, gtid, counter, taskdata); }
271 gtid, counter, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d untied_count (%d) incremented for task %p\n"
, gtid, counter, taskdata); }
;
272 }
273
274 // The first check avoids building task_team thread data if serialized
275 if (taskdata->td_flags.task_serial) {
276 KA_TRACE(20, ("__kmp_push_task: T#%d team serialized; returning "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d team serialized; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
277 "TASK_NOT_PUSHED for task %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d team serialized; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
278 gtid, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d team serialized; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
;
279 return TASK_NOT_PUSHED1;
280 }
281
282 // Now that serialized tasks have returned, we can assume that we are not in
283 // immediate exec mode
284 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec)((__kmp_tasking_mode != tskm_immediate_exec) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode != tskm_immediate_exec", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 284))
;
285 if (!KMP_TASKING_ENABLED(task_team)(((task_team)->tt.tt_found_tasks) == (!0))) {
286 __kmp_enable_tasking(task_team, thread);
287 }
288 KMP_DEBUG_ASSERT(TCR_4(task_team->tt.tt_found_tasks) == TRUE)(((task_team->tt.tt_found_tasks) == (!0)) ? 0 : __kmp_debug_assert
("(task_team->tt.tt_found_tasks) == (!0)", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 288))
;
289 KMP_DEBUG_ASSERT(TCR_PTR(task_team->tt.tt_threads_data) != NULL)((((void *)(task_team->tt.tt_threads_data)) != __null) ? 0
: __kmp_debug_assert("((void *)(task_team->tt.tt_threads_data)) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 289))
;
290
291 // Find tasking deque specific to encountering thread
292 thread_data = &task_team->tt.tt_threads_data[tid];
293
294 // No lock needed since only owner can allocate
295 if (thread_data->td.td_deque == NULL__null) {
296 __kmp_alloc_task_deque(thread, thread_data);
297 }
298
299 // Check if deque is full
300 if (TCR_4(thread_data->td.td_deque_ntasks)(thread_data->td.td_deque_ntasks) >=
301 TASK_DEQUE_SIZE(thread_data->td)((thread_data->td).td_deque_size)) {
302 KA_TRACE(20, ("__kmp_push_task: T#%d deque is full; returning "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d deque is full; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
303 "TASK_NOT_PUSHED for task %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d deque is full; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
304 gtid, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d deque is full; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
;
305 return TASK_NOT_PUSHED1;
306 }
307
308 // Lock the deque for the task push operation
309 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
310
311#if OMP_45_ENABLED(50 >= 45)
312 // Need to recheck as we can get a proxy task from a thread outside of OpenMP
313 if (TCR_4(thread_data->td.td_deque_ntasks)(thread_data->td.td_deque_ntasks) >=
314 TASK_DEQUE_SIZE(thread_data->td)((thread_data->td).td_deque_size)) {
315 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
316 KA_TRACE(20, ("__kmp_push_task: T#%d deque is full on 2nd check; returning "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d deque is full on 2nd check; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
317 "TASK_NOT_PUSHED for task %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d deque is full on 2nd check; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
318 gtid, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d deque is full on 2nd check; returning "
"TASK_NOT_PUSHED for task %p\n", gtid, taskdata); }
;
319 return TASK_NOT_PUSHED1;
320 }
321#else
322 // Must have room since no thread can add tasks but calling thread
323 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) <(((thread_data->td.td_deque_ntasks) < ((thread_data->
td).td_deque_size)) ? 0 : __kmp_debug_assert("(thread_data->td.td_deque_ntasks) < ((thread_data->td).td_deque_size)"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 324))
324 TASK_DEQUE_SIZE(thread_data->td))(((thread_data->td.td_deque_ntasks) < ((thread_data->
td).td_deque_size)) ? 0 : __kmp_debug_assert("(thread_data->td.td_deque_ntasks) < ((thread_data->td).td_deque_size)"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 324))
;
325#endif
326
327 thread_data->td.td_deque[thread_data->td.td_deque_tail] =
328 taskdata; // Push taskdata
329 // Wrap index.
330 thread_data->td.td_deque_tail =
331 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td)((thread_data->td).td_deque_size - 1);
332 TCW_4(thread_data->td.td_deque_ntasks,(thread_data->td.td_deque_ntasks) = ((thread_data->td.td_deque_ntasks
) + 1)
333 TCR_4(thread_data->td.td_deque_ntasks) + 1)(thread_data->td.td_deque_ntasks) = ((thread_data->td.td_deque_ntasks
) + 1)
; // Adjust task count
334
335 KA_TRACE(20, ("__kmp_push_task: T#%d returning TASK_SUCCESSFULLY_PUSHED: "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d returning TASK_SUCCESSFULLY_PUSHED: "
"task=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data
->td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
336 "task=%p ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d returning TASK_SUCCESSFULLY_PUSHED: "
"task=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data
->td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
337 gtid, taskdata, thread_data->td.td_deque_ntasks,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d returning TASK_SUCCESSFULLY_PUSHED: "
"task=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data
->td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
338 thread_data->td.td_deque_head, thread_data->td.td_deque_tail))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_push_task: T#%d returning TASK_SUCCESSFULLY_PUSHED: "
"task=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data
->td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
;
339
340 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
341
342 return TASK_SUCCESSFULLY_PUSHED0;
343}
344
345// __kmp_pop_current_task_from_thread: set up current task from called thread
346// when team ends
347//
348// this_thr: thread structure to set current_task in.
349void __kmp_pop_current_task_from_thread(kmp_info_t *this_thr) {
350 KF_TRACE(10, ("__kmp_pop_current_task_from_thread(enter): T#%d "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(enter): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
351 "this_thread=%p, curtask=%p, "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(enter): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
352 "curtask_parent=%p\n",if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(enter): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
353 0, this_thr, this_thr->th.th_current_task,if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(enter): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
354 this_thr->th.th_current_task->td_parent))if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(enter): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
;
355
356 this_thr->th.th_current_task = this_thr->th.th_current_task->td_parent;
357
358 KF_TRACE(10, ("__kmp_pop_current_task_from_thread(exit): T#%d "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(exit): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
359 "this_thread=%p, curtask=%p, "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(exit): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
360 "curtask_parent=%p\n",if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(exit): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
361 0, this_thr, this_thr->th.th_current_task,if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(exit): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
362 this_thr->th.th_current_task->td_parent))if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_pop_current_task_from_thread(exit): T#%d "
"this_thread=%p, curtask=%p, " "curtask_parent=%p\n", 0, this_thr
, this_thr->th.th_current_task, this_thr->th.th_current_task
->td_parent); }
;
363}
364
365// __kmp_push_current_task_to_thread: set up current task in called thread for a
366// new team
367//
368// this_thr: thread structure to set up
369// team: team for implicit task data
370// tid: thread within team to set up
371void __kmp_push_current_task_to_thread(kmp_info_t *this_thr, kmp_team_t *team,
372 int tid) {
373 // current task of the thread is a parent of the new just created implicit
374 // tasks of new team
375 KF_TRACE(10, ("__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
376 "curtask=%p "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
377 "parent_task=%p\n",if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
378 tid, this_thr, this_thr->th.th_current_task,if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
379 team->t.t_implicit_task_taskdata[tid].td_parent))if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(enter): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
;
380
381 KMP_DEBUG_ASSERT(this_thr != NULL)((this_thr != __null) ? 0 : __kmp_debug_assert("this_thr != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 381))
;
382
383 if (tid == 0) {
384 if (this_thr->th.th_current_task != &team->t.t_implicit_task_taskdata[0]) {
385 team->t.t_implicit_task_taskdata[0].td_parent =
386 this_thr->th.th_current_task;
387 this_thr->th.th_current_task = &team->t.t_implicit_task_taskdata[0];
388 }
389 } else {
390 team->t.t_implicit_task_taskdata[tid].td_parent =
391 team->t.t_implicit_task_taskdata[0].td_parent;
392 this_thr->th.th_current_task = &team->t.t_implicit_task_taskdata[tid];
393 }
394
395 KF_TRACE(10, ("__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
396 "curtask=%p "if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
397 "parent_task=%p\n",if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
398 tid, this_thr, this_thr->th.th_current_task,if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
399 team->t.t_implicit_task_taskdata[tid].td_parent))if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_push_current_task_to_thread(exit): T#%d this_thread=%p "
"curtask=%p " "parent_task=%p\n", tid, this_thr, this_thr->
th.th_current_task, team->t.t_implicit_task_taskdata[tid].
td_parent); }
;
400}
401
402// __kmp_task_start: bookkeeping for a task starting execution
403//
404// GTID: global thread id of calling thread
405// task: task starting execution
406// current_task: task suspending
407static void __kmp_task_start(kmp_int32 gtid, kmp_task_t *task,
408 kmp_taskdata_t *current_task) {
409 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
410 kmp_info_t *thread = __kmp_threads[gtid];
411
412 KA_TRACE(10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_start(enter): T#%d starting task %p: current_task=%p\n"
, gtid, taskdata, current_task); }
413 ("__kmp_task_start(enter): T#%d starting task %p: current_task=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_start(enter): T#%d starting task %p: current_task=%p\n"
, gtid, taskdata, current_task); }
414 gtid, taskdata, current_task))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_start(enter): T#%d starting task %p: current_task=%p\n"
, gtid, taskdata, current_task); }
;
415
416 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT)((taskdata->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 416))
;
417
418 // mark currently executing task as suspended
419 // TODO: GEH - make sure root team implicit task is initialized properly.
420 // KMP_DEBUG_ASSERT( current_task -> td_flags.executing == 1 );
421 current_task->td_flags.executing = 0;
422
423// Add task to stack if tied
424#ifdef BUILD_TIED_TASK_STACK
425 if (taskdata->td_flags.tiedness == TASK_TIED1) {
426 __kmp_push_task_stack(gtid, thread, taskdata);
427 }
428#endif /* BUILD_TIED_TASK_STACK */
429
430 // mark starting task as executing and as current task
431 thread->th.th_current_task = taskdata;
432
433 KMP_DEBUG_ASSERT(taskdata->td_flags.started == 0 ||((taskdata->td_flags.started == 0 || taskdata->td_flags
.tiedness == 0) ? 0 : __kmp_debug_assert("taskdata->td_flags.started == 0 || taskdata->td_flags.tiedness == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 434))
434 taskdata->td_flags.tiedness == TASK_UNTIED)((taskdata->td_flags.started == 0 || taskdata->td_flags
.tiedness == 0) ? 0 : __kmp_debug_assert("taskdata->td_flags.started == 0 || taskdata->td_flags.tiedness == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 434))
;
435 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 0 ||((taskdata->td_flags.executing == 0 || taskdata->td_flags
.tiedness == 0) ? 0 : __kmp_debug_assert("taskdata->td_flags.executing == 0 || taskdata->td_flags.tiedness == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 436))
436 taskdata->td_flags.tiedness == TASK_UNTIED)((taskdata->td_flags.executing == 0 || taskdata->td_flags
.tiedness == 0) ? 0 : __kmp_debug_assert("taskdata->td_flags.executing == 0 || taskdata->td_flags.tiedness == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 436))
;
437 taskdata->td_flags.started = 1;
438 taskdata->td_flags.executing = 1;
439 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0)((taskdata->td_flags.complete == 0) ? 0 : __kmp_debug_assert
("taskdata->td_flags.complete == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 439))
;
440 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0)((taskdata->td_flags.freed == 0) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.freed == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 440))
;
441
442 // GEH TODO: shouldn't we pass some sort of location identifier here?
443 // APT: yes, we will pass location here.
444 // need to store current thread state (in a thread or taskdata structure)
445 // before setting work_state, otherwise wrong state is set after end of task
446
447 KA_TRACE(10, ("__kmp_task_start(exit): T#%d task=%p\n", gtid, taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_start(exit): T#%d task=%p\n"
, gtid, taskdata); }
;
448
449 return;
450}
451
452#if OMPT_SUPPORT1
453//------------------------------------------------------------------------------
454// __ompt_task_init:
455// Initialize OMPT fields maintained by a task. This will only be called after
456// ompt_start_tool, so we already know whether ompt is enabled or not.
457
458static inline void __ompt_task_init(kmp_taskdata_t *task, int tid) {
459 // The calls to __ompt_task_init already have the ompt_enabled condition.
460 task->ompt_task_info.task_data.value = 0;
461 task->ompt_task_info.frame.exit_frame = NULL__null;
462 task->ompt_task_info.frame.enter_frame = NULL__null;
463#if OMP_40_ENABLED(50 >= 40)
464 task->ompt_task_info.ndeps = 0;
465 task->ompt_task_info.deps = NULL__null;
466#endif /* OMP_40_ENABLED */
467}
468
469// __ompt_task_start:
470// Build and trigger task-begin event
471static inline void __ompt_task_start(kmp_task_t *task,
472 kmp_taskdata_t *current_task,
473 kmp_int32 gtid) {
474 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
475 ompt_task_status_t status = ompt_task_others;
476 if (__kmp_threads[gtid]->th.ompt_thread_info.ompt_task_yielded) {
477 status = ompt_task_yield;
478 __kmp_threads[gtid]->th.ompt_thread_info.ompt_task_yielded = 0;
479 }
480 /* let OMPT know that we're about to run this task */
481 if (ompt_enabled.ompt_callback_task_schedule) {
482 ompt_callbacks.ompt_callback(ompt_callback_task_schedule)ompt_callback_task_schedule_callback(
483 &(current_task->ompt_task_info.task_data), status,
484 &(taskdata->ompt_task_info.task_data));
485 }
486 taskdata->ompt_task_info.scheduling_parent = current_task;
487}
488
489// __ompt_task_finish:
490// Build and trigger final task-schedule event
491static inline void __ompt_task_finish(kmp_task_t *task,
492 kmp_taskdata_t *resumed_task) {
493 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
494 ompt_task_status_t status = ompt_task_complete;
495 if (taskdata->td_flags.tiedness == TASK_UNTIED0 &&
496 KMP_TEST_THEN_ADD32(&(taskdata->td_untied_count), 0)__sync_fetch_and_add((volatile kmp_int32 *)(&(taskdata->
td_untied_count)), (kmp_int32)(0))
> 1)
497 status = ompt_task_others;
498 if (__kmp_omp_cancellation && taskdata->td_taskgroup &&
499 taskdata->td_taskgroup->cancel_request == cancel_taskgroup) {
500 status = ompt_task_cancel;
501 }
502
503 /* let OMPT know that we're returning to the callee task */
504 if (ompt_enabled.ompt_callback_task_schedule) {
505 ompt_callbacks.ompt_callback(ompt_callback_task_schedule)ompt_callback_task_schedule_callback(
506 &(taskdata->ompt_task_info.task_data), status,
507 &((resumed_task ? resumed_task
508 : (taskdata->ompt_task_info.scheduling_parent
509 ? taskdata->ompt_task_info.scheduling_parent
510 : taskdata->td_parent))
511 ->ompt_task_info.task_data));
512 }
513}
514#endif
515
516template <bool ompt>
517static void __kmpc_omp_task_begin_if0_template(ident_t *loc_ref, kmp_int32 gtid,
518 kmp_task_t *task,
519 void *frame_address,
520 void *return_address) {
521 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
522 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
523
524 KA_TRACE(10, ("__kmpc_omp_task_begin_if0(enter): T#%d loc=%p task=%p "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0(enter): T#%d loc=%p task=%p "
"current_task=%p\n", gtid, loc_ref, taskdata, current_task);
}
525 "current_task=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0(enter): T#%d loc=%p task=%p "
"current_task=%p\n", gtid, loc_ref, taskdata, current_task);
}
526 gtid, loc_ref, taskdata, current_task))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0(enter): T#%d loc=%p task=%p "
"current_task=%p\n", gtid, loc_ref, taskdata, current_task);
}
;
527
528 if (taskdata->td_flags.tiedness == TASK_UNTIED0) {
529 // untied task needs to increment counter so that the task structure is not
530 // freed prematurely
531 kmp_int32 counter = 1 + KMP_ATOMIC_INC(&taskdata->td_untied_count)(&taskdata->td_untied_count)->fetch_add(1, std::memory_order_acq_rel
)
;
532 KA_TRACE(20, ("__kmpc_omp_task_begin_if0: T#%d untied_count (%d) "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0: T#%d untied_count (%d) "
"incremented for task %p\n", gtid, counter, taskdata); }
533 "incremented for task %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0: T#%d untied_count (%d) "
"incremented for task %p\n", gtid, counter, taskdata); }
534 gtid, counter, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0: T#%d untied_count (%d) "
"incremented for task %p\n", gtid, counter, taskdata); }
;
535 }
536
537 taskdata->td_flags.task_serial =
538 1; // Execute this task immediately, not deferred.
539 __kmp_task_start(gtid, task, current_task);
540
541#if OMPT_SUPPORT1
542 if (ompt) {
543 if (current_task->ompt_task_info.frame.enter_frame == NULL__null) {
544 current_task->ompt_task_info.frame.enter_frame =
545 taskdata->ompt_task_info.frame.exit_frame = frame_address;
546 }
547 if (ompt_enabled.ompt_callback_task_create) {
548 ompt_task_info_t *parent_info = &(current_task->ompt_task_info);
549 ompt_callbacks.ompt_callback(ompt_callback_task_create)ompt_callback_task_create_callback(
550 &(parent_info->task_data), &(parent_info->frame),
551 &(taskdata->ompt_task_info.task_data),
552 ompt_task_explicit | TASK_TYPE_DETAILS_FORMAT(taskdata)((taskdata->td_flags.task_serial || taskdata->td_flags.
tasking_ser) ? ompt_task_undeferred : 0x0) | ((!(taskdata->
td_flags.tiedness)) ? ompt_task_untied : 0x0) | (taskdata->
td_flags.final ? ompt_task_final : 0x0) | (taskdata->td_flags
.merged_if0 ? ompt_task_mergeable : 0x0)
, 0,
553 return_address);
554 }
555 __ompt_task_start(task, current_task, gtid);
556 }
557#endif // OMPT_SUPPORT
558
559 KA_TRACE(10, ("__kmpc_omp_task_begin_if0(exit): T#%d loc=%p task=%p,\n", gtid,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0(exit): T#%d loc=%p task=%p,\n"
, gtid, loc_ref, taskdata); }
560 loc_ref, taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin_if0(exit): T#%d loc=%p task=%p,\n"
, gtid, loc_ref, taskdata); }
;
561}
562
563#if OMPT_SUPPORT1
564OMPT_NOINLINE__attribute__((noinline))
565static void __kmpc_omp_task_begin_if0_ompt(ident_t *loc_ref, kmp_int32 gtid,
566 kmp_task_t *task,
567 void *frame_address,
568 void *return_address) {
569 __kmpc_omp_task_begin_if0_template<true>(loc_ref, gtid, task, frame_address,
570 return_address);
571}
572#endif // OMPT_SUPPORT
573
574// __kmpc_omp_task_begin_if0: report that a given serialized task has started
575// execution
576//
577// loc_ref: source location information; points to beginning of task block.
578// gtid: global thread number.
579// task: task thunk for the started task.
580void __kmpc_omp_task_begin_if0(ident_t *loc_ref, kmp_int32 gtid,
581 kmp_task_t *task) {
582#if OMPT_SUPPORT1
583 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
584 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
585 __kmpc_omp_task_begin_if0_ompt(loc_ref, gtid, task,
586 OMPT_GET_FRAME_ADDRESS(1)__builtin_frame_address(1),
587 OMPT_LOAD_RETURN_ADDRESS(gtid)__ompt_load_return_address(gtid));
588 return;
589 }
590#endif
591 __kmpc_omp_task_begin_if0_template<false>(loc_ref, gtid, task, NULL__null, NULL__null);
592}
593
594#ifdef TASK_UNUSED
595// __kmpc_omp_task_begin: report that a given task has started execution
596// NEVER GENERATED BY COMPILER, DEPRECATED!!!
597void __kmpc_omp_task_begin(ident_t *loc_ref, kmp_int32 gtid, kmp_task_t *task) {
598 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
599
600 KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin(enter): T#%d loc=%p task=%p current_task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1), current_task
); }
601 10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin(enter): T#%d loc=%p task=%p current_task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1), current_task
); }
602 ("__kmpc_omp_task_begin(enter): T#%d loc=%p task=%p current_task=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin(enter): T#%d loc=%p task=%p current_task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1), current_task
); }
603 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task), current_task))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin(enter): T#%d loc=%p task=%p current_task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1), current_task
); }
;
604
605 __kmp_task_start(gtid, task, current_task);
606
607 KA_TRACE(10, ("__kmpc_omp_task_begin(exit): T#%d loc=%p task=%p,\n", gtid,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin(exit): T#%d loc=%p task=%p,\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
608 loc_ref, KMP_TASK_TO_TASKDATA(task)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_begin(exit): T#%d loc=%p task=%p,\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
;
609 return;
610}
611#endif // TASK_UNUSED
612
613// __kmp_free_task: free the current task space and the space for shareds
614//
615// gtid: Global thread ID of calling thread
616// taskdata: task to free
617// thread: thread data structure of caller
618static void __kmp_free_task(kmp_int32 gtid, kmp_taskdata_t *taskdata,
619 kmp_info_t *thread) {
620 KA_TRACE(30, ("__kmp_free_task: T#%d freeing data from task %p\n", gtid,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_free_task: T#%d freeing data from task %p\n"
, gtid, taskdata); }
621 taskdata))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_free_task: T#%d freeing data from task %p\n"
, gtid, taskdata); }
;
622
623 // Check to make sure all flags and counters have the correct values
624 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT)((taskdata->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 624))
;
625 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 0)((taskdata->td_flags.executing == 0) ? 0 : __kmp_debug_assert
("taskdata->td_flags.executing == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 625))
;
626 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 1)((taskdata->td_flags.complete == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.complete == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 626))
;
627 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0)((taskdata->td_flags.freed == 0) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.freed == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 627))
;
628 KMP_DEBUG_ASSERT(taskdata->td_allocated_child_tasks == 0 ||((taskdata->td_allocated_child_tasks == 0 || taskdata->
td_flags.task_serial == 1) ? 0 : __kmp_debug_assert("taskdata->td_allocated_child_tasks == 0 || taskdata->td_flags.task_serial == 1"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 629))
629 taskdata->td_flags.task_serial == 1)((taskdata->td_allocated_child_tasks == 0 || taskdata->
td_flags.task_serial == 1) ? 0 : __kmp_debug_assert("taskdata->td_allocated_child_tasks == 0 || taskdata->td_flags.task_serial == 1"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 629))
;
630 KMP_DEBUG_ASSERT(taskdata->td_incomplete_child_tasks == 0)((taskdata->td_incomplete_child_tasks == 0) ? 0 : __kmp_debug_assert
("taskdata->td_incomplete_child_tasks == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 630))
;
631
632 taskdata->td_flags.freed = 1;
633 ANNOTATE_HAPPENS_BEFORE(taskdata);
634// deallocate the taskdata and shared variable blocks associated with this task
635#if USE_FAST_MEMORY3
636 __kmp_fast_free(thread, taskdata)___kmp_fast_free((thread), (taskdata), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 636)
;
637#else /* ! USE_FAST_MEMORY */
638 __kmp_thread_free(thread, taskdata)___kmp_thread_free((thread), (taskdata), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 638)
;
639#endif
640
641 KA_TRACE(20, ("__kmp_free_task: T#%d freed task %p\n", gtid, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task: T#%d freed task %p\n"
, gtid, taskdata); }
;
642}
643
644// __kmp_free_task_and_ancestors: free the current task and ancestors without
645// children
646//
647// gtid: Global thread ID of calling thread
648// taskdata: task to free
649// thread: thread data structure of caller
650static void __kmp_free_task_and_ancestors(kmp_int32 gtid,
651 kmp_taskdata_t *taskdata,
652 kmp_info_t *thread) {
653#if OMP_45_ENABLED(50 >= 45)
654 // Proxy tasks must always be allowed to free their parents
655 // because they can be run in background even in serial mode.
656 kmp_int32 team_serial =
657 (taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser) &&
658 !taskdata->td_flags.proxy;
659#else
660 kmp_int32 team_serial =
661 taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser;
662#endif
663 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT)((taskdata->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 663))
;
664
665 kmp_int32 children = KMP_ATOMIC_DEC(&taskdata->td_allocated_child_tasks)(&taskdata->td_allocated_child_tasks)->fetch_sub(1,
std::memory_order_acq_rel)
- 1;
666 KMP_DEBUG_ASSERT(children >= 0)((children >= 0) ? 0 : __kmp_debug_assert("children >= 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 666))
;
667
668 // Now, go up the ancestor tree to see if any ancestors can now be freed.
669 while (children == 0) {
670 kmp_taskdata_t *parent_taskdata = taskdata->td_parent;
671
672 KA_TRACE(20, ("__kmp_free_task_and_ancestors(enter): T#%d task %p complete "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_and_ancestors(enter): T#%d task %p complete "
"and freeing itself\n", gtid, taskdata); }
673 "and freeing itself\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_and_ancestors(enter): T#%d task %p complete "
"and freeing itself\n", gtid, taskdata); }
674 gtid, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_and_ancestors(enter): T#%d task %p complete "
"and freeing itself\n", gtid, taskdata); }
;
675
676 // --- Deallocate my ancestor task ---
677 __kmp_free_task(gtid, taskdata, thread);
678
679 taskdata = parent_taskdata;
680
681 // Stop checking ancestors at implicit task instead of walking up ancestor
682 // tree to avoid premature deallocation of ancestors.
683 if (team_serial || taskdata->td_flags.tasktype == TASK_IMPLICIT0)
684 return;
685
686 // Predecrement simulated by "- 1" calculation
687 children = KMP_ATOMIC_DEC(&taskdata->td_allocated_child_tasks)(&taskdata->td_allocated_child_tasks)->fetch_sub(1,
std::memory_order_acq_rel)
- 1;
688 KMP_DEBUG_ASSERT(children >= 0)((children >= 0) ? 0 : __kmp_debug_assert("children >= 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 688))
;
689 }
690
691 KA_TRACE(if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "
"not freeing it yet\n", gtid, taskdata, children); }
692 20, ("__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "
"not freeing it yet\n", gtid, taskdata, children); }
693 "not freeing it yet\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "
"not freeing it yet\n", gtid, taskdata, children); }
694 gtid, taskdata, children))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_and_ancestors(exit): T#%d task %p has %d children; "
"not freeing it yet\n", gtid, taskdata, children); }
;
695}
696
697// __kmp_task_finish: bookkeeping to do when a task finishes execution
698//
699// gtid: global thread ID for calling thread
700// task: task to be finished
701// resumed_task: task to be resumed. (may be NULL if task is serialized)
702static void __kmp_task_finish(kmp_int32 gtid, kmp_task_t *task,
703 kmp_taskdata_t *resumed_task) {
704 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
705 kmp_info_t *thread = __kmp_threads[gtid];
706 kmp_task_team_t *task_team =
707 thread->th.th_task_team; // might be NULL for serial teams...
708 kmp_int32 children = 0;
709
710 KA_TRACE(10, ("__kmp_task_finish(enter): T#%d finishing task %p and resuming "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(enter): T#%d finishing task %p and resuming "
"task %p\n", gtid, taskdata, resumed_task); }
711 "task %p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(enter): T#%d finishing task %p and resuming "
"task %p\n", gtid, taskdata, resumed_task); }
712 gtid, taskdata, resumed_task))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(enter): T#%d finishing task %p and resuming "
"task %p\n", gtid, taskdata, resumed_task); }
;
713
714 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT)((taskdata->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 714))
;
715
716// Pop task from stack if tied
717#ifdef BUILD_TIED_TASK_STACK
718 if (taskdata->td_flags.tiedness == TASK_TIED1) {
719 __kmp_pop_task_stack(gtid, thread, taskdata);
720 }
721#endif /* BUILD_TIED_TASK_STACK */
722
723 if (taskdata->td_flags.tiedness == TASK_UNTIED0) {
724 // untied task needs to check the counter so that the task structure is not
725 // freed prematurely
726 kmp_int32 counter = KMP_ATOMIC_DEC(&taskdata->td_untied_count)(&taskdata->td_untied_count)->fetch_sub(1, std::memory_order_acq_rel
)
- 1;
727 KA_TRACE(if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_finish: T#%d untied_count (%d) decremented for task %p\n"
, gtid, counter, taskdata); }
728 20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_finish: T#%d untied_count (%d) decremented for task %p\n"
, gtid, counter, taskdata); }
729 ("__kmp_task_finish: T#%d untied_count (%d) decremented for task %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_finish: T#%d untied_count (%d) decremented for task %p\n"
, gtid, counter, taskdata); }
730 gtid, counter, taskdata))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_finish: T#%d untied_count (%d) decremented for task %p\n"
, gtid, counter, taskdata); }
;
731 if (counter > 0) {
732 // untied task is not done, to be continued possibly by other thread, do
733 // not free it now
734 if (resumed_task == NULL__null) {
735 KMP_DEBUG_ASSERT(taskdata->td_flags.task_serial)((taskdata->td_flags.task_serial) ? 0 : __kmp_debug_assert
("taskdata->td_flags.task_serial", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 735))
;
736 resumed_task = taskdata->td_parent; // In a serialized task, the resumed
737 // task is the parent
738 }
739 thread->th.th_current_task = resumed_task; // restore current_task
740 resumed_task->td_flags.executing = 1; // resume previous task
741 KA_TRACE(10, ("__kmp_task_finish(exit): T#%d partially done task %p, "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(exit): T#%d partially done task %p, "
"resuming task %p\n", gtid, taskdata, resumed_task); }
742 "resuming task %p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(exit): T#%d partially done task %p, "
"resuming task %p\n", gtid, taskdata, resumed_task); }
743 gtid, taskdata, resumed_task))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(exit): T#%d partially done task %p, "
"resuming task %p\n", gtid, taskdata, resumed_task); }
;
744 return;
745 }
746 }
747
748 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0)((taskdata->td_flags.complete == 0) ? 0 : __kmp_debug_assert
("taskdata->td_flags.complete == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 748))
;
749 taskdata->td_flags.complete = 1; // mark the task as completed
750 KMP_DEBUG_ASSERT(taskdata->td_flags.started == 1)((taskdata->td_flags.started == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.started == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 750))
;
751 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0)((taskdata->td_flags.freed == 0) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.freed == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 751))
;
752
753 // Only need to keep track of count if team parallel and tasking not
754 // serialized
755 if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
756 // Predecrement simulated by "- 1" calculation
757 children =
758 KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks)(&taskdata->td_parent->td_incomplete_child_tasks)->
fetch_sub(1, std::memory_order_acq_rel)
- 1;
759 KMP_DEBUG_ASSERT(children >= 0)((children >= 0) ? 0 : __kmp_debug_assert("children >= 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 759))
;
760#if OMP_40_ENABLED(50 >= 40)
761 if (taskdata->td_taskgroup)
762 KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count)(&taskdata->td_taskgroup->count)->fetch_sub(1, std
::memory_order_acq_rel)
;
763#if OMP_45_ENABLED(50 >= 45)
764 }
765 // if we found proxy tasks there could exist a dependency chain
766 // with the proxy task as origin
767 if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser) ||
768 (task_team && task_team->tt.tt_found_proxy_tasks)) {
769#endif
770 __kmp_release_deps(gtid, taskdata);
771#endif
772 }
773
774 // td_flags.executing must be marked as 0 after __kmp_release_deps has been
775 // called. Othertwise, if a task is executed immediately from the release_deps
776 // code, the flag will be reset to 1 again by this same function
777 KMP_DEBUG_ASSERT(taskdata->td_flags.executing == 1)((taskdata->td_flags.executing == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.executing == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 777))
;
778 taskdata->td_flags.executing = 0; // suspend the finishing task
779
780 KA_TRACE(if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_finish: T#%d finished task %p, %d incomplete children\n"
, gtid, taskdata, children); }
781 20, ("__kmp_task_finish: T#%d finished task %p, %d incomplete children\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_finish: T#%d finished task %p, %d incomplete children\n"
, gtid, taskdata, children); }
782 gtid, taskdata, children))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_finish: T#%d finished task %p, %d incomplete children\n"
, gtid, taskdata, children); }
;
783
784#if OMP_40_ENABLED(50 >= 40)
785 /* If the tasks' destructor thunk flag has been set, we need to invoke the
786 destructor thunk that has been generated by the compiler. The code is
787 placed here, since at this point other tasks might have been released
788 hence overlapping the destructor invokations with some other work in the
789 released tasks. The OpenMP spec is not specific on when the destructors
790 are invoked, so we should be free to choose. */
791 if (taskdata->td_flags.destructors_thunk) {
792 kmp_routine_entry_t destr_thunk = task->data1.destructors;
793 KMP_ASSERT(destr_thunk)((destr_thunk) ? 0 : __kmp_debug_assert("destr_thunk", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 793))
;
794 destr_thunk(gtid, task);
795 }
796#endif // OMP_40_ENABLED
797
798 // bookkeeping for resuming task:
799 // GEH - note tasking_ser => task_serial
800 KMP_DEBUG_ASSERT((((taskdata->td_flags.tasking_ser || taskdata->td_flags
.task_serial) == taskdata->td_flags.task_serial) ? 0 : __kmp_debug_assert
("(taskdata->td_flags.tasking_ser || taskdata->td_flags.task_serial) == taskdata->td_flags.task_serial"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 802))
801 (taskdata->td_flags.tasking_ser || taskdata->td_flags.task_serial) ==(((taskdata->td_flags.tasking_ser || taskdata->td_flags
.task_serial) == taskdata->td_flags.task_serial) ? 0 : __kmp_debug_assert
("(taskdata->td_flags.tasking_ser || taskdata->td_flags.task_serial) == taskdata->td_flags.task_serial"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 802))
802 taskdata->td_flags.task_serial)(((taskdata->td_flags.tasking_ser || taskdata->td_flags
.task_serial) == taskdata->td_flags.task_serial) ? 0 : __kmp_debug_assert
("(taskdata->td_flags.tasking_ser || taskdata->td_flags.task_serial) == taskdata->td_flags.task_serial"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 802))
;
803 if (taskdata->td_flags.task_serial) {
804 if (resumed_task == NULL__null) {
805 resumed_task = taskdata->td_parent; // In a serialized task, the resumed
806 // task is the parent
807 }
808 } else {
809 KMP_DEBUG_ASSERT(resumed_task !=((resumed_task != __null) ? 0 : __kmp_debug_assert("resumed_task != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 810))
810 NULL)((resumed_task != __null) ? 0 : __kmp_debug_assert("resumed_task != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 810))
; // verify that resumed task is passed as arguemnt
811 }
812
813 // Free this task and then ancestor tasks if they have no children.
814 // Restore th_current_task first as suggested by John:
815 // johnmc: if an asynchronous inquiry peers into the runtime system
816 // it doesn't see the freed task as the current task.
817 thread->th.th_current_task = resumed_task;
818 __kmp_free_task_and_ancestors(gtid, taskdata, thread);
819
820 // TODO: GEH - make sure root team implicit task is initialized properly.
821 // KMP_DEBUG_ASSERT( resumed_task->td_flags.executing == 0 );
822 resumed_task->td_flags.executing = 1; // resume previous task
823
824 KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(exit): T#%d finished task %p, resuming task %p\n"
, gtid, taskdata, resumed_task); }
825 10, ("__kmp_task_finish(exit): T#%d finished task %p, resuming task %p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(exit): T#%d finished task %p, resuming task %p\n"
, gtid, taskdata, resumed_task); }
826 gtid, taskdata, resumed_task))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_finish(exit): T#%d finished task %p, resuming task %p\n"
, gtid, taskdata, resumed_task); }
;
827
828 return;
829}
830
831template <bool ompt>
832static void __kmpc_omp_task_complete_if0_template(ident_t *loc_ref,
833 kmp_int32 gtid,
834 kmp_task_t *task) {
835 KA_TRACE(10, ("__kmpc_omp_task_complete_if0(enter): T#%d loc=%p task=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete_if0(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
836 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete_if0(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
;
837 // this routine will provide task to resume
838 __kmp_task_finish(gtid, task, NULL__null);
839
840 KA_TRACE(10, ("__kmpc_omp_task_complete_if0(exit): T#%d loc=%p task=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete_if0(exit): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
841 gtid, loc_ref, KMP_TASK_TO_TASKDATA(task)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete_if0(exit): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
;
842
843#if OMPT_SUPPORT1
844 if (ompt) {
845 __ompt_task_finish(task, NULL__null);
846 omp_frame_t *ompt_frame;
847 __ompt_get_task_info_internal(0, NULL__null, NULL__null, &ompt_frame, NULL__null, NULL__null);
848 ompt_frame->enter_frame = NULL__null;
849 }
850#endif
851
852 return;
853}
854
855#if OMPT_SUPPORT1
856OMPT_NOINLINE__attribute__((noinline))
857void __kmpc_omp_task_complete_if0_ompt(ident_t *loc_ref, kmp_int32 gtid,
858 kmp_task_t *task) {
859 __kmpc_omp_task_complete_if0_template<true>(loc_ref, gtid, task);
860}
861#endif // OMPT_SUPPORT
862
863// __kmpc_omp_task_complete_if0: report that a task has completed execution
864//
865// loc_ref: source location information; points to end of task block.
866// gtid: global thread number.
867// task: task thunk for the completed task.
868void __kmpc_omp_task_complete_if0(ident_t *loc_ref, kmp_int32 gtid,
869 kmp_task_t *task) {
870#if OMPT_SUPPORT1
871 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
872 __kmpc_omp_task_complete_if0_ompt(loc_ref, gtid, task);
873 return;
874 }
875#endif
876 __kmpc_omp_task_complete_if0_template<false>(loc_ref, gtid, task);
877}
878
879#ifdef TASK_UNUSED
880// __kmpc_omp_task_complete: report that a task has completed execution
881// NEVER GENERATED BY COMPILER, DEPRECATED!!!
882void __kmpc_omp_task_complete(ident_t *loc_ref, kmp_int32 gtid,
883 kmp_task_t *task) {
884 KA_TRACE(10, ("__kmpc_omp_task_complete(enter): T#%d loc=%p task=%p\n", gtid,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
885 loc_ref, KMP_TASK_TO_TASKDATA(task)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
;
886
887 __kmp_task_finish(gtid, task, NULL__null); // Not sure how to find task to resume
888
889 KA_TRACE(10, ("__kmpc_omp_task_complete(exit): T#%d loc=%p task=%p\n", gtid,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete(exit): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
890 loc_ref, KMP_TASK_TO_TASKDATA(task)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_complete(exit): T#%d loc=%p task=%p\n"
, gtid, loc_ref, (((kmp_taskdata_t *)task) - 1)); }
;
891 return;
892}
893#endif // TASK_UNUSED
894
895// __kmp_init_implicit_task: Initialize the appropriate fields in the implicit
896// task for a given thread
897//
898// loc_ref: reference to source location of parallel region
899// this_thr: thread data structure corresponding to implicit task
900// team: team for this_thr
901// tid: thread id of given thread within team
902// set_curr_task: TRUE if need to push current task to thread
903// NOTE: Routine does not set up the implicit task ICVS. This is assumed to
904// have already been done elsewhere.
905// TODO: Get better loc_ref. Value passed in may be NULL
906void __kmp_init_implicit_task(ident_t *loc_ref, kmp_info_t *this_thr,
907 kmp_team_t *team, int tid, int set_curr_task) {
908 kmp_taskdata_t *task = &team->t.t_implicit_task_taskdata[tid];
909
910 KF_TRACE(if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_init_implicit_task(enter): T#:%d team=%p task=%p, reinit=%s\n"
, tid, team, task, set_curr_task ? "TRUE" : "FALSE"); }
911 10,if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_init_implicit_task(enter): T#:%d team=%p task=%p, reinit=%s\n"
, tid, team, task, set_curr_task ? "TRUE" : "FALSE"); }
912 ("__kmp_init_implicit_task(enter): T#:%d team=%p task=%p, reinit=%s\n",if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_init_implicit_task(enter): T#:%d team=%p task=%p, reinit=%s\n"
, tid, team, task, set_curr_task ? "TRUE" : "FALSE"); }
913 tid, team, task, set_curr_task ? "TRUE" : "FALSE"))if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_init_implicit_task(enter): T#:%d team=%p task=%p, reinit=%s\n"
, tid, team, task, set_curr_task ? "TRUE" : "FALSE"); }
;
914
915 task->td_task_id = KMP_GEN_TASK_ID()(~0);
916 task->td_team = team;
917 // task->td_parent = NULL; // fix for CQ230101 (broken parent task info
918 // in debugger)
919 task->td_ident = loc_ref;
920 task->td_taskwait_ident = NULL__null;
921 task->td_taskwait_counter = 0;
922 task->td_taskwait_thread = 0;
923
924 task->td_flags.tiedness = TASK_TIED1;
925 task->td_flags.tasktype = TASK_IMPLICIT0;
926#if OMP_45_ENABLED(50 >= 45)
927 task->td_flags.proxy = TASK_FULL0;
928#endif
929
930 // All implicit tasks are executed immediately, not deferred
931 task->td_flags.task_serial = 1;
932 task->td_flags.tasking_ser = (__kmp_tasking_mode == tskm_immediate_exec);
933 task->td_flags.team_serial = (team->t.t_serialized) ? 1 : 0;
934
935 task->td_flags.started = 1;
936 task->td_flags.executing = 1;
937 task->td_flags.complete = 0;
938 task->td_flags.freed = 0;
939
940#if OMP_40_ENABLED(50 >= 40)
941 task->td_depnode = NULL__null;
942#endif
943 task->td_last_tied = task;
944
945 if (set_curr_task) { // only do this init first time thread is created
946 KMP_ATOMIC_ST_REL(&task->td_incomplete_child_tasks, 0)(&task->td_incomplete_child_tasks)->store(0, std::memory_order_release
)
;
947 // Not used: don't need to deallocate implicit task
948 KMP_ATOMIC_ST_REL(&task->td_allocated_child_tasks, 0)(&task->td_allocated_child_tasks)->store(0, std::memory_order_release
)
;
949#if OMP_40_ENABLED(50 >= 40)
950 task->td_taskgroup = NULL__null; // An implicit task does not have taskgroup
951 task->td_dephash = NULL__null;
952#endif
953 __kmp_push_current_task_to_thread(this_thr, team, tid);
954 } else {
955 KMP_DEBUG_ASSERT(task->td_incomplete_child_tasks == 0)((task->td_incomplete_child_tasks == 0) ? 0 : __kmp_debug_assert
("task->td_incomplete_child_tasks == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 955))
;
956 KMP_DEBUG_ASSERT(task->td_allocated_child_tasks == 0)((task->td_allocated_child_tasks == 0) ? 0 : __kmp_debug_assert
("task->td_allocated_child_tasks == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 956))
;
957 }
958
959#if OMPT_SUPPORT1
960 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0))
961 __ompt_task_init(task, tid);
962#endif
963
964 KF_TRACE(10, ("__kmp_init_implicit_task(exit): T#:%d team=%p task=%p\n", tid,if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_init_implicit_task(exit): T#:%d team=%p task=%p\n"
, tid, team, task); }
965 team, task))if (kmp_f_debug >= 10) { __kmp_debug_printf ("__kmp_init_implicit_task(exit): T#:%d team=%p task=%p\n"
, tid, team, task); }
;
966}
967
968// __kmp_finish_implicit_task: Release resources associated to implicit tasks
969// at the end of parallel regions. Some resources are kept for reuse in the next
970// parallel region.
971//
972// thread: thread data structure corresponding to implicit task
973void __kmp_finish_implicit_task(kmp_info_t *thread) {
974 kmp_taskdata_t *task = thread->th.th_current_task;
975 if (task->td_dephash)
976 __kmp_dephash_free_entries(thread, task->td_dephash);
977}
978
979// __kmp_free_implicit_task: Release resources associated to implicit tasks
980// when these are destroyed regions
981//
982// thread: thread data structure corresponding to implicit task
983void __kmp_free_implicit_task(kmp_info_t *thread) {
984 kmp_taskdata_t *task = thread->th.th_current_task;
985 if (task && task->td_dephash) {
986 __kmp_dephash_free(thread, task->td_dephash);
987 task->td_dephash = NULL__null;
988 }
989}
990
991// Round up a size to a power of two specified by val: Used to insert padding
992// between structures co-allocated using a single malloc() call
993static size_t __kmp_round_up_to_val(size_t size, size_t val) {
994 if (size & (val - 1)) {
995 size &= ~(val - 1);
996 if (size <= KMP_SIZE_T_MAX(0xFFFFFFFFFFFFFFFF) - val) {
997 size += val; // Round up if there is no overflow.
998 }
999 }
1000 return size;
1001} // __kmp_round_up_to_va
1002
1003// __kmp_task_alloc: Allocate the taskdata and task data structures for a task
1004//
1005// loc_ref: source location information
1006// gtid: global thread number.
1007// flags: include tiedness & task type (explicit vs. implicit) of the ''new''
1008// task encountered. Converted from kmp_int32 to kmp_tasking_flags_t in routine.
1009// sizeof_kmp_task_t: Size in bytes of kmp_task_t data structure including
1010// private vars accessed in task.
1011// sizeof_shareds: Size in bytes of array of pointers to shared vars accessed
1012// in task.
1013// task_entry: Pointer to task code entry point generated by compiler.
1014// returns: a pointer to the allocated kmp_task_t structure (task).
1015kmp_task_t *__kmp_task_alloc(ident_t *loc_ref, kmp_int32 gtid,
1016 kmp_tasking_flags_t *flags,
1017 size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1018 kmp_routine_entry_t task_entry) {
1019 kmp_task_t *task;
1020 kmp_taskdata_t *taskdata;
1021 kmp_info_t *thread = __kmp_threads[gtid];
1022 kmp_team_t *team = thread->th.th_team;
1023 kmp_taskdata_t *parent_task = thread->th.th_current_task;
1024 size_t shareds_offset;
1025
1026 KA_TRACE(10, ("__kmp_task_alloc(enter): T#%d loc=%p, flags=(0x%x) "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_alloc(enter): T#%d loc=%p, flags=(0x%x) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, *((kmp_int32 *)flags), sizeof_kmp_task_t, sizeof_shareds, task_entry
); }
1027 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_alloc(enter): T#%d loc=%p, flags=(0x%x) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, *((kmp_int32 *)flags), sizeof_kmp_task_t, sizeof_shareds, task_entry
); }
1028 gtid, loc_ref, *((kmp_int32 *)flags), sizeof_kmp_task_t,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_alloc(enter): T#%d loc=%p, flags=(0x%x) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, *((kmp_int32 *)flags), sizeof_kmp_task_t, sizeof_shareds, task_entry
); }
1029 sizeof_shareds, task_entry))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_alloc(enter): T#%d loc=%p, flags=(0x%x) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, *((kmp_int32 *)flags), sizeof_kmp_task_t, sizeof_shareds, task_entry
); }
;
1030
1031 if (parent_task->td_flags.final) {
1032 if (flags->merged_if0) {
1033 }
1034 flags->final = 1;
1035 }
1036 if (flags->tiedness == TASK_UNTIED0 && !team->t.t_serialized) {
1037 // Untied task encountered causes the TSC algorithm to check entire deque of
1038 // the victim thread. If no untied task encountered, then checking the head
1039 // of the deque should be enough.
1040 KMP_CHECK_UPDATE(thread->th.th_task_team->tt.tt_untied_task_encountered, 1)if ((thread->th.th_task_team->tt.tt_untied_task_encountered
) != (1)) (thread->th.th_task_team->tt.tt_untied_task_encountered
) = (1)
;
1041 }
1042
1043#if OMP_45_ENABLED(50 >= 45)
1044 if (flags->proxy == TASK_PROXY1) {
1045 flags->tiedness = TASK_UNTIED0;
1046 flags->merged_if0 = 1;
1047
1048 /* are we running in a sequential parallel or tskm_immediate_exec... we need
1049 tasking support enabled */
1050 if ((thread->th.th_task_team) == NULL__null) {
1051 /* This should only happen if the team is serialized
1052 setup a task team and propagate it to the thread */
1053 KMP_DEBUG_ASSERT(team->t.t_serialized)((team->t.t_serialized) ? 0 : __kmp_debug_assert("team->t.t_serialized"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1053))
;
1054 KA_TRACE(30,if (kmp_a_debug >= 30) { __kmp_debug_printf ("T#%d creating task team in __kmp_task_alloc for proxy task\n"
, gtid); }
1055 ("T#%d creating task team in __kmp_task_alloc for proxy task\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("T#%d creating task team in __kmp_task_alloc for proxy task\n"
, gtid); }
1056 gtid))if (kmp_a_debug >= 30) { __kmp_debug_printf ("T#%d creating task team in __kmp_task_alloc for proxy task\n"
, gtid); }
;
1057 __kmp_task_team_setup(
1058 thread, team,
1059 1); // 1 indicates setup the current team regardless of nthreads
1060 thread->th.th_task_team = team->t.t_task_team[thread->th.th_task_state];
1061 }
1062 kmp_task_team_t *task_team = thread->th.th_task_team;
1063
1064 /* tasking must be enabled now as the task might not be pushed */
1065 if (!KMP_TASKING_ENABLED(task_team)(((task_team)->tt.tt_found_tasks) == (!0))) {
1066 KA_TRACE(if (kmp_a_debug >= 30) { __kmp_debug_printf ("T#%d enabling tasking in __kmp_task_alloc for proxy task\n"
, gtid); }
1067 30,if (kmp_a_debug >= 30) { __kmp_debug_printf ("T#%d enabling tasking in __kmp_task_alloc for proxy task\n"
, gtid); }
1068 ("T#%d enabling tasking in __kmp_task_alloc for proxy task\n", gtid))if (kmp_a_debug >= 30) { __kmp_debug_printf ("T#%d enabling tasking in __kmp_task_alloc for proxy task\n"
, gtid); }
;
1069 __kmp_enable_tasking(task_team, thread);
1070 kmp_int32 tid = thread->th.th_info.ds.ds_tid;
1071 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[tid];
1072 // No lock needed since only owner can allocate
1073 if (thread_data->td.td_deque == NULL__null) {
1074 __kmp_alloc_task_deque(thread, thread_data);
1075 }
1076 }
1077
1078 if (task_team->tt.tt_found_proxy_tasks == FALSE0)
1079 TCW_4(task_team->tt.tt_found_proxy_tasks, TRUE)(task_team->tt.tt_found_proxy_tasks) = ((!0));
1080 }
1081#endif
1082
1083 // Calculate shared structure offset including padding after kmp_task_t struct
1084 // to align pointers in shared struct
1085 shareds_offset = sizeof(kmp_taskdata_t) + sizeof_kmp_task_t;
1086 shareds_offset = __kmp_round_up_to_val(shareds_offset, sizeof(void *));
1087
1088 // Allocate a kmp_taskdata_t block and a kmp_task_t block.
1089 KA_TRACE(30, ("__kmp_task_alloc: T#%d First malloc size: %ld\n", gtid,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_task_alloc: T#%d First malloc size: %ld\n"
, gtid, shareds_offset); }
1090 shareds_offset))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_task_alloc: T#%d First malloc size: %ld\n"
, gtid, shareds_offset); }
;
1091 KA_TRACE(30, ("__kmp_task_alloc: T#%d Second malloc size: %ld\n", gtid,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_task_alloc: T#%d Second malloc size: %ld\n"
, gtid, sizeof_shareds); }
1092 sizeof_shareds))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_task_alloc: T#%d Second malloc size: %ld\n"
, gtid, sizeof_shareds); }
;
1093
1094// Avoid double allocation here by combining shareds with taskdata
1095#if USE_FAST_MEMORY3
1096 taskdata = (kmp_taskdata_t *)__kmp_fast_allocate(thread, shareds_offset +___kmp_fast_allocate((thread), (shareds_offset + sizeof_shareds
), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1097)
1097 sizeof_shareds)___kmp_fast_allocate((thread), (shareds_offset + sizeof_shareds
), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1097)
;
1098#else /* ! USE_FAST_MEMORY */
1099 taskdata = (kmp_taskdata_t *)__kmp_thread_malloc(thread, shareds_offset +___kmp_thread_malloc((thread), (shareds_offset + sizeof_shareds
), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1100)
1100 sizeof_shareds)___kmp_thread_malloc((thread), (shareds_offset + sizeof_shareds
), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1100)
;
1101#endif /* USE_FAST_MEMORY */
1102 ANNOTATE_HAPPENS_AFTER(taskdata);
1103
1104 task = KMP_TASKDATA_TO_TASK(taskdata)(kmp_task_t *)(taskdata + 1);
1105
1106// Make sure task & taskdata are aligned appropriately
1107#if KMP_ARCH_X860 || KMP_ARCH_PPC64(0 || 0) || !KMP_HAVE_QUAD0
1108 KMP_DEBUG_ASSERT((((kmp_uintptr_t)taskdata) & (sizeof(double) - 1)) == 0)(((((kmp_uintptr_t)taskdata) & (sizeof(double) - 1)) == 0
) ? 0 : __kmp_debug_assert("(((kmp_uintptr_t)taskdata) & (sizeof(double) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1108))
;
1109 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task) & (sizeof(double) - 1)) == 0)(((((kmp_uintptr_t)task) & (sizeof(double) - 1)) == 0) ? 0
: __kmp_debug_assert("(((kmp_uintptr_t)task) & (sizeof(double) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1109))
;
1110#else
1111 KMP_DEBUG_ASSERT((((kmp_uintptr_t)taskdata) & (sizeof(_Quad) - 1)) == 0)(((((kmp_uintptr_t)taskdata) & (sizeof(_Quad) - 1)) == 0)
? 0 : __kmp_debug_assert("(((kmp_uintptr_t)taskdata) & (sizeof(_Quad) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1111))
;
1112 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task) & (sizeof(_Quad) - 1)) == 0)(((((kmp_uintptr_t)task) & (sizeof(_Quad) - 1)) == 0) ? 0
: __kmp_debug_assert("(((kmp_uintptr_t)task) & (sizeof(_Quad) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1112))
;
1113#endif
1114 if (sizeof_shareds > 0) {
1115 // Avoid double allocation here by combining shareds with taskdata
1116 task->shareds = &((char *)taskdata)[shareds_offset];
1117 // Make sure shareds struct is aligned to pointer size
1118 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1)) ==(((((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1
)) == 0) ? 0 : __kmp_debug_assert("(((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1119))
1119 0)(((((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1
)) == 0) ? 0 : __kmp_debug_assert("(((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1119))
;
1120 } else {
1121 task->shareds = NULL__null;
1122 }
1123 task->routine = task_entry;
1124 task->part_id = 0; // AC: Always start with 0 part id
1125
1126 taskdata->td_task_id = KMP_GEN_TASK_ID()(~0);
1127 taskdata->td_team = team;
1128 taskdata->td_alloc_thread = thread;
1129 taskdata->td_parent = parent_task;
1130 taskdata->td_level = parent_task->td_level + 1; // increment nesting level
1131 KMP_ATOMIC_ST_RLX(&taskdata->td_untied_count, 0)(&taskdata->td_untied_count)->store(0, std::memory_order_relaxed
)
;
1132 taskdata->td_ident = loc_ref;
1133 taskdata->td_taskwait_ident = NULL__null;
1134 taskdata->td_taskwait_counter = 0;
1135 taskdata->td_taskwait_thread = 0;
1136 KMP_DEBUG_ASSERT(taskdata->td_parent != NULL)((taskdata->td_parent != __null) ? 0 : __kmp_debug_assert(
"taskdata->td_parent != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1136))
;
1137#if OMP_45_ENABLED(50 >= 45)
1138 // avoid copying icvs for proxy tasks
1139 if (flags->proxy == TASK_FULL0)
1140#endif
1141 copy_icvs(&taskdata->td_icvs, &taskdata->td_parent->td_icvs);
1142
1143 taskdata->td_flags.tiedness = flags->tiedness;
1144 taskdata->td_flags.final = flags->final;
1145 taskdata->td_flags.merged_if0 = flags->merged_if0;
1146#if OMP_40_ENABLED(50 >= 40)
1147 taskdata->td_flags.destructors_thunk = flags->destructors_thunk;
1148#endif // OMP_40_ENABLED
1149#if OMP_45_ENABLED(50 >= 45)
1150 taskdata->td_flags.proxy = flags->proxy;
1151 taskdata->td_task_team = thread->th.th_task_team;
1152 taskdata->td_size_alloc = shareds_offset + sizeof_shareds;
1153#endif
1154 taskdata->td_flags.tasktype = TASK_EXPLICIT1;
1155
1156 // GEH - TODO: fix this to copy parent task's value of tasking_ser flag
1157 taskdata->td_flags.tasking_ser = (__kmp_tasking_mode == tskm_immediate_exec);
1158
1159 // GEH - TODO: fix this to copy parent task's value of team_serial flag
1160 taskdata->td_flags.team_serial = (team->t.t_serialized) ? 1 : 0;
1161
1162 // GEH - Note we serialize the task if the team is serialized to make sure
1163 // implicit parallel region tasks are not left until program termination to
1164 // execute. Also, it helps locality to execute immediately.
1165
1166 taskdata->td_flags.task_serial =
1167 (parent_task->td_flags.final || taskdata->td_flags.team_serial ||
1168 taskdata->td_flags.tasking_ser);
1169
1170 taskdata->td_flags.started = 0;
1171 taskdata->td_flags.executing = 0;
1172 taskdata->td_flags.complete = 0;
1173 taskdata->td_flags.freed = 0;
1174
1175 taskdata->td_flags.native = flags->native;
1176
1177 KMP_ATOMIC_ST_RLX(&taskdata->td_incomplete_child_tasks, 0)(&taskdata->td_incomplete_child_tasks)->store(0, std
::memory_order_relaxed)
;
1178 // start at one because counts current task and children
1179 KMP_ATOMIC_ST_RLX(&taskdata->td_allocated_child_tasks, 1)(&taskdata->td_allocated_child_tasks)->store(1, std
::memory_order_relaxed)
;
1180#if OMP_40_ENABLED(50 >= 40)
1181 taskdata->td_taskgroup =
1182 parent_task->td_taskgroup; // task inherits taskgroup from the parent task
1183 taskdata->td_dephash = NULL__null;
1184 taskdata->td_depnode = NULL__null;
1185#endif
1186 if (flags->tiedness == TASK_UNTIED0)
1187 taskdata->td_last_tied = NULL__null; // will be set when the task is scheduled
1188 else
1189 taskdata->td_last_tied = taskdata;
1190
1191// Only need to keep track of child task counts if team parallel and tasking not
1192// serialized or if it is a proxy task
1193#if OMP_45_ENABLED(50 >= 45)
1194 if (flags->proxy == TASK_PROXY1 ||
1195 !(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser))
1196#else
1197 if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser))
1198#endif
1199 {
1200 KMP_ATOMIC_INC(&parent_task->td_incomplete_child_tasks)(&parent_task->td_incomplete_child_tasks)->fetch_add
(1, std::memory_order_acq_rel)
;
1201#if OMP_40_ENABLED(50 >= 40)
1202 if (parent_task->td_taskgroup)
1203 KMP_ATOMIC_INC(&parent_task->td_taskgroup->count)(&parent_task->td_taskgroup->count)->fetch_add(1
, std::memory_order_acq_rel)
;
1204#endif
1205 // Only need to keep track of allocated child tasks for explicit tasks since
1206 // implicit not deallocated
1207 if (taskdata->td_parent->td_flags.tasktype == TASK_EXPLICIT1) {
1208 KMP_ATOMIC_INC(&taskdata->td_parent->td_allocated_child_tasks)(&taskdata->td_parent->td_allocated_child_tasks)->
fetch_add(1, std::memory_order_acq_rel)
;
1209 }
1210 }
1211
1212 KA_TRACE(20, ("__kmp_task_alloc(exit): T#%d created task %p parent=%p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_alloc(exit): T#%d created task %p parent=%p\n"
, gtid, taskdata, taskdata->td_parent); }
1213 gtid, taskdata, taskdata->td_parent))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_alloc(exit): T#%d created task %p parent=%p\n"
, gtid, taskdata, taskdata->td_parent); }
;
1214 ANNOTATE_HAPPENS_BEFORE(task);
1215
1216#if OMPT_SUPPORT1
1217 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0))
1218 __ompt_task_init(taskdata, gtid);
1219#endif
1220
1221 return task;
1222}
1223
1224kmp_task_t *__kmpc_omp_task_alloc(ident_t *loc_ref, kmp_int32 gtid,
1225 kmp_int32 flags, size_t sizeof_kmp_task_t,
1226 size_t sizeof_shareds,
1227 kmp_routine_entry_t task_entry) {
1228 kmp_task_t *retval;
1229 kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
1230
1231 input_flags->native = FALSE0;
1232// __kmp_task_alloc() sets up all other runtime flags
1233
1234#if OMP_45_ENABLED(50 >= 45)
1235 KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", input_flags
->proxy ? "proxy" : "", sizeof_kmp_task_t, sizeof_shareds,
task_entry); }
1236 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", input_flags
->proxy ? "proxy" : "", sizeof_kmp_task_t, sizeof_shareds,
task_entry); }
1237 gtid, loc_ref, input_flags->tiedness ? "tied " : "untied",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", input_flags
->proxy ? "proxy" : "", sizeof_kmp_task_t, sizeof_shareds,
task_entry); }
1238 input_flags->proxy ? "proxy" : "", sizeof_kmp_task_t,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", input_flags
->proxy ? "proxy" : "", sizeof_kmp_task_t, sizeof_shareds,
task_entry); }
1239 sizeof_shareds, task_entry))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", input_flags
->proxy ? "proxy" : "", sizeof_kmp_task_t, sizeof_shareds,
task_entry); }
;
1240#else
1241 KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s) "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", sizeof_kmp_task_t
, sizeof_shareds, task_entry); }
1242 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", sizeof_kmp_task_t
, sizeof_shareds, task_entry); }
1243 gtid, loc_ref, input_flags->tiedness ? "tied " : "untied",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", sizeof_kmp_task_t
, sizeof_shareds, task_entry); }
1244 sizeof_kmp_task_t, sizeof_shareds, task_entry))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s) "
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n", gtid, loc_ref
, input_flags->tiedness ? "tied " : "untied", sizeof_kmp_task_t
, sizeof_shareds, task_entry); }
;
1245#endif
1246
1247 retval = __kmp_task_alloc(loc_ref, gtid, input_flags, sizeof_kmp_task_t,
1248 sizeof_shareds, task_entry);
1249
1250 KA_TRACE(20, ("__kmpc_omp_task_alloc(exit): T#%d retval %p\n", gtid, retval))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_omp_task_alloc(exit): T#%d retval %p\n"
, gtid, retval); }
;
1251
1252 return retval;
1253}
1254
1255// __kmp_invoke_task: invoke the specified task
1256//
1257// gtid: global thread ID of caller
1258// task: the task to invoke
1259// current_task: the task to resume after task invokation
1260static void __kmp_invoke_task(kmp_int32 gtid, kmp_task_t *task,
1261 kmp_taskdata_t *current_task) {
1262 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
1263 kmp_uint64 cur_time;
34
'cur_time' declared without an initial value
1264#if OMP_40_ENABLED(50 >= 40)
1265 int discard = 0 /* false */;
1266#endif
1267 KA_TRACE(if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(enter): T#%d invoking task %p, current_task=%p\n"
, gtid, taskdata, current_task); }
1268 30, ("__kmp_invoke_task(enter): T#%d invoking task %p, current_task=%p\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(enter): T#%d invoking task %p, current_task=%p\n"
, gtid, taskdata, current_task); }
1269 gtid, taskdata, current_task))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(enter): T#%d invoking task %p, current_task=%p\n"
, gtid, taskdata, current_task); }
;
1270 KMP_DEBUG_ASSERT(task)((task) ? 0 : __kmp_debug_assert("task", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1270))
;
1271#if OMP_45_ENABLED(50 >= 45)
1272 if (taskdata->td_flags.proxy == TASK_PROXY1 &&
1273 taskdata->td_flags.complete == 1) {
1274 // This is a proxy task that was already completed but it needs to run
1275 // its bottom-half finish
1276 KA_TRACE(if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task: T#%d running bottom finish for proxy task %p\n"
, gtid, taskdata); }
1277 30,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task: T#%d running bottom finish for proxy task %p\n"
, gtid, taskdata); }
1278 ("__kmp_invoke_task: T#%d running bottom finish for proxy task %p\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task: T#%d running bottom finish for proxy task %p\n"
, gtid, taskdata); }
1279 gtid, taskdata))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task: T#%d running bottom finish for proxy task %p\n"
, gtid, taskdata); }
;
1280
1281 __kmp_bottom_half_finish_proxy(gtid, task);
1282
1283 KA_TRACE(30, ("__kmp_invoke_task(exit): T#%d completed bottom finish for "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(exit): T#%d completed bottom finish for "
"proxy task %p, resuming task %p\n", gtid, taskdata, current_task
); }
1284 "proxy task %p, resuming task %p\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(exit): T#%d completed bottom finish for "
"proxy task %p, resuming task %p\n", gtid, taskdata, current_task
); }
1285 gtid, taskdata, current_task))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(exit): T#%d completed bottom finish for "
"proxy task %p, resuming task %p\n", gtid, taskdata, current_task
); }
;
1286
1287 return;
1288 }
1289#endif
1290
1291#if USE_ITT_BUILD1 && USE_ITT_NOTIFY1
1292 if (__kmp_forkjoin_frames_mode == 3) {
35
Assuming '__kmp_forkjoin_frames_mode' is not equal to 3
36
Taking false branch
1293 // Get the current time stamp to measure task execution time to correct
1294 // barrier imbalance time
1295 cur_time = __itt_get_timestamp(!__kmp_itt_get_timestamp_ptr__3_0) ? 0 : __kmp_itt_get_timestamp_ptr__3_0();
1296 }
1297#endif
1298
1299#if OMP_45_ENABLED(50 >= 45)
1300 // Proxy tasks are not handled by the runtime
1301 if (taskdata->td_flags.proxy != TASK_PROXY1) {
37
Taking true branch
1302#endif
1303 ANNOTATE_HAPPENS_AFTER(task);
1304 __kmp_task_start(gtid, task, current_task); // OMPT only if not discarded
1305#if OMP_45_ENABLED(50 >= 45)
1306 }
1307#endif
1308
1309#if OMPT_SUPPORT1
1310 ompt_thread_info_t oldInfo;
1311 kmp_info_t *thread;
1312 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
38
Taking false branch
1313 // Store the threads states and restore them after the task
1314 thread = __kmp_threads[gtid];
1315 oldInfo = thread->th.ompt_thread_info;
1316 thread->th.ompt_thread_info.wait_id = 0;
1317 thread->th.ompt_thread_info.state = (thread->th.th_team_serialized)
1318 ? omp_state_work_serial
1319 : omp_state_work_parallel;
1320 taskdata->ompt_task_info.frame.exit_frame = OMPT_GET_FRAME_ADDRESS(0)__builtin_frame_address(0);
1321 }
1322#endif
1323
1324#if OMP_40_ENABLED(50 >= 40)
1325 // TODO: cancel tasks if the parallel region has also been cancelled
1326 // TODO: check if this sequence can be hoisted above __kmp_task_start
1327 // if cancellation has been enabled for this run ...
1328 if (__kmp_omp_cancellation) {
39
Assuming '__kmp_omp_cancellation' is 0
40
Taking false branch
1329 kmp_info_t *this_thr = __kmp_threads[gtid];
1330 kmp_team_t *this_team = this_thr->th.th_team;
1331 kmp_taskgroup_t *taskgroup = taskdata->td_taskgroup;
1332 if ((taskgroup && taskgroup->cancel_request) ||
1333 (this_team->t.t_cancel_request == cancel_parallel)) {
1334#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
1335 ompt_data_t *task_data;
1336 if (UNLIKELY(ompt_enabled.ompt_callback_cancel)__builtin_expect(!!(ompt_enabled.ompt_callback_cancel), 0)) {
1337 __ompt_get_task_info_internal(0, NULL__null, &task_data, NULL__null, NULL__null, NULL__null);
1338 ompt_callbacks.ompt_callback(ompt_callback_cancel)ompt_callback_cancel_callback(
1339 task_data,
1340 ((taskgroup && taskgroup->cancel_request) ? ompt_cancel_taskgroup
1341 : ompt_cancel_parallel) |
1342 ompt_cancel_discarded_task,
1343 NULL__null);
1344 }
1345#endif
1346 KMP_COUNT_BLOCK(TASK_cancelled)((void)0);
1347 // this task belongs to a task group and we need to cancel it
1348 discard = 1 /* true */;
1349 }
1350 }
1351
1352 // Invoke the task routine and pass in relevant data.
1353 // Thunks generated by gcc take a different argument list.
1354 if (!discard) {
41
Taking true branch
1355 if (taskdata->td_flags.tiedness == TASK_UNTIED0) {
42
Taking false branch
1356 taskdata->td_last_tied = current_task->td_last_tied;
1357 KMP_DEBUG_ASSERT(taskdata->td_last_tied)((taskdata->td_last_tied) ? 0 : __kmp_debug_assert("taskdata->td_last_tied"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1357))
;
1358 }
1359#if KMP_STATS_ENABLED0
1360 KMP_COUNT_BLOCK(TASK_executed)((void)0);
1361 switch (KMP_GET_THREAD_STATE()((void)0)) {
1362 case FORK_JOIN_BARRIER:
1363 KMP_PUSH_PARTITIONED_TIMER(OMP_task_join_bar)((void)0);
1364 break;
1365 case PLAIN_BARRIER:
1366 KMP_PUSH_PARTITIONED_TIMER(OMP_task_plain_bar)((void)0);
1367 break;
1368 case TASKYIELD:
1369 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskyield)((void)0);
1370 break;
1371 case TASKWAIT:
1372 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskwait)((void)0);
1373 break;
1374 case TASKGROUP:
1375 KMP_PUSH_PARTITIONED_TIMER(OMP_task_taskgroup)((void)0);
1376 break;
1377 default:
1378 KMP_PUSH_PARTITIONED_TIMER(OMP_task_immediate)((void)0);
1379 break;
1380 }
1381#endif // KMP_STATS_ENABLED
1382#endif // OMP_40_ENABLED
1383
1384// OMPT task begin
1385#if OMPT_SUPPORT1
1386 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0))
43
Taking false branch
1387 __ompt_task_start(task, current_task, gtid);
1388#endif
1389
1390#ifdef KMP_GOMP_COMPAT
1391 if (taskdata->td_flags.native) {
44
Taking false branch
1392 ((void (*)(void *))(*(task->routine)))(task->shareds);
1393 } else
1394#endif /* KMP_GOMP_COMPAT */
1395 {
1396 (*(task->routine))(gtid, task);
1397 }
1398 KMP_POP_PARTITIONED_TIMER()((void)0);
1399
1400#if OMPT_SUPPORT1
1401 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0))
45
Taking false branch
1402 __ompt_task_finish(task, current_task);
1403#endif
1404#if OMP_40_ENABLED(50 >= 40)
1405 }
1406#endif // OMP_40_ENABLED
1407
1408#if OMPT_SUPPORT1
1409 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
46
Taking false branch
1410 thread->th.ompt_thread_info = oldInfo;
1411 taskdata->ompt_task_info.frame.exit_frame = NULL__null;
1412 }
1413#endif
1414
1415#if OMP_45_ENABLED(50 >= 45)
1416 // Proxy tasks are not handled by the runtime
1417 if (taskdata->td_flags.proxy != TASK_PROXY1) {
47
Assuming the condition is false
48
Taking false branch
1418#endif
1419 ANNOTATE_HAPPENS_BEFORE(taskdata->td_parent);
1420 __kmp_task_finish(gtid, task, current_task); // OMPT only if not discarded
1421#if OMP_45_ENABLED(50 >= 45)
1422 }
1423#endif
1424
1425#if USE_ITT_BUILD1 && USE_ITT_NOTIFY1
1426 // Barrier imbalance - correct arrive time after the task finished
1427 if (__kmp_forkjoin_frames_mode == 3) {
49
Assuming '__kmp_forkjoin_frames_mode' is equal to 3
50
Taking true branch
1428 kmp_info_t *this_thr = __kmp_threads[gtid];
1429 if (this_thr->th.th_bar_arrive_time) {
51
Assuming the condition is true
52
Taking true branch
1430 this_thr->th.th_bar_arrive_time += (__itt_get_timestamp(!__kmp_itt_get_timestamp_ptr__3_0) ? 0 : __kmp_itt_get_timestamp_ptr__3_0() - cur_time);
53
The right operand of '-' is a garbage value
1431 }
1432 }
1433#endif
1434 KA_TRACE(if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(exit): T#%d completed task %p, resuming task %p\n"
, gtid, taskdata, current_task); }
1435 30,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(exit): T#%d completed task %p, resuming task %p\n"
, gtid, taskdata, current_task); }
1436 ("__kmp_invoke_task(exit): T#%d completed task %p, resuming task %p\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(exit): T#%d completed task %p, resuming task %p\n"
, gtid, taskdata, current_task); }
1437 gtid, taskdata, current_task))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_invoke_task(exit): T#%d completed task %p, resuming task %p\n"
, gtid, taskdata, current_task); }
;
1438 return;
1439}
1440
1441// __kmpc_omp_task_parts: Schedule a thread-switchable task for execution
1442//
1443// loc_ref: location of original task pragma (ignored)
1444// gtid: Global Thread ID of encountering thread
1445// new_task: task thunk allocated by __kmp_omp_task_alloc() for the ''new task''
1446// Returns:
1447// TASK_CURRENT_NOT_QUEUED (0) if did not suspend and queue current task to
1448// be resumed later.
1449// TASK_CURRENT_QUEUED (1) if suspended and queued the current task to be
1450// resumed later.
1451kmp_int32 __kmpc_omp_task_parts(ident_t *loc_ref, kmp_int32 gtid,
1452 kmp_task_t *new_task) {
1453 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task)(((kmp_taskdata_t *)new_task) - 1);
1454
1455 KA_TRACE(10, ("__kmpc_omp_task_parts(enter): T#%d loc=%p task=%p\n", gtid,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_parts(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, new_taskdata); }
1456 loc_ref, new_taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_parts(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, new_taskdata); }
;
1457
1458#if OMPT_SUPPORT1
1459 kmp_taskdata_t *parent;
1460 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
1461 parent = new_taskdata->td_parent;
1462 if (ompt_enabled.ompt_callback_task_create) {
1463 ompt_data_t task_data = ompt_data_none;
1464 ompt_callbacks.ompt_callback(ompt_callback_task_create)ompt_callback_task_create_callback(
1465 parent ? &(parent->ompt_task_info.task_data) : &task_data,
1466 parent ? &(parent->ompt_task_info.frame) : NULL__null,
1467 &(new_taskdata->ompt_task_info.task_data), ompt_task_explicit, 0,
1468 OMPT_GET_RETURN_ADDRESS(0)__builtin_return_address(0));
1469 }
1470 }
1471#endif
1472
1473 /* Should we execute the new task or queue it? For now, let's just always try
1474 to queue it. If the queue fills up, then we'll execute it. */
1475
1476 if (__kmp_push_task(gtid, new_task) == TASK_NOT_PUSHED1) // if cannot defer
1477 { // Execute this task immediately
1478 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
1479 new_taskdata->td_flags.task_serial = 1;
1480 __kmp_invoke_task(gtid, new_task, current_task);
1481 }
1482
1483 KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "
"loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n", gtid, loc_ref
, new_taskdata); }
1484 10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "
"loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n", gtid, loc_ref
, new_taskdata); }
1485 ("__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "
"loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n", gtid, loc_ref
, new_taskdata); }
1486 "loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "
"loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n", gtid, loc_ref
, new_taskdata); }
1487 gtid, loc_ref, new_taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task_parts(exit): T#%d returning TASK_CURRENT_NOT_QUEUED: "
"loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n", gtid, loc_ref
, new_taskdata); }
;
1488
1489 ANNOTATE_HAPPENS_BEFORE(new_task);
1490#if OMPT_SUPPORT1
1491 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
1492 parent->ompt_task_info.frame.enter_frame = NULL__null;
1493 }
1494#endif
1495 return TASK_CURRENT_NOT_QUEUED0;
1496}
1497
1498// __kmp_omp_task: Schedule a non-thread-switchable task for execution
1499//
1500// gtid: Global Thread ID of encountering thread
1501// new_task:non-thread-switchable task thunk allocated by __kmp_omp_task_alloc()
1502// serialize_immediate: if TRUE then if the task is executed immediately its
1503// execution will be serialized
1504// Returns:
1505// TASK_CURRENT_NOT_QUEUED (0) if did not suspend and queue current task to
1506// be resumed later.
1507// TASK_CURRENT_QUEUED (1) if suspended and queued the current task to be
1508// resumed later.
1509kmp_int32 __kmp_omp_task(kmp_int32 gtid, kmp_task_t *new_task,
1510 bool serialize_immediate) {
1511 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task)(((kmp_taskdata_t *)new_task) - 1);
1512
1513/* Should we execute the new task or queue it? For now, let's just always try to
1514 queue it. If the queue fills up, then we'll execute it. */
1515#if OMP_45_ENABLED(50 >= 45)
1516 if (new_taskdata->td_flags.proxy == TASK_PROXY1 ||
30
Assuming the condition is false
31
Taking true branch
1517 __kmp_push_task(gtid, new_task) == TASK_NOT_PUSHED1) // if cannot defer
1518#else
1519 if (__kmp_push_task(gtid, new_task) == TASK_NOT_PUSHED1) // if cannot defer
1520#endif
1521 { // Execute this task immediately
1522 kmp_taskdata_t *current_task = __kmp_threads[gtid]->th.th_current_task;
1523 if (serialize_immediate)
32
Taking true branch
1524 new_taskdata->td_flags.task_serial = 1;
1525 __kmp_invoke_task(gtid, new_task, current_task);
33
Calling '__kmp_invoke_task'
1526 }
1527
1528 ANNOTATE_HAPPENS_BEFORE(new_task);
1529 return TASK_CURRENT_NOT_QUEUED0;
1530}
1531
1532// __kmpc_omp_task: Wrapper around __kmp_omp_task to schedule a
1533// non-thread-switchable task from the parent thread only!
1534//
1535// loc_ref: location of original task pragma (ignored)
1536// gtid: Global Thread ID of encountering thread
1537// new_task: non-thread-switchable task thunk allocated by
1538// __kmp_omp_task_alloc()
1539// Returns:
1540// TASK_CURRENT_NOT_QUEUED (0) if did not suspend and queue current task to
1541// be resumed later.
1542// TASK_CURRENT_QUEUED (1) if suspended and queued the current task to be
1543// resumed later.
1544kmp_int32 __kmpc_omp_task(ident_t *loc_ref, kmp_int32 gtid,
1545 kmp_task_t *new_task) {
1546 kmp_int32 res;
1547 KMP_SET_THREAD_STATE_BLOCK(EXPLICIT_TASK)((void)0);
1548
1549#if KMP_DEBUG1 || OMPT_SUPPORT1
1550 kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task)(((kmp_taskdata_t *)new_task) - 1);
1551#endif
1552 KA_TRACE(10, ("__kmpc_omp_task(enter): T#%d loc=%p task=%p\n", gtid, loc_ref,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, new_taskdata); }
1553 new_taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task(enter): T#%d loc=%p task=%p\n"
, gtid, loc_ref, new_taskdata); }
;
1554
1555#if OMPT_SUPPORT1
1556 kmp_taskdata_t *parent = NULL__null;
1557 if (UNLIKELY(ompt_enabled.enabled && !new_taskdata->td_flags.started)__builtin_expect(!!(ompt_enabled.enabled && !new_taskdata
->td_flags.started), 0)
) {
1558 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
1559 parent = new_taskdata->td_parent;
1560 if (!parent->ompt_task_info.frame.enter_frame)
1561 parent->ompt_task_info.frame.enter_frame = OMPT_GET_FRAME_ADDRESS(1)__builtin_frame_address(1);
1562 if (ompt_enabled.ompt_callback_task_create) {
1563 ompt_data_t task_data = ompt_data_none;
1564 ompt_callbacks.ompt_callback(ompt_callback_task_create)ompt_callback_task_create_callback(
1565 parent ? &(parent->ompt_task_info.task_data) : &task_data,
1566 parent ? &(parent->ompt_task_info.frame) : NULL__null,
1567 &(new_taskdata->ompt_task_info.task_data),
1568 ompt_task_explicit | TASK_TYPE_DETAILS_FORMAT(new_taskdata)((new_taskdata->td_flags.task_serial || new_taskdata->td_flags
.tasking_ser) ? ompt_task_undeferred : 0x0) | ((!(new_taskdata
->td_flags.tiedness)) ? ompt_task_untied : 0x0) | (new_taskdata
->td_flags.final ? ompt_task_final : 0x0) | (new_taskdata->
td_flags.merged_if0 ? ompt_task_mergeable : 0x0)
, 0,
1569 OMPT_LOAD_RETURN_ADDRESS(gtid)__ompt_load_return_address(gtid));
1570 }
1571 }
1572#endif
1573
1574 res = __kmp_omp_task(gtid, new_task, true);
1575
1576 KA_TRACE(10, ("__kmpc_omp_task(exit): T#%d returning "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task(exit): T#%d returning "
"TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n", gtid, loc_ref, new_taskdata
); }
1577 "TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task(exit): T#%d returning "
"TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n", gtid, loc_ref, new_taskdata
); }
1578 gtid, loc_ref, new_taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_task(exit): T#%d returning "
"TASK_CURRENT_NOT_QUEUED: loc=%p task=%p\n", gtid, loc_ref, new_taskdata
); }
;
1579#if OMPT_SUPPORT1
1580 if (UNLIKELY(ompt_enabled.enabled && parent != NULL)__builtin_expect(!!(ompt_enabled.enabled && parent !=
__null), 0)
) {
1581 parent->ompt_task_info.frame.enter_frame = NULL__null;
1582 }
1583#endif
1584 return res;
1585}
1586
1587template <bool ompt>
1588static kmp_int32 __kmpc_omp_taskwait_template(ident_t *loc_ref, kmp_int32 gtid,
1589 void *frame_address,
1590 void *return_address) {
1591 kmp_taskdata_t *taskdata;
1592 kmp_info_t *thread;
1593 int thread_finished = FALSE0;
1594 KMP_SET_THREAD_STATE_BLOCK(TASKWAIT)((void)0);
1595
1596 KA_TRACE(10, ("__kmpc_omp_taskwait(enter): T#%d loc=%p\n", gtid, loc_ref))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskwait(enter): T#%d loc=%p\n"
, gtid, loc_ref); }
;
1597
1598 if (__kmp_tasking_mode != tskm_immediate_exec) {
1599 thread = __kmp_threads[gtid];
1600 taskdata = thread->th.th_current_task;
1601
1602#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
1603 ompt_data_t *my_task_data;
1604 ompt_data_t *my_parallel_data;
1605
1606 if (ompt) {
1607 my_task_data = &(taskdata->ompt_task_info.task_data);
1608 my_parallel_data = OMPT_CUR_TEAM_DATA(thread)(&(thread->th.th_team->t.ompt_team_info.parallel_data
))
;
1609
1610 taskdata->ompt_task_info.frame.enter_frame = frame_address;
1611
1612 if (ompt_enabled.ompt_callback_sync_region) {
1613 ompt_callbacks.ompt_callback(ompt_callback_sync_region)ompt_callback_sync_region_callback(
1614 ompt_sync_region_taskwait, ompt_scope_begin, my_parallel_data,
1615 my_task_data, return_address);
1616 }
1617
1618 if (ompt_enabled.ompt_callback_sync_region_wait) {
1619 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)ompt_callback_sync_region_wait_callback(
1620 ompt_sync_region_taskwait, ompt_scope_begin, my_parallel_data,
1621 my_task_data, return_address);
1622 }
1623 }
1624#endif // OMPT_SUPPORT && OMPT_OPTIONAL
1625
1626// Debugger: The taskwait is active. Store location and thread encountered the
1627// taskwait.
1628#if USE_ITT_BUILD1
1629// Note: These values are used by ITT events as well.
1630#endif /* USE_ITT_BUILD */
1631 taskdata->td_taskwait_counter += 1;
1632 taskdata->td_taskwait_ident = loc_ref;
1633 taskdata->td_taskwait_thread = gtid + 1;
1634
1635#if USE_ITT_BUILD1
1636 void *itt_sync_obj = __kmp_itt_taskwait_object(gtid);
1637 if (itt_sync_obj != NULL__null)
1638 __kmp_itt_taskwait_starting(gtid, itt_sync_obj);
1639#endif /* USE_ITT_BUILD */
1640
1641 bool must_wait =
1642 !taskdata->td_flags.team_serial && !taskdata->td_flags.final;
1643
1644#if OMP_45_ENABLED(50 >= 45)
1645 must_wait = must_wait || (thread->th.th_task_team != NULL__null &&
1646 thread->th.th_task_team->tt.tt_found_proxy_tasks);
1647#endif
1648 if (must_wait) {
1649 kmp_flag_32 flag(RCAST(std::atomic<kmp_uint32> *,reinterpret_cast<std::atomic<kmp_uint32> *>(&
(taskdata->td_incomplete_child_tasks))
1650 &(taskdata->td_incomplete_child_tasks))reinterpret_cast<std::atomic<kmp_uint32> *>(&
(taskdata->td_incomplete_child_tasks))
,
1651 0U);
1652 while (KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks)(&taskdata->td_incomplete_child_tasks)->load(std::memory_order_acquire
)
!= 0) {
1653 flag.execute_tasks(thread, gtid, FALSE0,
1654 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), itt_sync_obj,
1655 __kmp_task_stealing_constraint);
1656 }
1657 }
1658#if USE_ITT_BUILD1
1659 if (itt_sync_obj != NULL__null)
1660 __kmp_itt_taskwait_finished(gtid, itt_sync_obj);
1661#endif /* USE_ITT_BUILD */
1662
1663 // Debugger: The taskwait is completed. Location remains, but thread is
1664 // negated.
1665 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
1666
1667#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
1668 if (ompt) {
1669 if (ompt_enabled.ompt_callback_sync_region_wait) {
1670 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)ompt_callback_sync_region_wait_callback(
1671 ompt_sync_region_taskwait, ompt_scope_end, my_parallel_data,
1672 my_task_data, return_address);
1673 }
1674 if (ompt_enabled.ompt_callback_sync_region) {
1675 ompt_callbacks.ompt_callback(ompt_callback_sync_region)ompt_callback_sync_region_callback(
1676 ompt_sync_region_taskwait, ompt_scope_end, my_parallel_data,
1677 my_task_data, return_address);
1678 }
1679 taskdata->ompt_task_info.frame.enter_frame = NULL__null;
1680 }
1681#endif // OMPT_SUPPORT && OMPT_OPTIONAL
1682
1683 ANNOTATE_HAPPENS_AFTER(taskdata);
1684 }
1685
1686 KA_TRACE(10, ("__kmpc_omp_taskwait(exit): T#%d task %p finished waiting, "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskwait(exit): T#%d task %p finished waiting, "
"returning TASK_CURRENT_NOT_QUEUED\n", gtid, taskdata); }
1687 "returning TASK_CURRENT_NOT_QUEUED\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskwait(exit): T#%d task %p finished waiting, "
"returning TASK_CURRENT_NOT_QUEUED\n", gtid, taskdata); }
1688 gtid, taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskwait(exit): T#%d task %p finished waiting, "
"returning TASK_CURRENT_NOT_QUEUED\n", gtid, taskdata); }
;
1689
1690 return TASK_CURRENT_NOT_QUEUED0;
1691}
1692
1693#if OMPT_SUPPORT1
1694OMPT_NOINLINE__attribute__((noinline))
1695static kmp_int32 __kmpc_omp_taskwait_ompt(ident_t *loc_ref, kmp_int32 gtid,
1696 void *frame_address,
1697 void *return_address) {
1698 return __kmpc_omp_taskwait_template<true>(loc_ref, gtid, frame_address,
1699 return_address);
1700}
1701#endif // OMPT_SUPPORT
1702
1703// __kmpc_omp_taskwait: Wait until all tasks generated by the current task are
1704// complete
1705kmp_int32 __kmpc_omp_taskwait(ident_t *loc_ref, kmp_int32 gtid) {
1706#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
1707 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
1708 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
1709 return __kmpc_omp_taskwait_ompt(loc_ref, gtid, OMPT_GET_FRAME_ADDRESS(1)__builtin_frame_address(1),
1710 OMPT_LOAD_RETURN_ADDRESS(gtid)__ompt_load_return_address(gtid));
1711 }
1712#endif
1713 return __kmpc_omp_taskwait_template<false>(loc_ref, gtid, NULL__null, NULL__null);
1714}
1715
1716// __kmpc_omp_taskyield: switch to a different task
1717kmp_int32 __kmpc_omp_taskyield(ident_t *loc_ref, kmp_int32 gtid, int end_part) {
1718 kmp_taskdata_t *taskdata;
1719 kmp_info_t *thread;
1720 int thread_finished = FALSE0;
1721
1722 KMP_COUNT_BLOCK(OMP_TASKYIELD)((void)0);
1723 KMP_SET_THREAD_STATE_BLOCK(TASKYIELD)((void)0);
1724
1725 KA_TRACE(10, ("__kmpc_omp_taskyield(enter): T#%d loc=%p end_part = %d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskyield(enter): T#%d loc=%p end_part = %d\n"
, gtid, loc_ref, end_part); }
1726 gtid, loc_ref, end_part))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskyield(enter): T#%d loc=%p end_part = %d\n"
, gtid, loc_ref, end_part); }
;
1727
1728 if (__kmp_tasking_mode != tskm_immediate_exec && __kmp_init_parallel) {
1729 thread = __kmp_threads[gtid];
1730 taskdata = thread->th.th_current_task;
1731// Should we model this as a task wait or not?
1732// Debugger: The taskwait is active. Store location and thread encountered the
1733// taskwait.
1734#if USE_ITT_BUILD1
1735// Note: These values are used by ITT events as well.
1736#endif /* USE_ITT_BUILD */
1737 taskdata->td_taskwait_counter += 1;
1738 taskdata->td_taskwait_ident = loc_ref;
1739 taskdata->td_taskwait_thread = gtid + 1;
1740
1741#if USE_ITT_BUILD1
1742 void *itt_sync_obj = __kmp_itt_taskwait_object(gtid);
1743 if (itt_sync_obj != NULL__null)
1744 __kmp_itt_taskwait_starting(gtid, itt_sync_obj);
1745#endif /* USE_ITT_BUILD */
1746 if (!taskdata->td_flags.team_serial) {
1747 kmp_task_team_t *task_team = thread->th.th_task_team;
1748 if (task_team != NULL__null) {
1749 if (KMP_TASKING_ENABLED(task_team)(((task_team)->tt.tt_found_tasks) == (!0))) {
1750#if OMPT_SUPPORT1
1751 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0))
1752 thread->th.ompt_thread_info.ompt_task_yielded = 1;
1753#endif
1754 __kmp_execute_tasks_32(
1755 thread, gtid, NULL__null, FALSE0,
1756 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), itt_sync_obj,
1757 __kmp_task_stealing_constraint);
1758#if OMPT_SUPPORT1
1759 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0))
1760 thread->th.ompt_thread_info.ompt_task_yielded = 0;
1761#endif
1762 }
1763 }
1764 }
1765#if USE_ITT_BUILD1
1766 if (itt_sync_obj != NULL__null)
1767 __kmp_itt_taskwait_finished(gtid, itt_sync_obj);
1768#endif /* USE_ITT_BUILD */
1769
1770 // Debugger: The taskwait is completed. Location remains, but thread is
1771 // negated.
1772 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread;
1773 }
1774
1775 KA_TRACE(10, ("__kmpc_omp_taskyield(exit): T#%d task %p resuming, "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskyield(exit): T#%d task %p resuming, "
"returning TASK_CURRENT_NOT_QUEUED\n", gtid, taskdata); }
1776 "returning TASK_CURRENT_NOT_QUEUED\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskyield(exit): T#%d task %p resuming, "
"returning TASK_CURRENT_NOT_QUEUED\n", gtid, taskdata); }
1777 gtid, taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_omp_taskyield(exit): T#%d task %p resuming, "
"returning TASK_CURRENT_NOT_QUEUED\n", gtid, taskdata); }
;
1778
1779 return TASK_CURRENT_NOT_QUEUED0;
1780}
1781
1782// TODO: change to OMP_50_ENABLED, need to change build tools for this to work
1783#if OMP_45_ENABLED(50 >= 45)
1784// Task Reduction implementation
1785
1786typedef struct kmp_task_red_flags {
1787 unsigned lazy_priv : 1; // hint: (1) use lazy allocation (big objects)
1788 unsigned reserved31 : 31;
1789} kmp_task_red_flags_t;
1790
1791// internal structure for reduction data item related info
1792typedef struct kmp_task_red_data {
1793 void *reduce_shar; // shared reduction item
1794 size_t reduce_size; // size of data item
1795 void *reduce_priv; // thread specific data
1796 void *reduce_pend; // end of private data for comparison op
1797 void *reduce_init; // data initialization routine
1798 void *reduce_fini; // data finalization routine
1799 void *reduce_comb; // data combiner routine
1800 kmp_task_red_flags_t flags; // flags for additional info from compiler
1801} kmp_task_red_data_t;
1802
1803// structure sent us by compiler - one per reduction item
1804typedef struct kmp_task_red_input {
1805 void *reduce_shar; // shared reduction item
1806 size_t reduce_size; // size of data item
1807 void *reduce_init; // data initialization routine
1808 void *reduce_fini; // data finalization routine
1809 void *reduce_comb; // data combiner routine
1810 kmp_task_red_flags_t flags; // flags for additional info from compiler
1811} kmp_task_red_input_t;
1812
1813/*!
1814@ingroup TASKING
1815@param gtid Global thread ID
1816@param num Number of data items to reduce
1817@param data Array of data for reduction
1818@return The taskgroup identifier
1819
1820Initialize task reduction for the taskgroup.
1821*/
1822void *__kmpc_task_reduction_init(int gtid, int num, void *data) {
1823 kmp_info_t *thread = __kmp_threads[gtid];
1824 kmp_taskgroup_t *tg = thread->th.th_current_task->td_taskgroup;
1825 kmp_int32 nth = thread->th.th_team_nproc;
1826 kmp_task_red_input_t *input = (kmp_task_red_input_t *)data;
1827 kmp_task_red_data_t *arr;
1828
1829 // check input data just in case
1830 KMP_ASSERT(tg != NULL)((tg != __null) ? 0 : __kmp_debug_assert("tg != NULL", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1830))
;
1831 KMP_ASSERT(data != NULL)((data != __null) ? 0 : __kmp_debug_assert("data != NULL", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1831))
;
1832 KMP_ASSERT(num > 0)((num > 0) ? 0 : __kmp_debug_assert("num > 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1832))
;
1833 if (nth == 1) {
1834 KA_TRACE(10, ("__kmpc_task_reduction_init: T#%d, tg %p, exiting nth=1\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_task_reduction_init: T#%d, tg %p, exiting nth=1\n"
, gtid, tg); }
1835 gtid, tg))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_task_reduction_init: T#%d, tg %p, exiting nth=1\n"
, gtid, tg); }
;
1836 return (void *)tg;
1837 }
1838 KA_TRACE(10, ("__kmpc_task_reduction_init: T#%d, taskgroup %p, #items %d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_task_reduction_init: T#%d, taskgroup %p, #items %d\n"
, gtid, tg, num); }
1839 gtid, tg, num))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_task_reduction_init: T#%d, taskgroup %p, #items %d\n"
, gtid, tg, num); }
;
1840 arr = (kmp_task_red_data_t *)__kmp_thread_malloc(___kmp_thread_malloc((thread), (num * sizeof(kmp_task_red_data_t
)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1841)
1841 thread, num * sizeof(kmp_task_red_data_t))___kmp_thread_malloc((thread), (num * sizeof(kmp_task_red_data_t
)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1841)
;
1842 for (int i = 0; i < num; ++i) {
1843 void (*f_init)(void *) = (void (*)(void *))(input[i].reduce_init);
1844 size_t size = input[i].reduce_size - 1;
1845 // round the size up to cache line per thread-specific item
1846 size += CACHE_LINE64 - size % CACHE_LINE64;
1847 KMP_ASSERT(input[i].reduce_comb != NULL)((input[i].reduce_comb != __null) ? 0 : __kmp_debug_assert("input[i].reduce_comb != NULL"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1847))
; // combiner is mandatory
1848 arr[i].reduce_shar = input[i].reduce_shar;
1849 arr[i].reduce_size = size;
1850 arr[i].reduce_init = input[i].reduce_init;
1851 arr[i].reduce_fini = input[i].reduce_fini;
1852 arr[i].reduce_comb = input[i].reduce_comb;
1853 arr[i].flags = input[i].flags;
1854 if (!input[i].flags.lazy_priv) {
1855 // allocate cache-line aligned block and fill it with zeros
1856 arr[i].reduce_priv = __kmp_allocate(nth * size)___kmp_allocate((nth * size), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1856)
;
1857 arr[i].reduce_pend = (char *)(arr[i].reduce_priv) + nth * size;
1858 if (f_init != NULL__null) {
1859 // initialize thread-specific items
1860 for (int j = 0; j < nth; ++j) {
1861 f_init((char *)(arr[i].reduce_priv) + j * size);
1862 }
1863 }
1864 } else {
1865 // only allocate space for pointers now,
1866 // objects will be lazily allocated/initialized once requested
1867 arr[i].reduce_priv = __kmp_allocate(nth * sizeof(void *))___kmp_allocate((nth * sizeof(void *)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1867)
;
1868 }
1869 }
1870 tg->reduce_data = (void *)arr;
1871 tg->reduce_num_data = num;
1872 return (void *)tg;
1873}
1874
1875/*!
1876@ingroup TASKING
1877@param gtid Global thread ID
1878@param tskgrp The taskgroup ID (optional)
1879@param data Shared location of the item
1880@return The pointer to per-thread data
1881
1882Get thread-specific location of data item
1883*/
1884void *__kmpc_task_reduction_get_th_data(int gtid, void *tskgrp, void *data) {
1885 kmp_info_t *thread = __kmp_threads[gtid];
1886 kmp_int32 nth = thread->th.th_team_nproc;
1887 if (nth == 1)
1888 return data; // nothing to do
1889
1890 kmp_taskgroup_t *tg = (kmp_taskgroup_t *)tskgrp;
1891 if (tg == NULL__null)
1892 tg = thread->th.th_current_task->td_taskgroup;
1893 KMP_ASSERT(tg != NULL)((tg != __null) ? 0 : __kmp_debug_assert("tg != NULL", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1893))
;
1894 kmp_task_red_data_t *arr = (kmp_task_red_data_t *)(tg->reduce_data);
1895 kmp_int32 num = tg->reduce_num_data;
1896 kmp_int32 tid = thread->th.th_info.ds.ds_tid;
1897
1898 KMP_ASSERT(data != NULL)((data != __null) ? 0 : __kmp_debug_assert("data != NULL", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1898))
;
1899 while (tg != NULL__null) {
1900 for (int i = 0; i < num; ++i) {
1901 if (!arr[i].flags.lazy_priv) {
1902 if (data == arr[i].reduce_shar ||
1903 (data >= arr[i].reduce_priv && data < arr[i].reduce_pend))
1904 return (char *)(arr[i].reduce_priv) + tid * arr[i].reduce_size;
1905 } else {
1906 // check shared location first
1907 void **p_priv = (void **)(arr[i].reduce_priv);
1908 if (data == arr[i].reduce_shar)
1909 goto found;
1910 // check if we get some thread specific location as parameter
1911 for (int j = 0; j < nth; ++j)
1912 if (data == p_priv[j])
1913 goto found;
1914 continue; // not found, continue search
1915 found:
1916 if (p_priv[tid] == NULL__null) {
1917 // allocate thread specific object lazily
1918 void (*f_init)(void *) = (void (*)(void *))(arr[i].reduce_init);
1919 p_priv[tid] = __kmp_allocate(arr[i].reduce_size)___kmp_allocate((arr[i].reduce_size), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1919)
;
1920 if (f_init != NULL__null) {
1921 f_init(p_priv[tid]);
1922 }
1923 }
1924 return p_priv[tid];
1925 }
1926 }
1927 tg = tg->parent;
1928 arr = (kmp_task_red_data_t *)(tg->reduce_data);
1929 num = tg->reduce_num_data;
1930 }
1931 KMP_ASSERT2(0, "Unknown task reduction item")((0) ? 0 : __kmp_debug_assert(("Unknown task reduction item")
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1931))
;
1932 return NULL__null; // ERROR, this line never executed
1933}
1934
1935// Finalize task reduction.
1936// Called from __kmpc_end_taskgroup()
1937static void __kmp_task_reduction_fini(kmp_info_t *th, kmp_taskgroup_t *tg) {
1938 kmp_int32 nth = th->th.th_team_nproc;
1939 KMP_DEBUG_ASSERT(nth > 1)((nth > 1) ? 0 : __kmp_debug_assert("nth > 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1939))
; // should not be called if nth == 1
1940 kmp_task_red_data_t *arr = (kmp_task_red_data_t *)tg->reduce_data;
1941 kmp_int32 num = tg->reduce_num_data;
1942 for (int i = 0; i < num; ++i) {
1943 void *sh_data = arr[i].reduce_shar;
1944 void (*f_fini)(void *) = (void (*)(void *))(arr[i].reduce_fini);
1945 void (*f_comb)(void *, void *) =
1946 (void (*)(void *, void *))(arr[i].reduce_comb);
1947 if (!arr[i].flags.lazy_priv) {
1948 void *pr_data = arr[i].reduce_priv;
1949 size_t size = arr[i].reduce_size;
1950 for (int j = 0; j < nth; ++j) {
1951 void *priv_data = (char *)pr_data + j * size;
1952 f_comb(sh_data, priv_data); // combine results
1953 if (f_fini)
1954 f_fini(priv_data); // finalize if needed
1955 }
1956 } else {
1957 void **pr_data = (void **)(arr[i].reduce_priv);
1958 for (int j = 0; j < nth; ++j) {
1959 if (pr_data[j] != NULL__null) {
1960 f_comb(sh_data, pr_data[j]); // combine results
1961 if (f_fini)
1962 f_fini(pr_data[j]); // finalize if needed
1963 __kmp_free(pr_data[j])___kmp_free((pr_data[j]), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1963)
;
1964 }
1965 }
1966 }
1967 __kmp_free(arr[i].reduce_priv)___kmp_free((arr[i].reduce_priv), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1967)
;
1968 }
1969 __kmp_thread_free(th, arr)___kmp_thread_free((th), (arr), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1969)
;
1970 tg->reduce_data = NULL__null;
1971 tg->reduce_num_data = 0;
1972}
1973#endif
1974
1975#if OMP_40_ENABLED(50 >= 40)
1976// __kmpc_taskgroup: Start a new taskgroup
1977void __kmpc_taskgroup(ident_t *loc, int gtid) {
1978 kmp_info_t *thread = __kmp_threads[gtid];
1979 kmp_taskdata_t *taskdata = thread->th.th_current_task;
1980 kmp_taskgroup_t *tg_new =
1981 (kmp_taskgroup_t *)__kmp_thread_malloc(thread, sizeof(kmp_taskgroup_t))___kmp_thread_malloc((thread), (sizeof(kmp_taskgroup_t)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 1981)
;
1982 KA_TRACE(10, ("__kmpc_taskgroup: T#%d loc=%p group=%p\n", gtid, loc, tg_new))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_taskgroup: T#%d loc=%p group=%p\n"
, gtid, loc, tg_new); }
;
1983 KMP_ATOMIC_ST_RLX(&tg_new->count, 0)(&tg_new->count)->store(0, std::memory_order_relaxed
)
;
1984 KMP_ATOMIC_ST_RLX(&tg_new->cancel_request, cancel_noreq)(&tg_new->cancel_request)->store(cancel_noreq, std::
memory_order_relaxed)
;
1985 tg_new->parent = taskdata->td_taskgroup;
1986// TODO: change to OMP_50_ENABLED, need to change build tools for this to work
1987#if OMP_45_ENABLED(50 >= 45)
1988 tg_new->reduce_data = NULL__null;
1989 tg_new->reduce_num_data = 0;
1990#endif
1991 taskdata->td_taskgroup = tg_new;
1992
1993#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
1994 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region)__builtin_expect(!!(ompt_enabled.ompt_callback_sync_region), 0
)
) {
1995 void *codeptr = OMPT_LOAD_RETURN_ADDRESS(gtid)__ompt_load_return_address(gtid);
1996 if (!codeptr)
1997 codeptr = OMPT_GET_RETURN_ADDRESS(0)__builtin_return_address(0);
1998 kmp_team_t *team = thread->th.th_team;
1999 ompt_data_t my_task_data = taskdata->ompt_task_info.task_data;
2000 // FIXME: I think this is wrong for lwt!
2001 ompt_data_t my_parallel_data = team->t.ompt_team_info.parallel_data;
2002
2003 ompt_callbacks.ompt_callback(ompt_callback_sync_region)ompt_callback_sync_region_callback(
2004 ompt_sync_region_taskgroup, ompt_scope_begin, &(my_parallel_data),
2005 &(my_task_data), codeptr);
2006 }
2007#endif
2008}
2009
2010// __kmpc_end_taskgroup: Wait until all tasks generated by the current task
2011// and its descendants are complete
2012void __kmpc_end_taskgroup(ident_t *loc, int gtid) {
2013 kmp_info_t *thread = __kmp_threads[gtid];
2014 kmp_taskdata_t *taskdata = thread->th.th_current_task;
2015 kmp_taskgroup_t *taskgroup = taskdata->td_taskgroup;
2016 int thread_finished = FALSE0;
2017
2018#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
2019 kmp_team_t *team;
2020 ompt_data_t my_task_data;
2021 ompt_data_t my_parallel_data;
2022 void *codeptr;
2023 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0)) {
2024 team = thread->th.th_team;
2025 my_task_data = taskdata->ompt_task_info.task_data;
2026 // FIXME: I think this is wrong for lwt!
2027 my_parallel_data = team->t.ompt_team_info.parallel_data;
2028 codeptr = OMPT_LOAD_RETURN_ADDRESS(gtid)__ompt_load_return_address(gtid);
2029 if (!codeptr)
2030 codeptr = OMPT_GET_RETURN_ADDRESS(0)__builtin_return_address(0);
2031 }
2032#endif
2033
2034 KA_TRACE(10, ("__kmpc_end_taskgroup(enter): T#%d loc=%p\n", gtid, loc))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_end_taskgroup(enter): T#%d loc=%p\n"
, gtid, loc); }
;
2035 KMP_DEBUG_ASSERT(taskgroup != NULL)((taskgroup != __null) ? 0 : __kmp_debug_assert("taskgroup != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2035))
;
2036 KMP_SET_THREAD_STATE_BLOCK(TASKGROUP)((void)0);
2037
2038 if (__kmp_tasking_mode != tskm_immediate_exec) {
2039 // mark task as waiting not on a barrier
2040 taskdata->td_taskwait_counter += 1;
2041 taskdata->td_taskwait_ident = loc;
2042 taskdata->td_taskwait_thread = gtid + 1;
2043#if USE_ITT_BUILD1
2044 // For ITT the taskgroup wait is similar to taskwait until we need to
2045 // distinguish them
2046 void *itt_sync_obj = __kmp_itt_taskwait_object(gtid);
2047 if (itt_sync_obj != NULL__null)
2048 __kmp_itt_taskwait_starting(gtid, itt_sync_obj);
2049#endif /* USE_ITT_BUILD */
2050
2051#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
2052 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region_wait)__builtin_expect(!!(ompt_enabled.ompt_callback_sync_region_wait
), 0)
) {
2053 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)ompt_callback_sync_region_wait_callback(
2054 ompt_sync_region_taskgroup, ompt_scope_begin, &(my_parallel_data),
2055 &(my_task_data), codeptr);
2056 }
2057#endif
2058
2059#if OMP_45_ENABLED(50 >= 45)
2060 if (!taskdata->td_flags.team_serial ||
2061 (thread->th.th_task_team != NULL__null &&
2062 thread->th.th_task_team->tt.tt_found_proxy_tasks))
2063#else
2064 if (!taskdata->td_flags.team_serial)
2065#endif
2066 {
2067 kmp_flag_32 flag(RCAST(std::atomic<kmp_uint32> *, &(taskgroup->count))reinterpret_cast<std::atomic<kmp_uint32> *>(&
(taskgroup->count))
,
2068 0U);
2069 while (KMP_ATOMIC_LD_ACQ(&taskgroup->count)(&taskgroup->count)->load(std::memory_order_acquire
)
!= 0) {
2070 flag.execute_tasks(thread, gtid, FALSE0,
2071 &thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), itt_sync_obj,
2072 __kmp_task_stealing_constraint);
2073 }
2074 }
2075 taskdata->td_taskwait_thread = -taskdata->td_taskwait_thread; // end waiting
2076
2077#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
2078 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region_wait)__builtin_expect(!!(ompt_enabled.ompt_callback_sync_region_wait
), 0)
) {
2079 ompt_callbacks.ompt_callback(ompt_callback_sync_region_wait)ompt_callback_sync_region_wait_callback(
2080 ompt_sync_region_taskgroup, ompt_scope_end, &(my_parallel_data),
2081 &(my_task_data), codeptr);
2082 }
2083#endif
2084
2085#if USE_ITT_BUILD1
2086 if (itt_sync_obj != NULL__null)
2087 __kmp_itt_taskwait_finished(gtid, itt_sync_obj);
2088#endif /* USE_ITT_BUILD */
2089 }
2090 KMP_DEBUG_ASSERT(taskgroup->count == 0)((taskgroup->count == 0) ? 0 : __kmp_debug_assert("taskgroup->count == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2090))
;
2091
2092// TODO: change to OMP_50_ENABLED, need to change build tools for this to work
2093#if OMP_45_ENABLED(50 >= 45)
2094 if (taskgroup->reduce_data != NULL__null) // need to reduce?
2095 __kmp_task_reduction_fini(thread, taskgroup);
2096#endif
2097 // Restore parent taskgroup for the current task
2098 taskdata->td_taskgroup = taskgroup->parent;
2099 __kmp_thread_free(thread, taskgroup)___kmp_thread_free((thread), (taskgroup), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2099)
;
2100
2101 KA_TRACE(10, ("__kmpc_end_taskgroup(exit): T#%d task %p finished waiting\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_end_taskgroup(exit): T#%d task %p finished waiting\n"
, gtid, taskdata); }
2102 gtid, taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmpc_end_taskgroup(exit): T#%d task %p finished waiting\n"
, gtid, taskdata); }
;
2103 ANNOTATE_HAPPENS_AFTER(taskdata);
2104
2105#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
2106 if (UNLIKELY(ompt_enabled.ompt_callback_sync_region)__builtin_expect(!!(ompt_enabled.ompt_callback_sync_region), 0
)
) {
2107 ompt_callbacks.ompt_callback(ompt_callback_sync_region)ompt_callback_sync_region_callback(
2108 ompt_sync_region_taskgroup, ompt_scope_end, &(my_parallel_data),
2109 &(my_task_data), codeptr);
2110 }
2111#endif
2112}
2113#endif
2114
2115// __kmp_remove_my_task: remove a task from my own deque
2116static kmp_task_t *__kmp_remove_my_task(kmp_info_t *thread, kmp_int32 gtid,
2117 kmp_task_team_t *task_team,
2118 kmp_int32 is_constrained) {
2119 kmp_task_t *task;
2120 kmp_taskdata_t *taskdata;
2121 kmp_thread_data_t *thread_data;
2122 kmp_uint32 tail;
2123
2124 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec)((__kmp_tasking_mode != tskm_immediate_exec) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode != tskm_immediate_exec", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2124))
;
2125 KMP_DEBUG_ASSERT(task_team->tt.tt_threads_data !=((task_team->tt.tt_threads_data != __null) ? 0 : __kmp_debug_assert
("task_team->tt.tt_threads_data != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2126))
2126 NULL)((task_team->tt.tt_threads_data != __null) ? 0 : __kmp_debug_assert
("task_team->tt.tt_threads_data != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2126))
; // Caller should check this condition
2127
2128 thread_data = &task_team->tt.tt_threads_data[__kmp_tid_from_gtid(gtid)((((gtid) >= 0) ? 0 : __kmp_debug_assert("(gtid) >= 0",
"/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2128)), __kmp_threads[(gtid)]->th.th_info.ds.ds_tid)
];
2129
2130 KA_TRACE(10, ("__kmp_remove_my_task(enter): T#%d ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(enter): T#%d ntasks=%d head=%u tail=%u\n"
, gtid, thread_data->td.td_deque_ntasks, thread_data->td
.td_deque_head, thread_data->td.td_deque_tail); }
2131 gtid, thread_data->td.td_deque_ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(enter): T#%d ntasks=%d head=%u tail=%u\n"
, gtid, thread_data->td.td_deque_ntasks, thread_data->td
.td_deque_head, thread_data->td.td_deque_tail); }
2132 thread_data->td.td_deque_head, thread_data->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(enter): T#%d ntasks=%d head=%u tail=%u\n"
, gtid, thread_data->td.td_deque_ntasks, thread_data->td
.td_deque_head, thread_data->td.td_deque_tail); }
;
2133
2134 if (TCR_4(thread_data->td.td_deque_ntasks)(thread_data->td.td_deque_ntasks) == 0) {
2135 KA_TRACE(10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2136 ("__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2137 "ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2138 gtid, thread_data->td.td_deque_ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2139 thread_data->td.td_deque_head, thread_data->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #1): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
;
2140 return NULL__null;
2141 }
2142
2143 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
2144
2145 if (TCR_4(thread_data->td.td_deque_ntasks)(thread_data->td.td_deque_ntasks) == 0) {
2146 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2147 KA_TRACE(10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2148 ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2149 "ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2150 gtid, thread_data->td.td_deque_ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2151 thread_data->td.td_deque_head, thread_data->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
;
2152 return NULL__null;
2153 }
2154
2155 tail = (thread_data->td.td_deque_tail - 1) &
2156 TASK_DEQUE_MASK(thread_data->td)((thread_data->td).td_deque_size - 1); // Wrap index.
2157 taskdata = thread_data->td.td_deque[tail];
2158
2159 if (is_constrained && (taskdata->td_flags.tiedness == TASK_TIED1)) {
2160 // we need to check if the candidate obeys task scheduling constraint (TSC)
2161 // only descendant of all deferred tied tasks can be scheduled, checking
2162 // the last one is enough, as it in turn is the descendant of all others
2163 kmp_taskdata_t *current = thread->th.th_current_task->td_last_tied;
2164 KMP_DEBUG_ASSERT(current != NULL)((current != __null) ? 0 : __kmp_debug_assert("current != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2164))
;
2165 // check if last tied task is not suspended on barrier
2166 if (current->td_flags.tasktype == TASK_EXPLICIT1 ||
2167 current->td_taskwait_thread > 0) { // <= 0 on barrier
2168 kmp_int32 level = current->td_level;
2169 kmp_taskdata_t *parent = taskdata->td_parent;
2170 while (parent != current && parent->td_level > level) {
2171 parent = parent->td_parent; // check generation up to the level of the
2172 // current task
2173 KMP_DEBUG_ASSERT(parent != NULL)((parent != __null) ? 0 : __kmp_debug_assert("parent != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2173))
;
2174 }
2175 if (parent != current) {
2176 // The TSC does not allow to steal victim task
2177 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2178 KA_TRACE(10, ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2179 "ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2180 gtid, thread_data->td.td_deque_ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2181 thread_data->td.td_deque_head,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
2182 thread_data->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d No tasks to remove: "
"ntasks=%d head=%u tail=%u\n", gtid, thread_data->td.td_deque_ntasks
, thread_data->td.td_deque_head, thread_data->td.td_deque_tail
); }
;
2183 return NULL__null;
2184 }
2185 }
2186 }
2187
2188 thread_data->td.td_deque_tail = tail;
2189 TCW_4(thread_data->td.td_deque_ntasks, thread_data->td.td_deque_ntasks - 1)(thread_data->td.td_deque_ntasks) = (thread_data->td.td_deque_ntasks
- 1)
;
2190
2191 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2192
2193 KA_TRACE(10, ("__kmp_remove_my_task(exit #2): T#%d task %p removed: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d task %p removed: "
"ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data->
td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
2194 "ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d task %p removed: "
"ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data->
td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
2195 gtid, taskdata, thread_data->td.td_deque_ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d task %p removed: "
"ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data->
td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
2196 thread_data->td.td_deque_head, thread_data->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_remove_my_task(exit #2): T#%d task %p removed: "
"ntasks=%d head=%u tail=%u\n", gtid, taskdata, thread_data->
td.td_deque_ntasks, thread_data->td.td_deque_head, thread_data
->td.td_deque_tail); }
;
2197
2198 task = KMP_TASKDATA_TO_TASK(taskdata)(kmp_task_t *)(taskdata + 1);
2199 return task;
2200}
2201
2202// __kmp_steal_task: remove a task from another thread's deque
2203// Assume that calling thread has already checked existence of
2204// task_team thread_data before calling this routine.
2205static kmp_task_t *__kmp_steal_task(kmp_info_t *victim_thr, kmp_int32 gtid,
2206 kmp_task_team_t *task_team,
2207 std::atomic<kmp_int32> *unfinished_threads,
2208 int *thread_finished,
2209 kmp_int32 is_constrained) {
2210 kmp_task_t *task;
2211 kmp_taskdata_t *taskdata;
2212 kmp_taskdata_t *current;
2213 kmp_thread_data_t *victim_td, *threads_data;
2214 kmp_int32 level, target;
2215 kmp_int32 victim_tid;
2216
2217 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec)((__kmp_tasking_mode != tskm_immediate_exec) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode != tskm_immediate_exec", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2217))
;
2218
2219 threads_data = task_team->tt.tt_threads_data;
2220 KMP_DEBUG_ASSERT(threads_data != NULL)((threads_data != __null) ? 0 : __kmp_debug_assert("threads_data != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2220))
; // Caller should check this condition
2221
2222 victim_tid = victim_thr->th.th_info.ds.ds_tid;
2223 victim_td = &threads_data[victim_tid];
2224
2225 KA_TRACE(10, ("__kmp_steal_task(enter): T#%d try to steal from T#%d: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(enter): T#%d try to steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2227)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2226 "task_team=%p ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(enter): T#%d try to steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2227)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2227 gtid, __kmp_gtid_from_thread(victim_thr), task_team,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(enter): T#%d try to steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2227)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2228 victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(enter): T#%d try to steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2227)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2229 victim_td->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(enter): T#%d try to steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2227)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
;
2230
2231 if (TCR_4(victim_td->td.td_deque_ntasks)(victim_td->td.td_deque_ntasks) == 0) {
2232 KA_TRACE(10, ("__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2234)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2233 "task_team=%p ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2234)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2234 gtid, __kmp_gtid_from_thread(victim_thr), task_team,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2234)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2235 victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2234)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
2236 victim_td->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #1): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2234)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
victim_td->td.td_deque_ntasks, victim_td->td.td_deque_head
, victim_td->td.td_deque_tail); }
;
2237 return NULL__null;
2238 }
2239
2240 __kmp_acquire_bootstrap_lock(&victim_td->td.td_deque_lock);
2241
2242 int ntasks = TCR_4(victim_td->td.td_deque_ntasks)(victim_td->td.td_deque_ntasks);
2243 // Check again after we acquire the lock
2244 if (ntasks == 0) {
2245 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2246 KA_TRACE(10, ("__kmp_steal_task(exit #2): T#%d could not steal from T#%d: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #2): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2248)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2247 "task_team=%p ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #2): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2248)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2248 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #2): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2248)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2249 victim_td->td.td_deque_head, victim_td->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #2): T#%d could not steal from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((victim_thr
) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2248)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
;
2250 return NULL__null;
2251 }
2252
2253 KMP_DEBUG_ASSERT(victim_td->td.td_deque != NULL)((victim_td->td.td_deque != __null) ? 0 : __kmp_debug_assert
("victim_td->td.td_deque != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2253))
;
2254
2255 taskdata = victim_td->td.td_deque[victim_td->td.td_deque_head];
2256 if (is_constrained && (taskdata->td_flags.tiedness == TASK_TIED1)) {
2257 // we need to check if the candidate obeys task scheduling constraint (TSC)
2258 // only descendant of all deferred tied tasks can be scheduled, checking
2259 // the last one is enough, as it in turn is the descendant of all others
2260 current = __kmp_threads[gtid]->th.th_current_task->td_last_tied;
2261 KMP_DEBUG_ASSERT(current != NULL)((current != __null) ? 0 : __kmp_debug_assert("current != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2261))
;
2262 // check if last tied task is not suspended on barrier
2263 if (current->td_flags.tasktype == TASK_EXPLICIT1 ||
2264 current->td_taskwait_thread > 0) { // <= 0 on barrier
2265 level = current->td_level;
2266 kmp_taskdata_t *parent = taskdata->td_parent;
2267 while (parent != current && parent->td_level > level) {
2268 parent = parent->td_parent; // check generation up to the level of the
2269 // current task
2270 KMP_DEBUG_ASSERT(parent != NULL)((parent != __null) ? 0 : __kmp_debug_assert("parent != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2270))
;
2271 }
2272 if (parent != current) {
2273 if (!task_team->tt.tt_untied_task_encountered) {
2274 // The TSC does not allow to steal victim task
2275 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2276 KA_TRACE(10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #3): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2279)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2277 ("__kmp_steal_task(exit #3): T#%d could not steal from "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #3): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2279)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2278 "T#%d: task_team=%p ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #3): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2279)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2279 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #3): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2279)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2280 victim_td->td.td_deque_head, victim_td->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #3): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2279)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
;
2281 return NULL__null;
2282 }
2283 taskdata = NULL__null; // will check other tasks in victim's deque
2284 }
2285 }
2286 }
2287 if (taskdata != NULL__null) {
2288 // Bump head pointer and Wrap.
2289 victim_td->td.td_deque_head =
2290 (victim_td->td.td_deque_head + 1) & TASK_DEQUE_MASK(victim_td->td)((victim_td->td).td_deque_size - 1);
2291 } else {
2292 int i;
2293 // walk through victim's deque trying to steal any task
2294 target = victim_td->td.td_deque_head;
2295 for (i = 1; i < ntasks; ++i) {
2296 target = (target + 1) & TASK_DEQUE_MASK(victim_td->td)((victim_td->td).td_deque_size - 1);
2297 taskdata = victim_td->td.td_deque[target];
2298 if (taskdata->td_flags.tiedness == TASK_TIED1) {
2299 // check if the candidate obeys the TSC
2300 kmp_taskdata_t *parent = taskdata->td_parent;
2301 // check generation up to the level of the current task
2302 while (parent != current && parent->td_level > level) {
2303 parent = parent->td_parent;
2304 KMP_DEBUG_ASSERT(parent != NULL)((parent != __null) ? 0 : __kmp_debug_assert("parent != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2304))
;
2305 }
2306 if (parent != current) {
2307 // The TSC does not allow to steal the candidate
2308 taskdata = NULL__null;
2309 continue;
2310 } else {
2311 // found victim tied task
2312 break;
2313 }
2314 } else {
2315 // found victim untied task
2316 break;
2317 }
2318 }
2319 if (taskdata == NULL__null) {
2320 // No appropriate candidate to steal found
2321 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2322 KA_TRACE(10, ("__kmp_steal_task(exit #4): T#%d could not steal from "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #4): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2324)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2323 "T#%d: task_team=%p ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #4): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2324)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2324 gtid, __kmp_gtid_from_thread(victim_thr), task_team, ntasks,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #4): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2324)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2325 victim_td->td.td_deque_head, victim_td->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #4): T#%d could not steal from "
"T#%d: task_team=%p ntasks=%d head=%u tail=%u\n", gtid, ((((
victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2324)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
;
2326 return NULL__null;
2327 }
2328 int prev = target;
2329 for (i = i + 1; i < ntasks; ++i) {
2330 // shift remaining tasks in the deque left by 1
2331 target = (target + 1) & TASK_DEQUE_MASK(victim_td->td)((victim_td->td).td_deque_size - 1);
2332 victim_td->td.td_deque[prev] = victim_td->td.td_deque[target];
2333 prev = target;
2334 }
2335 KMP_DEBUG_ASSERT(victim_td->td.td_deque_tail ==((victim_td->td.td_deque_tail == ((target + 1) & ((victim_td
->td).td_deque_size - 1))) ? 0 : __kmp_debug_assert("victim_td->td.td_deque_tail == ((target + 1) & ((victim_td->td).td_deque_size - 1))"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2336))
2336 ((target + 1) & TASK_DEQUE_MASK(victim_td->td)))((victim_td->td.td_deque_tail == ((target + 1) & ((victim_td
->td).td_deque_size - 1))) ? 0 : __kmp_debug_assert("victim_td->td.td_deque_tail == ((target + 1) & ((victim_td->td).td_deque_size - 1))"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2336))
;
2337 victim_td->td.td_deque_tail = target; // tail -= 1 (wrapped))
2338 }
2339 if (*thread_finished) {
2340 // We need to un-mark this victim as a finished victim. This must be done
2341 // before releasing the lock, or else other threads (starting with the
2342 // master victim) might be prematurely released from the barrier!!!
2343 kmp_int32 count;
2344
2345 count = KMP_ATOMIC_INC(unfinished_threads)(unfinished_threads)->fetch_add(1, std::memory_order_acq_rel
)
;
2346
2347 KA_TRACE(if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_steal_task: T#%d inc unfinished_threads to %d: task_team=%p\n"
, gtid, count + 1, task_team); }
2348 20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_steal_task: T#%d inc unfinished_threads to %d: task_team=%p\n"
, gtid, count + 1, task_team); }
2349 ("__kmp_steal_task: T#%d inc unfinished_threads to %d: task_team=%p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_steal_task: T#%d inc unfinished_threads to %d: task_team=%p\n"
, gtid, count + 1, task_team); }
2350 gtid, count + 1, task_team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_steal_task: T#%d inc unfinished_threads to %d: task_team=%p\n"
, gtid, count + 1, task_team); }
;
2351
2352 *thread_finished = FALSE0;
2353 }
2354 TCW_4(victim_td->td.td_deque_ntasks, ntasks - 1)(victim_td->td.td_deque_ntasks) = (ntasks - 1);
2355
2356 __kmp_release_bootstrap_lock(&victim_td->td.td_deque_lock);
2357
2358 KMP_COUNT_BLOCK(TASK_stolen)((void)0);
2359 KA_TRACE(10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, (
(((victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2362)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2360 ("__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, (
(((victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2362)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2361 "task_team=%p ntasks=%d head=%u tail=%u\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, (
(((victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2362)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2362 gtid, taskdata, __kmp_gtid_from_thread(victim_thr), task_team,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, (
(((victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2362)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
2363 ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_steal_task(exit #5): T#%d stole task %p from T#%d: "
"task_team=%p ntasks=%d head=%u tail=%u\n", gtid, taskdata, (
(((victim_thr) != __null) ? 0 : __kmp_debug_assert("(victim_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2362)), (victim_thr)->th.th_info.ds.ds_gtid), task_team,
ntasks, victim_td->td.td_deque_head, victim_td->td.td_deque_tail
); }
;
2364
2365 task = KMP_TASKDATA_TO_TASK(taskdata)(kmp_task_t *)(taskdata + 1);
2366 return task;
2367}
2368
2369// __kmp_execute_tasks_template: Choose and execute tasks until either the
2370// condition is statisfied (return true) or there are none left (return false).
2371//
2372// final_spin is TRUE if this is the spin at the release barrier.
2373// thread_finished indicates whether the thread is finished executing all
2374// the tasks it has on its deque, and is at the release barrier.
2375// spinner is the location on which to spin.
2376// spinner == NULL means only execute a single task and return.
2377// checker is the value to check to terminate the spin.
2378template <class C>
2379static inline int __kmp_execute_tasks_template(
2380 kmp_info_t *thread, kmp_int32 gtid, C *flag, int final_spin,
2381 int *thread_finished USE_ITT_BUILD_ARG(void *itt_sync_obj), void *itt_sync_obj,
2382 kmp_int32 is_constrained) {
2383 kmp_task_team_t *task_team = thread->th.th_task_team;
2384 kmp_thread_data_t *threads_data;
2385 kmp_task_t *task;
2386 kmp_info_t *other_thread;
2387 kmp_taskdata_t *current_task = thread->th.th_current_task;
2388 std::atomic<kmp_int32> *unfinished_threads;
2389 kmp_int32 nthreads, victim_tid = -2, use_own_tasks = 1, new_victim = 0,
2390 tid = thread->th.th_info.ds.ds_tid;
2391
2392 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec)((__kmp_tasking_mode != tskm_immediate_exec) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode != tskm_immediate_exec", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2392))
;
2393 KMP_DEBUG_ASSERT(thread == __kmp_threads[gtid])((thread == __kmp_threads[gtid]) ? 0 : __kmp_debug_assert("thread == __kmp_threads[gtid]"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2393))
;
2394
2395 if (task_team == NULL__null)
2396 return FALSE0;
2397
2398 KA_TRACE(15, ("__kmp_execute_tasks_template(enter): T#%d final_spin=%d "if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template(enter): T#%d final_spin=%d "
"*thread_finished=%d\n", gtid, final_spin, *thread_finished)
; }
2399 "*thread_finished=%d\n",if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template(enter): T#%d final_spin=%d "
"*thread_finished=%d\n", gtid, final_spin, *thread_finished)
; }
2400 gtid, final_spin, *thread_finished))if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template(enter): T#%d final_spin=%d "
"*thread_finished=%d\n", gtid, final_spin, *thread_finished)
; }
;
2401
2402 thread->th.th_reap_state = KMP_NOT_SAFE_TO_REAP0;
2403 threads_data = (kmp_thread_data_t *)TCR_PTR(task_team->tt.tt_threads_data)((void *)(task_team->tt.tt_threads_data));
2404 KMP_DEBUG_ASSERT(threads_data != NULL)((threads_data != __null) ? 0 : __kmp_debug_assert("threads_data != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2404))
;
2405
2406 nthreads = task_team->tt.tt_nproc;
2407 unfinished_threads = &(task_team->tt.tt_unfinished_threads);
2408#if OMP_45_ENABLED(50 >= 45)
2409 KMP_DEBUG_ASSERT(nthreads > 1 || task_team->tt.tt_found_proxy_tasks)((nthreads > 1 || task_team->tt.tt_found_proxy_tasks) ?
0 : __kmp_debug_assert("nthreads > 1 || task_team->tt.tt_found_proxy_tasks"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2409))
;
2410#else
2411 KMP_DEBUG_ASSERT(nthreads > 1)((nthreads > 1) ? 0 : __kmp_debug_assert("nthreads > 1"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2411))
;
2412#endif
2413 KMP_DEBUG_ASSERT(*unfinished_threads >= 0)((*unfinished_threads >= 0) ? 0 : __kmp_debug_assert("*unfinished_threads >= 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2413))
;
2414
2415 while (1) { // Outer loop keeps trying to find tasks in case of single thread
2416 // getting tasks from target constructs
2417 while (1) { // Inner loop to find a task and execute it
2418 task = NULL__null;
2419 if (use_own_tasks) { // check on own queue first
2420 task = __kmp_remove_my_task(thread, gtid, task_team, is_constrained);
2421 }
2422 if ((task == NULL__null) && (nthreads > 1)) { // Steal a task
2423 int asleep = 1;
2424 use_own_tasks = 0;
2425 // Try to steal from the last place I stole from successfully.
2426 if (victim_tid == -2) { // haven't stolen anything yet
2427 victim_tid = threads_data[tid].td.td_deque_last_stolen;
2428 if (victim_tid !=
2429 -1) // if we have a last stolen from victim, get the thread
2430 other_thread = threads_data[victim_tid].td.td_thr;
2431 }
2432 if (victim_tid != -1) { // found last victim
2433 asleep = 0;
2434 } else if (!new_victim) { // no recent steals and we haven't already
2435 // used a new victim; select a random thread
2436 do { // Find a different thread to steal work from.
2437 // Pick a random thread. Initial plan was to cycle through all the
2438 // threads, and only return if we tried to steal from every thread,
2439 // and failed. Arch says that's not such a great idea.
2440 victim_tid = __kmp_get_random(thread) % (nthreads - 1);
2441 if (victim_tid >= tid) {
2442 ++victim_tid; // Adjusts random distribution to exclude self
2443 }
2444 // Found a potential victim
2445 other_thread = threads_data[victim_tid].td.td_thr;
2446 // There is a slight chance that __kmp_enable_tasking() did not wake
2447 // up all threads waiting at the barrier. If victim is sleeping,
2448 // then wake it up. Since we were going to pay the cache miss
2449 // penalty for referencing another thread's kmp_info_t struct
2450 // anyway,
2451 // the check shouldn't cost too much performance at this point. In
2452 // extra barrier mode, tasks do not sleep at the separate tasking
2453 // barrier, so this isn't a problem.
2454 asleep = 0;
2455 if ((__kmp_tasking_mode == tskm_task_teams) &&
2456 (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME(2147483647)) &&
2457 (TCR_PTR(CCAST(void *, other_thread->th.th_sleep_loc))((void *)(const_cast<void *>(other_thread->th.th_sleep_loc
)))
!=
2458 NULL__null)) {
2459 asleep = 1;
2460 __kmp_null_resume_wrapper(__kmp_gtid_from_thread(other_thread)((((other_thread) != __null) ? 0 : __kmp_debug_assert("(other_thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2460)), (other_thread)->th.th_info.ds.ds_gtid)
,
2461 other_thread->th.th_sleep_loc);
2462 // A sleeping thread should not have any tasks on it's queue.
2463 // There is a slight possibility that it resumes, steals a task
2464 // from another thread, which spawns more tasks, all in the time
2465 // that it takes this thread to check => don't write an assertion
2466 // that the victim's queue is empty. Try stealing from a
2467 // different thread.
2468 }
2469 } while (asleep);
2470 }
2471
2472 if (!asleep) {
2473 // We have a victim to try to steal from
2474 task = __kmp_steal_task(other_thread, gtid, task_team,
2475 unfinished_threads, thread_finished,
2476 is_constrained);
2477 }
2478 if (task != NULL__null) { // set last stolen to victim
2479 if (threads_data[tid].td.td_deque_last_stolen != victim_tid) {
2480 threads_data[tid].td.td_deque_last_stolen = victim_tid;
2481 // The pre-refactored code did not try more than 1 successful new
2482 // vicitm, unless the last one generated more local tasks;
2483 // new_victim keeps track of this
2484 new_victim = 1;
2485 }
2486 } else { // No tasks found; unset last_stolen
2487 KMP_CHECK_UPDATE(threads_data[tid].td.td_deque_last_stolen, -1)if ((threads_data[tid].td.td_deque_last_stolen) != (-1)) (threads_data
[tid].td.td_deque_last_stolen) = (-1)
;
2488 victim_tid = -2; // no successful victim found
2489 }
2490 }
2491
2492 if (task == NULL__null) // break out of tasking loop
2493 break;
2494
2495// Found a task; execute it
2496#if USE_ITT_BUILD1 && USE_ITT_NOTIFY1
2497 if (__itt_sync_create_ptr__kmp_itt_sync_create_ptr__3_0 || KMP_ITT_DEBUG0) {
2498 if (itt_sync_obj == NULL__null) { // we are at fork barrier where we could not
2499 // get the object reliably
2500 itt_sync_obj = __kmp_itt_barrier_object(gtid, bs_forkjoin_barrier);
2501 }
2502 __kmp_itt_task_starting(itt_sync_obj);
2503 }
2504#endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
2505 __kmp_invoke_task(gtid, task, current_task);
2506#if USE_ITT_BUILD1
2507 if (itt_sync_obj != NULL__null)
2508 __kmp_itt_task_finished(itt_sync_obj);
2509#endif /* USE_ITT_BUILD */
2510 // If this thread is only partway through the barrier and the condition is
2511 // met, then return now, so that the barrier gather/release pattern can
2512 // proceed. If this thread is in the last spin loop in the barrier,
2513 // waiting to be released, we know that the termination condition will not
2514 // be satisified, so don't waste any cycles checking it.
2515 if (flag == NULL__null || (!final_spin && flag->done_check())) {
2516 KA_TRACE(if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
2517 15,if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
2518 ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n",if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
2519 gtid))if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
;
2520 return TRUE(!0);
2521 }
2522 if (thread->th.th_task_team == NULL__null) {
2523 break;
2524 }
2525 // Yield before executing next task
2526 KMP_YIELD(__kmp_library == library_throughput){ __kmp_x86_pause(); __kmp_yield((__kmp_library == library_throughput
)); }
;
2527 // If execution of a stolen task results in more tasks being placed on our
2528 // run queue, reset use_own_tasks
2529 if (!use_own_tasks && TCR_4(threads_data[tid].td.td_deque_ntasks)(threads_data[tid].td.td_deque_ntasks) != 0) {
2530 KA_TRACE(20, ("__kmp_execute_tasks_template: T#%d stolen task spawned "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d stolen task spawned "
"other tasks, restart\n", gtid); }
2531 "other tasks, restart\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d stolen task spawned "
"other tasks, restart\n", gtid); }
2532 gtid))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d stolen task spawned "
"other tasks, restart\n", gtid); }
;
2533 use_own_tasks = 1;
2534 new_victim = 0;
2535 }
2536 }
2537
2538// The task source has been exhausted. If in final spin loop of barrier, check
2539// if termination condition is satisfied.
2540#if OMP_45_ENABLED(50 >= 45)
2541 // The work queue may be empty but there might be proxy tasks still
2542 // executing
2543 if (final_spin &&
2544 KMP_ATOMIC_LD_ACQ(&current_task->td_incomplete_child_tasks)(&current_task->td_incomplete_child_tasks)->load(std
::memory_order_acquire)
== 0)
2545#else
2546 if (final_spin)
2547#endif
2548 {
2549 // First, decrement the #unfinished threads, if that has not already been
2550 // done. This decrement might be to the spin location, and result in the
2551 // termination condition being satisfied.
2552 if (!*thread_finished) {
2553 kmp_int32 count;
2554
2555 count = KMP_ATOMIC_DEC(unfinished_threads)(unfinished_threads)->fetch_sub(1, std::memory_order_acq_rel
)
- 1;
2556 KA_TRACE(20, ("__kmp_execute_tasks_template: T#%d dec "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d dec "
"unfinished_threads to %d task_team=%p\n", gtid, count, task_team
); }
2557 "unfinished_threads to %d task_team=%p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d dec "
"unfinished_threads to %d task_team=%p\n", gtid, count, task_team
); }
2558 gtid, count, task_team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d dec "
"unfinished_threads to %d task_team=%p\n", gtid, count, task_team
); }
;
2559 *thread_finished = TRUE(!0);
2560 }
2561
2562 // It is now unsafe to reference thread->th.th_team !!!
2563 // Decrementing task_team->tt.tt_unfinished_threads can allow the master
2564 // thread to pass through the barrier, where it might reset each thread's
2565 // th.th_team field for the next parallel region. If we can steal more
2566 // work, we know that this has not happened yet.
2567 if (flag != NULL__null && flag->done_check()) {
2568 KA_TRACE(if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
2569 15,if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
2570 ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n",if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
2571 gtid))if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d spin condition satisfied\n"
, gtid); }
;
2572 return TRUE(!0);
2573 }
2574 }
2575
2576 // If this thread's task team is NULL, master has recognized that there are
2577 // no more tasks; bail out
2578 if (thread->th.th_task_team == NULL__null) {
2579 KA_TRACE(15,if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d no more tasks\n"
, gtid); }
2580 ("__kmp_execute_tasks_template: T#%d no more tasks\n", gtid))if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d no more tasks\n"
, gtid); }
;
2581 return FALSE0;
2582 }
2583
2584#if OMP_45_ENABLED(50 >= 45)
2585 // We could be getting tasks from target constructs; if this is the only
2586 // thread, keep trying to execute tasks from own queue
2587 if (nthreads == 1)
2588 use_own_tasks = 1;
2589 else
2590#endif
2591 {
2592 KA_TRACE(15,if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d can't find work\n"
, gtid); }
2593 ("__kmp_execute_tasks_template: T#%d can't find work\n", gtid))if (kmp_a_debug >= 15) { __kmp_debug_printf ("__kmp_execute_tasks_template: T#%d can't find work\n"
, gtid); }
;
2594 return FALSE0;
2595 }
2596 }
2597}
2598
2599int __kmp_execute_tasks_32(
2600 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_32 *flag, int final_spin,
2601 int *thread_finished USE_ITT_BUILD_ARG(void *itt_sync_obj), void *itt_sync_obj,
2602 kmp_int32 is_constrained) {
2603 return __kmp_execute_tasks_template(
2604 thread, gtid, flag, final_spin,
2605 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), itt_sync_obj, is_constrained);
2606}
2607
2608int __kmp_execute_tasks_64(
2609 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_64 *flag, int final_spin,
2610 int *thread_finished USE_ITT_BUILD_ARG(void *itt_sync_obj), void *itt_sync_obj,
2611 kmp_int32 is_constrained) {
2612 return __kmp_execute_tasks_template(
2613 thread, gtid, flag, final_spin,
2614 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), itt_sync_obj, is_constrained);
2615}
2616
2617int __kmp_execute_tasks_oncore(
2618 kmp_info_t *thread, kmp_int32 gtid, kmp_flag_oncore *flag, int final_spin,
2619 int *thread_finished USE_ITT_BUILD_ARG(void *itt_sync_obj), void *itt_sync_obj,
2620 kmp_int32 is_constrained) {
2621 return __kmp_execute_tasks_template(
2622 thread, gtid, flag, final_spin,
2623 thread_finished USE_ITT_BUILD_ARG(itt_sync_obj), itt_sync_obj, is_constrained);
2624}
2625
2626// __kmp_enable_tasking: Allocate task team and resume threads sleeping at the
2627// next barrier so they can assist in executing enqueued tasks.
2628// First thread in allocates the task team atomically.
2629static void __kmp_enable_tasking(kmp_task_team_t *task_team,
2630 kmp_info_t *this_thr) {
2631 kmp_thread_data_t *threads_data;
2632 int nthreads, i, is_init_thread;
2633
2634 KA_TRACE(10, ("__kmp_enable_tasking(enter): T#%d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_enable_tasking(enter): T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2635)), (this_thr)->th.th_info.ds.ds_gtid)); }
2635 __kmp_gtid_from_thread(this_thr)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_enable_tasking(enter): T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2635)), (this_thr)->th.th_info.ds.ds_gtid)); }
;
2636
2637 KMP_DEBUG_ASSERT(task_team != NULL)((task_team != __null) ? 0 : __kmp_debug_assert("task_team != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2637))
;
2638 KMP_DEBUG_ASSERT(this_thr->th.th_team != NULL)((this_thr->th.th_team != __null) ? 0 : __kmp_debug_assert
("this_thr->th.th_team != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2638))
;
2639
2640 nthreads = task_team->tt.tt_nproc;
2641 KMP_DEBUG_ASSERT(nthreads > 0)((nthreads > 0) ? 0 : __kmp_debug_assert("nthreads > 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2641))
;
2642 KMP_DEBUG_ASSERT(nthreads == this_thr->th.th_team->t.t_nproc)((nthreads == this_thr->th.th_team->t.t_nproc) ? 0 : __kmp_debug_assert
("nthreads == this_thr->th.th_team->t.t_nproc", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2642))
;
2643
2644 // Allocate or increase the size of threads_data if necessary
2645 is_init_thread = __kmp_realloc_task_threads_data(this_thr, task_team);
2646
2647 if (!is_init_thread) {
2648 // Some other thread already set up the array.
2649 KA_TRACE(if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_enable_tasking(exit): T#%d: threads array already set up.\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2652)), (this_thr)->th.th_info.ds.ds_gtid)); }
2650 20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_enable_tasking(exit): T#%d: threads array already set up.\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2652)), (this_thr)->th.th_info.ds.ds_gtid)); }
2651 ("__kmp_enable_tasking(exit): T#%d: threads array already set up.\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_enable_tasking(exit): T#%d: threads array already set up.\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2652)), (this_thr)->th.th_info.ds.ds_gtid)); }
2652 __kmp_gtid_from_thread(this_thr)))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_enable_tasking(exit): T#%d: threads array already set up.\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2652)), (this_thr)->th.th_info.ds.ds_gtid)); }
;
2653 return;
2654 }
2655 threads_data = (kmp_thread_data_t *)TCR_PTR(task_team->tt.tt_threads_data)((void *)(task_team->tt.tt_threads_data));
2656 KMP_DEBUG_ASSERT(threads_data != NULL)((threads_data != __null) ? 0 : __kmp_debug_assert("threads_data != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2656))
;
2657
2658 if ((__kmp_tasking_mode == tskm_task_teams) &&
2659 (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME(2147483647))) {
2660 // Release any threads sleeping at the barrier, so that they can steal
2661 // tasks and execute them. In extra barrier mode, tasks do not sleep
2662 // at the separate tasking barrier, so this isn't a problem.
2663 for (i = 0; i < nthreads; i++) {
2664 volatile void *sleep_loc;
2665 kmp_info_t *thread = threads_data[i].td.td_thr;
2666
2667 if (i == this_thr->th.th_info.ds.ds_tid) {
2668 continue;
2669 }
2670 // Since we haven't locked the thread's suspend mutex lock at this
2671 // point, there is a small window where a thread might be putting
2672 // itself to sleep, but hasn't set the th_sleep_loc field yet.
2673 // To work around this, __kmp_execute_tasks_template() periodically checks
2674 // see if other threads are sleeping (using the same random mechanism that
2675 // is used for task stealing) and awakens them if they are.
2676 if ((sleep_loc = TCR_PTR(CCAST(void *, thread->th.th_sleep_loc))((void *)(const_cast<void *>(thread->th.th_sleep_loc
)))
) !=
2677 NULL__null) {
2678 KF_TRACE(50, ("__kmp_enable_tasking: T#%d waking up thread T#%d\n",if (kmp_f_debug >= 50) { __kmp_debug_printf ("__kmp_enable_tasking: T#%d waking up thread T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2679)), (this_thr)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2680)), (thread)->th.th_info.ds.ds_gtid)); }
2679 __kmp_gtid_from_thread(this_thr),if (kmp_f_debug >= 50) { __kmp_debug_printf ("__kmp_enable_tasking: T#%d waking up thread T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2679)), (this_thr)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2680)), (thread)->th.th_info.ds.ds_gtid)); }
2680 __kmp_gtid_from_thread(thread)))if (kmp_f_debug >= 50) { __kmp_debug_printf ("__kmp_enable_tasking: T#%d waking up thread T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2679)), (this_thr)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2680)), (thread)->th.th_info.ds.ds_gtid)); }
;
2681 __kmp_null_resume_wrapper(__kmp_gtid_from_thread(thread)((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2681)), (thread)->th.th_info.ds.ds_gtid)
, sleep_loc);
2682 } else {
2683 KF_TRACE(50, ("__kmp_enable_tasking: T#%d don't wake up thread T#%d\n",if (kmp_f_debug >= 50) { __kmp_debug_printf ("__kmp_enable_tasking: T#%d don't wake up thread T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2684)), (this_thr)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2685)), (thread)->th.th_info.ds.ds_gtid)); }
2684 __kmp_gtid_from_thread(this_thr),if (kmp_f_debug >= 50) { __kmp_debug_printf ("__kmp_enable_tasking: T#%d don't wake up thread T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2684)), (this_thr)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2685)), (thread)->th.th_info.ds.ds_gtid)); }
2685 __kmp_gtid_from_thread(thread)))if (kmp_f_debug >= 50) { __kmp_debug_printf ("__kmp_enable_tasking: T#%d don't wake up thread T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2684)), (this_thr)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2685)), (thread)->th.th_info.ds.ds_gtid)); }
;
2686 }
2687 }
2688 }
2689
2690 KA_TRACE(10, ("__kmp_enable_tasking(exit): T#%d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_enable_tasking(exit): T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2691)), (this_thr)->th.th_info.ds.ds_gtid)); }
2691 __kmp_gtid_from_thread(this_thr)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_enable_tasking(exit): T#%d\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2691)), (this_thr)->th.th_info.ds.ds_gtid)); }
;
2692}
2693
2694/* // TODO: Check the comment consistency
2695 * Utility routines for "task teams". A task team (kmp_task_t) is kind of
2696 * like a shadow of the kmp_team_t data struct, with a different lifetime.
2697 * After a child * thread checks into a barrier and calls __kmp_release() from
2698 * the particular variant of __kmp_<barrier_kind>_barrier_gather(), it can no
2699 * longer assume that the kmp_team_t structure is intact (at any moment, the
2700 * master thread may exit the barrier code and free the team data structure,
2701 * and return the threads to the thread pool).
2702 *
2703 * This does not work with the the tasking code, as the thread is still
2704 * expected to participate in the execution of any tasks that may have been
2705 * spawned my a member of the team, and the thread still needs access to all
2706 * to each thread in the team, so that it can steal work from it.
2707 *
2708 * Enter the existence of the kmp_task_team_t struct. It employs a reference
2709 * counting mechanims, and is allocated by the master thread before calling
2710 * __kmp_<barrier_kind>_release, and then is release by the last thread to
2711 * exit __kmp_<barrier_kind>_release at the next barrier. I.e. the lifetimes
2712 * of the kmp_task_team_t structs for consecutive barriers can overlap
2713 * (and will, unless the master thread is the last thread to exit the barrier
2714 * release phase, which is not typical).
2715 *
2716 * The existence of such a struct is useful outside the context of tasking,
2717 * but for now, I'm trying to keep it specific to the OMP_30_ENABLED macro,
2718 * so that any performance differences show up when comparing the 2.5 vs. 3.0
2719 * libraries.
2720 *
2721 * We currently use the existence of the threads array as an indicator that
2722 * tasks were spawned since the last barrier. If the structure is to be
2723 * useful outside the context of tasking, then this will have to change, but
2724 * not settting the field minimizes the performance impact of tasking on
2725 * barriers, when no explicit tasks were spawned (pushed, actually).
2726 */
2727
2728static kmp_task_team_t *__kmp_free_task_teams =
2729 NULL__null; // Free list for task_team data structures
2730// Lock for task team data structures
2731kmp_bootstrap_lock_t __kmp_task_team_lock =
2732 KMP_BOOTSTRAP_LOCK_INITIALIZER(__kmp_task_team_lock){ { { true } , &((__kmp_task_team_lock)), __null, { 0U },
{ 0U }, { 0 }, { -1 } } }
;
2733
2734// __kmp_alloc_task_deque:
2735// Allocates a task deque for a particular thread, and initialize the necessary
2736// data structures relating to the deque. This only happens once per thread
2737// per task team since task teams are recycled. No lock is needed during
2738// allocation since each thread allocates its own deque.
2739static void __kmp_alloc_task_deque(kmp_info_t *thread,
2740 kmp_thread_data_t *thread_data) {
2741 __kmp_init_bootstrap_lock(&thread_data->td.td_deque_lock);
2742 KMP_DEBUG_ASSERT(thread_data->td.td_deque == NULL)((thread_data->td.td_deque == __null) ? 0 : __kmp_debug_assert
("thread_data->td.td_deque == __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2742))
;
2743
2744 // Initialize last stolen task field to "none"
2745 thread_data->td.td_deque_last_stolen = -1;
2746
2747 KMP_DEBUG_ASSERT(TCR_4(thread_data->td.td_deque_ntasks) == 0)(((thread_data->td.td_deque_ntasks) == 0) ? 0 : __kmp_debug_assert
("(thread_data->td.td_deque_ntasks) == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2747))
;
2748 KMP_DEBUG_ASSERT(thread_data->td.td_deque_head == 0)((thread_data->td.td_deque_head == 0) ? 0 : __kmp_debug_assert
("thread_data->td.td_deque_head == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2748))
;
2749 KMP_DEBUG_ASSERT(thread_data->td.td_deque_tail == 0)((thread_data->td.td_deque_tail == 0) ? 0 : __kmp_debug_assert
("thread_data->td.td_deque_tail == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2749))
;
2750
2751 KE_TRACE(if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_alloc_task_deque: T#%d allocating deque[%d] for thread_data %p\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2754)), (thread)->th.th_info.ds.ds_gtid), (1 << 8)
, thread_data); }
2752 10,if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_alloc_task_deque: T#%d allocating deque[%d] for thread_data %p\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2754)), (thread)->th.th_info.ds.ds_gtid), (1 << 8)
, thread_data); }
2753 ("__kmp_alloc_task_deque: T#%d allocating deque[%d] for thread_data %p\n",if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_alloc_task_deque: T#%d allocating deque[%d] for thread_data %p\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2754)), (thread)->th.th_info.ds.ds_gtid), (1 << 8)
, thread_data); }
2754 __kmp_gtid_from_thread(thread), INITIAL_TASK_DEQUE_SIZE, thread_data))if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_alloc_task_deque: T#%d allocating deque[%d] for thread_data %p\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2754)), (thread)->th.th_info.ds.ds_gtid), (1 << 8)
, thread_data); }
;
2755 // Allocate space for task deque, and zero the deque
2756 // Cannot use __kmp_thread_calloc() because threads not around for
2757 // kmp_reap_task_team( ).
2758 thread_data->td.td_deque = (kmp_taskdata_t **)__kmp_allocate(___kmp_allocate(((1 << 8) * sizeof(kmp_taskdata_t *)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2759)
2759 INITIAL_TASK_DEQUE_SIZE * sizeof(kmp_taskdata_t *))___kmp_allocate(((1 << 8) * sizeof(kmp_taskdata_t *)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2759)
;
2760 thread_data->td.td_deque_size = INITIAL_TASK_DEQUE_SIZE(1 << 8);
2761}
2762
2763// __kmp_realloc_task_deque:
2764// Re-allocates a task deque for a particular thread, copies the content from
2765// the old deque and adjusts the necessary data structures relating to the
2766// deque. This operation must be done with a the deque_lock being held
2767static void __kmp_realloc_task_deque(kmp_info_t *thread,
2768 kmp_thread_data_t *thread_data) {
2769 kmp_int32 size = TASK_DEQUE_SIZE(thread_data->td)((thread_data->td).td_deque_size);
2770 kmp_int32 new_size = 2 * size;
2771
2772 KE_TRACE(10, ("__kmp_realloc_task_deque: T#%d reallocating deque[from %d to "if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_deque: T#%d reallocating deque[from %d to "
"%d] for thread_data %p\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2774)), (thread)->th.th_info.ds.ds_gtid), size, new_size
, thread_data); }
2773 "%d] for thread_data %p\n",if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_deque: T#%d reallocating deque[from %d to "
"%d] for thread_data %p\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2774)), (thread)->th.th_info.ds.ds_gtid), size, new_size
, thread_data); }
2774 __kmp_gtid_from_thread(thread), size, new_size, thread_data))if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_deque: T#%d reallocating deque[from %d to "
"%d] for thread_data %p\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2774)), (thread)->th.th_info.ds.ds_gtid), size, new_size
, thread_data); }
;
2775
2776 kmp_taskdata_t **new_deque =
2777 (kmp_taskdata_t **)__kmp_allocate(new_size * sizeof(kmp_taskdata_t *))___kmp_allocate((new_size * sizeof(kmp_taskdata_t *)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2777)
;
2778
2779 int i, j;
2780 for (i = thread_data->td.td_deque_head, j = 0; j < size;
2781 i = (i + 1) & TASK_DEQUE_MASK(thread_data->td)((thread_data->td).td_deque_size - 1), j++)
2782 new_deque[j] = thread_data->td.td_deque[i];
2783
2784 __kmp_free(thread_data->td.td_deque)___kmp_free((thread_data->td.td_deque), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2784)
;
2785
2786 thread_data->td.td_deque_head = 0;
2787 thread_data->td.td_deque_tail = size;
2788 thread_data->td.td_deque = new_deque;
2789 thread_data->td.td_deque_size = new_size;
2790}
2791
2792// __kmp_free_task_deque:
2793// Deallocates a task deque for a particular thread. Happens at library
2794// deallocation so don't need to reset all thread data fields.
2795static void __kmp_free_task_deque(kmp_thread_data_t *thread_data) {
2796 if (thread_data->td.td_deque != NULL__null) {
2797 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
2798 TCW_4(thread_data->td.td_deque_ntasks, 0)(thread_data->td.td_deque_ntasks) = (0);
2799 __kmp_free(thread_data->td.td_deque)___kmp_free((thread_data->td.td_deque), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2799)
;
2800 thread_data->td.td_deque = NULL__null;
2801 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
2802 }
2803
2804#ifdef BUILD_TIED_TASK_STACK
2805 // GEH: Figure out what to do here for td_susp_tied_tasks
2806 if (thread_data->td.td_susp_tied_tasks.ts_entries != TASK_STACK_EMPTY) {
2807 __kmp_free_task_stack(__kmp_thread_from_gtid(gtid)((((gtid) >= 0) ? 0 : __kmp_debug_assert("(gtid) >= 0",
"/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2807)), __kmp_threads[(gtid)])
, thread_data);
2808 }
2809#endif // BUILD_TIED_TASK_STACK
2810}
2811
2812// __kmp_realloc_task_threads_data:
2813// Allocates a threads_data array for a task team, either by allocating an
2814// initial array or enlarging an existing array. Only the first thread to get
2815// the lock allocs or enlarges the array and re-initializes the array eleemnts.
2816// That thread returns "TRUE", the rest return "FALSE".
2817// Assumes that the new array size is given by task_team -> tt.tt_nproc.
2818// The current size is given by task_team -> tt.tt_max_threads.
2819static int __kmp_realloc_task_threads_data(kmp_info_t *thread,
2820 kmp_task_team_t *task_team) {
2821 kmp_thread_data_t **threads_data_p;
2822 kmp_int32 nthreads, maxthreads;
2823 int is_init_thread = FALSE0;
2824
2825 if (TCR_4(task_team->tt.tt_found_tasks)(task_team->tt.tt_found_tasks)) {
2826 // Already reallocated and initialized.
2827 return FALSE0;
2828 }
2829
2830 threads_data_p = &task_team->tt.tt_threads_data;
2831 nthreads = task_team->tt.tt_nproc;
2832 maxthreads = task_team->tt.tt_max_threads;
2833
2834 // All threads must lock when they encounter the first task of the implicit
2835 // task region to make sure threads_data fields are (re)initialized before
2836 // used.
2837 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_threads_lock);
2838
2839 if (!TCR_4(task_team->tt.tt_found_tasks)(task_team->tt.tt_found_tasks)) {
2840 // first thread to enable tasking
2841 kmp_team_t *team = thread->th.th_team;
2842 int i;
2843
2844 is_init_thread = TRUE(!0);
2845 if (maxthreads < nthreads) {
2846
2847 if (*threads_data_p != NULL__null) {
2848 kmp_thread_data_t *old_data = *threads_data_p;
2849 kmp_thread_data_t *new_data = NULL__null;
2850
2851 KE_TRACE(if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d reallocating "
"threads data for task_team %p, new_size = %d, old_size = %d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2855)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
, maxthreads); }
2852 10,if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d reallocating "
"threads data for task_team %p, new_size = %d, old_size = %d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2855)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
, maxthreads); }
2853 ("__kmp_realloc_task_threads_data: T#%d reallocating "if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d reallocating "
"threads data for task_team %p, new_size = %d, old_size = %d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2855)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
, maxthreads); }
2854 "threads data for task_team %p, new_size = %d, old_size = %d\n",if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d reallocating "
"threads data for task_team %p, new_size = %d, old_size = %d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2855)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
, maxthreads); }
2855 __kmp_gtid_from_thread(thread), task_team, nthreads, maxthreads))if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d reallocating "
"threads data for task_team %p, new_size = %d, old_size = %d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2855)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
, maxthreads); }
;
2856 // Reallocate threads_data to have more elements than current array
2857 // Cannot use __kmp_thread_realloc() because threads not around for
2858 // kmp_reap_task_team( ). Note all new array entries are initialized
2859 // to zero by __kmp_allocate().
2860 new_data = (kmp_thread_data_t *)__kmp_allocate(___kmp_allocate((nthreads * sizeof(kmp_thread_data_t)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2861)
2861 nthreads * sizeof(kmp_thread_data_t))___kmp_allocate((nthreads * sizeof(kmp_thread_data_t)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2861)
;
2862 // copy old data to new data
2863 KMP_MEMCPY_S((void *)new_data, nthreads * sizeof(kmp_thread_data_t),memcpy((void *)new_data, (void *)old_data, maxthreads * sizeof
(kmp_thread_data_t))
2864 (void *)old_data, maxthreads * sizeof(kmp_thread_data_t))memcpy((void *)new_data, (void *)old_data, maxthreads * sizeof
(kmp_thread_data_t))
;
2865
2866#ifdef BUILD_TIED_TASK_STACK
2867 // GEH: Figure out if this is the right thing to do
2868 for (i = maxthreads; i < nthreads; i++) {
2869 kmp_thread_data_t *thread_data = &(*threads_data_p)[i];
2870 __kmp_init_task_stack(__kmp_gtid_from_thread(thread)((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2870)), (thread)->th.th_info.ds.ds_gtid)
, thread_data);
2871 }
2872#endif // BUILD_TIED_TASK_STACK
2873 // Install the new data and free the old data
2874 (*threads_data_p) = new_data;
2875 __kmp_free(old_data)___kmp_free((old_data), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2875)
;
2876 } else {
2877 KE_TRACE(10, ("__kmp_realloc_task_threads_data: T#%d allocating "if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d allocating "
"threads data for task_team %p, size = %d\n", ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2879)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
); }
2878 "threads data for task_team %p, size = %d\n",if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d allocating "
"threads data for task_team %p, size = %d\n", ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2879)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
); }
2879 __kmp_gtid_from_thread(thread), task_team, nthreads))if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_realloc_task_threads_data: T#%d allocating "
"threads data for task_team %p, size = %d\n", ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2879)), (thread)->th.th_info.ds.ds_gtid), task_team, nthreads
); }
;
2880 // Make the initial allocate for threads_data array, and zero entries
2881 // Cannot use __kmp_thread_calloc() because threads not around for
2882 // kmp_reap_task_team( ).
2883 ANNOTATE_IGNORE_WRITES_BEGIN();
2884 *threads_data_p = (kmp_thread_data_t *)__kmp_allocate(___kmp_allocate((nthreads * sizeof(kmp_thread_data_t)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2885)
2885 nthreads * sizeof(kmp_thread_data_t))___kmp_allocate((nthreads * sizeof(kmp_thread_data_t)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2885)
;
2886 ANNOTATE_IGNORE_WRITES_END();
2887#ifdef BUILD_TIED_TASK_STACK
2888 // GEH: Figure out if this is the right thing to do
2889 for (i = 0; i < nthreads; i++) {
2890 kmp_thread_data_t *thread_data = &(*threads_data_p)[i];
2891 __kmp_init_task_stack(__kmp_gtid_from_thread(thread)((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2891)), (thread)->th.th_info.ds.ds_gtid)
, thread_data);
2892 }
2893#endif // BUILD_TIED_TASK_STACK
2894 }
2895 task_team->tt.tt_max_threads = nthreads;
2896 } else {
2897 // If array has (more than) enough elements, go ahead and use it
2898 KMP_DEBUG_ASSERT(*threads_data_p != NULL)((*threads_data_p != __null) ? 0 : __kmp_debug_assert("*threads_data_p != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2898))
;
2899 }
2900
2901 // initialize threads_data pointers back to thread_info structures
2902 for (i = 0; i < nthreads; i++) {
2903 kmp_thread_data_t *thread_data = &(*threads_data_p)[i];
2904 thread_data->td.td_thr = team->t.t_threads[i];
2905
2906 if (thread_data->td.td_deque_last_stolen >= nthreads) {
2907 // The last stolen field survives across teams / barrier, and the number
2908 // of threads may have changed. It's possible (likely?) that a new
2909 // parallel region will exhibit the same behavior as previous region.
2910 thread_data->td.td_deque_last_stolen = -1;
2911 }
2912 }
2913
2914 KMP_MB();
2915 TCW_SYNC_4(task_team->tt.tt_found_tasks, TRUE)(task_team->tt.tt_found_tasks) = ((!0));
2916 }
2917
2918 __kmp_release_bootstrap_lock(&task_team->tt.tt_threads_lock);
2919 return is_init_thread;
2920}
2921
2922// __kmp_free_task_threads_data:
2923// Deallocates a threads_data array for a task team, including any attached
2924// tasking deques. Only occurs at library shutdown.
2925static void __kmp_free_task_threads_data(kmp_task_team_t *task_team) {
2926 __kmp_acquire_bootstrap_lock(&task_team->tt.tt_threads_lock);
2927 if (task_team->tt.tt_threads_data != NULL__null) {
2928 int i;
2929 for (i = 0; i < task_team->tt.tt_max_threads; i++) {
2930 __kmp_free_task_deque(&task_team->tt.tt_threads_data[i]);
2931 }
2932 __kmp_free(task_team->tt.tt_threads_data)___kmp_free((task_team->tt.tt_threads_data), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2932)
;
2933 task_team->tt.tt_threads_data = NULL__null;
2934 }
2935 __kmp_release_bootstrap_lock(&task_team->tt.tt_threads_lock);
2936}
2937
2938// __kmp_allocate_task_team:
2939// Allocates a task team associated with a specific team, taking it from
2940// the global task team free list if possible. Also initializes data
2941// structures.
2942static kmp_task_team_t *__kmp_allocate_task_team(kmp_info_t *thread,
2943 kmp_team_t *team) {
2944 kmp_task_team_t *task_team = NULL__null;
2945 int nthreads;
2946
2947 KA_TRACE(20, ("__kmp_allocate_task_team: T#%d entering; team = %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d entering; team = %p\n"
, (thread ? ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2948)), (thread)->th.th_info.ds.ds_gtid) : -1), team); }
2948 (thread ? __kmp_gtid_from_thread(thread) : -1), team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d entering; team = %p\n"
, (thread ? ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2948)), (thread)->th.th_info.ds.ds_gtid) : -1), team); }
;
2949
2950 if (TCR_PTR(__kmp_free_task_teams)((void *)(__kmp_free_task_teams)) != NULL__null) {
2951 // Take a task team from the task team pool
2952 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
2953 if (__kmp_free_task_teams != NULL__null) {
2954 task_team = __kmp_free_task_teams;
2955 TCW_PTR(__kmp_free_task_teams, task_team->tt.tt_next)((__kmp_free_task_teams)) = ((task_team->tt.tt_next));
2956 task_team->tt.tt_next = NULL__null;
2957 }
2958 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
2959 }
2960
2961 if (task_team == NULL__null) {
2962 KE_TRACE(10, ("__kmp_allocate_task_team: T#%d allocating "if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d allocating "
"task team for team %p\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2964)), (thread)->th.th_info.ds.ds_gtid), team); }
2963 "task team for team %p\n",if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d allocating "
"task team for team %p\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2964)), (thread)->th.th_info.ds.ds_gtid), team); }
2964 __kmp_gtid_from_thread(thread), team))if (kmp_e_debug >= 10) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d allocating "
"task team for team %p\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2964)), (thread)->th.th_info.ds.ds_gtid), team); }
;
2965 // Allocate a new task team if one is not available.
2966 // Cannot use __kmp_thread_malloc() because threads not around for
2967 // kmp_reap_task_team( ).
2968 task_team = (kmp_task_team_t *)__kmp_allocate(sizeof(kmp_task_team_t))___kmp_allocate((sizeof(kmp_task_team_t)), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2968)
;
2969 __kmp_init_bootstrap_lock(&task_team->tt.tt_threads_lock);
2970 // AC: __kmp_allocate zeroes returned memory
2971 // task_team -> tt.tt_threads_data = NULL;
2972 // task_team -> tt.tt_max_threads = 0;
2973 // task_team -> tt.tt_next = NULL;
2974 }
2975
2976 TCW_4(task_team->tt.tt_found_tasks, FALSE)(task_team->tt.tt_found_tasks) = (0);
2977#if OMP_45_ENABLED(50 >= 45)
2978 TCW_4(task_team->tt.tt_found_proxy_tasks, FALSE)(task_team->tt.tt_found_proxy_tasks) = (0);
2979#endif
2980 task_team->tt.tt_nproc = nthreads = team->t.t_nproc;
2981
2982 KMP_ATOMIC_ST_REL(&task_team->tt.tt_unfinished_threads, nthreads)(&task_team->tt.tt_unfinished_threads)->store(nthreads
, std::memory_order_release)
;
2983 TCW_4(task_team->tt.tt_active, TRUE)(task_team->tt.tt_active) = ((!0));
2984
2985 KA_TRACE(20, ("__kmp_allocate_task_team: T#%d exiting; task_team = %p "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d exiting; task_team = %p "
"unfinished_threads init'd to %d\n", (thread ? ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2987)), (thread)->th.th_info.ds.ds_gtid) : -1), task_team
, (&task_team->tt.tt_unfinished_threads)->load(std::
memory_order_relaxed)); }
2986 "unfinished_threads init'd to %d\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d exiting; task_team = %p "
"unfinished_threads init'd to %d\n", (thread ? ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2987)), (thread)->th.th_info.ds.ds_gtid) : -1), task_team
, (&task_team->tt.tt_unfinished_threads)->load(std::
memory_order_relaxed)); }
2987 (thread ? __kmp_gtid_from_thread(thread) : -1), task_team,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d exiting; task_team = %p "
"unfinished_threads init'd to %d\n", (thread ? ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2987)), (thread)->th.th_info.ds.ds_gtid) : -1), task_team
, (&task_team->tt.tt_unfinished_threads)->load(std::
memory_order_relaxed)); }
2988 KMP_ATOMIC_LD_RLX(&task_team->tt.tt_unfinished_threads)))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_allocate_task_team: T#%d exiting; task_team = %p "
"unfinished_threads init'd to %d\n", (thread ? ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2987)), (thread)->th.th_info.ds.ds_gtid) : -1), task_team
, (&task_team->tt.tt_unfinished_threads)->load(std::
memory_order_relaxed)); }
;
2989 return task_team;
2990}
2991
2992// __kmp_free_task_team:
2993// Frees the task team associated with a specific thread, and adds it
2994// to the global task team free list.
2995void __kmp_free_task_team(kmp_info_t *thread, kmp_task_team_t *task_team) {
2996 KA_TRACE(20, ("__kmp_free_task_team: T#%d task_team = %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_team: T#%d task_team = %p\n"
, thread ? ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2997)), (thread)->th.th_info.ds.ds_gtid) : -1, task_team
); }
2997 thread ? __kmp_gtid_from_thread(thread) : -1, task_team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_free_task_team: T#%d task_team = %p\n"
, thread ? ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 2997)), (thread)->th.th_info.ds.ds_gtid) : -1, task_team
); }
;
2998
2999 // Put task team back on free list
3000 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3001
3002 KMP_DEBUG_ASSERT(task_team->tt.tt_next == NULL)((task_team->tt.tt_next == __null) ? 0 : __kmp_debug_assert
("task_team->tt.tt_next == __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3002))
;
3003 task_team->tt.tt_next = __kmp_free_task_teams;
3004 TCW_PTR(__kmp_free_task_teams, task_team)((__kmp_free_task_teams)) = ((task_team));
3005
3006 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3007}
3008
3009// __kmp_reap_task_teams:
3010// Free all the task teams on the task team free list.
3011// Should only be done during library shutdown.
3012// Cannot do anything that needs a thread structure or gtid since they are
3013// already gone.
3014void __kmp_reap_task_teams(void) {
3015 kmp_task_team_t *task_team;
3016
3017 if (TCR_PTR(__kmp_free_task_teams)((void *)(__kmp_free_task_teams)) != NULL__null) {
3018 // Free all task_teams on the free list
3019 __kmp_acquire_bootstrap_lock(&__kmp_task_team_lock);
3020 while ((task_team = __kmp_free_task_teams) != NULL__null) {
3021 __kmp_free_task_teams = task_team->tt.tt_next;
3022 task_team->tt.tt_next = NULL__null;
3023
3024 // Free threads_data if necessary
3025 if (task_team->tt.tt_threads_data != NULL__null) {
3026 __kmp_free_task_threads_data(task_team);
3027 }
3028 __kmp_free(task_team)___kmp_free((task_team), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3028)
;
3029 }
3030 __kmp_release_bootstrap_lock(&__kmp_task_team_lock);
3031 }
3032}
3033
3034// __kmp_wait_to_unref_task_teams:
3035// Some threads could still be in the fork barrier release code, possibly
3036// trying to steal tasks. Wait for each thread to unreference its task team.
3037void __kmp_wait_to_unref_task_teams(void) {
3038 kmp_info_t *thread;
3039 kmp_uint32 spins;
3040 int done;
3041
3042 KMP_INIT_YIELD(spins){ (spins) = __kmp_yield_init; };
3043
3044 for (;;) {
3045 done = TRUE(!0);
3046
3047 // TODO: GEH - this may be is wrong because some sync would be necessary
3048 // in case threads are added to the pool during the traversal. Need to
3049 // verify that lock for thread pool is held when calling this routine.
3050 for (thread = CCAST(kmp_info_t *, __kmp_thread_pool)const_cast<kmp_info_t *>(__kmp_thread_pool); thread != NULL__null;
3051 thread = thread->th.th_next_pool) {
3052#if KMP_OS_WINDOWS0
3053 DWORD exit_val;
3054#endif
3055 if (TCR_PTR(thread->th.th_task_team)((void *)(thread->th.th_task_team)) == NULL__null) {
3056 KA_TRACE(10, ("__kmp_wait_to_unref_task_team: T#%d task_team == NULL\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: T#%d task_team == NULL\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3057)), (thread)->th.th_info.ds.ds_gtid)); }
3057 __kmp_gtid_from_thread(thread)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: T#%d task_team == NULL\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3057)), (thread)->th.th_info.ds.ds_gtid)); }
;
3058 continue;
3059 }
3060#if KMP_OS_WINDOWS0
3061 // TODO: GEH - add this check for Linux* OS / OS X* as well?
3062 if (!__kmp_is_thread_alive(thread, &exit_val)) {
3063 thread->th.th_task_team = NULL__null;
3064 continue;
3065 }
3066#endif
3067
3068 done = FALSE0; // Because th_task_team pointer is not NULL for this thread
3069
3070 KA_TRACE(10, ("__kmp_wait_to_unref_task_team: Waiting for T#%d to "if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: Waiting for T#%d to "
"unreference task_team\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3072)), (thread)->th.th_info.ds.ds_gtid)); }
3071 "unreference task_team\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: Waiting for T#%d to "
"unreference task_team\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3072)), (thread)->th.th_info.ds.ds_gtid)); }
3072 __kmp_gtid_from_thread(thread)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: Waiting for T#%d to "
"unreference task_team\n", ((((thread) != __null) ? 0 : __kmp_debug_assert
("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3072)), (thread)->th.th_info.ds.ds_gtid)); }
;
3073
3074 if (__kmp_dflt_blocktime != KMP_MAX_BLOCKTIME(2147483647)) {
3075 volatile void *sleep_loc;
3076 // If the thread is sleeping, awaken it.
3077 if ((sleep_loc = TCR_PTR(CCAST(void *, thread->th.th_sleep_loc))((void *)(const_cast<void *>(thread->th.th_sleep_loc
)))
) !=
3078 NULL__null) {
3079 KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: T#%d waking up thread T#%d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid)); }
3080 10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: T#%d waking up thread T#%d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid)); }
3081 ("__kmp_wait_to_unref_task_team: T#%d waking up thread T#%d\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: T#%d waking up thread T#%d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid)); }
3082 __kmp_gtid_from_thread(thread), __kmp_gtid_from_thread(thread)))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_wait_to_unref_task_team: T#%d waking up thread T#%d\n"
, ((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid), ((((thread) !=
__null) ? 0 : __kmp_debug_assert("(thread) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3082)), (thread)->th.th_info.ds.ds_gtid)); }
;
3083 __kmp_null_resume_wrapper(__kmp_gtid_from_thread(thread)((((thread) != __null) ? 0 : __kmp_debug_assert("(thread) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3083)), (thread)->th.th_info.ds.ds_gtid)
, sleep_loc);
3084 }
3085 }
3086 }
3087 if (done) {
3088 break;
3089 }
3090
3091 // If we are oversubscribed, or have waited a bit (and library mode is
3092 // throughput), yield. Pause is in the following code.
3093 KMP_YIELD(TCR_4(__kmp_nth) > __kmp_avail_proc){ __kmp_x86_pause(); __kmp_yield(((__kmp_nth) > __kmp_avail_proc
)); }
;
3094 KMP_YIELD_SPIN(spins){ __kmp_x86_pause(); (spins) -= 2; if (!(spins)) { __kmp_yield
(1); (spins) = __kmp_yield_next; } }
; // Yields only if KMP_LIBRARY=throughput
3095 }
3096}
3097
3098// __kmp_task_team_setup: Create a task_team for the current team, but use
3099// an already created, unused one if it already exists.
3100void __kmp_task_team_setup(kmp_info_t *this_thr, kmp_team_t *team, int always) {
3101 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec)((__kmp_tasking_mode != tskm_immediate_exec) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode != tskm_immediate_exec", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3101))
;
3102
3103 // If this task_team hasn't been created yet, allocate it. It will be used in
3104 // the region after the next.
3105 // If it exists, it is the current task team and shouldn't be touched yet as
3106 // it may still be in use.
3107 if (team->t.t_task_team[this_thr->th.th_task_state] == NULL__null &&
3108 (always || team->t.t_nproc > 1)) {
3109 team->t.t_task_team[this_thr->th.th_task_state] =
3110 __kmp_allocate_task_team(this_thr, team);
3111 KA_TRACE(20, ("__kmp_task_team_setup: Master T#%d created new task_team %p "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created new task_team %p "
"for team %d at parity=%d\n", ((((this_thr) != __null) ? 0 :
__kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3113)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[this_thr->th.th_task_state], ((team != __null) ? team->
t.t_id : -1), this_thr->th.th_task_state); }
3112 "for team %d at parity=%d\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created new task_team %p "
"for team %d at parity=%d\n", ((((this_thr) != __null) ? 0 :
__kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3113)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[this_thr->th.th_task_state], ((team != __null) ? team->
t.t_id : -1), this_thr->th.th_task_state); }
3113 __kmp_gtid_from_thread(this_thr),if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created new task_team %p "
"for team %d at parity=%d\n", ((((this_thr) != __null) ? 0 :
__kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3113)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[this_thr->th.th_task_state], ((team != __null) ? team->
t.t_id : -1), this_thr->th.th_task_state); }
3114 team->t.t_task_team[this_thr->th.th_task_state],if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created new task_team %p "
"for team %d at parity=%d\n", ((((this_thr) != __null) ? 0 :
__kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3113)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[this_thr->th.th_task_state], ((team != __null) ? team->
t.t_id : -1), this_thr->th.th_task_state); }
3115 ((team != NULL) ? team->t.t_id : -1),if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created new task_team %p "
"for team %d at parity=%d\n", ((((this_thr) != __null) ? 0 :
__kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3113)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[this_thr->th.th_task_state], ((team != __null) ? team->
t.t_id : -1), this_thr->th.th_task_state); }
3116 this_thr->th.th_task_state))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created new task_team %p "
"for team %d at parity=%d\n", ((((this_thr) != __null) ? 0 :
__kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3113)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[this_thr->th.th_task_state], ((team != __null) ? team->
t.t_id : -1), this_thr->th.th_task_state); }
;
3117 }
3118
3119 // After threads exit the release, they will call sync, and then point to this
3120 // other task_team; make sure it is allocated and properly initialized. As
3121 // threads spin in the barrier release phase, they will continue to use the
3122 // previous task_team struct(above), until they receive the signal to stop
3123 // checking for tasks (they can't safely reference the kmp_team_t struct,
3124 // which could be reallocated by the master thread). No task teams are formed
3125 // for serialized teams.
3126 if (team->t.t_nproc > 1) {
3127 int other_team = 1 - this_thr->th.th_task_state;
3128 if (team->t.t_task_team[other_team] == NULL__null) { // setup other team as well
3129 team->t.t_task_team[other_team] =
3130 __kmp_allocate_task_team(this_thr, team);
3131 KA_TRACE(20, ("__kmp_task_team_setup: Master T#%d created second new "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created second new "
"task_team %p for team %d at parity=%d\n", ((((this_thr) != __null
) ? 0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3133)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3132 "task_team %p for team %d at parity=%d\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created second new "
"task_team %p for team %d at parity=%d\n", ((((this_thr) != __null
) ? 0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3133)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3133 __kmp_gtid_from_thread(this_thr),if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created second new "
"task_team %p for team %d at parity=%d\n", ((((this_thr) != __null
) ? 0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3133)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3134 team->t.t_task_team[other_team],if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created second new "
"task_team %p for team %d at parity=%d\n", ((((this_thr) != __null
) ? 0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3133)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3135 ((team != NULL) ? team->t.t_id : -1), other_team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d created second new "
"task_team %p for team %d at parity=%d\n", ((((this_thr) != __null
) ? 0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3133)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
;
3136 } else { // Leave the old task team struct in place for the upcoming region;
3137 // adjust as needed
3138 kmp_task_team_t *task_team = team->t.t_task_team[other_team];
3139 if (!task_team->tt.tt_active ||
3140 team->t.t_nproc != task_team->tt.tt_nproc) {
3141 TCW_4(task_team->tt.tt_nproc, team->t.t_nproc)(task_team->tt.tt_nproc) = (team->t.t_nproc);
3142 TCW_4(task_team->tt.tt_found_tasks, FALSE)(task_team->tt.tt_found_tasks) = (0);
3143#if OMP_45_ENABLED(50 >= 45)
3144 TCW_4(task_team->tt.tt_found_proxy_tasks, FALSE)(task_team->tt.tt_found_proxy_tasks) = (0);
3145#endif
3146 KMP_ATOMIC_ST_REL(&task_team->tt.tt_unfinished_threads,(&task_team->tt.tt_unfinished_threads)->store(team->
t.t_nproc, std::memory_order_release)
3147 team->t.t_nproc)(&task_team->tt.tt_unfinished_threads)->store(team->
t.t_nproc, std::memory_order_release)
;
3148 TCW_4(task_team->tt.tt_active, TRUE)(task_team->tt.tt_active) = ((!0));
3149 }
3150 // if team size has changed, the first thread to enable tasking will
3151 // realloc threads_data if necessary
3152 KA_TRACE(20, ("__kmp_task_team_setup: Master T#%d reset next task_team "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d reset next task_team "
"%p for team %d at parity=%d\n", ((((this_thr) != __null) ? 0
: __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3154)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3153 "%p for team %d at parity=%d\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d reset next task_team "
"%p for team %d at parity=%d\n", ((((this_thr) != __null) ? 0
: __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3154)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3154 __kmp_gtid_from_thread(this_thr),if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d reset next task_team "
"%p for team %d at parity=%d\n", ((((this_thr) != __null) ? 0
: __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3154)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3155 team->t.t_task_team[other_team],if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d reset next task_team "
"%p for team %d at parity=%d\n", ((((this_thr) != __null) ? 0
: __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3154)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
3156 ((team != NULL) ? team->t.t_id : -1), other_team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_setup: Master T#%d reset next task_team "
"%p for team %d at parity=%d\n", ((((this_thr) != __null) ? 0
: __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3154)), (this_thr)->th.th_info.ds.ds_gtid), team->t.t_task_team
[other_team], ((team != __null) ? team->t.t_id : -1), other_team
); }
;
3157 }
3158 }
3159}
3160
3161// __kmp_task_team_sync: Propagation of task team data from team to threads
3162// which happens just after the release phase of a team barrier. This may be
3163// called by any thread, but only for teams with # threads > 1.
3164void __kmp_task_team_sync(kmp_info_t *this_thr, kmp_team_t *team) {
3165 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec)((__kmp_tasking_mode != tskm_immediate_exec) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode != tskm_immediate_exec", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3165))
;
3166
3167 // Toggle the th_task_state field, to switch which task_team this thread
3168 // refers to
3169 this_thr->th.th_task_state = 1 - this_thr->th.th_task_state;
3170 // It is now safe to propagate the task team pointer from the team struct to
3171 // the current thread.
3172 TCW_PTR(this_thr->th.th_task_team,((this_thr->th.th_task_team)) = ((team->t.t_task_team[this_thr
->th.th_task_state]))
3173 team->t.t_task_team[this_thr->th.th_task_state])((this_thr->th.th_task_team)) = ((team->t.t_task_team[this_thr
->th.th_task_state]))
;
3174 KA_TRACE(20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_sync: Thread T#%d task team switched to task_team "
"%p from Team #%d (parity=%d)\n", ((((this_thr) != __null) ?
0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3177)), (this_thr)->th.th_info.ds.ds_gtid), this_thr->
th.th_task_team, ((team != __null) ? team->t.t_id : -1), this_thr
->th.th_task_state); }
3175 ("__kmp_task_team_sync: Thread T#%d task team switched to task_team "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_sync: Thread T#%d task team switched to task_team "
"%p from Team #%d (parity=%d)\n", ((((this_thr) != __null) ?
0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3177)), (this_thr)->th.th_info.ds.ds_gtid), this_thr->
th.th_task_team, ((team != __null) ? team->t.t_id : -1), this_thr
->th.th_task_state); }
3176 "%p from Team #%d (parity=%d)\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_sync: Thread T#%d task team switched to task_team "
"%p from Team #%d (parity=%d)\n", ((((this_thr) != __null) ?
0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3177)), (this_thr)->th.th_info.ds.ds_gtid), this_thr->
th.th_task_team, ((team != __null) ? team->t.t_id : -1), this_thr
->th.th_task_state); }
3177 __kmp_gtid_from_thread(this_thr), this_thr->th.th_task_team,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_sync: Thread T#%d task team switched to task_team "
"%p from Team #%d (parity=%d)\n", ((((this_thr) != __null) ?
0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3177)), (this_thr)->th.th_info.ds.ds_gtid), this_thr->
th.th_task_team, ((team != __null) ? team->t.t_id : -1), this_thr
->th.th_task_state); }
3178 ((team != NULL) ? team->t.t_id : -1), this_thr->th.th_task_state))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_sync: Thread T#%d task team switched to task_team "
"%p from Team #%d (parity=%d)\n", ((((this_thr) != __null) ?
0 : __kmp_debug_assert("(this_thr) != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3177)), (this_thr)->th.th_info.ds.ds_gtid), this_thr->
th.th_task_team, ((team != __null) ? team->t.t_id : -1), this_thr
->th.th_task_state); }
;
3179}
3180
3181// __kmp_task_team_wait: Master thread waits for outstanding tasks after the
3182// barrier gather phase. Only called by master thread if #threads in team > 1 or
3183// if proxy tasks were created.
3184//
3185// wait is a flag that defaults to 1 (see kmp.h), but waiting can be turned off
3186// by passing in 0 optionally as the last argument. When wait is zero, master
3187// thread does not wait for unfinished_threads to reach 0.
3188void __kmp_task_team_wait(
3189 kmp_info_t *this_thr,
3190 kmp_team_t *team USE_ITT_BUILD_ARG(void *itt_sync_obj), void *itt_sync_obj, int wait) {
3191 kmp_task_team_t *task_team = team->t.t_task_team[this_thr->th.th_task_state];
3192
3193 KMP_DEBUG_ASSERT(__kmp_tasking_mode != tskm_immediate_exec)((__kmp_tasking_mode != tskm_immediate_exec) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode != tskm_immediate_exec", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3193))
;
3194 KMP_DEBUG_ASSERT(task_team == this_thr->th.th_task_team)((task_team == this_thr->th.th_task_team) ? 0 : __kmp_debug_assert
("task_team == this_thr->th.th_task_team", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3194))
;
3195
3196 if ((task_team != NULL__null) && KMP_TASKING_ENABLED(task_team)(((task_team)->tt.tt_found_tasks) == (!0))) {
3197 if (wait) {
3198 KA_TRACE(20, ("__kmp_task_team_wait: Master T#%d waiting for all tasks "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d waiting for all tasks "
"(for unfinished_threads to reach 0) on task_team = %p\n", (
(((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3200)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
3199 "(for unfinished_threads to reach 0) on task_team = %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d waiting for all tasks "
"(for unfinished_threads to reach 0) on task_team = %p\n", (
(((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3200)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
3200 __kmp_gtid_from_thread(this_thr), task_team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d waiting for all tasks "
"(for unfinished_threads to reach 0) on task_team = %p\n", (
(((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3200)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
;
3201 // Worker threads may have dropped through to release phase, but could
3202 // still be executing tasks. Wait here for tasks to complete. To avoid
3203 // memory contention, only master thread checks termination condition.
3204 kmp_flag_32 flag(RCAST(std::atomic<kmp_uint32> *,reinterpret_cast<std::atomic<kmp_uint32> *>(&
task_team->tt.tt_unfinished_threads)
3205 &task_team->tt.tt_unfinished_threads)reinterpret_cast<std::atomic<kmp_uint32> *>(&
task_team->tt.tt_unfinished_threads)
,
3206 0U);
3207 flag.wait(this_thr, TRUE(!0) USE_ITT_BUILD_ARG(itt_sync_obj), itt_sync_obj);
3208 }
3209 // Deactivate the old task team, so that the worker threads will stop
3210 // referencing it while spinning.
3211 KA_TRACE(if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d deactivating task_team %p: "
"setting active to false, setting local and team's pointer to NULL\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3215)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
3212 20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d deactivating task_team %p: "
"setting active to false, setting local and team's pointer to NULL\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3215)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
3213 ("__kmp_task_team_wait: Master T#%d deactivating task_team %p: "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d deactivating task_team %p: "
"setting active to false, setting local and team's pointer to NULL\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3215)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
3214 "setting active to false, setting local and team's pointer to NULL\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d deactivating task_team %p: "
"setting active to false, setting local and team's pointer to NULL\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3215)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
3215 __kmp_gtid_from_thread(this_thr), task_team))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_team_wait: Master T#%d deactivating task_team %p: "
"setting active to false, setting local and team's pointer to NULL\n"
, ((((this_thr) != __null) ? 0 : __kmp_debug_assert("(this_thr) != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3215)), (this_thr)->th.th_info.ds.ds_gtid), task_team); }
;
3216#if OMP_45_ENABLED(50 >= 45)
3217 KMP_DEBUG_ASSERT(task_team->tt.tt_nproc > 1 ||((task_team->tt.tt_nproc > 1 || task_team->tt.tt_found_proxy_tasks
== (!0)) ? 0 : __kmp_debug_assert("task_team->tt.tt_nproc > 1 || task_team->tt.tt_found_proxy_tasks == (!0)"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3218))
3218 task_team->tt.tt_found_proxy_tasks == TRUE)((task_team->tt.tt_nproc > 1 || task_team->tt.tt_found_proxy_tasks
== (!0)) ? 0 : __kmp_debug_assert("task_team->tt.tt_nproc > 1 || task_team->tt.tt_found_proxy_tasks == (!0)"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3218))
;
3219 TCW_SYNC_4(task_team->tt.tt_found_proxy_tasks, FALSE)(task_team->tt.tt_found_proxy_tasks) = (0);
3220#else
3221 KMP_DEBUG_ASSERT(task_team->tt.tt_nproc > 1)((task_team->tt.tt_nproc > 1) ? 0 : __kmp_debug_assert(
"task_team->tt.tt_nproc > 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3221))
;
3222#endif
3223 KMP_CHECK_UPDATE(task_team->tt.tt_untied_task_encountered, 0)if ((task_team->tt.tt_untied_task_encountered) != (0)) (task_team
->tt.tt_untied_task_encountered) = (0)
;
3224 TCW_SYNC_4(task_team->tt.tt_active, FALSE)(task_team->tt.tt_active) = (0);
3225 KMP_MB();
3226
3227 TCW_PTR(this_thr->th.th_task_team, NULL)((this_thr->th.th_task_team)) = ((__null));
3228 }
3229}
3230
3231// __kmp_tasking_barrier:
3232// This routine may only called when __kmp_tasking_mode == tskm_extra_barrier.
3233// Internal function to execute all tasks prior to a regular barrier or a join
3234// barrier. It is a full barrier itself, which unfortunately turns regular
3235// barriers into double barriers and join barriers into 1 1/2 barriers.
3236void __kmp_tasking_barrier(kmp_team_t *team, kmp_info_t *thread, int gtid) {
3237 std::atomic<kmp_uint32> *spin = RCAST(reinterpret_cast<std::atomic<kmp_uint32> *>(&
team->t.t_task_team[thread->th.th_task_state]->tt.tt_unfinished_threads
)
3238 std::atomic<kmp_uint32> *,reinterpret_cast<std::atomic<kmp_uint32> *>(&
team->t.t_task_team[thread->th.th_task_state]->tt.tt_unfinished_threads
)
3239 &team->t.t_task_team[thread->th.th_task_state]->tt.tt_unfinished_threads)reinterpret_cast<std::atomic<kmp_uint32> *>(&
team->t.t_task_team[thread->th.th_task_state]->tt.tt_unfinished_threads
)
;
3240 int flag = FALSE0;
3241 KMP_DEBUG_ASSERT(__kmp_tasking_mode == tskm_extra_barrier)((__kmp_tasking_mode == tskm_extra_barrier) ? 0 : __kmp_debug_assert
("__kmp_tasking_mode == tskm_extra_barrier", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3241))
;
3242
3243#if USE_ITT_BUILD1
3244 KMP_FSYNC_SPIN_INIT(spin, NULL)int sync_iters = 0; if (__kmp_itt_fsync_prepare_ptr__3_0) { if
(spin == __null) { spin = __null; } } __asm__ __volatile__("movl %0, %%ebx; .byte 0x64, 0x67, 0x90 "
::"i"(0x4376) : "%ebx")
;
3245#endif /* USE_ITT_BUILD */
3246 kmp_flag_32 spin_flag(spin, 0U);
3247 while (!spin_flag.execute_tasks(thread, gtid, TRUE(!0),
3248 &flag USE_ITT_BUILD_ARG(NULL), __null, 0)) {
3249#if USE_ITT_BUILD1
3250 // TODO: What about itt_sync_obj??
3251 KMP_FSYNC_SPIN_PREPARE(RCAST(void *, spin))do { if (__kmp_itt_fsync_prepare_ptr__3_0 && sync_iters
< __kmp_itt_prepare_delay) { ++sync_iters; if (sync_iters
>= __kmp_itt_prepare_delay) { (!__kmp_itt_fsync_prepare_ptr__3_0
) ? (void)0 : __kmp_itt_fsync_prepare_ptr__3_0((void *)((void
*)reinterpret_cast<void *>(spin))); } } } while (0)
;
3252#endif /* USE_ITT_BUILD */
3253
3254 if (TCR_4(__kmp_global.g.g_done)(__kmp_global.g.g_done)) {
3255 if (__kmp_global.g.g_abort)
3256 __kmp_abort_thread();
3257 break;
3258 }
3259 KMP_YIELD(TRUE){ __kmp_x86_pause(); __kmp_yield(((!0))); }; // GH: We always yield here
3260 }
3261#if USE_ITT_BUILD1
3262 KMP_FSYNC_SPIN_ACQUIRED(RCAST(void *, spin))do { __asm__ __volatile__("movl %0, %%ebx; .byte 0x64, 0x67, 0x90 "
::"i"(0x4377) : "%ebx"); if (sync_iters >= __kmp_itt_prepare_delay
) { (!__kmp_itt_fsync_acquired_ptr__3_0) ? (void)0 : __kmp_itt_fsync_acquired_ptr__3_0
((void *)((void *)reinterpret_cast<void *>(spin))); } }
while (0)
;
3263#endif /* USE_ITT_BUILD */
3264}
3265
3266#if OMP_45_ENABLED(50 >= 45)
3267
3268// __kmp_give_task puts a task into a given thread queue if:
3269// - the queue for that thread was created
3270// - there's space in that queue
3271// Because of this, __kmp_push_task needs to check if there's space after
3272// getting the lock
3273static bool __kmp_give_task(kmp_info_t *thread, kmp_int32 tid, kmp_task_t *task,
3274 kmp_int32 pass) {
3275 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
3276 kmp_task_team_t *task_team = taskdata->td_task_team;
3277
3278 KA_TRACE(20, ("__kmp_give_task: trying to give task %p to thread %d.\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_give_task: trying to give task %p to thread %d.\n"
, taskdata, tid); }
3279 taskdata, tid))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_give_task: trying to give task %p to thread %d.\n"
, taskdata, tid); }
;
3280
3281 // If task_team is NULL something went really bad...
3282 KMP_DEBUG_ASSERT(task_team != NULL)((task_team != __null) ? 0 : __kmp_debug_assert("task_team != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3282))
;
3283
3284 bool result = false;
3285 kmp_thread_data_t *thread_data = &task_team->tt.tt_threads_data[tid];
3286
3287 if (thread_data->td.td_deque == NULL__null) {
3288 // There's no queue in this thread, go find another one
3289 // We're guaranteed that at least one thread has a queue
3290 KA_TRACE(30,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: thread %d has no queue while giving task %p.\n"
, tid, taskdata); }
3291 ("__kmp_give_task: thread %d has no queue while giving task %p.\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: thread %d has no queue while giving task %p.\n"
, tid, taskdata); }
3292 tid, taskdata))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: thread %d has no queue while giving task %p.\n"
, tid, taskdata); }
;
3293 return result;
3294 }
3295
3296 if (TCR_4(thread_data->td.td_deque_ntasks)(thread_data->td.td_deque_ntasks) >=
3297 TASK_DEQUE_SIZE(thread_data->td)((thread_data->td).td_deque_size)) {
3298 KA_TRACE(if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: queue is full while giving task %p to thread %d.\n"
, taskdata, tid); }
3299 30,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: queue is full while giving task %p to thread %d.\n"
, taskdata, tid); }
3300 ("__kmp_give_task: queue is full while giving task %p to thread %d.\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: queue is full while giving task %p to thread %d.\n"
, taskdata, tid); }
3301 taskdata, tid))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: queue is full while giving task %p to thread %d.\n"
, taskdata, tid); }
;
3302
3303 // if this deque is bigger than the pass ratio give a chance to another
3304 // thread
3305 if (TASK_DEQUE_SIZE(thread_data->td)((thread_data->td).td_deque_size) / INITIAL_TASK_DEQUE_SIZE(1 << 8) >= pass)
3306 return result;
3307
3308 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
3309 __kmp_realloc_task_deque(thread, thread_data);
3310
3311 } else {
3312
3313 __kmp_acquire_bootstrap_lock(&thread_data->td.td_deque_lock);
3314
3315 if (TCR_4(thread_data->td.td_deque_ntasks)(thread_data->td.td_deque_ntasks) >=
3316 TASK_DEQUE_SIZE(thread_data->td)((thread_data->td).td_deque_size)) {
3317 KA_TRACE(30, ("__kmp_give_task: queue is full while giving task %p to "if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: queue is full while giving task %p to "
"thread %d.\n", taskdata, tid); }
3318 "thread %d.\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: queue is full while giving task %p to "
"thread %d.\n", taskdata, tid); }
3319 taskdata, tid))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: queue is full while giving task %p to "
"thread %d.\n", taskdata, tid); }
;
3320
3321 // if this deque is bigger than the pass ratio give a chance to another
3322 // thread
3323 if (TASK_DEQUE_SIZE(thread_data->td)((thread_data->td).td_deque_size) / INITIAL_TASK_DEQUE_SIZE(1 << 8) >= pass)
3324 goto release_and_exit;
3325
3326 __kmp_realloc_task_deque(thread, thread_data);
3327 }
3328 }
3329
3330 // lock is held here, and there is space in the deque
3331
3332 thread_data->td.td_deque[thread_data->td.td_deque_tail] = taskdata;
3333 // Wrap index.
3334 thread_data->td.td_deque_tail =
3335 (thread_data->td.td_deque_tail + 1) & TASK_DEQUE_MASK(thread_data->td)((thread_data->td).td_deque_size - 1);
3336 TCW_4(thread_data->td.td_deque_ntasks,(thread_data->td.td_deque_ntasks) = ((thread_data->td.td_deque_ntasks
) + 1)
3337 TCR_4(thread_data->td.td_deque_ntasks) + 1)(thread_data->td.td_deque_ntasks) = ((thread_data->td.td_deque_ntasks
) + 1)
;
3338
3339 result = true;
3340 KA_TRACE(30, ("__kmp_give_task: successfully gave task %p to thread %d.\n",if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: successfully gave task %p to thread %d.\n"
, taskdata, tid); }
3341 taskdata, tid))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_give_task: successfully gave task %p to thread %d.\n"
, taskdata, tid); }
;
3342
3343release_and_exit:
3344 __kmp_release_bootstrap_lock(&thread_data->td.td_deque_lock);
3345
3346 return result;
3347}
3348
3349/* The finish of the proxy tasks is divided in two pieces:
3350 - the top half is the one that can be done from a thread outside the team
3351 - the bottom half must be run from a them within the team
3352
3353 In order to run the bottom half the task gets queued back into one of the
3354 threads of the team. Once the td_incomplete_child_task counter of the parent
3355 is decremented the threads can leave the barriers. So, the bottom half needs
3356 to be queued before the counter is decremented. The top half is therefore
3357 divided in two parts:
3358 - things that can be run before queuing the bottom half
3359 - things that must be run after queuing the bottom half
3360
3361 This creates a second race as the bottom half can free the task before the
3362 second top half is executed. To avoid this we use the
3363 td_incomplete_child_task of the proxy task to synchronize the top and bottom
3364 half. */
3365static void __kmp_first_top_half_finish_proxy(kmp_taskdata_t *taskdata) {
3366 KMP_DEBUG_ASSERT(taskdata->td_flags.tasktype == TASK_EXPLICIT)((taskdata->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3366))
;
3367 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY)((taskdata->td_flags.proxy == 1) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.proxy == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3367))
;
3368 KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0)((taskdata->td_flags.complete == 0) ? 0 : __kmp_debug_assert
("taskdata->td_flags.complete == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3368))
;
3369 KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0)((taskdata->td_flags.freed == 0) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.freed == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3369))
;
3370
3371 taskdata->td_flags.complete = 1; // mark the task as completed
3372
3373 if (taskdata->td_taskgroup)
3374 KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count)(&taskdata->td_taskgroup->count)->fetch_sub(1, std
::memory_order_acq_rel)
;
3375
3376 // Create an imaginary children for this task so the bottom half cannot
3377 // release the task before we have completed the second top half
3378 KMP_ATOMIC_INC(&taskdata->td_incomplete_child_tasks)(&taskdata->td_incomplete_child_tasks)->fetch_add(1
, std::memory_order_acq_rel)
;
3379}
3380
3381static void __kmp_second_top_half_finish_proxy(kmp_taskdata_t *taskdata) {
3382 kmp_int32 children = 0;
3383
3384 // Predecrement simulated by "- 1" calculation
3385 children =
3386 KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks)(&taskdata->td_parent->td_incomplete_child_tasks)->
fetch_sub(1, std::memory_order_acq_rel)
- 1;
3387 KMP_DEBUG_ASSERT(children >= 0)((children >= 0) ? 0 : __kmp_debug_assert("children >= 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3387))
;
3388
3389 // Remove the imaginary children
3390 KMP_ATOMIC_DEC(&taskdata->td_incomplete_child_tasks)(&taskdata->td_incomplete_child_tasks)->fetch_sub(1
, std::memory_order_acq_rel)
;
3391}
3392
3393static void __kmp_bottom_half_finish_proxy(kmp_int32 gtid, kmp_task_t *ptask) {
3394 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask)(((kmp_taskdata_t *)ptask) - 1);
3395 kmp_info_t *thread = __kmp_threads[gtid];
3396
3397 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY)((taskdata->td_flags.proxy == 1) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.proxy == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3397))
;
3398 KMP_DEBUG_ASSERT(taskdata->td_flags.complete ==((taskdata->td_flags.complete == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.complete == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3399))
3399 1)((taskdata->td_flags.complete == 1) ? 0 : __kmp_debug_assert
("taskdata->td_flags.complete == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3399))
; // top half must run before bottom half
3400
3401 // We need to wait to make sure the top half is finished
3402 // Spinning here should be ok as this should happen quickly
3403 while (KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks)(&taskdata->td_incomplete_child_tasks)->load(std::memory_order_acquire
)
> 0)
3404 ;
3405
3406 __kmp_release_deps(gtid, taskdata);
3407 __kmp_free_task_and_ancestors(gtid, taskdata, thread);
3408}
3409
3410/*!
3411@ingroup TASKING
3412@param gtid Global Thread ID of encountering thread
3413@param ptask Task which execution is completed
3414
3415Execute the completation of a proxy task from a thread of that is part of the
3416team. Run first and bottom halves directly.
3417*/
3418void __kmpc_proxy_task_completed(kmp_int32 gtid, kmp_task_t *ptask) {
3419 KMP_DEBUG_ASSERT(ptask != NULL)((ptask != __null) ? 0 : __kmp_debug_assert("ptask != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3419))
;
3420 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask)(((kmp_taskdata_t *)ptask) - 1);
3421 KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed(enter): T#%d proxy task %p completing\n"
, gtid, taskdata); }
3422 10, ("__kmp_proxy_task_completed(enter): T#%d proxy task %p completing\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed(enter): T#%d proxy task %p completing\n"
, gtid, taskdata); }
3423 gtid, taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed(enter): T#%d proxy task %p completing\n"
, gtid, taskdata); }
;
3424
3425 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY)((taskdata->td_flags.proxy == 1) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.proxy == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3425))
;
3426
3427 __kmp_first_top_half_finish_proxy(taskdata);
3428 __kmp_second_top_half_finish_proxy(taskdata);
3429 __kmp_bottom_half_finish_proxy(gtid, ptask);
3430
3431 KA_TRACE(10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed(exit): T#%d proxy task %p completing\n"
, gtid, taskdata); }
3432 ("__kmp_proxy_task_completed(exit): T#%d proxy task %p completing\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed(exit): T#%d proxy task %p completing\n"
, gtid, taskdata); }
3433 gtid, taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed(exit): T#%d proxy task %p completing\n"
, gtid, taskdata); }
;
3434}
3435
3436/*!
3437@ingroup TASKING
3438@param ptask Task which execution is completed
3439
3440Execute the completation of a proxy task from a thread that could not belong to
3441the team.
3442*/
3443void __kmpc_proxy_task_completed_ooo(kmp_task_t *ptask) {
3444 KMP_DEBUG_ASSERT(ptask != NULL)((ptask != __null) ? 0 : __kmp_debug_assert("ptask != __null"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3444))
;
3445 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask)(((kmp_taskdata_t *)ptask) - 1);
3446
3447 KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(enter): proxy task completing ooo %p\n"
, taskdata); }
3448 10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(enter): proxy task completing ooo %p\n"
, taskdata); }
3449 ("__kmp_proxy_task_completed_ooo(enter): proxy task completing ooo %p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(enter): proxy task completing ooo %p\n"
, taskdata); }
3450 taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(enter): proxy task completing ooo %p\n"
, taskdata); }
;
3451
3452 KMP_DEBUG_ASSERT(taskdata->td_flags.proxy == TASK_PROXY)((taskdata->td_flags.proxy == 1) ? 0 : __kmp_debug_assert(
"taskdata->td_flags.proxy == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3452))
;
3453
3454 __kmp_first_top_half_finish_proxy(taskdata);
3455
3456 // Enqueue task to complete bottom half completion from a thread within the
3457 // corresponding team
3458 kmp_team_t *team = taskdata->td_team;
3459 kmp_int32 nthreads = team->t.t_nproc;
3460 kmp_info_t *thread;
3461
3462 // This should be similar to start_k = __kmp_get_random( thread ) % nthreads
3463 // but we cannot use __kmp_get_random here
3464 kmp_int32 start_k = 0;
3465 kmp_int32 pass = 1;
3466 kmp_int32 k = start_k;
3467
3468 do {
3469 // For now we're just linearly trying to find a thread
3470 thread = team->t.t_threads[k];
3471 k = (k + 1) % nthreads;
3472
3473 // we did a full pass through all the threads
3474 if (k == start_k)
3475 pass = pass << 1;
3476
3477 } while (!__kmp_give_task(thread, k, ptask, pass));
3478
3479 __kmp_second_top_half_finish_proxy(taskdata);
3480
3481 KA_TRACE(if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(exit): proxy task completing ooo %p\n"
, taskdata); }
3482 10,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(exit): proxy task completing ooo %p\n"
, taskdata); }
3483 ("__kmp_proxy_task_completed_ooo(exit): proxy task completing ooo %p\n",if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(exit): proxy task completing ooo %p\n"
, taskdata); }
3484 taskdata))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_proxy_task_completed_ooo(exit): proxy task completing ooo %p\n"
, taskdata); }
;
3485}
3486
3487// __kmp_task_dup_alloc: Allocate the taskdata and make a copy of source task
3488// for taskloop
3489//
3490// thread: allocating thread
3491// task_src: pointer to source task to be duplicated
3492// returns: a pointer to the allocated kmp_task_t structure (task).
3493kmp_task_t *__kmp_task_dup_alloc(kmp_info_t *thread, kmp_task_t *task_src) {
3494 kmp_task_t *task;
3495 kmp_taskdata_t *taskdata;
3496 kmp_taskdata_t *taskdata_src;
3497 kmp_taskdata_t *parent_task = thread->th.th_current_task;
3498 size_t shareds_offset;
3499 size_t task_size;
3500
3501 KA_TRACE(10, ("__kmp_task_dup_alloc(enter): Th %p, source task %p\n", thread,if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_dup_alloc(enter): Th %p, source task %p\n"
, thread, task_src); }
3502 task_src))if (kmp_a_debug >= 10) { __kmp_debug_printf ("__kmp_task_dup_alloc(enter): Th %p, source task %p\n"
, thread, task_src); }
;
3503 taskdata_src = KMP_TASK_TO_TASKDATA(task_src)(((kmp_taskdata_t *)task_src) - 1);
3504 KMP_DEBUG_ASSERT(taskdata_src->td_flags.proxy ==((taskdata_src->td_flags.proxy == 0) ? 0 : __kmp_debug_assert
("taskdata_src->td_flags.proxy == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3505))
3505 TASK_FULL)((taskdata_src->td_flags.proxy == 0) ? 0 : __kmp_debug_assert
("taskdata_src->td_flags.proxy == 0", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3505))
; // it should not be proxy task
3506 KMP_DEBUG_ASSERT(taskdata_src->td_flags.tasktype == TASK_EXPLICIT)((taskdata_src->td_flags.tasktype == 1) ? 0 : __kmp_debug_assert
("taskdata_src->td_flags.tasktype == 1", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3506))
;
3507 task_size = taskdata_src->td_size_alloc;
3508
3509 // Allocate a kmp_taskdata_t block and a kmp_task_t block.
3510 KA_TRACE(30, ("__kmp_task_dup_alloc: Th %p, malloc size %ld\n", thread,if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_task_dup_alloc: Th %p, malloc size %ld\n"
, thread, task_size); }
3511 task_size))if (kmp_a_debug >= 30) { __kmp_debug_printf ("__kmp_task_dup_alloc: Th %p, malloc size %ld\n"
, thread, task_size); }
;
3512#if USE_FAST_MEMORY3
3513 taskdata = (kmp_taskdata_t *)__kmp_fast_allocate(thread, task_size)___kmp_fast_allocate((thread), (task_size), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3513)
;
3514#else
3515 taskdata = (kmp_taskdata_t *)__kmp_thread_malloc(thread, task_size)___kmp_thread_malloc((thread), (task_size), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3515)
;
3516#endif /* USE_FAST_MEMORY */
3517 KMP_MEMCPYmemcpy(taskdata, taskdata_src, task_size);
3518
3519 task = KMP_TASKDATA_TO_TASK(taskdata)(kmp_task_t *)(taskdata + 1);
3520
3521 // Initialize new task (only specific fields not affected by memcpy)
3522 taskdata->td_task_id = KMP_GEN_TASK_ID()(~0);
3523 if (task->shareds != NULL__null) { // need setup shareds pointer
3524 shareds_offset = (char *)task_src->shareds - (char *)taskdata_src;
3525 task->shareds = &((char *)taskdata)[shareds_offset];
3526 KMP_DEBUG_ASSERT((((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1)) ==(((((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1
)) == 0) ? 0 : __kmp_debug_assert("(((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3527))
3527 0)(((((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1
)) == 0) ? 0 : __kmp_debug_assert("(((kmp_uintptr_t)task->shareds) & (sizeof(void *) - 1)) == 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3527))
;
3528 }
3529 taskdata->td_alloc_thread = thread;
3530 taskdata->td_parent = parent_task;
3531 taskdata->td_taskgroup =
3532 parent_task
3533 ->td_taskgroup; // task inherits the taskgroup from the parent task
3534
3535 // Only need to keep track of child task counts if team parallel and tasking
3536 // not serialized
3537 if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
3538 KMP_ATOMIC_INC(&parent_task->td_incomplete_child_tasks)(&parent_task->td_incomplete_child_tasks)->fetch_add
(1, std::memory_order_acq_rel)
;
3539 if (parent_task->td_taskgroup)
3540 KMP_ATOMIC_INC(&parent_task->td_taskgroup->count)(&parent_task->td_taskgroup->count)->fetch_add(1
, std::memory_order_acq_rel)
;
3541 // Only need to keep track of allocated child tasks for explicit tasks since
3542 // implicit not deallocated
3543 if (taskdata->td_parent->td_flags.tasktype == TASK_EXPLICIT1)
3544 KMP_ATOMIC_INC(&taskdata->td_parent->td_allocated_child_tasks)(&taskdata->td_parent->td_allocated_child_tasks)->
fetch_add(1, std::memory_order_acq_rel)
;
3545 }
3546
3547 KA_TRACE(20,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_dup_alloc(exit): Th %p, created task %p, parent=%p\n"
, thread, taskdata, taskdata->td_parent); }
3548 ("__kmp_task_dup_alloc(exit): Th %p, created task %p, parent=%p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_dup_alloc(exit): Th %p, created task %p, parent=%p\n"
, thread, taskdata, taskdata->td_parent); }
3549 thread, taskdata, taskdata->td_parent))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_task_dup_alloc(exit): Th %p, created task %p, parent=%p\n"
, thread, taskdata, taskdata->td_parent); }
;
3550#if OMPT_SUPPORT1
3551 if (UNLIKELY(ompt_enabled.enabled)__builtin_expect(!!(ompt_enabled.enabled), 0))
3552 __ompt_task_init(taskdata, thread->th.th_info.ds.ds_gtid);
3553#endif
3554 return task;
3555}
3556
3557// Routine optionally generated by the compiler for setting the lastprivate flag
3558// and calling needed constructors for private/firstprivate objects
3559// (used to form taskloop tasks from pattern task)
3560// Parameters: dest task, src task, lastprivate flag.
3561typedef void (*p_task_dup_t)(kmp_task_t *, kmp_task_t *, kmp_int32);
3562
3563KMP_BUILD_ASSERT(sizeof(long) == 4 || sizeof(long) == 8)static_assert(sizeof(long) == 4 || sizeof(long) == 8, "Build condition error"
)
;
3564
3565// class to encapsulate manipulating loop bounds in a taskloop task.
3566// this abstracts away the Intel vs GOMP taskloop interface for setting/getting
3567// the loop bound variables.
3568class kmp_taskloop_bounds_t {
3569 kmp_task_t *task;
3570 const kmp_taskdata_t *taskdata;
3571 size_t lower_offset;
3572 size_t upper_offset;
3573
3574public:
3575 kmp_taskloop_bounds_t(kmp_task_t *_task, kmp_uint64 *lb, kmp_uint64 *ub)
3576 : task(_task), taskdata(KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1)),
3577 lower_offset((char *)lb - (char *)task),
3578 upper_offset((char *)ub - (char *)task) {
3579 KMP_DEBUG_ASSERT((char *)lb > (char *)_task)(((char *)lb > (char *)_task) ? 0 : __kmp_debug_assert("(char *)lb > (char *)_task"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3579))
;
3580 KMP_DEBUG_ASSERT((char *)ub > (char *)_task)(((char *)ub > (char *)_task) ? 0 : __kmp_debug_assert("(char *)ub > (char *)_task"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3580))
;
3581 }
3582 kmp_taskloop_bounds_t(kmp_task_t *_task, const kmp_taskloop_bounds_t &bounds)
3583 : task(_task), taskdata(KMP_TASK_TO_TASKDATA(_task)(((kmp_taskdata_t *)_task) - 1)),
3584 lower_offset(bounds.lower_offset), upper_offset(bounds.upper_offset) {}
3585 size_t get_lower_offset() const { return lower_offset; }
3586 size_t get_upper_offset() const { return upper_offset; }
3587 kmp_uint64 get_lb() const {
3588 kmp_int64 retval;
3589#if defined(KMP_GOMP_COMPAT)
3590 // Intel task just returns the lower bound normally
3591 if (!taskdata->td_flags.native) {
3592 retval = *(kmp_int64 *)((char *)task + lower_offset);
3593 } else {
3594 // GOMP task has to take into account the sizeof(long)
3595 if (taskdata->td_size_loop_bounds == 4) {
3596 kmp_int32 *lb = RCAST(kmp_int32 *, task->shareds)reinterpret_cast<kmp_int32 *>(task->shareds);
3597 retval = (kmp_int64)*lb;
3598 } else {
3599 kmp_int64 *lb = RCAST(kmp_int64 *, task->shareds)reinterpret_cast<kmp_int64 *>(task->shareds);
3600 retval = (kmp_int64)*lb;
3601 }
3602 }
3603#else
3604 retval = *(kmp_int64 *)((char *)task + lower_offset);
3605#endif // defined(KMP_GOMP_COMPAT)
3606 return retval;
3607 }
3608 kmp_uint64 get_ub() const {
3609 kmp_int64 retval;
3610#if defined(KMP_GOMP_COMPAT)
3611 // Intel task just returns the upper bound normally
3612 if (!taskdata->td_flags.native) {
3613 retval = *(kmp_int64 *)((char *)task + upper_offset);
3614 } else {
3615 // GOMP task has to take into account the sizeof(long)
3616 if (taskdata->td_size_loop_bounds == 4) {
3617 kmp_int32 *ub = RCAST(kmp_int32 *, task->shareds)reinterpret_cast<kmp_int32 *>(task->shareds) + 1;
3618 retval = (kmp_int64)*ub;
3619 } else {
3620 kmp_int64 *ub = RCAST(kmp_int64 *, task->shareds)reinterpret_cast<kmp_int64 *>(task->shareds) + 1;
3621 retval = (kmp_int64)*ub;
3622 }
3623 }
3624#else
3625 retval = *(kmp_int64 *)((char *)task + upper_offset);
3626#endif // defined(KMP_GOMP_COMPAT)
3627 return retval;
3628 }
3629 void set_lb(kmp_uint64 lb) {
3630#if defined(KMP_GOMP_COMPAT)
3631 // Intel task just sets the lower bound normally
3632 if (!taskdata->td_flags.native) {
3633 *(kmp_uint64 *)((char *)task + lower_offset) = lb;
3634 } else {
3635 // GOMP task has to take into account the sizeof(long)
3636 if (taskdata->td_size_loop_bounds == 4) {
3637 kmp_uint32 *lower = RCAST(kmp_uint32 *, task->shareds)reinterpret_cast<kmp_uint32 *>(task->shareds);
3638 *lower = (kmp_uint32)lb;
3639 } else {
3640 kmp_uint64 *lower = RCAST(kmp_uint64 *, task->shareds)reinterpret_cast<kmp_uint64 *>(task->shareds);
3641 *lower = (kmp_uint64)lb;
3642 }
3643 }
3644#else
3645 *(kmp_uint64 *)((char *)task + lower_offset) = lb;
3646#endif // defined(KMP_GOMP_COMPAT)
3647 }
3648 void set_ub(kmp_uint64 ub) {
3649#if defined(KMP_GOMP_COMPAT)
3650 // Intel task just sets the upper bound normally
3651 if (!taskdata->td_flags.native) {
3652 *(kmp_uint64 *)((char *)task + upper_offset) = ub;
3653 } else {
3654 // GOMP task has to take into account the sizeof(long)
3655 if (taskdata->td_size_loop_bounds == 4) {
3656 kmp_uint32 *upper = RCAST(kmp_uint32 *, task->shareds)reinterpret_cast<kmp_uint32 *>(task->shareds) + 1;
3657 *upper = (kmp_uint32)ub;
3658 } else {
3659 kmp_uint64 *upper = RCAST(kmp_uint64 *, task->shareds)reinterpret_cast<kmp_uint64 *>(task->shareds) + 1;
3660 *upper = (kmp_uint64)ub;
3661 }
3662 }
3663#else
3664 *(kmp_uint64 *)((char *)task + upper_offset) = ub;
3665#endif // defined(KMP_GOMP_COMPAT)
3666 }
3667};
3668
3669// __kmp_taskloop_linear: Start tasks of the taskloop linearly
3670//
3671// loc Source location information
3672// gtid Global thread ID
3673// task Pattern task, exposes the loop iteration range
3674// lb Pointer to loop lower bound in task structure
3675// ub Pointer to loop upper bound in task structure
3676// st Loop stride
3677// ub_glob Global upper bound (used for lastprivate check)
3678// num_tasks Number of tasks to execute
3679// grainsize Number of loop iterations per task
3680// extras Number of chunks with grainsize+1 iterations
3681// tc Iterations count
3682// task_dup Tasks duplication routine
3683void __kmp_taskloop_linear(ident_t *loc, int gtid, kmp_task_t *task,
3684 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
3685 kmp_uint64 ub_glob, kmp_uint64 num_tasks,
3686 kmp_uint64 grainsize, kmp_uint64 extras,
3687 kmp_uint64 tc, void *task_dup) {
3688 KMP_COUNT_BLOCK(OMP_TASKLOOP)((void)0);
3689 KMP_TIME_PARTITIONED_BLOCK(OMP_taskloop_scheduling)((void)0);
3690 p_task_dup_t ptask_dup = (p_task_dup_t)task_dup;
3691 // compiler provides global bounds here
3692 kmp_taskloop_bounds_t task_bounds(task, lb, ub);
3693 kmp_uint64 lower = task_bounds.get_lb();
3694 kmp_uint64 upper = task_bounds.get_ub();
3695 kmp_uint64 i;
3696 kmp_info_t *thread = __kmp_threads[gtid];
3697 kmp_taskdata_t *current_task = thread->th.th_current_task;
3698 kmp_task_t *next_task;
3699 kmp_int32 lastpriv = 0;
3700
3701 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize + extras)((tc == num_tasks * grainsize + extras) ? 0 : __kmp_debug_assert
("tc == num_tasks * grainsize + extras", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3701))
;
3702 KMP_DEBUG_ASSERT(num_tasks > extras)((num_tasks > extras) ? 0 : __kmp_debug_assert("num_tasks > extras"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3702))
;
3703 KMP_DEBUG_ASSERT(num_tasks > 0)((num_tasks > 0) ? 0 : __kmp_debug_assert("num_tasks > 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3703))
;
3704 KA_TRACE(20, ("__kmp_taskloop_linear: T#%d: %lld tasks, grainsize %lld, "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d: %lld tasks, grainsize %lld, "
"extras %lld, i=%lld,%lld(%d)%lld, dup %p\n", gtid, num_tasks
, grainsize, extras, lower, upper, ub_glob, st, task_dup); }
3705 "extras %lld, i=%lld,%lld(%d)%lld, dup %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d: %lld tasks, grainsize %lld, "
"extras %lld, i=%lld,%lld(%d)%lld, dup %p\n", gtid, num_tasks
, grainsize, extras, lower, upper, ub_glob, st, task_dup); }
3706 gtid, num_tasks, grainsize, extras, lower, upper, ub_glob, st,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d: %lld tasks, grainsize %lld, "
"extras %lld, i=%lld,%lld(%d)%lld, dup %p\n", gtid, num_tasks
, grainsize, extras, lower, upper, ub_glob, st, task_dup); }
3707 task_dup))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d: %lld tasks, grainsize %lld, "
"extras %lld, i=%lld,%lld(%d)%lld, dup %p\n", gtid, num_tasks
, grainsize, extras, lower, upper, ub_glob, st, task_dup); }
;
3708
3709 // Launch num_tasks tasks, assign grainsize iterations each task
3710 for (i = 0; i < num_tasks; ++i) {
21
Loop condition is true. Entering loop body
3711 kmp_uint64 chunk_minus_1;
3712 if (extras == 0) {
22
Assuming 'extras' is not equal to 0
23
Taking false branch
3713 chunk_minus_1 = grainsize - 1;
3714 } else {
3715 chunk_minus_1 = grainsize;
3716 --extras; // first extras iterations get bigger chunk (grainsize+1)
3717 }
3718 upper = lower + st * chunk_minus_1;
3719 if (i == num_tasks - 1) {
24
Assuming the condition is false
25
Taking false branch
3720 // schedule the last task, set lastprivate flag if needed
3721 if (st == 1) { // most common case
3722 KMP_DEBUG_ASSERT(upper == *ub)((upper == *ub) ? 0 : __kmp_debug_assert("upper == *ub", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3722))
;
3723 if (upper == ub_glob)
3724 lastpriv = 1;
3725 } else if (st > 0) { // positive loop stride
3726 KMP_DEBUG_ASSERT((kmp_uint64)st > *ub - upper)(((kmp_uint64)st > *ub - upper) ? 0 : __kmp_debug_assert("(kmp_uint64)st > *ub - upper"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3726))
;
3727 if ((kmp_uint64)st > ub_glob - upper)
3728 lastpriv = 1;
3729 } else { // negative loop stride
3730 KMP_DEBUG_ASSERT(upper + st < *ub)((upper + st < *ub) ? 0 : __kmp_debug_assert("upper + st < *ub"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3730))
;
3731 if (upper - ub_glob < (kmp_uint64)(-st))
3732 lastpriv = 1;
3733 }
3734 }
3735 next_task = __kmp_task_dup_alloc(thread, task); // allocate new task
3736 kmp_taskdata_t *next_taskdata = KMP_TASK_TO_TASKDATA(next_task)(((kmp_taskdata_t *)next_task) - 1);
3737 kmp_taskloop_bounds_t next_task_bounds =
3738 kmp_taskloop_bounds_t(next_task, task_bounds);
3739
3740 // adjust task-specific bounds
3741 next_task_bounds.set_lb(lower);
3742 if (next_taskdata->td_flags.native) {
26
Taking false branch
3743 next_task_bounds.set_ub(upper + (st > 0 ? 1 : -1));
3744 } else {
3745 next_task_bounds.set_ub(upper);
3746 }
3747 if (ptask_dup != NULL__null) // set lastprivate flag, construct fistprivates, etc.
27
Assuming 'ptask_dup' is equal to NULL
28
Taking false branch
3748 ptask_dup(next_task, task, lastpriv);
3749 KA_TRACE(40,if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
"upper %lld stride %lld, (offsets %p %p)\n", gtid, i, next_task
, lower, upper, st, next_task_bounds.get_lower_offset(), next_task_bounds
.get_upper_offset()); }
3750 ("__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
"upper %lld stride %lld, (offsets %p %p)\n", gtid, i, next_task
, lower, upper, st, next_task_bounds.get_lower_offset(), next_task_bounds
.get_upper_offset()); }
3751 "upper %lld stride %lld, (offsets %p %p)\n",if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
"upper %lld stride %lld, (offsets %p %p)\n", gtid, i, next_task
, lower, upper, st, next_task_bounds.get_lower_offset(), next_task_bounds
.get_upper_offset()); }
3752 gtid, i, next_task, lower, upper, st,if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
"upper %lld stride %lld, (offsets %p %p)\n", gtid, i, next_task
, lower, upper, st, next_task_bounds.get_lower_offset(), next_task_bounds
.get_upper_offset()); }
3753 next_task_bounds.get_lower_offset(),if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
"upper %lld stride %lld, (offsets %p %p)\n", gtid, i, next_task
, lower, upper, st, next_task_bounds.get_lower_offset(), next_task_bounds
.get_upper_offset()); }
3754 next_task_bounds.get_upper_offset()))if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmp_taskloop_linear: T#%d; task #%llu: task %p: lower %lld, "
"upper %lld stride %lld, (offsets %p %p)\n", gtid, i, next_task
, lower, upper, st, next_task_bounds.get_lower_offset(), next_task_bounds
.get_upper_offset()); }
;
3755 __kmp_omp_task(gtid, next_task, true); // schedule new task
29
Calling '__kmp_omp_task'
3756 lower = upper + st; // adjust lower bound for the next iteration
3757 }
3758 // free the pattern task and exit
3759 __kmp_task_start(gtid, task, current_task); // make internal bookkeeping
3760 // do not execute the pattern task, just do internal bookkeeping
3761 __kmp_task_finish(gtid, task, current_task);
3762}
3763
3764// Structure to keep taskloop parameters for auxiliary task
3765// kept in the shareds of the task structure.
3766typedef struct __taskloop_params {
3767 kmp_task_t *task;
3768 kmp_uint64 *lb;
3769 kmp_uint64 *ub;
3770 void *task_dup;
3771 kmp_int64 st;
3772 kmp_uint64 ub_glob;
3773 kmp_uint64 num_tasks;
3774 kmp_uint64 grainsize;
3775 kmp_uint64 extras;
3776 kmp_uint64 tc;
3777 kmp_uint64 num_t_min;
3778} __taskloop_params_t;
3779
3780void __kmp_taskloop_recur(ident_t *, int, kmp_task_t *, kmp_uint64 *,
3781 kmp_uint64 *, kmp_int64, kmp_uint64, kmp_uint64,
3782 kmp_uint64, kmp_uint64, kmp_uint64, kmp_uint64,
3783 void *);
3784
3785// Execute part of the the taskloop submitted as a task.
3786int __kmp_taskloop_task(int gtid, void *ptask) {
3787 __taskloop_params_t *p =
3788 (__taskloop_params_t *)((kmp_task_t *)ptask)->shareds;
3789 kmp_task_t *task = p->task;
3790 kmp_uint64 *lb = p->lb;
3791 kmp_uint64 *ub = p->ub;
3792 void *task_dup = p->task_dup;
3793 // p_task_dup_t ptask_dup = (p_task_dup_t)task_dup;
3794 kmp_int64 st = p->st;
3795 kmp_uint64 ub_glob = p->ub_glob;
3796 kmp_uint64 num_tasks = p->num_tasks;
3797 kmp_uint64 grainsize = p->grainsize;
3798 kmp_uint64 extras = p->extras;
3799 kmp_uint64 tc = p->tc;
3800 kmp_uint64 num_t_min = p->num_t_min;
3801#if KMP_DEBUG1
3802 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
3803 KMP_DEBUG_ASSERT(task != NULL)((task != __null) ? 0 : __kmp_debug_assert("task != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3803))
;
3804 KA_TRACE(20, ("__kmp_taskloop_task: T#%d, task %p: %lld tasks, grainsize"if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_task: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
3805 " %lld, extras %lld, i=%lld,%lld(%d), dup %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_task: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
3806 gtid, taskdata, num_tasks, grainsize, extras, *lb, *ub, st,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_task: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
3807 task_dup))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_task: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
;
3808#endif
3809 KMP_DEBUG_ASSERT(num_tasks * 2 + 1 > num_t_min)((num_tasks * 2 + 1 > num_t_min) ? 0 : __kmp_debug_assert(
"num_tasks * 2 + 1 > num_t_min", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3809))
;
3810 if (num_tasks > num_t_min)
3811 __kmp_taskloop_recur(NULL__null, gtid, task, lb, ub, st, ub_glob, num_tasks,
3812 grainsize, extras, tc, num_t_min, task_dup);
3813 else
3814 __kmp_taskloop_linear(NULL__null, gtid, task, lb, ub, st, ub_glob, num_tasks,
3815 grainsize, extras, tc, task_dup);
3816
3817 KA_TRACE(40, ("__kmp_taskloop_task(exit): T#%d\n", gtid))if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmp_taskloop_task(exit): T#%d\n"
, gtid); }
;
3818 return 0;
3819}
3820
3821// Schedule part of the the taskloop as a task,
3822// execute the rest of the the taskloop.
3823//
3824// loc Source location information
3825// gtid Global thread ID
3826// task Pattern task, exposes the loop iteration range
3827// lb Pointer to loop lower bound in task structure
3828// ub Pointer to loop upper bound in task structure
3829// st Loop stride
3830// ub_glob Global upper bound (used for lastprivate check)
3831// num_tasks Number of tasks to execute
3832// grainsize Number of loop iterations per task
3833// extras Number of chunks with grainsize+1 iterations
3834// tc Iterations count
3835// num_t_min Threashold to launch tasks recursively
3836// task_dup Tasks duplication routine
3837void __kmp_taskloop_recur(ident_t *loc, int gtid, kmp_task_t *task,
3838 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st,
3839 kmp_uint64 ub_glob, kmp_uint64 num_tasks,
3840 kmp_uint64 grainsize, kmp_uint64 extras,
3841 kmp_uint64 tc, kmp_uint64 num_t_min, void *task_dup) {
3842#if KMP_DEBUG1
3843 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
3844 KMP_DEBUG_ASSERT(task != NULL)((task != __null) ? 0 : __kmp_debug_assert("task != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3844))
;
3845 KMP_DEBUG_ASSERT(num_tasks > num_t_min)((num_tasks > num_t_min) ? 0 : __kmp_debug_assert("num_tasks > num_t_min"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3845))
;
3846 KA_TRACE(20, ("__kmp_taskloop_recur: T#%d, task %p: %lld tasks, grainsize"if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_recur: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
3847 " %lld, extras %lld, i=%lld,%lld(%d), dup %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_recur: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
3848 gtid, taskdata, num_tasks, grainsize, extras, *lb, *ub, st,if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_recur: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
3849 task_dup))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmp_taskloop_recur: T#%d, task %p: %lld tasks, grainsize"
" %lld, extras %lld, i=%lld,%lld(%d), dup %p\n", gtid, taskdata
, num_tasks, grainsize, extras, *lb, *ub, st, task_dup); }
;
3850#endif
3851 p_task_dup_t ptask_dup = (p_task_dup_t)task_dup;
3852 kmp_uint64 lower = *lb;
3853 kmp_uint64 upper = *ub;
3854 kmp_info_t *thread = __kmp_threads[gtid];
3855 // kmp_taskdata_t *current_task = thread->th.th_current_task;
3856 kmp_task_t *next_task;
3857 kmp_int32 lastpriv = 0;
3858 size_t lower_offset =
3859 (char *)lb - (char *)task; // remember offset of lb in the task structure
3860 size_t upper_offset =
3861 (char *)ub - (char *)task; // remember offset of ub in the task structure
3862
3863 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize + extras)((tc == num_tasks * grainsize + extras) ? 0 : __kmp_debug_assert
("tc == num_tasks * grainsize + extras", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3863))
;
3864 KMP_DEBUG_ASSERT(num_tasks > extras)((num_tasks > extras) ? 0 : __kmp_debug_assert("num_tasks > extras"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3864))
;
3865 KMP_DEBUG_ASSERT(num_tasks > 0)((num_tasks > 0) ? 0 : __kmp_debug_assert("num_tasks > 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3865))
;
3866
3867 // split the loop in two halves
3868 kmp_uint64 lb1, ub0, tc0, tc1, ext0, ext1;
3869 kmp_uint64 gr_size0 = grainsize;
3870 kmp_uint64 n_tsk0 = num_tasks >> 1; // num_tasks/2 to execute
3871 kmp_uint64 n_tsk1 = num_tasks - n_tsk0; // to schedule as a task
3872 if (n_tsk0 <= extras) {
3873 gr_size0++; // integrate extras into grainsize
3874 ext0 = 0; // no extra iters in 1st half
3875 ext1 = extras - n_tsk0; // remaining extras
3876 tc0 = gr_size0 * n_tsk0;
3877 tc1 = tc - tc0;
3878 } else { // n_tsk0 > extras
3879 ext1 = 0; // no extra iters in 2nd half
3880 ext0 = extras;
3881 tc1 = grainsize * n_tsk1;
3882 tc0 = tc - tc1;
3883 }
3884 ub0 = lower + st * (tc0 - 1);
3885 lb1 = ub0 + st;
3886
3887 // create pattern task for 2nd half of the loop
3888 next_task = __kmp_task_dup_alloc(thread, task); // duplicate the task
3889 // adjust lower bound (upper bound is not changed) for the 2nd half
3890 *(kmp_uint64 *)((char *)next_task + lower_offset) = lb1;
3891 if (ptask_dup != NULL__null) // construct fistprivates, etc.
3892 ptask_dup(next_task, task, 0);
3893 *ub = ub0; // adjust upper bound for the 1st half
3894
3895 // create auxiliary task for 2nd half of the loop
3896 kmp_task_t *new_task =
3897 __kmpc_omp_task_alloc(loc, gtid, 1, 3 * sizeof(void *),
3898 sizeof(__taskloop_params_t), &__kmp_taskloop_task);
3899 __taskloop_params_t *p = (__taskloop_params_t *)new_task->shareds;
3900 p->task = next_task;
3901 p->lb = (kmp_uint64 *)((char *)next_task + lower_offset);
3902 p->ub = (kmp_uint64 *)((char *)next_task + upper_offset);
3903 p->task_dup = task_dup;
3904 p->st = st;
3905 p->ub_glob = ub_glob;
3906 p->num_tasks = n_tsk1;
3907 p->grainsize = grainsize;
3908 p->extras = ext1;
3909 p->tc = tc1;
3910 p->num_t_min = num_t_min;
3911 __kmp_omp_task(gtid, new_task, true); // schedule new task
3912
3913 // execute the 1st half of current subrange
3914 if (n_tsk0 > num_t_min)
3915 __kmp_taskloop_recur(loc, gtid, task, lb, ub, st, ub_glob, n_tsk0, gr_size0,
3916 ext0, tc0, num_t_min, task_dup);
3917 else
3918 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, n_tsk0,
3919 gr_size0, ext0, tc0, task_dup);
3920
3921 KA_TRACE(40, ("__kmpc_taskloop_recur(exit): T#%d\n", gtid))if (kmp_a_debug >= 40) { __kmp_debug_printf ("__kmpc_taskloop_recur(exit): T#%d\n"
, gtid); }
;
3922}
3923
3924/*!
3925@ingroup TASKING
3926@param loc Source location information
3927@param gtid Global thread ID
3928@param task Task structure
3929@param if_val Value of the if clause
3930@param lb Pointer to loop lower bound in task structure
3931@param ub Pointer to loop upper bound in task structure
3932@param st Loop stride
3933@param nogroup Flag, 1 if nogroup clause specified, 0 otherwise
3934@param sched Schedule specified 0/1/2 for none/grainsize/num_tasks
3935@param grainsize Schedule value if specified
3936@param task_dup Tasks duplication routine
3937
3938Execute the taskloop construct.
3939*/
3940void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int if_val,
3941 kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup,
3942 int sched, kmp_uint64 grainsize, void *task_dup) {
3943 kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task)(((kmp_taskdata_t *)task) - 1);
3944 KMP_DEBUG_ASSERT(task != NULL)((task != __null) ? 0 : __kmp_debug_assert("task != __null", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 3944))
;
3945
3946#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
3947 ompt_team_info_t *team_info = __ompt_get_teaminfo(0, NULL__null);
3948 ompt_task_info_t *task_info = __ompt_get_task_info_object(0);
3949 if (ompt_enabled.ompt_callback_work) {
1
Assuming the condition is false
2
Taking false branch
3950 ompt_callbacks.ompt_callback(ompt_callback_work)ompt_callback_work_callback(
3951 ompt_work_taskloop, ompt_scope_begin, &(team_info->parallel_data),
3952 &(task_info->task_data), 0, OMPT_GET_RETURN_ADDRESS(0)__builtin_return_address(0));
3953 }
3954#endif
3955
3956 if (nogroup == 0) {
3
Assuming 'nogroup' is not equal to 0
4
Taking false branch
3957#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
3958 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
3959#endif
3960 __kmpc_taskgroup(loc, gtid);
3961 }
3962
3963 // =========================================================================
3964 // calculate loop parameters
3965 kmp_taskloop_bounds_t task_bounds(task, lb, ub);
3966 kmp_uint64 tc;
3967 // compiler provides global bounds here
3968 kmp_uint64 lower = task_bounds.get_lb();
3969 kmp_uint64 upper = task_bounds.get_ub();
3970 kmp_uint64 ub_glob = upper; // global upper used to calc lastprivate flag
3971 kmp_uint64 num_tasks = 0, extras = 0;
3972 kmp_uint64 num_tasks_min = __kmp_taskloop_min_tasks;
3973 kmp_info_t *thread = __kmp_threads[gtid];
3974 kmp_taskdata_t *current_task = thread->th.th_current_task;
3975
3976 KA_TRACE(20, ("__kmpc_taskloop: T#%d, task %p, lb %lld, ub %lld, st %lld, "if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, task %p, lb %lld, ub %lld, st %lld, "
"grain %llu(%d), dup %p\n", gtid, taskdata, lower, upper, st
, grainsize, sched, task_dup); }
3977 "grain %llu(%d), dup %p\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, task %p, lb %lld, ub %lld, st %lld, "
"grain %llu(%d), dup %p\n", gtid, taskdata, lower, upper, st
, grainsize, sched, task_dup); }
3978 gtid, taskdata, lower, upper, st, grainsize, sched, task_dup))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, task %p, lb %lld, ub %lld, st %lld, "
"grain %llu(%d), dup %p\n", gtid, taskdata, lower, upper, st
, grainsize, sched, task_dup); }
;
3979
3980 // compute trip count
3981 if (st == 1) { // most common case
5
Assuming 'st' is not equal to 1
6
Taking false branch
3982 tc = upper - lower + 1;
3983 } else if (st < 0) {
7
Assuming 'st' is >= 0
8
Taking false branch
3984 tc = (lower - upper) / (-st) + 1;
3985 } else { // st > 0
3986 tc = (upper - lower) / st + 1;
3987 }
3988 if (tc == 0) {
9
Assuming 'tc' is not equal to 0
10
Taking false branch
3989 KA_TRACE(20, ("__kmpc_taskloop(exit): T#%d zero-trip loop\n", gtid))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop(exit): T#%d zero-trip loop\n"
, gtid); }
;
3990 // free the pattern task and exit
3991 __kmp_task_start(gtid, task, current_task);
3992 // do not execute anything for zero-trip loop
3993 __kmp_task_finish(gtid, task, current_task);
3994 return;
3995 }
3996 if (num_tasks_min == 0)
11
Assuming 'num_tasks_min' is not equal to 0
12
Taking false branch
3997 // TODO: can we choose better default heuristic?
3998 num_tasks_min =
3999 KMP_MIN(thread->th.th_team_nproc * 10, INITIAL_TASK_DEQUE_SIZE)((thread->th.th_team_nproc * 10) < ((1 << 8)) ? (
thread->th.th_team_nproc * 10) : ((1 << 8)))
;
4000
4001 // compute num_tasks/grainsize based on the input provided
4002 switch (sched) {
13
Control jumps to 'case 1:' at line 4017
4003 case 0: // no schedule clause specified, we can choose the default
4004 // let's try to schedule (team_size*10) tasks
4005 grainsize = thread->th.th_team_nproc * 10;
4006 case 2: // num_tasks provided
4007 if (grainsize > tc) {
4008 num_tasks = tc; // too big num_tasks requested, adjust values
4009 grainsize = 1;
4010 extras = 0;
4011 } else {
4012 num_tasks = grainsize;
4013 grainsize = tc / num_tasks;
4014 extras = tc % num_tasks;
4015 }
4016 break;
4017 case 1: // grainsize provided
4018 if (grainsize > tc) {
14
Assuming 'grainsize' is <= 'tc'
15
Taking false branch
4019 num_tasks = 1; // too big grainsize requested, adjust values
4020 grainsize = tc;
4021 extras = 0;
4022 } else {
4023 num_tasks = tc / grainsize;
4024 // adjust grainsize for balanced distribution of iterations
4025 grainsize = tc / num_tasks;
4026 extras = tc % num_tasks;
4027 }
4028 break;
16
Execution continues on line 4032
4029 default:
4030 KMP_ASSERT2(0, "unknown scheduling of taskloop")((0) ? 0 : __kmp_debug_assert(("unknown scheduling of taskloop"
), "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 4030))
;
4031 }
4032 KMP_DEBUG_ASSERT(tc == num_tasks * grainsize + extras)((tc == num_tasks * grainsize + extras) ? 0 : __kmp_debug_assert
("tc == num_tasks * grainsize + extras", "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 4032))
;
4033 KMP_DEBUG_ASSERT(num_tasks > extras)((num_tasks > extras) ? 0 : __kmp_debug_assert("num_tasks > extras"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 4033))
;
4034 KMP_DEBUG_ASSERT(num_tasks > 0)((num_tasks > 0) ? 0 : __kmp_debug_assert("num_tasks > 0"
, "/build/llvm-toolchain-snapshot-7~svn337957/projects/openmp/runtime/src/kmp_tasking.cpp"
, 4034))
;
4035 // =========================================================================
4036
4037 // check if clause value first
4038 // Also require GOMP_taskloop to reduce to linear (taskdata->td_flags.native)
4039 if (if_val == 0) { // if(0) specified, mark task as serial
17
Assuming 'if_val' is not equal to 0
18
Taking false branch
4040 taskdata->td_flags.task_serial = 1;
4041 taskdata->td_flags.tiedness = TASK_TIED1; // AC: serial task cannot be untied
4042#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
4043 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
4044#endif
4045 // always start serial tasks linearly
4046 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
4047 grainsize, extras, tc, task_dup);
4048 // !taskdata->td_flags.native => currently force linear spawning of tasks
4049 // for GOMP_taskloop
4050 } else if (num_tasks > num_tasks_min && !taskdata->td_flags.native) {
19
Assuming 'num_tasks' is <= 'num_tasks_min'
4051 KA_TRACE(20, ("__kmpc_taskloop: T#%d, go recursive: tc %llu, #tasks %llu"if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, go recursive: tc %llu, #tasks %llu"
"(%lld), grain %llu, extras %llu\n", gtid, tc, num_tasks, num_tasks_min
, grainsize, extras); }
4052 "(%lld), grain %llu, extras %llu\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, go recursive: tc %llu, #tasks %llu"
"(%lld), grain %llu, extras %llu\n", gtid, tc, num_tasks, num_tasks_min
, grainsize, extras); }
4053 gtid, tc, num_tasks, num_tasks_min, grainsize, extras))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, go recursive: tc %llu, #tasks %llu"
"(%lld), grain %llu, extras %llu\n", gtid, tc, num_tasks, num_tasks_min
, grainsize, extras); }
;
4054#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
4055 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
4056#endif
4057 __kmp_taskloop_recur(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
4058 grainsize, extras, tc, num_tasks_min, task_dup);
4059 } else {
4060 KA_TRACE(20, ("__kmpc_taskloop: T#%d, go linear: tc %llu, #tasks %llu"if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, go linear: tc %llu, #tasks %llu"
"(%lld), grain %llu, extras %llu\n", gtid, tc, num_tasks, num_tasks_min
, grainsize, extras); }
4061 "(%lld), grain %llu, extras %llu\n",if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, go linear: tc %llu, #tasks %llu"
"(%lld), grain %llu, extras %llu\n", gtid, tc, num_tasks, num_tasks_min
, grainsize, extras); }
4062 gtid, tc, num_tasks, num_tasks_min, grainsize, extras))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop: T#%d, go linear: tc %llu, #tasks %llu"
"(%lld), grain %llu, extras %llu\n", gtid, tc, num_tasks, num_tasks_min
, grainsize, extras); }
;
4063#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
4064 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
4065#endif
4066 __kmp_taskloop_linear(loc, gtid, task, lb, ub, st, ub_glob, num_tasks,
20
Calling '__kmp_taskloop_linear'
4067 grainsize, extras, tc, task_dup);
4068 }
4069
4070 if (nogroup == 0) {
4071#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
4072 OMPT_STORE_RETURN_ADDRESS(gtid)if (ompt_enabled.enabled && gtid >= 0 && __kmp_threads
[gtid] && !__kmp_threads[gtid]->th.ompt_thread_info
.return_address) __kmp_threads[gtid]->th.ompt_thread_info.
return_address = __builtin_return_address(0)
;
4073#endif
4074 __kmpc_end_taskgroup(loc, gtid);
4075 }
4076#if OMPT_SUPPORT1 && OMPT_OPTIONAL1
4077 if (ompt_enabled.ompt_callback_work) {
4078 ompt_callbacks.ompt_callback(ompt_callback_work)ompt_callback_work_callback(
4079 ompt_work_taskloop, ompt_scope_end, &(team_info->parallel_data),
4080 &(task_info->task_data), 0, OMPT_GET_RETURN_ADDRESS(0)__builtin_return_address(0));
4081 }
4082#endif
4083 KA_TRACE(20, ("__kmpc_taskloop(exit): T#%d\n", gtid))if (kmp_a_debug >= 20) { __kmp_debug_printf ("__kmpc_taskloop(exit): T#%d\n"
, gtid); }
;
4084}
4085
4086#endif