Bug Summary

File:projects/openmp/runtime/src/kmp_threadprivate.cpp
Warning:line 637, column 9
1st function call argument is an uninitialized 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_threadprivate.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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-8/lib/clang/8.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-8~svn345461/build-llvm/projects/openmp/runtime/src -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/i18n -I /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/include/50 -I /build/llvm-toolchain-snapshot-8~svn345461/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/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/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-comment -Wno-switch -Wno-missing-field-initializers -Wno-missing-braces -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/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-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp -faddrsig
1/*
2 * kmp_threadprivate.cpp -- OpenMP threadprivate support library
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
18#define USE_CHECKS_COMMON
19
20#define KMP_INLINE_SUBR1 1
21
22void kmp_threadprivate_insert_private_data(int gtid, void *pc_addr,
23 void *data_addr, size_t pc_size);
24struct private_common *kmp_threadprivate_insert(int gtid, void *pc_addr,
25 void *data_addr,
26 size_t pc_size);
27
28struct shared_table __kmp_threadprivate_d_table;
29
30static
31#ifdef KMP_INLINE_SUBR1
32 __forceinline__inline
33#endif
34 struct private_common *
35 __kmp_threadprivate_find_task_common(struct common_table *tbl, int gtid,
36 void *pc_addr)
37
38{
39 struct private_common *tn;
40
41#ifdef KMP_TASK_COMMON_DEBUG
42 KC_TRACE(10, ("__kmp_threadprivate_find_task_common: thread#%d, called with "if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_find_task_common: thread#%d, called with "
"address %p\n", gtid, pc_addr); }
43 "address %p\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_find_task_common: thread#%d, called with "
"address %p\n", gtid, pc_addr); }
44 gtid, pc_addr))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_find_task_common: thread#%d, called with "
"address %p\n", gtid, pc_addr); }
;
45 dump_list();
46#endif
47
48 for (tn = tbl->data[KMP_HASH(pc_addr)((((kmp_uintptr_t)pc_addr) >> 3) & ((1 << 9) -
1))
]; tn; tn = tn->next) {
49 if (tn->gbl_addr == pc_addr) {
50#ifdef KMP_TASK_COMMON_DEBUG
51 KC_TRACE(10, ("__kmp_threadprivate_find_task_common: thread#%d, found "if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_find_task_common: thread#%d, found "
"node %p on list\n", gtid, pc_addr); }
52 "node %p on list\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_find_task_common: thread#%d, found "
"node %p on list\n", gtid, pc_addr); }
53 gtid, pc_addr))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_find_task_common: thread#%d, found "
"node %p on list\n", gtid, pc_addr); }
;
54#endif
55 return tn;
56 }
57 }
58 return 0;
59}
60
61static
62#ifdef KMP_INLINE_SUBR1
63 __forceinline__inline
64#endif
65 struct shared_common *
66 __kmp_find_shared_task_common(struct shared_table *tbl, int gtid,
67 void *pc_addr) {
68 struct shared_common *tn;
69
70 for (tn = tbl->data[KMP_HASH(pc_addr)((((kmp_uintptr_t)pc_addr) >> 3) & ((1 << 9) -
1))
]; tn; tn = tn->next) {
71 if (tn->gbl_addr == pc_addr) {
72#ifdef KMP_TASK_COMMON_DEBUG
73 KC_TRACE(if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_find_shared_task_common: thread#%d, found node %p on list\n"
, gtid, pc_addr); }
74 10,if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_find_shared_task_common: thread#%d, found node %p on list\n"
, gtid, pc_addr); }
75 ("__kmp_find_shared_task_common: thread#%d, found node %p on list\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_find_shared_task_common: thread#%d, found node %p on list\n"
, gtid, pc_addr); }
76 gtid, pc_addr))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_find_shared_task_common: thread#%d, found node %p on list\n"
, gtid, pc_addr); }
;
77#endif
78 return tn;
79 }
80 }
81 return 0;
82}
83
84// Create a template for the data initialized storage. Either the template is
85// NULL indicating zero fill, or the template is a copy of the original data.
86static struct private_data *__kmp_init_common_data(void *pc_addr,
87 size_t pc_size) {
88 struct private_data *d;
89 size_t i;
90 char *p;
91
92 d = (struct private_data *)__kmp_allocate(sizeof(struct private_data))___kmp_allocate((sizeof(struct private_data)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 92)
;
93 /*
94 d->data = 0; // AC: commented out because __kmp_allocate zeroes the
95 memory
96 d->next = 0;
97 */
98 d->size = pc_size;
99 d->more = 1;
100
101 p = (char *)pc_addr;
102
103 for (i = pc_size; i > 0; --i) {
104 if (*p++ != '\0') {
105 d->data = __kmp_allocate(pc_size)___kmp_allocate((pc_size), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 105)
;
106 KMP_MEMCPYmemcpy(d->data, pc_addr, pc_size);
107 break;
108 }
109 }
110
111 return d;
112}
113
114// Initialize the data area from the template.
115static void __kmp_copy_common_data(void *pc_addr, struct private_data *d) {
116 char *addr = (char *)pc_addr;
117 int i, offset;
118
119 for (offset = 0; d != 0; d = d->next) {
120 for (i = d->more; i > 0; --i) {
121 if (d->data == 0)
122 memset(&addr[offset], '\0', d->size);
123 else
124 KMP_MEMCPYmemcpy(&addr[offset], d->data, d->size);
125 offset += d->size;
126 }
127 }
128}
129
130/* we are called from __kmp_serial_initialize() with __kmp_initz_lock held. */
131void __kmp_common_initialize(void) {
132 if (!TCR_4(__kmp_init_common)(__kmp_init_common)) {
133 int q;
134#ifdef KMP_DEBUG1
135 int gtid;
136#endif
137
138 __kmp_threadpriv_cache_list = NULL__null;
139
140#ifdef KMP_DEBUG1
141 /* verify the uber masters were initialized */
142 for (gtid = 0; gtid < __kmp_threads_capacity; gtid++)
143 if (__kmp_root[gtid]) {
144 KMP_DEBUG_ASSERT(__kmp_root[gtid]->r.r_uber_thread)if (!(__kmp_root[gtid]->r.r_uber_thread)) { __kmp_debug_assert
("__kmp_root[gtid]->r.r_uber_thread", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 144); }
;
145 for (q = 0; q < KMP_HASH_TABLE_SIZE(1 << 9); ++q)
146 KMP_DEBUG_ASSERT(if (!(!__kmp_root[gtid]->r.r_uber_thread->th.th_pri_common
->data[q])) { __kmp_debug_assert("!__kmp_root[gtid]->r.r_uber_thread->th.th_pri_common->data[q]"
, "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 147); }
147 !__kmp_root[gtid]->r.r_uber_thread->th.th_pri_common->data[q])if (!(!__kmp_root[gtid]->r.r_uber_thread->th.th_pri_common
->data[q])) { __kmp_debug_assert("!__kmp_root[gtid]->r.r_uber_thread->th.th_pri_common->data[q]"
, "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 147); }
;
148 /* __kmp_root[ gitd ]-> r.r_uber_thread ->
149 * th.th_pri_common -> data[ q ] = 0;*/
150 }
151#endif /* KMP_DEBUG */
152
153 for (q = 0; q < KMP_HASH_TABLE_SIZE(1 << 9); ++q)
154 __kmp_threadprivate_d_table.data[q] = 0;
155
156 TCW_4(__kmp_init_common, TRUE)(__kmp_init_common) = ((!0));
157 }
158}
159
160/* Call all destructors for threadprivate data belonging to all threads.
161 Currently unused! */
162void __kmp_common_destroy(void) {
163 if (TCR_4(__kmp_init_common)(__kmp_init_common)) {
164 int q;
165
166 TCW_4(__kmp_init_common, FALSE)(__kmp_init_common) = (0);
167
168 for (q = 0; q < KMP_HASH_TABLE_SIZE(1 << 9); ++q) {
169 int gtid;
170 struct private_common *tn;
171 struct shared_common *d_tn;
172
173 /* C++ destructors need to be called once per thread before exiting.
174 Don't call destructors for master thread though unless we used copy
175 constructor */
176
177 for (d_tn = __kmp_threadprivate_d_table.data[q]; d_tn;
178 d_tn = d_tn->next) {
179 if (d_tn->is_vec) {
180 if (d_tn->dt.dtorv != 0) {
181 for (gtid = 0; gtid < __kmp_all_nth; ++gtid) {
182 if (__kmp_threads[gtid]) {
183 if ((__kmp_foreign_tp) ? (!KMP_INITIAL_GTID(gtid)((gtid) == 0))
184 : (!KMP_UBER_GTID(gtid))) {
185 tn = __kmp_threadprivate_find_task_common(
186 __kmp_threads[gtid]->th.th_pri_common, gtid,
187 d_tn->gbl_addr);
188 if (tn) {
189 (*d_tn->dt.dtorv)(tn->par_addr, d_tn->vec_len);
190 }
191 }
192 }
193 }
194 if (d_tn->obj_init != 0) {
195 (*d_tn->dt.dtorv)(d_tn->obj_init, d_tn->vec_len);
196 }
197 }
198 } else {
199 if (d_tn->dt.dtor != 0) {
200 for (gtid = 0; gtid < __kmp_all_nth; ++gtid) {
201 if (__kmp_threads[gtid]) {
202 if ((__kmp_foreign_tp) ? (!KMP_INITIAL_GTID(gtid)((gtid) == 0))
203 : (!KMP_UBER_GTID(gtid))) {
204 tn = __kmp_threadprivate_find_task_common(
205 __kmp_threads[gtid]->th.th_pri_common, gtid,
206 d_tn->gbl_addr);
207 if (tn) {
208 (*d_tn->dt.dtor)(tn->par_addr);
209 }
210 }
211 }
212 }
213 if (d_tn->obj_init != 0) {
214 (*d_tn->dt.dtor)(d_tn->obj_init);
215 }
216 }
217 }
218 }
219 __kmp_threadprivate_d_table.data[q] = 0;
220 }
221 }
222}
223
224/* Call all destructors for threadprivate data belonging to this thread */
225void __kmp_common_destroy_gtid(int gtid) {
226 struct private_common *tn;
227 struct shared_common *d_tn;
228
229 if (!TCR_4(__kmp_init_gtid)(__kmp_init_gtid)) {
230 // This is possible when one of multiple roots initiates early library
231 // termination in a sequential region while other teams are active, and its
232 // child threads are about to end.
233 return;
234 }
235
236 KC_TRACE(10, ("__kmp_common_destroy_gtid: T#%d called\n", gtid))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_common_destroy_gtid: T#%d called\n"
, gtid); }
;
237 if ((__kmp_foreign_tp) ? (!KMP_INITIAL_GTID(gtid)((gtid) == 0)) : (!KMP_UBER_GTID(gtid))) {
238
239 if (TCR_4(__kmp_init_common)(__kmp_init_common)) {
240
241 /* Cannot do this here since not all threads have destroyed their data */
242 /* TCW_4(__kmp_init_common, FALSE); */
243
244 for (tn = __kmp_threads[gtid]->th.th_pri_head; tn; tn = tn->link) {
245
246 d_tn = __kmp_find_shared_task_common(&__kmp_threadprivate_d_table, gtid,
247 tn->gbl_addr);
248
249 KMP_DEBUG_ASSERT(d_tn)if (!(d_tn)) { __kmp_debug_assert("d_tn", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 249); }
;
250
251 if (d_tn->is_vec) {
252 if (d_tn->dt.dtorv != 0) {
253 (void)(*d_tn->dt.dtorv)(tn->par_addr, d_tn->vec_len);
254 }
255 if (d_tn->obj_init != 0) {
256 (void)(*d_tn->dt.dtorv)(d_tn->obj_init, d_tn->vec_len);
257 }
258 } else {
259 if (d_tn->dt.dtor != 0) {
260 (void)(*d_tn->dt.dtor)(tn->par_addr);
261 }
262 if (d_tn->obj_init != 0) {
263 (void)(*d_tn->dt.dtor)(d_tn->obj_init);
264 }
265 }
266 }
267 KC_TRACE(30, ("__kmp_common_destroy_gtid: T#%d threadprivate destructors "if (kmp_c_debug >= 30) { __kmp_debug_printf ("__kmp_common_destroy_gtid: T#%d threadprivate destructors "
"complete\n", gtid); }
268 "complete\n",if (kmp_c_debug >= 30) { __kmp_debug_printf ("__kmp_common_destroy_gtid: T#%d threadprivate destructors "
"complete\n", gtid); }
269 gtid))if (kmp_c_debug >= 30) { __kmp_debug_printf ("__kmp_common_destroy_gtid: T#%d threadprivate destructors "
"complete\n", gtid); }
;
270 }
271 }
272}
273
274#ifdef KMP_TASK_COMMON_DEBUG
275static void dump_list(void) {
276 int p, q;
277
278 for (p = 0; p < __kmp_all_nth; ++p) {
279 if (!__kmp_threads[p])
280 continue;
281 for (q = 0; q < KMP_HASH_TABLE_SIZE(1 << 9); ++q) {
282 if (__kmp_threads[p]->th.th_pri_common->data[q]) {
283 struct private_common *tn;
284
285 KC_TRACE(10, ("\tdump_list: gtid:%d addresses\n", p))if (kmp_c_debug >= 10) { __kmp_debug_printf ("\tdump_list: gtid:%d addresses\n"
, p); }
;
286
287 for (tn = __kmp_threads[p]->th.th_pri_common->data[q]; tn;
288 tn = tn->next) {
289 KC_TRACE(10,if (kmp_c_debug >= 10) { __kmp_debug_printf ("\tdump_list: THREADPRIVATE: Serial %p -> Parallel %p\n"
, tn->gbl_addr, tn->par_addr); }
290 ("\tdump_list: THREADPRIVATE: Serial %p -> Parallel %p\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("\tdump_list: THREADPRIVATE: Serial %p -> Parallel %p\n"
, tn->gbl_addr, tn->par_addr); }
291 tn->gbl_addr, tn->par_addr))if (kmp_c_debug >= 10) { __kmp_debug_printf ("\tdump_list: THREADPRIVATE: Serial %p -> Parallel %p\n"
, tn->gbl_addr, tn->par_addr); }
;
292 }
293 }
294 }
295 }
296}
297#endif /* KMP_TASK_COMMON_DEBUG */
298
299// NOTE: this routine is to be called only from the serial part of the program.
300void kmp_threadprivate_insert_private_data(int gtid, void *pc_addr,
301 void *data_addr, size_t pc_size) {
302 struct shared_common **lnk_tn, *d_tn;
303 KMP_DEBUG_ASSERT(__kmp_threads[gtid] &&if (!(__kmp_threads[gtid] && __kmp_threads[gtid]->
th.th_root->r.r_active == 0)) { __kmp_debug_assert("__kmp_threads[gtid] && __kmp_threads[gtid]->th.th_root->r.r_active == 0"
, "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 304); }
304 __kmp_threads[gtid]->th.th_root->r.r_active == 0)if (!(__kmp_threads[gtid] && __kmp_threads[gtid]->
th.th_root->r.r_active == 0)) { __kmp_debug_assert("__kmp_threads[gtid] && __kmp_threads[gtid]->th.th_root->r.r_active == 0"
, "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 304); }
;
305
306 d_tn = __kmp_find_shared_task_common(&__kmp_threadprivate_d_table, gtid,
307 pc_addr);
308
309 if (d_tn == 0) {
310 d_tn = (struct shared_common *)__kmp_allocate(sizeof(struct shared_common))___kmp_allocate((sizeof(struct shared_common)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 310)
;
311
312 d_tn->gbl_addr = pc_addr;
313 d_tn->pod_init = __kmp_init_common_data(data_addr, pc_size);
314 /*
315 d_tn->obj_init = 0; // AC: commented out because __kmp_allocate
316 zeroes the memory
317 d_tn->ct.ctor = 0;
318 d_tn->cct.cctor = 0;;
319 d_tn->dt.dtor = 0;
320 d_tn->is_vec = FALSE;
321 d_tn->vec_len = 0L;
322 */
323 d_tn->cmn_size = pc_size;
324
325 __kmp_acquire_lock(&__kmp_global_lock, gtid);
326
327 lnk_tn = &(__kmp_threadprivate_d_table.data[KMP_HASH(pc_addr)((((kmp_uintptr_t)pc_addr) >> 3) & ((1 << 9) -
1))
]);
328
329 d_tn->next = *lnk_tn;
330 *lnk_tn = d_tn;
331
332 __kmp_release_lock(&__kmp_global_lock, gtid);
333 }
334}
335
336struct private_common *kmp_threadprivate_insert(int gtid, void *pc_addr,
337 void *data_addr,
338 size_t pc_size) {
339 struct private_common *tn, **tt;
340 struct shared_common *d_tn;
341
342 /* +++++++++ START OF CRITICAL SECTION +++++++++ */
343 __kmp_acquire_lock(&__kmp_global_lock, gtid);
344
345 tn = (struct private_common *)__kmp_allocate(sizeof(struct private_common))___kmp_allocate((sizeof(struct private_common)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 345)
;
346
347 tn->gbl_addr = pc_addr;
348
349 d_tn = __kmp_find_shared_task_common(
350 &__kmp_threadprivate_d_table, gtid,
351 pc_addr); /* Only the MASTER data table exists. */
352
353 if (d_tn != 0) {
354 /* This threadprivate variable has already been seen. */
355
356 if (d_tn->pod_init == 0 && d_tn->obj_init == 0) {
357 d_tn->cmn_size = pc_size;
358
359 if (d_tn->is_vec) {
360 if (d_tn->ct.ctorv != 0) {
361 /* Construct from scratch so no prototype exists */
362 d_tn->obj_init = 0;
363 } else if (d_tn->cct.cctorv != 0) {
364 /* Now data initialize the prototype since it was previously
365 * registered */
366 d_tn->obj_init = (void *)__kmp_allocate(d_tn->cmn_size)___kmp_allocate((d_tn->cmn_size), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 366)
;
367 (void)(*d_tn->cct.cctorv)(d_tn->obj_init, pc_addr, d_tn->vec_len);
368 } else {
369 d_tn->pod_init = __kmp_init_common_data(data_addr, d_tn->cmn_size);
370 }
371 } else {
372 if (d_tn->ct.ctor != 0) {
373 /* Construct from scratch so no prototype exists */
374 d_tn->obj_init = 0;
375 } else if (d_tn->cct.cctor != 0) {
376 /* Now data initialize the prototype since it was previously
377 registered */
378 d_tn->obj_init = (void *)__kmp_allocate(d_tn->cmn_size)___kmp_allocate((d_tn->cmn_size), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 378)
;
379 (void)(*d_tn->cct.cctor)(d_tn->obj_init, pc_addr);
380 } else {
381 d_tn->pod_init = __kmp_init_common_data(data_addr, d_tn->cmn_size);
382 }
383 }
384 }
385 } else {
386 struct shared_common **lnk_tn;
387
388 d_tn = (struct shared_common *)__kmp_allocate(sizeof(struct shared_common))___kmp_allocate((sizeof(struct shared_common)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 388)
;
389 d_tn->gbl_addr = pc_addr;
390 d_tn->cmn_size = pc_size;
391 d_tn->pod_init = __kmp_init_common_data(data_addr, pc_size);
392 /*
393 d_tn->obj_init = 0; // AC: commented out because __kmp_allocate
394 zeroes the memory
395 d_tn->ct.ctor = 0;
396 d_tn->cct.cctor = 0;
397 d_tn->dt.dtor = 0;
398 d_tn->is_vec = FALSE;
399 d_tn->vec_len = 0L;
400 */
401 lnk_tn = &(__kmp_threadprivate_d_table.data[KMP_HASH(pc_addr)((((kmp_uintptr_t)pc_addr) >> 3) & ((1 << 9) -
1))
]);
402
403 d_tn->next = *lnk_tn;
404 *lnk_tn = d_tn;
405 }
406
407 tn->cmn_size = d_tn->cmn_size;
408
409 if ((__kmp_foreign_tp) ? (KMP_INITIAL_GTID(gtid)((gtid) == 0)) : (KMP_UBER_GTID(gtid))) {
410 tn->par_addr = (void *)pc_addr;
411 } else {
412 tn->par_addr = (void *)__kmp_allocate(tn->cmn_size)___kmp_allocate((tn->cmn_size), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 412)
;
413 }
414
415 __kmp_release_lock(&__kmp_global_lock, gtid);
416/* +++++++++ END OF CRITICAL SECTION +++++++++ */
417
418#ifdef USE_CHECKS_COMMON
419 if (pc_size > d_tn->cmn_size) {
420 KC_TRACE(if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: THREADPRIVATE: %p (%"
"lu" " ,%" "lu" ")\n", pc_addr, pc_size, d_tn->cmn_size);
}
421 10, ("__kmp_threadprivate_insert: THREADPRIVATE: %p (%" KMP_UINTPTR_SPECif (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: THREADPRIVATE: %p (%"
"lu" " ,%" "lu" ")\n", pc_addr, pc_size, d_tn->cmn_size);
}
422 " ,%" KMP_UINTPTR_SPEC ")\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: THREADPRIVATE: %p (%"
"lu" " ,%" "lu" ")\n", pc_addr, pc_size, d_tn->cmn_size);
}
423 pc_addr, pc_size, d_tn->cmn_size))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: THREADPRIVATE: %p (%"
"lu" " ,%" "lu" ")\n", pc_addr, pc_size, d_tn->cmn_size);
}
;
424 KMP_FATAL(TPCommonBlocksInconsist)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_TPCommonBlocksInconsist
), __kmp_msg_null)
;
425 }
426#endif /* USE_CHECKS_COMMON */
427
428 tt = &(__kmp_threads[gtid]->th.th_pri_common->data[KMP_HASH(pc_addr)((((kmp_uintptr_t)pc_addr) >> 3) & ((1 << 9) -
1))
]);
429
430#ifdef KMP_TASK_COMMON_DEBUG
431 if (*tt != 0) {
432 KC_TRACE(if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: WARNING! thread#%d: collision on %p\n"
, gtid, pc_addr); }
433 10,if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: WARNING! thread#%d: collision on %p\n"
, gtid, pc_addr); }
434 ("__kmp_threadprivate_insert: WARNING! thread#%d: collision on %p\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: WARNING! thread#%d: collision on %p\n"
, gtid, pc_addr); }
435 gtid, pc_addr))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: WARNING! thread#%d: collision on %p\n"
, gtid, pc_addr); }
;
436 }
437#endif
438 tn->next = *tt;
439 *tt = tn;
440
441#ifdef KMP_TASK_COMMON_DEBUG
442 KC_TRACE(10,if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: thread#%d, inserted node %p on list\n"
, gtid, pc_addr); }
443 ("__kmp_threadprivate_insert: thread#%d, inserted node %p on list\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: thread#%d, inserted node %p on list\n"
, gtid, pc_addr); }
444 gtid, pc_addr))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_insert: thread#%d, inserted node %p on list\n"
, gtid, pc_addr); }
;
445 dump_list();
446#endif
447
448 /* Link the node into a simple list */
449
450 tn->link = __kmp_threads[gtid]->th.th_pri_head;
451 __kmp_threads[gtid]->th.th_pri_head = tn;
452
453 if ((__kmp_foreign_tp) ? (KMP_INITIAL_GTID(gtid)((gtid) == 0)) : (KMP_UBER_GTID(gtid)))
454 return tn;
455
456 /* if C++ object with copy constructor, use it;
457 * else if C++ object with constructor, use it for the non-master copies only;
458 * else use pod_init and memcpy
459 *
460 * C++ constructors need to be called once for each non-master thread on
461 * allocate
462 * C++ copy constructors need to be called once for each thread on allocate */
463
464 /* C++ object with constructors/destructors; don't call constructors for
465 master thread though */
466 if (d_tn->is_vec) {
467 if (d_tn->ct.ctorv != 0) {
468 (void)(*d_tn->ct.ctorv)(tn->par_addr, d_tn->vec_len);
469 } else if (d_tn->cct.cctorv != 0) {
470 (void)(*d_tn->cct.cctorv)(tn->par_addr, d_tn->obj_init, d_tn->vec_len);
471 } else if (tn->par_addr != tn->gbl_addr) {
472 __kmp_copy_common_data(tn->par_addr, d_tn->pod_init);
473 }
474 } else {
475 if (d_tn->ct.ctor != 0) {
476 (void)(*d_tn->ct.ctor)(tn->par_addr);
477 } else if (d_tn->cct.cctor != 0) {
478 (void)(*d_tn->cct.cctor)(tn->par_addr, d_tn->obj_init);
479 } else if (tn->par_addr != tn->gbl_addr) {
480 __kmp_copy_common_data(tn->par_addr, d_tn->pod_init);
481 }
482 }
483 /* !BUILD_OPENMP_C
484 if (tn->par_addr != tn->gbl_addr)
485 __kmp_copy_common_data( tn->par_addr, d_tn->pod_init ); */
486
487 return tn;
488}
489
490/* ------------------------------------------------------------------------ */
491/* We are currently parallel, and we know the thread id. */
492/* ------------------------------------------------------------------------ */
493
494/*!
495 @ingroup THREADPRIVATE
496
497 @param loc source location information
498 @param data pointer to data being privatized
499 @param ctor pointer to constructor function for data
500 @param cctor pointer to copy constructor function for data
501 @param dtor pointer to destructor function for data
502
503 Register constructors and destructors for thread private data.
504 This function is called when executing in parallel, when we know the thread id.
505*/
506void __kmpc_threadprivate_register(ident_t *loc, void *data, kmpc_ctor ctor,
507 kmpc_cctor cctor, kmpc_dtor dtor) {
508 struct shared_common *d_tn, **lnk_tn;
509
510 KC_TRACE(10, ("__kmpc_threadprivate_register: called\n"))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_register: called\n"
); }
;
511
512#ifdef USE_CHECKS_COMMON
513 /* copy constructor must be zero for current code gen (Nov 2002 - jph) */
514 KMP_ASSERT(cctor == 0)if (!(cctor == 0)) { __kmp_debug_assert("cctor == 0", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 514); }
;
515#endif /* USE_CHECKS_COMMON */
516
517 /* Only the global data table exists. */
518 d_tn = __kmp_find_shared_task_common(&__kmp_threadprivate_d_table, -1, data);
519
520 if (d_tn == 0) {
521 d_tn = (struct shared_common *)__kmp_allocate(sizeof(struct shared_common))___kmp_allocate((sizeof(struct shared_common)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 521)
;
522 d_tn->gbl_addr = data;
523
524 d_tn->ct.ctor = ctor;
525 d_tn->cct.cctor = cctor;
526 d_tn->dt.dtor = dtor;
527 /*
528 d_tn->is_vec = FALSE; // AC: commented out because __kmp_allocate
529 zeroes the memory
530 d_tn->vec_len = 0L;
531 d_tn->obj_init = 0;
532 d_tn->pod_init = 0;
533 */
534 lnk_tn = &(__kmp_threadprivate_d_table.data[KMP_HASH(data)((((kmp_uintptr_t)data) >> 3) & ((1 << 9) - 1
))
]);
535
536 d_tn->next = *lnk_tn;
537 *lnk_tn = d_tn;
538 }
539}
540
541void *__kmpc_threadprivate(ident_t *loc, kmp_int32 global_tid, void *data,
542 size_t size) {
543 void *ret;
544 struct private_common *tn;
545
546 KC_TRACE(10, ("__kmpc_threadprivate: T#%d called\n", global_tid))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d called\n"
, global_tid); }
;
547
548#ifdef USE_CHECKS_COMMON
549 if (!__kmp_init_serial)
550 KMP_FATAL(RTLNotInitialized)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_RTLNotInitialized),
__kmp_msg_null)
;
551#endif /* USE_CHECKS_COMMON */
552
553 if (!__kmp_threads[global_tid]->th.th_root->r.r_active && !__kmp_foreign_tp) {
554 /* The parallel address will NEVER overlap with the data_address */
555 /* dkp: 3rd arg to kmp_threadprivate_insert_private_data() is the
556 * data_address; use data_address = data */
557
558 KC_TRACE(20, ("__kmpc_threadprivate: T#%d inserting private data\n",if (kmp_c_debug >= 20) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d inserting private data\n"
, global_tid); }
559 global_tid))if (kmp_c_debug >= 20) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d inserting private data\n"
, global_tid); }
;
560 kmp_threadprivate_insert_private_data(global_tid, data, data, size);
561
562 ret = data;
563 } else {
564 KC_TRACE(if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d try to find private data at address %p\n"
, global_tid, data); }
565 50,if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d try to find private data at address %p\n"
, global_tid, data); }
566 ("__kmpc_threadprivate: T#%d try to find private data at address %p\n",if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d try to find private data at address %p\n"
, global_tid, data); }
567 global_tid, data))if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d try to find private data at address %p\n"
, global_tid, data); }
;
568 tn = __kmp_threadprivate_find_task_common(
569 __kmp_threads[global_tid]->th.th_pri_common, global_tid, data);
570
571 if (tn) {
572 KC_TRACE(20, ("__kmpc_threadprivate: T#%d found data\n", global_tid))if (kmp_c_debug >= 20) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d found data\n"
, global_tid); }
;
573#ifdef USE_CHECKS_COMMON
574 if ((size_t)size > tn->cmn_size) {
575 KC_TRACE(10, ("THREADPRIVATE: %p (%" KMP_UINTPTR_SPECif (kmp_c_debug >= 10) { __kmp_debug_printf ("THREADPRIVATE: %p (%"
"lu" " ,%" "lu" ")\n", data, size, tn->cmn_size); }
576 " ,%" KMP_UINTPTR_SPEC ")\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("THREADPRIVATE: %p (%"
"lu" " ,%" "lu" ")\n", data, size, tn->cmn_size); }
577 data, size, tn->cmn_size))if (kmp_c_debug >= 10) { __kmp_debug_printf ("THREADPRIVATE: %p (%"
"lu" " ,%" "lu" ")\n", data, size, tn->cmn_size); }
;
578 KMP_FATAL(TPCommonBlocksInconsist)__kmp_fatal(__kmp_msg_format(kmp_i18n_msg_TPCommonBlocksInconsist
), __kmp_msg_null)
;
579 }
580#endif /* USE_CHECKS_COMMON */
581 } else {
582 /* The parallel address will NEVER overlap with the data_address */
583 /* dkp: 3rd arg to kmp_threadprivate_insert() is the data_address; use
584 * data_address = data */
585 KC_TRACE(20, ("__kmpc_threadprivate: T#%d inserting data\n", global_tid))if (kmp_c_debug >= 20) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d inserting data\n"
, global_tid); }
;
586 tn = kmp_threadprivate_insert(global_tid, data, data, size);
587 }
588
589 ret = tn->par_addr;
590 }
591 KC_TRACE(10, ("__kmpc_threadprivate: T#%d exiting; return value = %p\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d exiting; return value = %p\n"
, global_tid, ret); }
592 global_tid, ret))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate: T#%d exiting; return value = %p\n"
, global_tid, ret); }
;
593
594 return ret;
595}
596
597static kmp_cached_addr_t *__kmp_find_cache(void *data) {
598 kmp_cached_addr_t *ptr = __kmp_threadpriv_cache_list;
599 while (ptr && ptr->data != data)
600 ptr = ptr->next;
601 return ptr;
602}
603
604/*!
605 @ingroup THREADPRIVATE
606 @param loc source location information
607 @param global_tid global thread number
608 @param data pointer to data to privatize
609 @param size size of data to privatize
610 @param cache pointer to cache
611 @return pointer to private storage
612
613 Allocate private storage for threadprivate data.
614*/
615void *
616__kmpc_threadprivate_cached(ident_t *loc,
617 kmp_int32 global_tid, // gtid.
618 void *data, // Pointer to original global variable.
619 size_t size, // Size of original global variable.
620 void ***cache) {
621 KC_TRACE(10, ("__kmpc_threadprivate_cached: T#%d called with cache: %p, "if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d called with cache: %p, "
"address: %p, size: %" "llu" "\n", global_tid, *cache, data,
size); }
622 "address: %p, size: %" KMP_SIZE_T_SPEC "\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d called with cache: %p, "
"address: %p, size: %" "llu" "\n", global_tid, *cache, data,
size); }
623 global_tid, *cache, data, size))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d called with cache: %p, "
"address: %p, size: %" "llu" "\n", global_tid, *cache, data,
size); }
;
624
625 if (TCR_PTR(*cache)((void *)(*cache)) == 0) {
1
Taking true branch
626 __kmp_acquire_lock(&__kmp_global_lock, global_tid);
627
628 if (TCR_PTR(*cache)((void *)(*cache)) == 0) {
2
Taking true branch
629 __kmp_acquire_bootstrap_lock(&__kmp_tp_cached_lock);
630 // Compiler often passes in NULL cache, even if it's already been created
631 void **my_cache;
632 kmp_cached_addr_t *tp_cache_addr;
633 // Look for an existing cache
634 tp_cache_addr = __kmp_find_cache(data);
635 if (!tp_cache_addr) { // Cache was never created; do it now
3
Assuming 'tp_cache_addr' is null
4
Taking true branch
636 __kmp_tp_cached = 1;
637 KMP_ITT_IGNORE(my_cache = (void **)__kmp_allocate(do { __itt_state_t __itt_state_; if (__kmp_itt_state_get_ptr__3_0
) { __itt_state_ = (!__kmp_itt_state_get_ptr__3_0) ? 0 : __kmp_itt_state_get_ptr__3_0
(); (!__kmp_itt_obj_mode_set_ptr__3_0) ? 0 : __kmp_itt_obj_mode_set_ptr__3_0
(__itt_obj_prop_ignore, __itt_obj_state_set); } { my_cache = (
void **)___kmp_allocate((sizeof(void *) * __kmp_tp_capacity +
sizeof(kmp_cached_addr_t)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 639); } if (__kmp_itt_state_get_ptr__3_0) { (!__kmp_itt_state_set_ptr__3_0
) ? 0 : __kmp_itt_state_set_ptr__3_0(__itt_state_); } } while
(0)
5
Within the expansion of the macro 'KMP_ITT_IGNORE':
a
'__itt_state_' declared without an initial value
b
Assuming '__kmp_itt_state_get_ptr__3_0' is null
c
Assuming '__kmp_itt_state_get_ptr__3_0' is non-null
d
Assuming '__kmp_itt_state_set_ptr__3_0' is non-null
e
1st function call argument is an uninitialized value
638 sizeof(void *) * __kmp_tp_capacity +do { __itt_state_t __itt_state_; if (__kmp_itt_state_get_ptr__3_0
) { __itt_state_ = (!__kmp_itt_state_get_ptr__3_0) ? 0 : __kmp_itt_state_get_ptr__3_0
(); (!__kmp_itt_obj_mode_set_ptr__3_0) ? 0 : __kmp_itt_obj_mode_set_ptr__3_0
(__itt_obj_prop_ignore, __itt_obj_state_set); } { my_cache = (
void **)___kmp_allocate((sizeof(void *) * __kmp_tp_capacity +
sizeof(kmp_cached_addr_t)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 639); } if (__kmp_itt_state_get_ptr__3_0) { (!__kmp_itt_state_set_ptr__3_0
) ? 0 : __kmp_itt_state_set_ptr__3_0(__itt_state_); } } while
(0)
639 sizeof(kmp_cached_addr_t));)do { __itt_state_t __itt_state_; if (__kmp_itt_state_get_ptr__3_0
) { __itt_state_ = (!__kmp_itt_state_get_ptr__3_0) ? 0 : __kmp_itt_state_get_ptr__3_0
(); (!__kmp_itt_obj_mode_set_ptr__3_0) ? 0 : __kmp_itt_obj_mode_set_ptr__3_0
(__itt_obj_prop_ignore, __itt_obj_state_set); } { my_cache = (
void **)___kmp_allocate((sizeof(void *) * __kmp_tp_capacity +
sizeof(kmp_cached_addr_t)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 639); } if (__kmp_itt_state_get_ptr__3_0) { (!__kmp_itt_state_set_ptr__3_0
) ? 0 : __kmp_itt_state_set_ptr__3_0(__itt_state_); } } while
(0)
;
640 // No need to zero the allocated memory; __kmp_allocate does that.
641 KC_TRACE(50, ("__kmpc_threadprivate_cached: T#%d allocated cache at "if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d allocated cache at "
"address %p\n", global_tid, my_cache); }
642 "address %p\n",if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d allocated cache at "
"address %p\n", global_tid, my_cache); }
643 global_tid, my_cache))if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d allocated cache at "
"address %p\n", global_tid, my_cache); }
;
644 /* TODO: free all this memory in __kmp_common_destroy using
645 * __kmp_threadpriv_cache_list */
646 /* Add address of mycache to linked list for cleanup later */
647 tp_cache_addr = (kmp_cached_addr_t *)&my_cache[__kmp_tp_capacity];
648 tp_cache_addr->addr = my_cache;
649 tp_cache_addr->data = data;
650 tp_cache_addr->compiler_cache = cache;
651 tp_cache_addr->next = __kmp_threadpriv_cache_list;
652 __kmp_threadpriv_cache_list = tp_cache_addr;
653 } else { // A cache was already created; use it
654 my_cache = tp_cache_addr->addr;
655 tp_cache_addr->compiler_cache = cache;
656 }
657 KMP_MB();
658
659 TCW_PTR(*cache, my_cache)((*cache)) = ((my_cache));
660 __kmp_release_bootstrap_lock(&__kmp_tp_cached_lock);
661
662 KMP_MB();
663 }
664 __kmp_release_lock(&__kmp_global_lock, global_tid);
665 }
666
667 void *ret;
668 if ((ret = TCR_PTR((*cache)[global_tid])((void *)((*cache)[global_tid]))) == 0) {
669 ret = __kmpc_threadprivate(loc, global_tid, data, (size_t)size);
670
671 TCW_PTR((*cache)[global_tid], ret)(((*cache)[global_tid])) = ((ret));
672 }
673 KC_TRACE(10,if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d exiting; return value = %p\n"
, global_tid, ret); }
674 ("__kmpc_threadprivate_cached: T#%d exiting; return value = %p\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d exiting; return value = %p\n"
, global_tid, ret); }
675 global_tid, ret))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_cached: T#%d exiting; return value = %p\n"
, global_tid, ret); }
;
676 return ret;
677}
678
679// This function should only be called when both __kmp_tp_cached_lock and
680// kmp_forkjoin_lock are held.
681void __kmp_threadprivate_resize_cache(int newCapacity) {
682 KC_TRACE(10, ("__kmp_threadprivate_resize_cache: called with size: %d\n",if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_resize_cache: called with size: %d\n"
, newCapacity); }
683 newCapacity))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmp_threadprivate_resize_cache: called with size: %d\n"
, newCapacity); }
;
684
685 kmp_cached_addr_t *ptr = __kmp_threadpriv_cache_list;
686
687 while (ptr) {
688 if (ptr->data) { // this location has an active cache; resize it
689 void **my_cache;
690 KMP_ITT_IGNORE(my_cache =do { __itt_state_t __itt_state_; if (__kmp_itt_state_get_ptr__3_0
) { __itt_state_ = (!__kmp_itt_state_get_ptr__3_0) ? 0 : __kmp_itt_state_get_ptr__3_0
(); (!__kmp_itt_obj_mode_set_ptr__3_0) ? 0 : __kmp_itt_obj_mode_set_ptr__3_0
(__itt_obj_prop_ignore, __itt_obj_state_set); } { my_cache = (
void **)___kmp_allocate((sizeof(void *) * newCapacity + sizeof
(kmp_cached_addr_t)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 692); } if (__kmp_itt_state_get_ptr__3_0) { (!__kmp_itt_state_set_ptr__3_0
) ? 0 : __kmp_itt_state_set_ptr__3_0(__itt_state_); } } while
(0)
691 (void **)__kmp_allocate(sizeof(void *) * newCapacity +do { __itt_state_t __itt_state_; if (__kmp_itt_state_get_ptr__3_0
) { __itt_state_ = (!__kmp_itt_state_get_ptr__3_0) ? 0 : __kmp_itt_state_get_ptr__3_0
(); (!__kmp_itt_obj_mode_set_ptr__3_0) ? 0 : __kmp_itt_obj_mode_set_ptr__3_0
(__itt_obj_prop_ignore, __itt_obj_state_set); } { my_cache = (
void **)___kmp_allocate((sizeof(void *) * newCapacity + sizeof
(kmp_cached_addr_t)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 692); } if (__kmp_itt_state_get_ptr__3_0) { (!__kmp_itt_state_set_ptr__3_0
) ? 0 : __kmp_itt_state_set_ptr__3_0(__itt_state_); } } while
(0)
692 sizeof(kmp_cached_addr_t));)do { __itt_state_t __itt_state_; if (__kmp_itt_state_get_ptr__3_0
) { __itt_state_ = (!__kmp_itt_state_get_ptr__3_0) ? 0 : __kmp_itt_state_get_ptr__3_0
(); (!__kmp_itt_obj_mode_set_ptr__3_0) ? 0 : __kmp_itt_obj_mode_set_ptr__3_0
(__itt_obj_prop_ignore, __itt_obj_state_set); } { my_cache = (
void **)___kmp_allocate((sizeof(void *) * newCapacity + sizeof
(kmp_cached_addr_t)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 692); } if (__kmp_itt_state_get_ptr__3_0) { (!__kmp_itt_state_set_ptr__3_0
) ? 0 : __kmp_itt_state_set_ptr__3_0(__itt_state_); } } while
(0)
;
693 // No need to zero the allocated memory; __kmp_allocate does that.
694 KC_TRACE(50, ("__kmp_threadprivate_resize_cache: allocated cache at %p\n",if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmp_threadprivate_resize_cache: allocated cache at %p\n"
, my_cache); }
695 my_cache))if (kmp_c_debug >= 50) { __kmp_debug_printf ("__kmp_threadprivate_resize_cache: allocated cache at %p\n"
, my_cache); }
;
696 // Now copy old cache into new cache
697 void **old_cache = ptr->addr;
698 for (int i = 0; i < __kmp_tp_capacity; ++i) {
699 my_cache[i] = old_cache[i];
700 }
701
702 // Add address of new my_cache to linked list for cleanup later
703 kmp_cached_addr_t *tp_cache_addr;
704 tp_cache_addr = (kmp_cached_addr_t *)&my_cache[newCapacity];
705 tp_cache_addr->addr = my_cache;
706 tp_cache_addr->data = ptr->data;
707 tp_cache_addr->compiler_cache = ptr->compiler_cache;
708 tp_cache_addr->next = __kmp_threadpriv_cache_list;
709 __kmp_threadpriv_cache_list = tp_cache_addr;
710
711 // Copy new cache to compiler's location: We can copy directly
712 // to (*compiler_cache) if compiler guarantees it will keep
713 // using the same location for the cache. This is not yet true
714 // for some compilers, in which case we have to check if
715 // compiler_cache is still pointing at old cache, and if so, we
716 // can point it at the new cache with an atomic compare&swap
717 // operation. (Old method will always work, but we should shift
718 // to new method (commented line below) when Intel and Clang
719 // compilers use new method.)
720 (void)KMP_COMPARE_AND_STORE_PTR(tp_cache_addr->compiler_cache, old_cache,__sync_bool_compare_and_swap((void *volatile *)(tp_cache_addr
->compiler_cache), (void *)(old_cache), (void *)(my_cache)
)
721 my_cache)__sync_bool_compare_and_swap((void *volatile *)(tp_cache_addr
->compiler_cache), (void *)(old_cache), (void *)(my_cache)
)
;
722 // TCW_PTR(*(tp_cache_addr->compiler_cache), my_cache);
723
724 // If the store doesn't happen here, the compiler's old behavior will
725 // inevitably call __kmpc_threadprivate_cache with a new location for the
726 // cache, and that function will store the resized cache there at that
727 // point.
728
729 // Nullify old cache's data pointer so we skip it next time
730 ptr->data = NULL__null;
731 }
732 ptr = ptr->next;
733 }
734 // After all caches are resized, update __kmp_tp_capacity to the new size
735 *(volatile int *)&__kmp_tp_capacity = newCapacity;
736}
737
738/*!
739 @ingroup THREADPRIVATE
740 @param loc source location information
741 @param data pointer to data being privatized
742 @param ctor pointer to constructor function for data
743 @param cctor pointer to copy constructor function for data
744 @param dtor pointer to destructor function for data
745 @param vector_length length of the vector (bytes or elements?)
746 Register vector constructors and destructors for thread private data.
747*/
748void __kmpc_threadprivate_register_vec(ident_t *loc, void *data,
749 kmpc_ctor_vec ctor, kmpc_cctor_vec cctor,
750 kmpc_dtor_vec dtor,
751 size_t vector_length) {
752 struct shared_common *d_tn, **lnk_tn;
753
754 KC_TRACE(10, ("__kmpc_threadprivate_register_vec: called\n"))if (kmp_c_debug >= 10) { __kmp_debug_printf ("__kmpc_threadprivate_register_vec: called\n"
); }
;
755
756#ifdef USE_CHECKS_COMMON
757 /* copy constructor must be zero for current code gen (Nov 2002 - jph) */
758 KMP_ASSERT(cctor == 0)if (!(cctor == 0)) { __kmp_debug_assert("cctor == 0", "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 758); }
;
759#endif /* USE_CHECKS_COMMON */
760
761 d_tn = __kmp_find_shared_task_common(
762 &__kmp_threadprivate_d_table, -1,
763 data); /* Only the global data table exists. */
764
765 if (d_tn == 0) {
766 d_tn = (struct shared_common *)__kmp_allocate(sizeof(struct shared_common))___kmp_allocate((sizeof(struct shared_common)), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 766)
;
767 d_tn->gbl_addr = data;
768
769 d_tn->ct.ctorv = ctor;
770 d_tn->cct.cctorv = cctor;
771 d_tn->dt.dtorv = dtor;
772 d_tn->is_vec = TRUE(!0);
773 d_tn->vec_len = (size_t)vector_length;
774 // d_tn->obj_init = 0; // AC: __kmp_allocate zeroes the memory
775 // d_tn->pod_init = 0;
776 lnk_tn = &(__kmp_threadprivate_d_table.data[KMP_HASH(data)((((kmp_uintptr_t)data) >> 3) & ((1 << 9) - 1
))
]);
777
778 d_tn->next = *lnk_tn;
779 *lnk_tn = d_tn;
780 }
781}
782
783void __kmp_cleanup_threadprivate_caches() {
784 kmp_cached_addr_t *ptr = __kmp_threadpriv_cache_list;
785
786 while (ptr) {
787 void **cache = ptr->addr;
788 __kmp_threadpriv_cache_list = ptr->next;
789 if (*ptr->compiler_cache)
790 *ptr->compiler_cache = NULL__null;
791 ptr->compiler_cache = NULL__null;
792 ptr->data = NULL__null;
793 ptr->addr = NULL__null;
794 ptr->next = NULL__null;
795 // Threadprivate data pointed at by cache entries are destroyed at end of
796 // __kmp_launch_thread with __kmp_common_destroy_gtid.
797 __kmp_free(cache)___kmp_free((cache), "/build/llvm-toolchain-snapshot-8~svn345461/projects/openmp/runtime/src/kmp_threadprivate.cpp"
, 797)
; // implicitly frees ptr too
798 ptr = __kmp_threadpriv_cache_list;
799 }
800}