]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgomp/env.c
c++: Allow IS_FAKE_BASE_TYPE for union types [PR114954]
[thirdparty/gcc.git] / libgomp / env.c
CommitLineData
a945c346 1/* Copyright (C) 2005-2024 Free Software Foundation, Inc.
953ff289
DN
2 Contributed by Richard Henderson <rth@redhat.com>.
3
f1f3453e
TS
4 This file is part of the GNU Offloading and Multi Processing Library
5 (libgomp).
953ff289
DN
6
7 Libgomp is free software; you can redistribute it and/or modify it
748086b7
JJ
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
953ff289
DN
11
12 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
748086b7 14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
953ff289
DN
15 more details.
16
748086b7
JJ
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
953ff289 20
748086b7
JJ
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
953ff289 25
630e3c3a
AM
26/* This file defines the OpenMP internal control variables and arranges
27 for them to be initialized from environment variables at startup. */
953ff289 28
22f1a037 29#define _GNU_SOURCE
953ff289 30#include "libgomp.h"
630e3c3a
AM
31#include "gomp-constants.h"
32#include <limits.h>
33#ifndef LIBGOMP_OFFLOADED_ONLY
953ff289 34#include "libgomp_f.h"
41dbbb37 35#include "oacc-int.h"
89b3e3cd 36#include <ctype.h>
953ff289 37#include <stdlib.h>
acf0174b
JJ
38#include <stdio.h>
39#ifdef HAVE_INTTYPES_H
40# include <inttypes.h> /* For PRIu64. */
41#endif
a1b25e49
PG
42#ifdef STRING_WITH_STRINGS
43# include <string.h>
44# include <strings.h>
45#else
46# ifdef HAVE_STRING_H
47# include <string.h>
48# else
49# ifdef HAVE_STRINGS_H
50# include <strings.h>
51# endif
52# endif
53#endif
d0d1b24d 54#include <errno.h>
c4060df4 55#include "thread-stacksize.h"
953ff289 56
976e44e3
JJ
57#ifndef HAVE_STRTOULL
58# define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
59#endif
630e3c3a
AM
60#endif /* LIBGOMP_OFFLOADED_ONLY */
61
22f1a037 62#include "secure_getenv.h"
7d37c7f6 63#include "environ.h"
e1e127de 64#include "spincount.h"
22f1a037 65
18c8b56c
TB
66/* Default values of ICVs according to the OpenMP standard,
67 except for default-device-var. */
9f2fca56 68const struct gomp_default_icv gomp_default_icv_values = {
630e3c3a
AM
69 .nthreads_var = 1,
70 .thread_limit_var = UINT_MAX,
71 .run_sched_var = GFS_DYNAMIC,
72 .run_sched_chunk_size = 1,
18c8b56c 73 .default_device_var = INT_MIN,
6fae7eda 74 .max_active_levels_var = 1,
630e3c3a 75 .bind_var = omp_proc_bind_false,
9f2fca56
MV
76 .nteams_var = 0,
77 .teams_thread_limit_var = 0,
78 .dyn_var = false
79};
80
81struct gomp_task_icv gomp_global_icv = {
82 .nthreads_var = gomp_default_icv_values.nthreads_var,
83 .thread_limit_var = gomp_default_icv_values.thread_limit_var,
84 .run_sched_var = gomp_default_icv_values.run_sched_var,
85 .run_sched_chunk_size = gomp_default_icv_values.run_sched_chunk_size,
86 .default_device_var = gomp_default_icv_values.default_device_var,
87 .dyn_var = gomp_default_icv_values.dyn_var,
88 .max_active_levels_var = gomp_default_icv_values.max_active_levels_var,
89 .bind_var = gomp_default_icv_values.bind_var,
630e3c3a
AM
90 .target_data = NULL
91};
92
9f2fca56
MV
93/* List for initial "_DEV", "_ALL", and "_DEV_X" ICVs like OMP_NUM_TEAMS_DEV,
94 OMP_NUM_TEAMS_ALL, or OMP_NUM_TEAMS_DEV_42. */
95struct gomp_icv_list *gomp_initial_icv_list = NULL;
96
97/* List for "_DEV_X" ICVs like OMP_NUM_TEAMS_DEV_42. This list contains all
98 device-specific ICVs that are copied from host to device and back. */
99struct gomp_offload_icv_list *gomp_offload_icv_list = NULL;
100
630e3c3a 101bool gomp_cancel_var = false;
1bfc07d1
KCY
102enum gomp_target_offload_t gomp_target_offload_var
103 = GOMP_TARGET_OFFLOAD_DEFAULT;
630e3c3a
AM
104int gomp_max_task_priority_var = 0;
105#ifndef HAVE_SYNC_BUILTINS
106gomp_mutex_t gomp_managed_threads_lock;
107#endif
108unsigned long gomp_available_cpus = 1, gomp_managed_threads = 1;
109unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
110unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len;
111char *gomp_bind_var_list;
112unsigned long gomp_bind_var_list_len;
113void **gomp_places_list;
114unsigned long gomp_places_list_len;
800bcc8c 115uintptr_t gomp_def_allocator = omp_default_mem_alloc;
73a0d3bf 116char *gomp_def_allocator_envvar = NULL;
630e3c3a
AM
117int gomp_debug_var;
118unsigned int gomp_num_teams_var;
07dd3bcd
JJ
119int gomp_nteams_var;
120int gomp_teams_thread_limit_var;
28567c40
JJ
121bool gomp_display_affinity_var;
122char *gomp_affinity_format_var = "level %L thread %i affinity %A";
123size_t gomp_affinity_format_len;
630e3c3a
AM
124char *goacc_device_type;
125int goacc_device_num;
ec00d3fa 126int goacc_default_dims[GOMP_DIM_MAX];
630e3c3a
AM
127
128#ifndef LIBGOMP_OFFLOADED_ONLY
953ff289 129
288bc7b5 130static int wait_policy = -1;
7123ae24
UD
131static unsigned long stacksize = GOMP_DEFAULT_STACKSIZE;
132
953ff289 133static void
9f2fca56 134print_env_var_error (const char *env, const char *val)
953ff289 135{
9f2fca56
MV
136 gomp_error ("Invalid value for environment variable %.*s: %s",
137 (int) (val - env - 1), env, val);
138}
139
140/* Parse the OMP_SCHEDULE environment variable. */
141static bool
142parse_schedule (const char *env, const char *val, void *const params[])
143{
144 enum gomp_schedule_type *schedule = (enum gomp_schedule_type *) params[0];
145 int *chunk_size = (int *) params[1];
146 char *end;
6acf0b38 147 unsigned long value;
28567c40 148 int monotonic = 0;
953ff289 149
9f2fca56
MV
150 if (val == NULL)
151 return false;
953ff289 152
9f2fca56
MV
153 while (isspace ((unsigned char) *val))
154 ++val;
155 if (strncasecmp (val, "monotonic", 9) == 0)
28567c40
JJ
156 {
157 monotonic = 1;
9f2fca56 158 val += 9;
28567c40 159 }
9f2fca56 160 else if (strncasecmp (val, "nonmonotonic", 12) == 0)
28567c40
JJ
161 {
162 monotonic = -1;
9f2fca56 163 val += 12;
28567c40
JJ
164 }
165 if (monotonic)
166 {
9f2fca56
MV
167 while (isspace ((unsigned char) *val))
168 ++val;
169 if (*val != ':')
28567c40 170 goto unknown;
9f2fca56
MV
171 ++val;
172 while (isspace ((unsigned char) *val))
173 ++val;
28567c40 174 }
9f2fca56 175 if (strncasecmp (val, "static", 6) == 0)
953ff289 176 {
9f2fca56
MV
177 *schedule = GFS_STATIC;
178 val += 6;
953ff289 179 }
9f2fca56 180 else if (strncasecmp (val, "dynamic", 7) == 0)
953ff289 181 {
9f2fca56
MV
182 *schedule = GFS_DYNAMIC;
183 val += 7;
953ff289 184 }
9f2fca56 185 else if (strncasecmp (val, "guided", 6) == 0)
953ff289 186 {
9f2fca56
MV
187 *schedule = GFS_GUIDED;
188 val += 6;
953ff289 189 }
9f2fca56 190 else if (strncasecmp (val, "auto", 4) == 0)
a68ab351 191 {
9f2fca56
MV
192 *schedule = GFS_AUTO;
193 val += 4;
a68ab351 194 }
953ff289
DN
195 else
196 goto unknown;
197
28567c40 198 if (monotonic == 1
9f2fca56
MV
199 || (monotonic == 0 && *schedule == GFS_STATIC))
200 *schedule |= GFS_MONOTONIC;
28567c40 201
9f2fca56
MV
202 while (isspace ((unsigned char) *val))
203 ++val;
204 if (*val == '\0')
fb79f500 205 {
9f2fca56
MV
206 *chunk_size = (*schedule & ~GFS_MONOTONIC) != GFS_STATIC;
207 return true;
fb79f500 208 }
9f2fca56 209 if (*val++ != ',')
953ff289 210 goto unknown;
9f2fca56
MV
211 while (isspace ((unsigned char) *val))
212 ++val;
213 if (*val == '\0')
953ff289
DN
214 goto invalid;
215
6acf0b38 216 errno = 0;
9f2fca56
MV
217 value = strtoul (val, &end, 10);
218 if (errno || end == val)
6acf0b38
UB
219 goto invalid;
220
89b3e3cd
JJ
221 while (isspace ((unsigned char) *end))
222 ++end;
953ff289
DN
223 if (*end != '\0')
224 goto invalid;
6acf0b38 225
a68ab351
JJ
226 if ((int)value != value)
227 goto invalid;
228
9f2fca56 229 if (value == 0 && (*schedule & ~GFS_MONOTONIC) != GFS_STATIC)
fb79f500 230 value = 1;
9f2fca56
MV
231 *chunk_size = value;
232 return true;
953ff289
DN
233
234 unknown:
9f2fca56
MV
235 print_env_var_error (env, val);
236 return false;
953ff289
DN
237
238 invalid:
9f2fca56
MV
239 char name[val - env];
240 memcpy (name, env, val - env - 1);
241 name[val - env - 1] = '\0';
953ff289 242 gomp_error ("Invalid value for chunk size in "
9f2fca56
MV
243 "environment variable %s: %s", name, val);
244 return false;
953ff289
DN
245}
246
a68ab351 247/* Parse an unsigned long environment variable. Return true if one was
22f1a037
TV
248 present and it was successfully parsed. If SECURE, use secure_getenv to the
249 environment variable. */
953ff289
DN
250
251static bool
9f2fca56
MV
252parse_unsigned_long_1 (const char *env, const char *val, unsigned long *pvalue,
253 bool allow_zero)
953ff289 254{
9f2fca56 255 char *end;
d0d1b24d 256 unsigned long value;
953ff289 257
9f2fca56 258 if (val == NULL)
953ff289
DN
259 return false;
260
9f2fca56
MV
261 while (isspace ((unsigned char) *val))
262 ++val;
263 if (*val == '\0')
953ff289
DN
264 goto invalid;
265
6acf0b38 266 errno = 0;
9f2fca56
MV
267 value = strtoul (val, &end, 10);
268 if (errno || end == val || (long) value <= 0 - allow_zero)
6acf0b38
UB
269 goto invalid;
270
89b3e3cd
JJ
271 while (isspace ((unsigned char) *end))
272 ++end;
953ff289
DN
273 if (*end != '\0')
274 goto invalid;
d0d1b24d
RH
275
276 *pvalue = value;
953ff289
DN
277 return true;
278
279 invalid:
9f2fca56 280 print_env_var_error (env, val);
953ff289
DN
281 return false;
282}
283
22f1a037
TV
284/* As parse_unsigned_long_1, but always use getenv. */
285
286static bool
9f2fca56 287parse_unsigned_long (const char *env, const char *val, void *const params[])
22f1a037 288{
2a193e9d 289 unsigned long upper = (uintptr_t) params[2];
9f2fca56
MV
290 unsigned long pvalue = 0;
291 bool ret = parse_unsigned_long_1 (env, val, &pvalue, (bool) params[1]);
292 if (!ret)
293 return false;
294
295 if (upper == 0)
296 *(unsigned long *) params[0] = pvalue;
297 else
298 {
299 if (pvalue > upper)
300 pvalue = upper;
301 if (upper <= UCHAR_MAX)
302 *(unsigned char *) params[0] = pvalue;
303 else if (upper <= UINT_MAX)
304 *(unsigned int *) params[0] = pvalue;
305 else
306 *(unsigned long *) params[0] = pvalue;
307 }
308
309 return ret;
22f1a037
TV
310}
311
acf0174b 312/* Parse a positive int environment variable. Return true if one was
22f1a037
TV
313 present and it was successfully parsed. If SECURE, use secure_getenv to the
314 environment variable. */
acf0174b
JJ
315
316static bool
9f2fca56 317parse_int_1 (const char *env, const char *val, int *pvalue, bool allow_zero)
acf0174b
JJ
318{
319 unsigned long value;
9f2fca56 320 if (!parse_unsigned_long_1 (env, val, &value, allow_zero))
acf0174b
JJ
321 return false;
322 if (value > INT_MAX)
323 {
9f2fca56 324 print_env_var_error (env, val);
acf0174b
JJ
325 return false;
326 }
327 *pvalue = (int) value;
328 return true;
329}
330
22f1a037 331static bool
9f2fca56 332parse_int (const char *env, const char *val, void *const params[])
22f1a037 333{
9f2fca56 334 return parse_int_1 (env, val, (int *) params[0], (bool) params[1]);
22f1a037
TV
335}
336
337/* As parse_int_1, but use getenv_secure. */
338
339static bool
9f2fca56 340parse_int_secure (const char *env, int *pvalue, bool allow_zero)
22f1a037 341{
9f2fca56 342 return parse_int_1 (env, secure_getenv (env), pvalue, allow_zero);
22f1a037
TV
343}
344
20906c66
JJ
345/* Parse an unsigned long list environment variable. Return true if one was
346 present and it was successfully parsed. */
347
348static bool
9f2fca56
MV
349parse_unsigned_long_list (const char *env, const char *val,
350 void *const params[])
20906c66 351{
9f2fca56
MV
352 unsigned long *p1stvalue = (unsigned long *) params[0];
353 unsigned long **pvalues = (unsigned long **) params[1];
354 unsigned long *pnvalues = (unsigned long *) params[2];
355 char *end;
20906c66
JJ
356 unsigned long value, *values = NULL;
357
9f2fca56 358 if (val == NULL)
20906c66
JJ
359 return false;
360
9f2fca56
MV
361 while (isspace ((unsigned char) *val))
362 ++val;
363 if (*val == '\0')
20906c66
JJ
364 goto invalid;
365
366 errno = 0;
9f2fca56 367 value = strtoul (val, &end, 10);
20906c66
JJ
368 if (errno || (long) value <= 0)
369 goto invalid;
370
371 while (isspace ((unsigned char) *end))
372 ++end;
373 if (*end != '\0')
374 {
375 if (*end == ',')
376 {
377 unsigned long nvalues = 0, nalloced = 0;
378
379 do
380 {
9f2fca56 381 val = end + 1;
20906c66
JJ
382 if (nvalues == nalloced)
383 {
384 unsigned long *n;
385 nalloced = nalloced ? nalloced * 2 : 16;
386 n = realloc (values, nalloced * sizeof (unsigned long));
387 if (n == NULL)
388 {
389 free (values);
9f2fca56
MV
390 char name[val - env];
391 memcpy (name, env, val - env - 1);
392 name[val - env - 1] = '\0';
20906c66
JJ
393 gomp_error ("Out of memory while trying to parse"
394 " environment variable %s", name);
395 return false;
396 }
397 values = n;
398 if (nvalues == 0)
399 values[nvalues++] = value;
400 }
401
9f2fca56
MV
402 while (isspace ((unsigned char) *val))
403 ++val;
404 if (*val == '\0')
20906c66
JJ
405 goto invalid;
406
407 errno = 0;
9f2fca56 408 value = strtoul (val, &end, 10);
20906c66
JJ
409 if (errno || (long) value <= 0)
410 goto invalid;
411
412 values[nvalues++] = value;
413 while (isspace ((unsigned char) *end))
414 ++end;
415 if (*end == '\0')
416 break;
417 if (*end != ',')
418 goto invalid;
419 }
420 while (1);
421 *p1stvalue = values[0];
422 *pvalues = values;
423 *pnvalues = nvalues;
424 return true;
425 }
426 goto invalid;
427 }
9f2fca56
MV
428 else
429 {
430 *pnvalues = 0;
431 *pvalues = NULL;
432 }
20906c66
JJ
433
434 *p1stvalue = value;
435 return true;
436
437 invalid:
438 free (values);
9f2fca56 439 print_env_var_error (env, val);
20906c66
JJ
440 return false;
441}
442
9f2fca56
MV
443static bool
444parse_target_offload (const char *env, const char *val, void *const params[])
1bfc07d1 445{
121a8812 446 int new_offload = -1;
1bfc07d1 447
9f2fca56
MV
448 if (val == NULL)
449 return false;
1bfc07d1 450
9f2fca56
MV
451 while (isspace ((unsigned char) *val))
452 ++val;
453 if (strncasecmp (val, "default", 7) == 0)
1bfc07d1 454 {
9f2fca56 455 val += 7;
1bfc07d1
KCY
456 new_offload = GOMP_TARGET_OFFLOAD_DEFAULT;
457 }
9f2fca56 458 else if (strncasecmp (val, "mandatory", 9) == 0)
1bfc07d1 459 {
9f2fca56 460 val += 9;
1bfc07d1
KCY
461 new_offload = GOMP_TARGET_OFFLOAD_MANDATORY;
462 }
9f2fca56 463 else if (strncasecmp (val, "disabled", 8) == 0)
1bfc07d1 464 {
9f2fca56 465 val += 8;
1bfc07d1
KCY
466 new_offload = GOMP_TARGET_OFFLOAD_DISABLED;
467 }
9f2fca56
MV
468 while (isspace ((unsigned char) *val))
469 ++val;
470 if (new_offload != -1 && *val == '\0')
1bfc07d1 471 {
9f2fca56
MV
472 *(enum gomp_target_offload_t *) params[0] = new_offload;
473 return true;
1bfc07d1
KCY
474 }
475
9f2fca56
MV
476 print_env_var_error (env, val);
477 return false;
1bfc07d1
KCY
478}
479
acf0174b
JJ
480/* Parse environment variable set to a boolean or list of omp_proc_bind_t
481 enum values. Return true if one was present and it was successfully
482 parsed. */
483
484static bool
9f2fca56 485parse_bind_var (const char *env, const char *val, void *const params[])
acf0174b 486{
9f2fca56
MV
487 char *p1stvalue = (char *) params[0];
488 char **pvalues = (char **) params[1];
489 unsigned long *pnvalues = (unsigned long *) params[2];
c8673881 490 char value = omp_proc_bind_false, *values = NULL;
acf0174b
JJ
491 int i;
492 static struct proc_bind_kinds
493 {
494 const char name[7];
495 const char len;
496 omp_proc_bind_t kind;
497 } kinds[] =
498 {
499 { "false", 5, omp_proc_bind_false },
500 { "true", 4, omp_proc_bind_true },
501 { "master", 6, omp_proc_bind_master },
432de084 502 { "primary", 7, omp_proc_bind_primary },
acf0174b
JJ
503 { "close", 5, omp_proc_bind_close },
504 { "spread", 6, omp_proc_bind_spread }
505 };
506
9f2fca56 507 if (val == NULL)
acf0174b
JJ
508 return false;
509
9f2fca56
MV
510 while (isspace ((unsigned char) *val))
511 ++val;
512 if (*val == '\0')
acf0174b
JJ
513 goto invalid;
514
432de084 515 for (i = 0; i < 6; i++)
9f2fca56 516 if (strncasecmp (val, kinds[i].name, kinds[i].len) == 0)
acf0174b
JJ
517 {
518 value = kinds[i].kind;
9f2fca56 519 val += kinds[i].len;
acf0174b
JJ
520 break;
521 }
432de084 522 if (i == 6)
acf0174b
JJ
523 goto invalid;
524
9f2fca56
MV
525 while (isspace ((unsigned char) *val))
526 ++val;
527 if (*val != '\0')
acf0174b 528 {
9f2fca56 529 if (*val == ',')
acf0174b
JJ
530 {
531 unsigned long nvalues = 0, nalloced = 0;
532
533 if (value == omp_proc_bind_false
534 || value == omp_proc_bind_true)
535 goto invalid;
536
537 do
538 {
9f2fca56 539 val++;
acf0174b
JJ
540 if (nvalues == nalloced)
541 {
542 char *n;
543 nalloced = nalloced ? nalloced * 2 : 16;
544 n = realloc (values, nalloced);
545 if (n == NULL)
546 {
547 free (values);
9f2fca56
MV
548 char name[val - env];
549 memcpy (name, env, val - env - 1);
550 name[val - env - 1] = '\0';
acf0174b
JJ
551 gomp_error ("Out of memory while trying to parse"
552 " environment variable %s", name);
553 return false;
554 }
555 values = n;
556 if (nvalues == 0)
557 values[nvalues++] = value;
558 }
559
9f2fca56
MV
560 while (isspace ((unsigned char) *val))
561 ++val;
562 if (*val == '\0')
acf0174b
JJ
563 goto invalid;
564
432de084 565 for (i = 2; i < 6; i++)
9f2fca56 566 if (strncasecmp (val, kinds[i].name, kinds[i].len) == 0)
acf0174b
JJ
567 {
568 value = kinds[i].kind;
9f2fca56 569 val += kinds[i].len;
acf0174b
JJ
570 break;
571 }
432de084 572 if (i == 6)
acf0174b
JJ
573 goto invalid;
574
575 values[nvalues++] = value;
9f2fca56
MV
576 while (isspace ((unsigned char) *val))
577 ++val;
578 if (*val == '\0')
acf0174b 579 break;
9f2fca56 580 if (*val != ',')
acf0174b
JJ
581 goto invalid;
582 }
583 while (1);
584 *p1stvalue = values[0];
585 *pvalues = values;
586 *pnvalues = nvalues;
587 return true;
588 }
589 goto invalid;
590 }
591
592 *p1stvalue = value;
593 return true;
594
595 invalid:
596 free (values);
9f2fca56 597 print_env_var_error (env, val);
acf0174b
JJ
598 return false;
599}
600
601static bool
602parse_one_place (char **envp, bool *negatep, unsigned long *lenp,
603 long *stridep)
604{
605 char *env = *envp, *start;
606 void *p = gomp_places_list ? gomp_places_list[gomp_places_list_len] : NULL;
607 unsigned long len = 1;
608 long stride = 1;
609 int pass;
610 bool any_negate = false;
4a0fed0c 611 bool has_braces = true;
acf0174b
JJ
612 *negatep = false;
613 while (isspace ((unsigned char) *env))
614 ++env;
615 if (*env == '!')
616 {
617 *negatep = true;
618 ++env;
619 while (isspace ((unsigned char) *env))
620 ++env;
621 }
622 if (*env != '{')
4a0fed0c
JJ
623 {
624 char *end;
625 unsigned long this_num;
626
627 errno = 0;
628 this_num = strtoul (env, &end, 10);
629 if (errno || end == env)
630 return false;
631 env = end - 1;
632 has_braces = false;
633 if (gomp_places_list
634 && !gomp_affinity_add_cpus (p, this_num, 1, 1, false))
635 return false;
636 }
637 else
638 {
639 ++env;
640 while (isspace ((unsigned char) *env))
641 ++env;
642 }
acf0174b 643 start = env;
4a0fed0c 644 for (pass = 0; pass < (any_negate ? 2 : has_braces); pass++)
acf0174b
JJ
645 {
646 env = start;
647 do
648 {
649 unsigned long this_num, this_len = 1;
650 long this_stride = 1;
651 bool this_negate = (*env == '!');
c057ed9c 652 char *end;
acf0174b
JJ
653 if (this_negate)
654 {
655 if (gomp_places_list)
656 any_negate = true;
657 ++env;
658 while (isspace ((unsigned char) *env))
659 ++env;
660 }
661
662 errno = 0;
c057ed9c
JJ
663 this_num = strtoul (env, &end, 10);
664 if (errno || end == env)
acf0174b 665 return false;
c057ed9c 666 env = end;
acf0174b
JJ
667 while (isspace ((unsigned char) *env))
668 ++env;
669 if (*env == ':')
670 {
671 ++env;
4a0fed0c
JJ
672 if (this_negate)
673 return false;
acf0174b
JJ
674 while (isspace ((unsigned char) *env))
675 ++env;
676 errno = 0;
677 this_len = strtoul (env, &env, 10);
678 if (errno || this_len == 0)
679 return false;
680 while (isspace ((unsigned char) *env))
681 ++env;
682 if (*env == ':')
683 {
684 ++env;
685 while (isspace ((unsigned char) *env))
686 ++env;
687 errno = 0;
c057ed9c
JJ
688 this_stride = strtol (env, &end, 10);
689 if (errno || end == env)
acf0174b 690 return false;
c057ed9c 691 env = end;
acf0174b
JJ
692 while (isspace ((unsigned char) *env))
693 ++env;
694 }
695 }
acf0174b
JJ
696 if (gomp_places_list && pass == this_negate)
697 {
698 if (this_negate)
699 {
700 if (!gomp_affinity_remove_cpu (p, this_num))
701 return false;
702 }
703 else if (!gomp_affinity_add_cpus (p, this_num, this_len,
704 this_stride, false))
705 return false;
706 }
707 if (*env == '}')
708 break;
709 if (*env != ',')
710 return false;
711 ++env;
712 }
713 while (1);
714 }
715
716 ++env;
717 while (isspace ((unsigned char) *env))
718 ++env;
719 if (*env == ':')
720 {
c057ed9c 721 char *end;
4a0fed0c
JJ
722 if (*negatep)
723 return false;
acf0174b
JJ
724 ++env;
725 while (isspace ((unsigned char) *env))
726 ++env;
727 errno = 0;
728 len = strtoul (env, &env, 10);
729 if (errno || len == 0 || len >= 65536)
730 return false;
731 while (isspace ((unsigned char) *env))
732 ++env;
733 if (*env == ':')
734 {
735 ++env;
736 while (isspace ((unsigned char) *env))
737 ++env;
738 errno = 0;
c057ed9c
JJ
739 stride = strtol (env, &end, 10);
740 if (errno || end == env)
acf0174b 741 return false;
c057ed9c 742 env = end;
acf0174b
JJ
743 while (isspace ((unsigned char) *env))
744 ++env;
745 }
746 }
acf0174b
JJ
747 *envp = env;
748 *lenp = len;
749 *stridep = stride;
750 return true;
751}
752
753static bool
f89163fd 754parse_places_var (const char *name, bool ignore)
acf0174b
JJ
755{
756 char *env = getenv (name), *end;
757 bool any_negate = false;
758 int level = 0;
759 unsigned long count = 0;
760 if (env == NULL)
761 return false;
762
763 while (isspace ((unsigned char) *env))
764 ++env;
765 if (*env == '\0')
766 goto invalid;
767
768 if (strncasecmp (env, "threads", 7) == 0)
769 {
770 env += 7;
771 level = 1;
772 }
773 else if (strncasecmp (env, "cores", 5) == 0)
774 {
775 env += 5;
776 level = 2;
777 }
778 else if (strncasecmp (env, "sockets", 7) == 0)
779 {
780 env += 7;
781 level = 3;
782 }
5809be05
JJ
783 else if (strncasecmp (env, "ll_caches", 9) == 0)
784 {
785 env += 9;
786 level = 4;
787 }
e7ce32c7
JJ
788 else if (strncasecmp (env, "numa_domains", 12) == 0)
789 {
790 env += 12;
791 level = 5;
792 }
acf0174b
JJ
793 if (level)
794 {
795 count = ULONG_MAX;
796 while (isspace ((unsigned char) *env))
797 ++env;
798 if (*env != '\0')
799 {
800 if (*env++ != '(')
801 goto invalid;
802 while (isspace ((unsigned char) *env))
803 ++env;
804
805 errno = 0;
806 count = strtoul (env, &end, 10);
c057ed9c 807 if (errno || end == env)
acf0174b
JJ
808 goto invalid;
809 env = end;
810 while (isspace ((unsigned char) *env))
811 ++env;
812 if (*env != ')')
813 goto invalid;
814 ++env;
815 while (isspace ((unsigned char) *env))
816 ++env;
817 if (*env != '\0')
818 goto invalid;
819 }
f89163fd
JJ
820
821 if (ignore)
822 return false;
823
acf0174b
JJ
824 return gomp_affinity_init_level (level, count, false);
825 }
826
827 count = 0;
828 end = env;
829 do
830 {
831 bool negate;
832 unsigned long len;
833 long stride;
834 if (!parse_one_place (&end, &negate, &len, &stride))
835 goto invalid;
836 if (negate)
837 {
838 if (!any_negate)
839 count++;
840 any_negate = true;
841 }
842 else
843 count += len;
844 if (count > 65536)
845 goto invalid;
846 if (*end == '\0')
847 break;
848 if (*end != ',')
849 goto invalid;
850 end++;
851 }
852 while (1);
853
f89163fd 854 if (ignore)
acf0174b
JJ
855 return false;
856
857 gomp_places_list_len = 0;
858 gomp_places_list = gomp_affinity_alloc (count, false);
859 if (gomp_places_list == NULL)
860 return false;
861
862 do
863 {
864 bool negate;
865 unsigned long len;
866 long stride;
867 gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
868 if (!parse_one_place (&env, &negate, &len, &stride))
869 goto invalid;
870 if (negate)
871 {
872 void *p;
873 for (count = 0; count < gomp_places_list_len; count++)
874 if (gomp_affinity_same_place
875 (gomp_places_list[count],
876 gomp_places_list[gomp_places_list_len]))
877 break;
878 if (count == gomp_places_list_len)
879 {
880 gomp_error ("Trying to remove a non-existing place from list "
881 "of places");
882 goto invalid;
883 }
884 p = gomp_places_list[count];
885 memmove (&gomp_places_list[count],
886 &gomp_places_list[count + 1],
887 (gomp_places_list_len - count - 1) * sizeof (void *));
888 --gomp_places_list_len;
889 gomp_places_list[gomp_places_list_len] = p;
890 }
891 else if (len == 1)
892 ++gomp_places_list_len;
893 else
894 {
895 for (count = 0; count < len - 1; count++)
896 if (!gomp_affinity_copy_place
897 (gomp_places_list[gomp_places_list_len + count + 1],
898 gomp_places_list[gomp_places_list_len + count],
899 stride))
900 goto invalid;
901 gomp_places_list_len += len;
902 }
903 if (*env == '\0')
904 break;
905 env++;
906 }
907 while (1);
908
909 if (gomp_places_list_len == 0)
910 {
911 gomp_error ("All places have been removed");
912 goto invalid;
913 }
914 if (!gomp_affinity_finalize_place_list (false))
915 goto invalid;
916 return true;
917
918 invalid:
919 free (gomp_places_list);
920 gomp_places_list = NULL;
921 gomp_places_list_len = 0;
922 gomp_error ("Invalid value for environment variable %s", name);
923 return false;
924}
925
a68ab351
JJ
926/* Parse the OMP_STACKSIZE environment varible. Return true if one was
927 present and it was successfully parsed. */
928
929static bool
9f2fca56 930parse_stacksize (const char *env, const char *val, void *const params[])
a68ab351 931{
9f2fca56 932 char *end;
a68ab351
JJ
933 unsigned long value, shift = 10;
934
9f2fca56 935 if (val == NULL)
a68ab351
JJ
936 return false;
937
9f2fca56
MV
938 while (isspace ((unsigned char) *val))
939 ++val;
940 if (*val == '\0')
a68ab351
JJ
941 goto invalid;
942
943 errno = 0;
9f2fca56
MV
944 value = strtoul (val, &end, 10);
945 if (errno || end == val)
a68ab351
JJ
946 goto invalid;
947
948 while (isspace ((unsigned char) *end))
949 ++end;
950 if (*end != '\0')
951 {
323ff903 952 switch (tolower ((unsigned char) *end))
a68ab351
JJ
953 {
954 case 'b':
955 shift = 0;
956 break;
957 case 'k':
958 break;
959 case 'm':
960 shift = 20;
961 break;
962 case 'g':
963 shift = 30;
964 break;
965 default:
966 goto invalid;
967 }
968 ++end;
969 while (isspace ((unsigned char) *end))
970 ++end;
971 if (*end != '\0')
972 goto invalid;
973 }
974
975 if (((value << shift) >> shift) != value)
976 goto invalid;
977
9f2fca56 978 *(unsigned long *) params[0] = value << shift;
a68ab351
JJ
979 return true;
980
981 invalid:
9f2fca56 982 print_env_var_error (env, val);
a68ab351
JJ
983 return false;
984}
985
986/* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
987 present and it was successfully parsed. */
988
989static bool
990parse_spincount (const char *name, unsigned long long *pvalue)
991{
992 char *env, *end;
993 unsigned long long value, mult = 1;
994
995 env = getenv (name);
996 if (env == NULL)
997 return false;
998
999 while (isspace ((unsigned char) *env))
1000 ++env;
1001 if (*env == '\0')
1002 goto invalid;
1003
1004 if (strncasecmp (env, "infinite", 8) == 0
1005 || strncasecmp (env, "infinity", 8) == 0)
1006 {
1007 value = ~0ULL;
1008 end = env + 8;
1009 goto check_tail;
1010 }
1011
1012 errno = 0;
1013 value = strtoull (env, &end, 10);
c057ed9c 1014 if (errno || end == env)
a68ab351
JJ
1015 goto invalid;
1016
1017 while (isspace ((unsigned char) *end))
1018 ++end;
1019 if (*end != '\0')
1020 {
323ff903 1021 switch (tolower ((unsigned char) *end))
a68ab351
JJ
1022 {
1023 case 'k':
1024 mult = 1000LL;
1025 break;
1026 case 'm':
1027 mult = 1000LL * 1000LL;
1028 break;
1029 case 'g':
1030 mult = 1000LL * 1000LL * 1000LL;
1031 break;
1032 case 't':
1033 mult = 1000LL * 1000LL * 1000LL * 1000LL;
1034 break;
1035 default:
1036 goto invalid;
1037 }
1038 ++end;
1039 check_tail:
1040 while (isspace ((unsigned char) *end))
1041 ++end;
1042 if (*end != '\0')
1043 goto invalid;
1044 }
1045
1046 if (value > ~0ULL / mult)
1047 value = ~0ULL;
1048 else
1049 value *= mult;
1050
1051 *pvalue = value;
1052 return true;
1053
1054 invalid:
1055 gomp_error ("Invalid value for environment variable %s", name);
1056 return false;
1057}
1058
1059/* Parse a boolean value for environment variable NAME and store the
6fae7eda
KCY
1060 result in VALUE. Return true if one was present and it was
1061 successfully parsed. */
6fae7eda 1062static bool
9f2fca56 1063parse_boolean (const char *env, const char *val, void *const params[])
953ff289 1064{
9f2fca56 1065 bool *value = (bool *) params[0];
953ff289 1066
9f2fca56 1067 if (val == NULL)
6fae7eda 1068 return false;
953ff289 1069
9f2fca56
MV
1070 while (isspace ((unsigned char) *val))
1071 ++val;
1072 if (strncasecmp (val, "true", 4) == 0)
89b3e3cd
JJ
1073 {
1074 *value = true;
9f2fca56 1075 val += 4;
89b3e3cd 1076 }
9f2fca56 1077 else if (strncasecmp (val, "false", 5) == 0)
89b3e3cd
JJ
1078 {
1079 *value = false;
9f2fca56 1080 val += 5;
89b3e3cd 1081 }
953ff289 1082 else
9f2fca56
MV
1083 val = "X";
1084 while (isspace ((unsigned char) *val))
1085 ++val;
1086 if (*val != '\0')
6fae7eda 1087 {
9f2fca56 1088 print_env_var_error (env, val);
6fae7eda
KCY
1089 return false;
1090 }
1091 return true;
953ff289
DN
1092}
1093
800bcc8c 1094/* Parse the OMP_WAIT_POLICY environment variable and return the value. */
a68ab351 1095
9f2fca56
MV
1096static bool
1097parse_wait_policy (const char *env, const char *val, void *const params[])
a68ab351 1098{
9f2fca56 1099 int *pvalue = (int *) params[0];
a68ab351
JJ
1100 int ret = -1;
1101
9f2fca56
MV
1102 if (val == NULL)
1103 {
1104 *pvalue = -1;
1105 return false;
1106 }
a68ab351 1107
9f2fca56
MV
1108 while (isspace ((unsigned char) *val))
1109 ++val;
1110 if (strncasecmp (val, "active", 6) == 0)
a68ab351
JJ
1111 {
1112 ret = 1;
9f2fca56 1113 val += 6;
a68ab351 1114 }
9f2fca56 1115 else if (strncasecmp (val, "passive", 7) == 0)
a68ab351
JJ
1116 {
1117 ret = 0;
9f2fca56 1118 val += 7;
a68ab351
JJ
1119 }
1120 else
9f2fca56
MV
1121 val = "X";
1122 while (isspace ((unsigned char) *val))
1123 ++val;
1124 if (*val == '\0')
1125 {
1126 *pvalue = ret;
1127 return true;
1128 }
1129 print_env_var_error (env, val);
1130 *pvalue = -1;
1131 return false;
a68ab351
JJ
1132}
1133
a0884cf0
JJ
1134/* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1135 present and it was successfully parsed. */
1136
1137static bool
f89163fd 1138parse_affinity (bool ignore)
a0884cf0 1139{
acf0174b
JJ
1140 char *env, *end, *start;
1141 int pass;
a0884cf0 1142 unsigned long cpu_beg, cpu_end, cpu_stride;
acf0174b 1143 size_t count = 0, needed;
a0884cf0
JJ
1144
1145 env = getenv ("GOMP_CPU_AFFINITY");
1146 if (env == NULL)
1147 return false;
1148
acf0174b
JJ
1149 start = env;
1150 for (pass = 0; pass < 2; pass++)
a0884cf0 1151 {
acf0174b
JJ
1152 env = start;
1153 if (pass == 1)
a0884cf0 1154 {
f89163fd
JJ
1155 if (ignore)
1156 return false;
1157
acf0174b
JJ
1158 gomp_places_list_len = 0;
1159 gomp_places_list = gomp_affinity_alloc (count, true);
1160 if (gomp_places_list == NULL)
1161 return false;
1162 }
1163 do
1164 {
1165 while (isspace ((unsigned char) *env))
1166 ++env;
1167
1168 errno = 0;
1169 cpu_beg = strtoul (env, &end, 0);
c057ed9c 1170 if (errno || end == env || cpu_beg >= 65536)
a0884cf0 1171 goto invalid;
acf0174b
JJ
1172 cpu_end = cpu_beg;
1173 cpu_stride = 1;
a0884cf0
JJ
1174
1175 env = end;
acf0174b 1176 if (*env == '-')
a0884cf0 1177 {
acf0174b
JJ
1178 errno = 0;
1179 cpu_end = strtoul (++env, &end, 0);
c057ed9c 1180 if (errno || end == env || cpu_end >= 65536 || cpu_end < cpu_beg)
a0884cf0
JJ
1181 goto invalid;
1182
1183 env = end;
acf0174b
JJ
1184 if (*env == ':')
1185 {
1186 errno = 0;
1187 cpu_stride = strtoul (++env, &end, 0);
1188 if (errno || cpu_stride == 0 || cpu_stride >= 65536)
1189 goto invalid;
a0884cf0 1190
acf0174b
JJ
1191 env = end;
1192 }
1193 }
a0884cf0 1194
acf0174b
JJ
1195 needed = (cpu_end - cpu_beg) / cpu_stride + 1;
1196 if (pass == 0)
1197 count += needed;
a0884cf0 1198 else
a0884cf0 1199 {
acf0174b
JJ
1200 while (needed--)
1201 {
1202 void *p = gomp_places_list[gomp_places_list_len];
1203 gomp_affinity_init_place (p);
1204 if (gomp_affinity_add_cpus (p, cpu_beg, 1, 0, true))
1205 ++gomp_places_list_len;
1206 cpu_beg += cpu_stride;
1207 }
a0884cf0
JJ
1208 }
1209
acf0174b
JJ
1210 while (isspace ((unsigned char) *env))
1211 ++env;
a0884cf0 1212
acf0174b
JJ
1213 if (*env == ',')
1214 env++;
1215 else if (*env == '\0')
1216 break;
a0884cf0 1217 }
acf0174b 1218 while (1);
a0884cf0 1219 }
a0884cf0 1220
acf0174b
JJ
1221 if (gomp_places_list_len == 0)
1222 {
1223 free (gomp_places_list);
1224 gomp_places_list = NULL;
f89163fd 1225 return false;
acf0174b 1226 }
a0884cf0
JJ
1227 return true;
1228
1229 invalid:
1230 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1231 return false;
1232}
1233
800bcc8c 1234/* Parse the OMP_ALLOCATOR environment variable and return the value. */
9f2fca56
MV
1235static bool
1236parse_allocator (const char *env, const char *val, void *const params[])
800bcc8c 1237{
73a0d3bf 1238 const char *orig_val = val;
9f2fca56
MV
1239 uintptr_t *ret = (uintptr_t *) params[0];
1240 *ret = omp_default_mem_alloc;
73a0d3bf
TB
1241 bool memspace = false;
1242 size_t ntraits = 0;
1243 omp_alloctrait_t *traits;
800bcc8c 1244
9f2fca56
MV
1245 if (val == NULL)
1246 return false;
800bcc8c 1247
9f2fca56
MV
1248 while (isspace ((unsigned char) *val))
1249 ++val;
800bcc8c
JJ
1250 if (0)
1251 ;
73a0d3bf 1252#define C(v, m) \
9f2fca56 1253 else if (strncasecmp (val, #v, sizeof (#v) - 1) == 0) \
800bcc8c 1254 { \
9f2fca56
MV
1255 *ret = v; \
1256 val += sizeof (#v) - 1; \
73a0d3bf 1257 memspace = m; \
800bcc8c 1258 }
73a0d3bf
TB
1259 C (omp_default_mem_alloc, false)
1260 C (omp_large_cap_mem_alloc, false)
1261 C (omp_const_mem_alloc, false)
1262 C (omp_high_bw_mem_alloc, false)
1263 C (omp_low_lat_mem_alloc, false)
1264 C (omp_cgroup_mem_alloc, false)
1265 C (omp_pteam_mem_alloc, false)
1266 C (omp_thread_mem_alloc, false)
1267 C (omp_default_mem_space, true)
1268 C (omp_large_cap_mem_space, true)
1269 C (omp_const_mem_space, true)
1270 C (omp_high_bw_mem_space, true)
1271 C (omp_low_lat_mem_space, true)
800bcc8c
JJ
1272#undef C
1273 else
73a0d3bf
TB
1274 goto invalid;
1275 if (memspace && *val == ':')
1276 {
1277 ++val;
1278 const char *cp = val;
1279 while (*cp != '\0')
1280 {
1281 if (*cp == '=')
1282 ++ntraits;
1283 ++cp;
1284 }
1285 traits = gomp_alloca (ntraits * sizeof (omp_alloctrait_t));
1286 size_t n = 0;
1287 while (*val != '\0')
1288 {
1289#define C(v) \
1290 else if (strncasecmp (val, #v "=", sizeof (#v)) == 0) \
1291 { \
1292 val += sizeof (#v); \
1293 traits[n].key = omp_atk_ ## v;
1294#define V(v) \
1295 else if (strncasecmp (val, #v, sizeof (#v) - 1) == 0) \
1296 { \
1297 val += sizeof (#v) - 1; \
1298 traits[n].value = omp_atv_ ## v; \
1299 }
1300 if (0)
1301 ;
1302 C (sync_hint)
1303 if (0)
1304 ;
1305 V (contended)
1306 V (uncontended)
1307 V (serialized)
1308 V (private)
1309 else
1310 goto invalid;
1311 }
1312 C (alignment)
1313 char *end;
1314 errno = 0;
1315 traits[n].value = strtol (val, &end, 10);
1316 if (errno || end == val || traits[n].value <= 0)
1317 goto invalid;
1318 val = end;
1319 }
1320 C (access)
1321 if (0)
1322 ;
1323 V (all)
1324 V (cgroup)
1325 V (pteam)
1326 V (thread)
1327 else
1328 goto invalid;
1329 }
1330 C (pool_size)
1331 char *end;
1332 errno = 0;
1333 traits[n].value = strtol (val, &end, 10);
1334 if (errno || end == val || traits[n].value <= 0)
1335 goto invalid;
1336 val = end;
1337 }
1338 C (fallback)
1339 if (0)
1340 ;
1341 V (default_mem_fb)
1342 V (null_fb)
1343 V (abort_fb)
1344 V (allocator_fb)
1345 else
1346 goto invalid;
1347 }
1348 /* Ignore fb_data, which expects an allocator handle. */
1349 C (pinned)
1350 if (0)
1351 ;
1352 V (true)
1353 V (false)
1354 else
1355 goto invalid;
1356 }
1357 C (partition)
1358 if (0)
1359 ;
1360 V (environment)
1361 V (nearest)
1362 V (blocked)
1363 V (interleaved)
1364 else
1365 goto invalid;
1366 }
1367 else
1368 goto invalid;
1369 if (*val != ',')
1370 break;
1371 ++val;
1372 ++n;
1373 if (*val == '\0')
1374 goto invalid;
1375 }
1376#undef C
1377#undef V
1378 }
1379 else if (memspace)
1380 switch (*ret)
1381 {
1382 case omp_default_mem_space: *ret = omp_default_mem_alloc; break;
1383 case omp_large_cap_mem_space: *ret = omp_large_cap_mem_alloc; break;
1384 case omp_const_mem_space: *ret = omp_const_mem_alloc; break;
1385 case omp_high_bw_mem_space: *ret = omp_high_bw_mem_alloc; break;
1386 case omp_low_lat_mem_space: *ret = omp_low_lat_mem_alloc; break;
1387 default: __builtin_unreachable ();
1388 }
9f2fca56
MV
1389 while (isspace ((unsigned char) *val))
1390 ++val;
1391 if (*val == '\0')
73a0d3bf
TB
1392 {
1393 if (ntraits)
1394 {
1395 *ret = omp_init_allocator (*ret, ntraits, traits);
1396 if (*ret == omp_null_allocator)
1397 {
1398 gomp_error ("Allocator of environment variable %.*s cannot be "
1399 "created, using omp_default_mem_alloc instead",
1400 (int) (orig_val - env - 1), env);
1401 *ret = omp_default_mem_alloc;
1402 }
1403 else
1404 gomp_def_allocator_envvar = strdup (orig_val);
1405 }
1406 return true;
1407 }
1408invalid:
1409 int len = (orig_val - env - 1);
1410 if (*val == '\0')
1411 gomp_error ("Missing value at the end of environment variable %s", env);
1412 else
1413 gomp_error ("Invalid value for environment variable %.*s when parsing: %s",
1414 len, env, val);
9f2fca56
MV
1415 *ret = omp_default_mem_alloc;
1416 return false;
800bcc8c
JJ
1417}
1418
41dbbb37
TS
1419static void
1420parse_acc_device_type (void)
1421{
1422 const char *env = getenv ("ACC_DEVICE_TYPE");
1423
1424 if (env && *env != '\0')
1425 goacc_device_type = strdup (env);
1426 else
1427 goacc_device_type = NULL;
1428}
acf0174b 1429
ec00d3fa
TV
1430static void
1431parse_gomp_openacc_dim (void)
1432{
1433 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1434 const char *var_name = "GOMP_OPENACC_DIM";
1435 const char *env_var = getenv (var_name);
c057ed9c
JJ
1436 const char *pos = env_var;
1437 int i;
1438
ec00d3fa
TV
1439 if (!env_var)
1440 return;
1441
ec00d3fa
TV
1442 for (i = 0; *pos && i != GOMP_DIM_MAX; i++)
1443 {
c057ed9c
JJ
1444 char *eptr;
1445 long val;
1446
ec00d3fa
TV
1447 if (i && *pos++ != ':')
1448 break;
1449
1450 if (*pos == ':')
1451 continue;
1452
ec00d3fa 1453 errno = 0;
c057ed9c 1454 val = strtol (pos, &eptr, 10);
00c9ce13 1455 if (errno || eptr == pos || val < 0 || (unsigned)val != val)
ec00d3fa
TV
1456 break;
1457
1458 goacc_default_dims[i] = (int)val;
c057ed9c 1459 pos = (const char *) eptr;
ec00d3fa
TV
1460 }
1461}
1462
9f2fca56
MV
1463/* Helper function for omp_display_env which prints the values of run_sched_var.
1464 'device' can be 'host', 'dev', 'all' or a particular device number. */
acf0174b 1465
9f2fca56
MV
1466static void
1467print_schedule (enum gomp_schedule_type run_sched_var, int run_sched_chunk_size,
1468 const char *device)
1469{
1470 fprintf (stderr, " [%s] OMP_SCHEDULE = '", device);
1471 if ((run_sched_var & GFS_MONOTONIC))
28567c40 1472 {
9f2fca56 1473 if (run_sched_var != (GFS_MONOTONIC | GFS_STATIC))
28567c40
JJ
1474 fputs ("MONOTONIC:", stderr);
1475 }
9f2fca56 1476 else if (run_sched_var == GFS_STATIC)
28567c40 1477 fputs ("NONMONOTONIC:", stderr);
9f2fca56 1478 switch (run_sched_var & ~GFS_MONOTONIC)
acf0174b
JJ
1479 {
1480 case GFS_RUNTIME:
1481 fputs ("RUNTIME", stderr);
9f2fca56
MV
1482 if (run_sched_chunk_size != 1)
1483 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1484 break;
1485 case GFS_STATIC:
1486 fputs ("STATIC", stderr);
9f2fca56
MV
1487 if (run_sched_chunk_size != 0)
1488 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1489 break;
1490 case GFS_DYNAMIC:
1491 fputs ("DYNAMIC", stderr);
9f2fca56
MV
1492 if (run_sched_chunk_size != 1)
1493 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1494 break;
1495 case GFS_GUIDED:
1496 fputs ("GUIDED", stderr);
9f2fca56
MV
1497 if (run_sched_chunk_size != 1)
1498 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1499 break;
1500 case GFS_AUTO:
1501 fputs ("AUTO", stderr);
1502 break;
1503 }
1504 fputs ("'\n", stderr);
9f2fca56
MV
1505}
1506
1507/* Helper function for omp_display_env which prints the values of proc_bind_var.
1508 'device' can be 'host', 'dev', 'all', or a particular device number. */
acf0174b 1509
9f2fca56
MV
1510static void
1511print_proc_bind (char proc_bind_var, unsigned long len, char **list,
1512 const char *device)
1513{
1514 fprintf (stderr, " [%s] OMP_PROC_BIND = '", device);
1515 switch (proc_bind_var)
acf0174b
JJ
1516 {
1517 case omp_proc_bind_false:
1518 fputs ("FALSE", stderr);
1519 break;
1520 case omp_proc_bind_true:
1521 fputs ("TRUE", stderr);
1522 break;
1523 case omp_proc_bind_master:
432de084 1524 fputs ("MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1525 break;
1526 case omp_proc_bind_close:
1527 fputs ("CLOSE", stderr);
1528 break;
1529 case omp_proc_bind_spread:
1530 fputs ("SPREAD", stderr);
1531 break;
1532 }
9f2fca56
MV
1533 for (int i = 1; i < len; i++)
1534 switch ((*list)[i])
acf0174b
JJ
1535 {
1536 case omp_proc_bind_master:
432de084 1537 fputs (",MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1538 break;
1539 case omp_proc_bind_close:
1540 fputs (",CLOSE", stderr);
1541 break;
1542 case omp_proc_bind_spread:
1543 fputs (",SPREAD", stderr);
1544 break;
1545 }
1546 fputs ("'\n", stderr);
9f2fca56
MV
1547}
1548
1549enum gomp_parse_type
1550{
1551 PARSE_INT = 1,
1552 PARSE_BOOL = 2,
1553 PARSE_UINT = 3,
1554 PARSE_ULONG = 4,
1555 PARSE_UCHAR = 5,
1556 PARSE_SCHEDULE =6,
1557 PARSE_BIND = 7
1558};
1559
1560/* The following table contains items that help parsing environment variables
1561 and fill corresponding ICVs with values. FLAG_VARS contain all ICVS which
1562 are affected by the environment variable. FLAGS determine what variant of
1563 environment variable is allowed. */
1564
1565#define ENTRY(NAME) NAME, sizeof (NAME) - 1
1566static const struct envvar
1567{
1568 const char *name;
1569 int name_len;
1570 uint8_t flag_vars[3];
1571 uint8_t flag;
1572 bool (*parse_func) (const char *, const char *, void *const[]);
1573} envvars[] = {
1574 { ENTRY ("SCHEDULE"),
1575 { GOMP_ICV_SCHEDULE, GOMP_ICV_SCHEDULE_CHUNK_SIZE },
1576 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1577 &parse_schedule },
1578 { ENTRY ("NUM_TEAMS"),
1579 { GOMP_ICV_NTEAMS },
1580 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1581 &parse_int },
1582 { ENTRY ("DYNAMIC"),
1583 { GOMP_ICV_DYNAMIC },
1584 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1585 &parse_boolean },
1586 { ENTRY ("TEAMS_THREAD_LIMIT"),
1587 { GOMP_ICV_TEAMS_THREAD_LIMIT },
1588 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1589 &parse_int },
1590 { ENTRY ("THREAD_LIMIT"),
1591 { GOMP_ICV_THREAD_LIMIT },
1592 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1593 &parse_unsigned_long },
1594 { ENTRY ("NUM_THREADS"),
1595 { GOMP_ICV_NTHREADS, GOMP_ICV_NTHREADS_LIST, GOMP_ICV_NTHREADS_LIST_LEN },
1596 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1597 &parse_unsigned_long_list },
1598 { ENTRY ("PROC_BIND"),
1599 { GOMP_ICV_BIND, GOMP_ICV_BIND_LIST, GOMP_ICV_BIND_LIST_LEN },
1600 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1601 &parse_bind_var },
1602 { ENTRY ("MAX_ACTIVE_LEVELS"),
1603 { GOMP_ICV_MAX_ACTIVE_LEVELS },
1604 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1605 &parse_unsigned_long },
1606 { ENTRY ("WAIT_POLICY"),
1607 { GOMP_ICV_WAIT_POLICY },
1608 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1609 &parse_wait_policy },
1610 { ENTRY ("STACKSIZE"),
1611 { GOMP_ICV_STACKSIZE },
1612 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1613 &parse_stacksize },
1614 { ENTRY ("CANCELLATION"), { GOMP_ICV_CANCELLATION }, 0, &parse_boolean },
1615 { ENTRY ("DISPLAY_AFFINITY"), { GOMP_ICV_DISPLAY_AFFINITY }, 0,
1616 &parse_boolean },
1617 { ENTRY ("TARGET_OFFLOAD"), { GOMP_ICV_TARGET_OFFLOAD }, 0,
1618 &parse_target_offload },
1619 { ENTRY ("MAX_TASK_PRIORITY"), { GOMP_ICV_MAX_TASK_PRIORITY }, 0,
1620 &parse_int },
1621 { ENTRY ("ALLOCATOR"), { GOMP_ICV_ALLOCATOR }, 0, &parse_allocator },
1622 { ENTRY ("DEFAULT_DEVICE"), { GOMP_ICV_DEFAULT_DEVICE },
1623 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1624 &parse_int }
1625};
1626#undef ENTRY
1627#define OMP_VAR_CNT (sizeof (envvars) / sizeof (envvars[0]))
1628
1629/* The following table is used to apply the hierarchy of ICV variants for host
1630 variables, e.g. nteams_var is set to OMP_NUM_TEAMS_ALL if OMP_NUM_TEAMS is
1631 undefined. */
1632
1633static const struct host_envvar
1634{
1635 unsigned char flag_var;
1636 void *dest[3];
1637 int type_code;
1638} host_envvars[] = {
1639 { GOMP_ICV_NTEAMS, { &gomp_nteams_var }, PARSE_INT },
1640 { GOMP_ICV_DYNAMIC, { &gomp_global_icv.dyn_var }, PARSE_BOOL },
1641 { GOMP_ICV_DEFAULT_DEVICE, { &gomp_global_icv.default_device_var },
1642 PARSE_INT },
1643 { GOMP_ICV_TEAMS_THREAD_LIMIT, { &gomp_teams_thread_limit_var }, PARSE_INT },
1644 { GOMP_ICV_SCHEDULE,
1645 { &gomp_global_icv.run_sched_var, &gomp_global_icv.run_sched_chunk_size },
1646 PARSE_SCHEDULE },
1647 { GOMP_ICV_THREAD_LIMIT, { &gomp_global_icv.thread_limit_var }, PARSE_UINT },
1648 { GOMP_ICV_NTHREADS,
1649 { &gomp_global_icv.nthreads_var, &gomp_nthreads_var_list,
1650 &gomp_nthreads_var_list_len }, PARSE_ULONG },
1651 { GOMP_ICV_BIND,
1652 { &gomp_global_icv.bind_var, &gomp_bind_var_list, &gomp_bind_var_list_len },
1653 PARSE_BIND },
1654 { GOMP_ICV_MAX_ACTIVE_LEVELS, { &gomp_global_icv.max_active_levels_var },
1655 PARSE_UCHAR },
1656};
1657#define OMP_HOST_VAR_CNT (sizeof (host_envvars) / sizeof (host_envvars[0]))
1658
1659#define INT_MAX_STR_LEN 10
1660
1661bool
1662gomp_get_icv_flag (uint32_t value, enum gomp_icvs icv)
1663{
1664 return value & (1 << (icv - 1));
1665}
1666
1667static void
1668gomp_set_icv_flag (uint32_t *value, enum gomp_icvs icv)
1669{
1670 *value |= 1 << (icv - 1);
1671}
1672
1673static void
1674print_device_specific_icvs (int icv_code)
1675{
1676 struct gomp_icv_list *list = gomp_initial_icv_list;
1677 int i;
1678 char dev_num[INT_MAX_STR_LEN + 1];
1679
1680 while (list != NULL)
1681 {
1682 if (list->device_num < 0)
1683 {
1684 list = list->next;
1685 continue;
1686 }
1687
1688 switch (icv_code)
1689 {
1690 case GOMP_ICV_NTEAMS:
1691 if (gomp_get_icv_flag (list->flags, GOMP_ICV_NTEAMS))
1692 fprintf (stderr, " [%d] OMP_NUM_TEAMS = '%d'\n",
1693 list->device_num, list->icvs.nteams_var);
1694 break;
1695 case GOMP_ICV_DYNAMIC:
1696 if (gomp_get_icv_flag (list->flags, GOMP_ICV_DYNAMIC))
1697 fprintf (stderr, " [%d] OMP_DYNAMIC = '%s'\n",
1698 list->device_num, list->icvs.dyn_var ? "TRUE" : "FALSE");
1699 break;
1700 case GOMP_ICV_TEAMS_THREAD_LIMIT:
1701 if (gomp_get_icv_flag (list->flags, GOMP_ICV_TEAMS_THREAD_LIMIT))
1702 fprintf (stderr, " [%d] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1703 list->device_num, list->icvs.teams_thread_limit_var);
1704 break;
1705 case GOMP_ICV_SCHEDULE:
1706 if (!(gomp_get_icv_flag (list->flags, GOMP_ICV_SCHEDULE)))
1707 break;
1708 sprintf (dev_num, "%d", list->device_num);
1709 print_schedule (list->icvs.run_sched_var,
1710 list->icvs.run_sched_chunk_size,
1711 dev_num);
1712 break;
1713 case GOMP_ICV_THREAD_LIMIT:
1714 if (gomp_get_icv_flag (list->flags, GOMP_ICV_THREAD_LIMIT))
1715 fprintf (stderr, " [%d] OMP_THREAD_LIMIT = '%d'\n",
1716 list->device_num, list->icvs.thread_limit_var);
1717 break;
1718 case GOMP_ICV_NTHREADS:
1719 if (!(gomp_get_icv_flag (list->flags, GOMP_ICV_NTHREADS)))
1720 break;
1721 fprintf (stderr, " [%d] OMP_NUM_THREADS = '%lu", list->device_num,
1722 list->icvs.nthreads_var);
1723 for (i = 1; i < list->icvs.nthreads_var_list_len; i++)
1724 fprintf (stderr, ",%lu", list->icvs.nthreads_var_list[i]);
1725 fputs ("'\n", stderr);
1726 break;
1727 case GOMP_ICV_MAX_ACTIVE_LEVELS:
1728 fprintf (stderr, " [%d] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1729 list->device_num, list->icvs.max_active_levels_var);
1730 break;
1731 case GOMP_ICV_BIND:
1732 if (!(gomp_get_icv_flag (list->flags, GOMP_ICV_BIND)))
1733 break;
1734 sprintf (dev_num, "%d", list->device_num);
1735 print_proc_bind (list->icvs.bind_var, list->icvs.bind_var_list_len,
1736 &list->icvs.bind_var_list, dev_num);
1737 break;
1738 case GOMP_ICV_WAIT_POLICY:
1739 if (gomp_get_icv_flag (list->flags, GOMP_ICV_WAIT_POLICY))
1740 fprintf (stderr, " [%d] OMP_WAIT_POLICY = '%s'\n",
1741 list->device_num,
1742 list->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1743 break;
1744 case GOMP_ICV_STACKSIZE:
1745 if (gomp_get_icv_flag (list->flags, GOMP_ICV_STACKSIZE))
1746 fprintf (stderr, " [%d] OMP_STACKSIZE = '%lu'\n",
1747 list->device_num, list->icvs.stacksize);
1748 break;
1749 }
1750 list = list->next;
1751 }
1752}
1753
1754void
1755omp_display_env (int verbose)
1756{
1757 int i;
1758 struct gomp_icv_list *dev
1759 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_DEV);
1760 struct gomp_icv_list *all
1761 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_ALL);
1762 struct gomp_icv_list *none
1763 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX);
1764
18c8b56c
TB
1765 if (none->icvs.default_device_var == INT_MIN)
1766 /* This implies OMP_TARGET_OFFLOAD=mandatory. */
1767 gomp_init_targets_once ();
1768
9f2fca56
MV
1769 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr);
1770
1771 fputs (" _OPENMP = '201511'\n", stderr);
1772
1773 fprintf (stderr, " [host] OMP_DYNAMIC = '%s'\n",
1774 none->icvs.dyn_var ? "TRUE" : "FALSE");
1775 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_DYNAMIC))
1776 fprintf (stderr, " [all] OMP_DYNAMIC = '%s'\n",
1777 all->icvs.dyn_var ? "TRUE" : "FALSE");
1778 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_DYNAMIC))
1779 fprintf (stderr, " [device] OMP_DYNAMIC = '%s'\n",
1780 dev->icvs.dyn_var ? "TRUE" : "FALSE");
1781 print_device_specific_icvs (GOMP_ICV_DYNAMIC);
1782
1783 /* The OMP_NESTED environment variable has been deprecated. */
1784 fprintf (stderr, " [host] OMP_NESTED = '%s'\n",
1785 none->icvs.max_active_levels_var > 1 ? "TRUE" : "FALSE");
1786
1787 fprintf (stderr, " [host] OMP_NUM_THREADS = '%lu",
1788 none->icvs.nthreads_var);
1789 for (i = 1; i < none->icvs.nthreads_var_list_len; i++)
1790 fprintf (stderr, ",%lu", none->icvs.nthreads_var_list[i]);
1791 fputs ("'\n", stderr);
1792 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_NTHREADS))
1793 {
1794 fprintf (stderr, " [all] OMP_NUM_THREADS = '%lu",
1795 all->icvs.nthreads_var);
1796 for (i = 1; i < all->icvs.nthreads_var_list_len; i++)
1797 fprintf (stderr, ",%lu", all->icvs.nthreads_var_list[i]);
1798 fputs ("'\n", stderr);
1799 }
1800 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_NTHREADS))
1801 {
1802 fprintf (stderr, " [device] OMP_NUM_THREADS = '%lu",
1803 dev->icvs.nthreads_var);
1804 for (i = 1; i < dev->icvs.nthreads_var_list_len; i++)
1805 fprintf (stderr, ",%lu", dev->icvs.nthreads_var_list[i]);
1806 fputs ("'\n", stderr);
1807 }
1808 print_device_specific_icvs (GOMP_ICV_NTHREADS);
1809
1810
1811 print_schedule (none->icvs.run_sched_var,
1812 none->icvs.run_sched_chunk_size, "host");
1813 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_SCHEDULE))
1814 print_schedule (all->icvs.run_sched_var,
1815 all->icvs.run_sched_chunk_size, "all");
1816 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_SCHEDULE))
1817 print_schedule (dev->icvs.run_sched_var,
1818 dev->icvs.run_sched_chunk_size, "device");
1819 print_device_specific_icvs (GOMP_ICV_SCHEDULE);
1820
1821 print_proc_bind (none->icvs.bind_var,
1822 none->icvs.bind_var_list_len,
1823 &none->icvs.bind_var_list, "host");
1824 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_BIND))
1825 print_proc_bind (all->icvs.bind_var,
1826 all->icvs.bind_var_list_len,
1827 &all->icvs.bind_var_list, "all");
1828 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_BIND))
1829 print_proc_bind (dev->icvs.bind_var,
1830 dev->icvs.bind_var_list_len,
1831 &dev->icvs.bind_var_list, "device");
1832 print_device_specific_icvs (GOMP_ICV_BIND);
1833
1834 fputs (" [host] OMP_PLACES = '", stderr);
acf0174b
JJ
1835 for (i = 0; i < gomp_places_list_len; i++)
1836 {
1837 fputs ("{", stderr);
1838 gomp_affinity_print_place (gomp_places_list[i]);
1839 fputs (i + 1 == gomp_places_list_len ? "}" : "},", stderr);
1840 }
1841 fputs ("'\n", stderr);
1842
9f2fca56
MV
1843 fprintf (stderr, " [host] OMP_STACKSIZE = '%lu'\n",
1844 none->icvs.stacksize);
1845 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_STACKSIZE))
1846 fprintf (stderr, " [all] OMP_STACKSIZE = '%lu'\n",
1847 all->icvs.stacksize);
1848 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_STACKSIZE))
1849 fprintf (stderr, " [device] OMP_STACKSIZE = '%lu'\n",
1850 dev->icvs.stacksize);
1851 print_device_specific_icvs (GOMP_ICV_STACKSIZE);
acf0174b
JJ
1852
1853 /* GOMP's default value is actually neither active nor passive. */
9f2fca56
MV
1854 fprintf (stderr, " [host] OMP_WAIT_POLICY = '%s'\n",
1855 none->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1856 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_WAIT_POLICY))
1857 fprintf (stderr, " [all] OMP_WAIT_POLICY = '%s'\n",
1858 all->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1859 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_WAIT_POLICY))
1860 fprintf (stderr, " [device] OMP_WAIT_POLICY = '%s'\n",
1861 dev->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1862 print_device_specific_icvs (GOMP_ICV_WAIT_POLICY);
1863
1864 fprintf (stderr, " [host] OMP_THREAD_LIMIT = '%u'\n",
1865 none->icvs.thread_limit_var);
1866 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_THREAD_LIMIT))
1867 fprintf (stderr, " [all] OMP_THREAD_LIMIT = '%d'\n",
1868 all->icvs.thread_limit_var);
1869 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_THREAD_LIMIT))
1870 fprintf (stderr, " [device] OMP_THREAD_LIMIT = '%d'\n",
1871 dev->icvs.thread_limit_var);
1872 print_device_specific_icvs (GOMP_ICV_THREAD_LIMIT);
1873
1874 fprintf (stderr, " [host] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1875 none->icvs.max_active_levels_var);
1876 if (all != NULL && gomp_get_icv_flag (all->flags,
1877 GOMP_ICV_MAX_ACTIVE_LEVELS))
1878 fprintf (stderr, " [all] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1879 all->icvs.max_active_levels_var);
1880 if (dev != NULL && gomp_get_icv_flag (dev->flags,
1881 GOMP_ICV_MAX_ACTIVE_LEVELS))
1882 fprintf (stderr, " [device] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1883 dev->icvs.max_active_levels_var);
1884 print_device_specific_icvs (GOMP_ICV_MAX_ACTIVE_LEVELS);
1885
1886
1887 fprintf (stderr, " [host] OMP_NUM_TEAMS = '%d'\n",
1888 none->icvs.nteams_var);
1889 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_NTEAMS))
1890 fprintf (stderr, " [all] OMP_NUM_TEAMS = '%d'\n",
1891 all->icvs.nteams_var);
1892 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_NTEAMS))
1893 fprintf (stderr, " [device] OMP_NUM_TEAMS = '%d'\n",
1894 dev->icvs.nteams_var);
1895 print_device_specific_icvs (GOMP_ICV_NTEAMS);
1896
1897 fprintf (stderr, " [host] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1898 none->icvs.teams_thread_limit_var);
1899 if (all != NULL && gomp_get_icv_flag (all->flags,
1900 GOMP_ICV_TEAMS_THREAD_LIMIT))
1901 fprintf (stderr, " [all] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1902 all->icvs.teams_thread_limit_var);
1903 if (dev != NULL && gomp_get_icv_flag (dev->flags,
1904 GOMP_ICV_TEAMS_THREAD_LIMIT))
1905 fprintf (stderr, " [device] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1906 dev->icvs.teams_thread_limit_var);
1907 print_device_specific_icvs (GOMP_ICV_TEAMS_THREAD_LIMIT);
1908
1909 fprintf (stderr, " [all] OMP_CANCELLATION = '%s'\n",
acf0174b 1910 gomp_cancel_var ? "TRUE" : "FALSE");
9f2fca56
MV
1911
1912 fprintf (stderr, " [all] OMP_DEFAULT_DEVICE = '%d'\n",
1913 none->icvs.default_device_var);
1914
1915 fprintf (stderr, " [all] OMP_MAX_TASK_PRIORITY = '%d'\n",
d9a6bd32 1916 gomp_max_task_priority_var);
9f2fca56 1917 fprintf (stderr, " [all] OMP_DISPLAY_AFFINITY = '%s'\n",
28567c40 1918 gomp_display_affinity_var ? "TRUE" : "FALSE");
9f2fca56 1919 fprintf (stderr, " [host] OMP_AFFINITY_FORMAT = '%s'\n",
28567c40 1920 gomp_affinity_format_var);
9f2fca56 1921 fprintf (stderr, " [host] OMP_ALLOCATOR = '");
800bcc8c
JJ
1922 switch (gomp_def_allocator)
1923 {
1924#define C(v) case v: fputs (#v, stderr); break;
1925 C (omp_default_mem_alloc)
1926 C (omp_large_cap_mem_alloc)
1927 C (omp_const_mem_alloc)
1928 C (omp_high_bw_mem_alloc)
1929 C (omp_low_lat_mem_alloc)
1930 C (omp_cgroup_mem_alloc)
1931 C (omp_pteam_mem_alloc)
1932 C (omp_thread_mem_alloc)
1933#undef C
73a0d3bf
TB
1934 /* For an OMP_ALLOCATOR with traits, '' will be output. */
1935 default:
1936 if (gomp_def_allocator_envvar)
1937 fputs (gomp_def_allocator_envvar, stderr);
1938 break;
800bcc8c
JJ
1939 }
1940 fputs ("'\n", stderr);
acf0174b 1941
9f2fca56 1942 fputs (" [all] OMP_TARGET_OFFLOAD = '", stderr);
1bfc07d1
KCY
1943 switch (gomp_target_offload_var)
1944 {
1945 case GOMP_TARGET_OFFLOAD_DEFAULT:
1946 fputs ("DEFAULT", stderr);
1947 break;
1948 case GOMP_TARGET_OFFLOAD_MANDATORY:
1949 fputs ("MANDATORY", stderr);
1950 break;
1951 case GOMP_TARGET_OFFLOAD_DISABLED:
1952 fputs ("DISABLED", stderr);
1953 break;
1954 }
1955 fputs ("'\n", stderr);
1956
acf0174b
JJ
1957 if (verbose)
1958 {
9f2fca56
MV
1959 fputs (" [host] GOMP_CPU_AFFINITY = ''\n", stderr);
1960 fprintf (stderr, " [host] GOMP_STACKSIZE = '%lu'\n", stacksize);
acf0174b 1961#ifdef HAVE_INTTYPES_H
9f2fca56 1962 fprintf (stderr, " [host] GOMP_SPINCOUNT = '%"PRIu64"'\n",
acf0174b
JJ
1963 (uint64_t) gomp_spin_count_var);
1964#else
9f2fca56 1965 fprintf (stderr, " [host] GOMP_SPINCOUNT = '%lu'\n",
acf0174b
JJ
1966 (unsigned long) gomp_spin_count_var);
1967#endif
1968 }
1969
1970 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr);
1971}
7123ae24
UD
1972ialias (omp_display_env)
1973
1974static void
1975handle_omp_display_env (void)
1976{
1977 const char *env;
1978 bool display = false;
1979 bool verbose = false;
1980
1981 env = getenv ("OMP_DISPLAY_ENV");
1982 if (env == NULL)
1983 return;
1984
1985 while (isspace ((unsigned char) *env))
1986 ++env;
1987 if (strncasecmp (env, "true", 4) == 0)
1988 {
1989 display = true;
1990 env += 4;
1991 }
1992 else if (strncasecmp (env, "false", 5) == 0)
1993 {
1994 display = false;
1995 env += 5;
1996 }
1997 else if (strncasecmp (env, "verbose", 7) == 0)
1998 {
1999 display = true;
2000 verbose = true;
2001 env += 7;
2002 }
2003 else
2004 env = "X";
2005 while (isspace ((unsigned char) *env))
2006 ++env;
2007 if (*env != '\0')
2008 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
2009
2010 if (display)
3749c3af 2011 ialias_call (omp_display_env) (verbose);
7123ae24 2012}
acf0174b 2013
9f2fca56
MV
2014/* Helper function for initialize_env. Extracts the device number from
2015 an environment variable name. ENV is the complete environment variable.
2016 DEV_NUM_PTR points to the start of the device number in the environment
2017 variable string. DEV_NUM_LEN is the returned length of the device num
2018 string. */
2019
2020static bool
2021get_device_num (char *env, char *dev_num_ptr, int *dev_num, int *dev_num_len)
2022{
2023 char *end;
2024 unsigned long val = strtoul (dev_num_ptr, &end, 10);
2025 if (val > INT_MAX
2026 || *end != '='
2027 || (dev_num_ptr[0] == '0' && end != dev_num_ptr + 1)
2028 || (dev_num_ptr[0] < '0' || dev_num_ptr[0] > '9'))
2029 {
2030 gomp_error ("Invalid device number in %s", env);
2031 return false;
2032 }
2033 *dev_num = val;
2034 *dev_num_len = end - dev_num_ptr;
2035 return true;
2036}
2037
2038static void
2039get_icv_member_addr (struct gomp_initial_icvs *icvs, int icv_code,
2040 void *icv_addr[3])
2041{
2042 if (icv_code == 0 || icv_addr == NULL)
2043 return;
2044
2045 icv_addr[0] = icv_addr[1] = icv_addr[2] = NULL;
2046
2047 switch (icv_code)
2048 {
2049 case GOMP_ICV_NTEAMS:
2050 icv_addr[0] = &icvs->nteams_var;
e11babbf 2051 /* icv_addr[1] = (void *) false; */
9f2fca56
MV
2052 break;
2053 case GOMP_ICV_DYNAMIC:
2054 icv_addr[0] = &(*icvs).dyn_var;
2055 break;
2056 case GOMP_ICV_TEAMS_THREAD_LIMIT:
2057 icv_addr[0] = &icvs->teams_thread_limit_var;
e11babbf 2058 /* icv_addr[1] = (void *) false; */
9f2fca56
MV
2059 break;
2060 case GOMP_ICV_SCHEDULE:
2061 icv_addr[0] = &icvs->run_sched_var;
2062 icv_addr[1] = &icvs->run_sched_chunk_size;
2063 break;
2064 case GOMP_ICV_THREAD_LIMIT:
2065 icv_addr[0] = &icvs->thread_limit_var;
e11babbf 2066 /* icv_addr[1] = (void *) false; */
9f2fca56
MV
2067 icv_addr[2] = (void *) UINT_MAX;
2068 break;
2069 case GOMP_ICV_NTHREADS:
2070 icv_addr[0] = &icvs->nthreads_var;
2071 icv_addr[1] = &icvs->nthreads_var_list;
2072 icv_addr[2] = &icvs->nthreads_var_list_len;
2073 break;
2074 case GOMP_ICV_MAX_ACTIVE_LEVELS:
2075 icv_addr[0] = &icvs->max_active_levels_var;
2076 icv_addr[1] = (void *) true;
2077 icv_addr[2] = (void *) gomp_supported_active_levels;
2078 break;
2079 case GOMP_ICV_BIND:
2080 icv_addr[0] = &icvs->bind_var;
2081 icv_addr[1] = &icvs->bind_var_list;
2082 icv_addr[2] = &icvs->bind_var_list_len;
2083 break;
2084 case GOMP_ICV_WAIT_POLICY:
2085 icv_addr[0] = &icvs->wait_policy;
2086 break;
2087 case GOMP_ICV_STACKSIZE:
2088 icv_addr[0] = &icvs->stacksize;
2089 break;
2090 case GOMP_ICV_CANCELLATION:
2091 icv_addr[0] = &gomp_cancel_var;
2092 break;
2093 case GOMP_ICV_DISPLAY_AFFINITY:
2094 icv_addr[0] = &gomp_display_affinity_var;
2095 break;
2096 case GOMP_ICV_TARGET_OFFLOAD:
2097 icv_addr[0] = &gomp_target_offload_var;
2098 break;
2099 case GOMP_ICV_MAX_TASK_PRIORITY:
2100 icv_addr[0] = &gomp_max_task_priority_var;
2101 break;
2102 case GOMP_ICV_ALLOCATOR:
2103 icv_addr[0] = &gomp_def_allocator;
2104 break;
2105 case GOMP_ICV_DEFAULT_DEVICE:
2106 icv_addr[0] = &icvs->default_device_var;
2107 icv_addr[1] = (void *) true;
2108 break;
2109 }
2110}
2111
2112struct gomp_icv_list *
2113gomp_get_initial_icv_item (int dev_num)
2114{
2115 struct gomp_icv_list *l = gomp_initial_icv_list;
2116 while (l != NULL && l->device_num != dev_num)
2117 l = l->next;
2118
2119 return l;
2120}
2121
2122static void
2123initialize_icvs (struct gomp_initial_icvs *icvs)
2124{
2125 icvs->nthreads_var_list = NULL;
2126 icvs->bind_var_list = NULL;
2127 icvs->nthreads_var = gomp_default_icv_values.nthreads_var;
2128 icvs->nthreads_var_list_len = 0;
2129 icvs->bind_var_list_len = 0;
2130 icvs->stacksize = 0;
2131 icvs->thread_limit_var = gomp_default_icv_values.thread_limit_var;
2132 icvs->run_sched_var = gomp_default_icv_values.run_sched_var;
2133 icvs->run_sched_chunk_size = gomp_default_icv_values.run_sched_chunk_size;
2134 icvs->default_device_var = gomp_default_icv_values.default_device_var;
2135 icvs->dyn_var = gomp_default_icv_values.dyn_var;
2136 icvs->max_active_levels_var = gomp_default_icv_values.max_active_levels_var;
2137 icvs->bind_var = gomp_default_icv_values.bind_var;
2138 icvs->nteams_var = gomp_default_icv_values.nteams_var;
2139 icvs->teams_thread_limit_var = gomp_default_icv_values.teams_thread_limit_var;
288bc7b5 2140 icvs->wait_policy = -1;
9f2fca56
MV
2141}
2142
2143/* Helper function for initialize_env to add a device specific ICV value
2144 to gomp_initial_icv_list. */
2145
2146static uint32_t *
2147add_initial_icv_to_list (int dev_num, int icv_code, void *icv_addr[3])
2148{
2149 struct gomp_icv_list *last = NULL, *l = gomp_initial_icv_list;
2150 while (l != NULL && l->device_num != dev_num)
2151 {
2152 last = l;
2153 l = l->next;
2154 }
2155
2156 if (l == NULL)
2157 {
2158 l = ((struct gomp_icv_list *)
2159 gomp_malloc_cleared (sizeof (struct gomp_icv_list)));
2160 l->device_num = dev_num;
2161 initialize_icvs (&l->icvs);
2162 if (dev_num < 0)
2163 {
2164 l->next = gomp_initial_icv_list;
2165 gomp_initial_icv_list = l;
2166 }
2167 else
2168 {
2169 l->next = NULL;
2170 if (last == NULL)
2171 gomp_initial_icv_list = l;
2172 else
2173 last->next = l;
2174 }
2175 }
2176
2177 get_icv_member_addr (&l->icvs, icv_code, icv_addr);
2178
2179 return &l->flags;
2180}
2181
2182/* Return true if STR string starts with PREFIX. */
2183
2184static inline bool
2185startswith (const char *str, const char *prefix)
2186{
2187 return strncmp (str, prefix, strlen (prefix)) == 0;
2188}
acf0174b 2189
73a0d3bf
TB
2190static void __attribute__((destructor))
2191cleanup_env (void)
2192{
2193 if (gomp_def_allocator_envvar != NULL)
2194 {
2195 free (gomp_def_allocator_envvar);
2196 omp_destroy_allocator (gomp_def_allocator);
2197 }
2198}
2199
953ff289
DN
2200static void __attribute__((constructor))
2201initialize_env (void)
2202{
9f2fca56
MV
2203 char **env;
2204 int omp_var, dev_num = 0, dev_num_len = 0, i;
2205 bool ignore = false;
2206 char *env_val;
2207 void *params[3];
2208 uint32_t *flag_var_addr = NULL;
2209 unsigned pos;
2210 struct gomp_icv_list *all, *none;
d0d1b24d 2211
953ff289
DN
2212 /* Do a compile time check that mkomp_h.pl did good job. */
2213 omp_check_defines ();
2214
a68ab351 2215#ifndef HAVE_SYNC_BUILTINS
acf0174b 2216 gomp_mutex_init (&gomp_managed_threads_lock);
a68ab351 2217#endif
a68ab351
JJ
2218 gomp_init_num_threads ();
2219 gomp_available_cpus = gomp_global_icv.nthreads_var;
9f2fca56
MV
2220
2221 /* Initial values for host environment variables should always exist even if
2222 there is no explicitly set host environment variable. Moreover, they are
2223 set to the initial global values. */
2224 add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX, 0, NULL);
2225 none = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX);
2226 initialize_icvs (&none->icvs);
2227
15345980
JJ
2228 if (environ)
2229 for (env = environ; *env != 0; env++)
2230 {
2231 if (!startswith (*env, "OMP_"))
2232 continue;
9f2fca56 2233
15345980
JJ
2234 /* Name of the environment variable without suffix "OMP_". */
2235 char *name = *env + sizeof ("OMP_") - 1;
2236 for (omp_var = 0; omp_var < OMP_VAR_CNT; omp_var++)
2237 {
2238 if (startswith (name, envvars[omp_var].name))
2239 {
2240 pos = envvars[omp_var].name_len;
2241 if (name[pos] == '=')
2242 {
2243 pos++;
2244 flag_var_addr
2245 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX,
2246 envvars[omp_var].flag_vars[0],
2247 params);
2248 }
2249 else if (startswith (&name[pos], "_DEV=")
2250 && envvars[omp_var].flag & GOMP_ENV_SUFFIX_DEV)
2251 {
2252 pos += 5;
2253 flag_var_addr
2254 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_DEV,
2255 envvars[omp_var].flag_vars[0],
2256 params);
2257 }
2258 else if (startswith (&name[pos], "_ALL=")
2259 && envvars[omp_var].flag & GOMP_ENV_SUFFIX_ALL)
2260 {
2261 pos += 5;
2262 flag_var_addr
2263 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_ALL,
2264 envvars[omp_var].flag_vars[0],
2265 params);
2266 }
2267 else if (startswith (&name[pos], "_DEV_")
2268 && envvars[omp_var].flag & GOMP_ENV_SUFFIX_DEV_X)
2269 {
2270 pos += 5;
2271 if (!get_device_num (*env, &name[pos], &dev_num,
2272 &dev_num_len))
9f2fca56 2273 break;
9f2fca56 2274
15345980
JJ
2275 pos += dev_num_len + 1;
2276 flag_var_addr
2277 = add_initial_icv_to_list (dev_num,
2278 envvars[omp_var].flag_vars[0],
2279 params);
2280 }
2281 else
2282 {
2283 gomp_error ("Invalid environment variable in %s", *env);
2284 break;
2285 }
2286 env_val = &name[pos];
9f2fca56 2287
15345980
JJ
2288 if (envvars[omp_var].parse_func (*env, env_val, params))
2289 {
2290 for (i = 0; i < 3; ++i)
2291 if (envvars[omp_var].flag_vars[i])
2292 gomp_set_icv_flag (flag_var_addr,
2293 envvars[omp_var].flag_vars[i]);
2294 else
2295 break;
2296 }
9f2fca56 2297
15345980
JJ
2298 break;
2299 }
9f2fca56
MV
2300 }
2301 }
2302
15345980
JJ
2303 all = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_ALL);
2304 for (omp_var = 0; omp_var < OMP_HOST_VAR_CNT; omp_var++)
2305 {
2306 if (none != NULL
2307 && gomp_get_icv_flag (none->flags, host_envvars[omp_var].flag_var))
2308 get_icv_member_addr (&none->icvs,
2309 host_envvars[omp_var].flag_var, params);
2310 else if (all != NULL
2311 && gomp_get_icv_flag (all->flags,
2312 host_envvars[omp_var].flag_var))
2313 get_icv_member_addr (&all->icvs, host_envvars[omp_var].flag_var,
2314 params);
2315 else
2316 continue;
2317
2318 switch (host_envvars[omp_var].type_code)
2319 {
2320 case PARSE_INT:
2321 for (i = 0; i < 3; ++i)
2322 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2323 *(int *) (host_envvars[omp_var].dest[i]) = *(int *) params[i];
2324 break;
2325 case PARSE_BOOL:
2326 for (i = 0; i < 3; ++i)
2327 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2328 *(bool *) (host_envvars[omp_var].dest[i]) = *(bool *) params[i];
2329 break;
2330 case PARSE_UINT:
2331 for (i = 0; i < 3; ++i)
2332 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2333 *(unsigned int *) (host_envvars[omp_var].dest[i])
2334 = *(unsigned int *) params[i];
2335 break;
2336 case PARSE_ULONG:
2337 for (i = 0; i < 3; ++i)
2338 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2339 *(unsigned long *) (host_envvars[omp_var].dest[i])
2340 = *(unsigned long *) params[i];
2341 break;
2342 case PARSE_UCHAR:
2343 for (i = 0; i < 3; ++i)
2344 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2345 *(unsigned char *) (host_envvars[omp_var].dest[i])
2346 = *(unsigned char *) params[i];
2347 break;
2348 case PARSE_SCHEDULE:
2349 *(enum gomp_schedule_type *) (host_envvars[omp_var].dest[0])
2350 = *(enum gomp_schedule_type *) params[0];
2351 *(int *) (host_envvars[omp_var].dest[1]) = *(int *) params[1];
2352 break;
2353 case PARSE_BIND:
2354 *(char *) (host_envvars[omp_var].dest[0]) = *(char *) params[0];
2355 *(char **) (host_envvars[omp_var].dest[1]) = *(char **) params[1];
2356 *(unsigned long *) (host_envvars[omp_var].dest[2])
2357 = *(unsigned long *) params[2];
2358 break;
2359 }
2360 }
2361
9f2fca56
MV
2362 if (((none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_BIND))
2363 || (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_BIND)))
f89163fd
JJ
2364 && gomp_global_icv.bind_var == omp_proc_bind_false)
2365 ignore = true;
9f2fca56
MV
2366
2367 if (!((none != NULL
2368 && gomp_get_icv_flag (none->flags, GOMP_ICV_MAX_ACTIVE_LEVELS))
2369 || (all != NULL
2370 && gomp_get_icv_flag (all->flags, GOMP_ICV_MAX_ACTIVE_LEVELS))))
6fae7eda
KCY
2371 {
2372 bool nested = true;
9f2fca56 2373 const char *env = getenv ("OMP_NESTED");
6fae7eda
KCY
2374
2375 /* OMP_NESTED is deprecated in OpenMP 5.0. */
9f2fca56 2376 if (parse_boolean ("OMP_NESTED", env, (void *[]) {&nested}))
6fae7eda
KCY
2377 gomp_global_icv.max_active_levels_var
2378 = nested ? gomp_supported_active_levels : 1;
2379 else if (gomp_nthreads_var_list_len > 1 || gomp_bind_var_list_len > 1)
2380 gomp_global_icv.max_active_levels_var = gomp_supported_active_levels;
2381 }
9f2fca56 2382
18c8b56c
TB
2383 if (gomp_global_icv.default_device_var == INT_MIN
2384 && gomp_target_offload_var != GOMP_TARGET_OFFLOAD_MANDATORY)
2385 none->icvs.default_device_var = gomp_global_icv.default_device_var = 0;
2386
9f2fca56
MV
2387 /* Process GOMP_* variables and dependencies between parsed ICVs. */
2388 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var, true);
2389
f89163fd
JJ
2390 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
2391 parsed if present in the environment. If OMP_PROC_BIND was set
93d90219 2392 explicitly to false, don't populate places list though. If places
f89163fd
JJ
2393 list was successfully set from OMP_PLACES, only parse but don't process
2394 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
2395 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
2396 was successfully parsed into a places list, otherwise to
2397 OMP_PROC_BIND=false. */
2398 if (parse_places_var ("OMP_PLACES", ignore))
2399 {
2400 if (gomp_global_icv.bind_var == omp_proc_bind_false)
2401 gomp_global_icv.bind_var = true;
2402 ignore = true;
2403 }
2404 if (parse_affinity (ignore))
2405 {
2406 if (gomp_global_icv.bind_var == omp_proc_bind_false)
2407 gomp_global_icv.bind_var = true;
2408 ignore = true;
2409 }
2410 if (gomp_global_icv.bind_var != omp_proc_bind_false)
a0884cf0 2411 gomp_init_affinity ();
28567c40
JJ
2412
2413 {
2414 const char *env = getenv ("OMP_AFFINITY_FORMAT");
2415 if (env != NULL)
2416 gomp_set_affinity_format (env, strlen (env));
2417 }
2418
9f2fca56
MV
2419 if (none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_WAIT_POLICY))
2420 wait_policy = none->icvs.wait_policy;
2421 else if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_WAIT_POLICY))
2422 wait_policy = all->icvs.wait_policy;
2423
a68ab351
JJ
2424 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
2425 {
2426 /* Using a rough estimation of 100000 spins per msec,
2427 use 5 min blocking for OMP_WAIT_POLICY=active,
4c698cf8 2428 3 msec blocking when OMP_WAIT_POLICY is not specificed
a68ab351
JJ
2429 and 0 when OMP_WAIT_POLICY=passive.
2430 Depending on the CPU speed, this can be e.g. 5 times longer
2431 or 5 times shorter. */
2432 if (wait_policy > 0)
2433 gomp_spin_count_var = 30000000000LL;
2434 else if (wait_policy < 0)
e1e127de
ZJ
2435 {
2436 gomp_spin_count_var = 300000LL;
2437 do_adjust_default_spincount ();
2438 }
a68ab351
JJ
2439 }
2440 /* gomp_throttled_spin_count_var is used when there are more libgomp
2441 managed threads than available CPUs. Use very short spinning. */
2442 if (wait_policy > 0)
2443 gomp_throttled_spin_count_var = 1000LL;
2444 else if (wait_policy < 0)
2445 gomp_throttled_spin_count_var = 100LL;
2446 if (gomp_throttled_spin_count_var > gomp_spin_count_var)
2447 gomp_throttled_spin_count_var = gomp_spin_count_var;
d0d1b24d
RH
2448
2449 /* Not strictly environment related, but ordering constructors is tricky. */
2450 pthread_attr_init (&gomp_thread_attr);
d0d1b24d 2451
9f2fca56
MV
2452 if (!(none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_STACKSIZE)))
2453 {
2454 const char *env = getenv ("GOMP_STACKSIZE");
2455 if (env != NULL
2456 && parse_stacksize ("GOMP_STACKSIZE", env,
2457 (void *[3]) {&none->icvs.stacksize}))
2458 gomp_set_icv_flag (&none->flags, GOMP_ICV_STACKSIZE);
2459 }
2460 if (none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_STACKSIZE))
2461 stacksize = none->icvs.stacksize;
2462 else if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_STACKSIZE))
2463 stacksize = all->icvs.stacksize;
2464
2465 if ((none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_STACKSIZE))
2466 || (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_STACKSIZE))
c4060df4 2467 || GOMP_DEFAULT_STACKSIZE)
d0d1b24d 2468 {
c3b11a40
RH
2469 int err;
2470
c3b11a40
RH
2471 err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
2472
2473#ifdef PTHREAD_STACK_MIN
2474 if (err == EINVAL)
d0d1b24d 2475 {
c3b11a40
RH
2476 if (stacksize < PTHREAD_STACK_MIN)
2477 gomp_error ("Stack size less than minimum of %luk",
2478 PTHREAD_STACK_MIN / 1024ul
2479 + (PTHREAD_STACK_MIN % 1024 != 0));
2480 else
d0d1b24d 2481 gomp_error ("Stack size larger than system limit");
d0d1b24d 2482 }
c3b11a40
RH
2483 else
2484#endif
2485 if (err != 0)
2486 gomp_error ("Stack size change failed: %s", strerror (err));
d0d1b24d 2487 }
acf0174b 2488
7123ae24 2489 handle_omp_display_env ();
41dbbb37
TS
2490
2491 /* OpenACC. */
2492
9f2fca56
MV
2493 if (!parse_int ("ACC_DEVICE_NUM", getenv ("ACC_DEVICE_NUM"),
2494 (void *[]) {&goacc_device_num, (void *) true}))
41dbbb37
TS
2495 goacc_device_num = 0;
2496
2497 parse_acc_device_type ();
ec00d3fa 2498 parse_gomp_openacc_dim ();
41dbbb37
TS
2499
2500 goacc_runtime_initialize ();
5fae049d
TS
2501
2502 goacc_profiling_initialize ();
953ff289 2503}
630e3c3a 2504#endif /* LIBGOMP_OFFLOADED_ONLY */