]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgomp/env.c
openmp: Fix up handling of OMP_PLACES=threads(1)
[thirdparty/gcc.git] / libgomp / env.c
CommitLineData
99dee823 1/* Copyright (C) 2005-2021 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
TV
62#include "secure_getenv.h"
63
630e3c3a
AM
64struct gomp_task_icv gomp_global_icv = {
65 .nthreads_var = 1,
66 .thread_limit_var = UINT_MAX,
67 .run_sched_var = GFS_DYNAMIC,
68 .run_sched_chunk_size = 1,
69 .default_device_var = 0,
70 .dyn_var = false,
6fae7eda 71 .max_active_levels_var = 1,
630e3c3a
AM
72 .bind_var = omp_proc_bind_false,
73 .target_data = NULL
74};
75
630e3c3a 76bool gomp_cancel_var = false;
1bfc07d1
KCY
77enum gomp_target_offload_t gomp_target_offload_var
78 = GOMP_TARGET_OFFLOAD_DEFAULT;
630e3c3a
AM
79int gomp_max_task_priority_var = 0;
80#ifndef HAVE_SYNC_BUILTINS
81gomp_mutex_t gomp_managed_threads_lock;
82#endif
83unsigned long gomp_available_cpus = 1, gomp_managed_threads = 1;
84unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
85unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len;
86char *gomp_bind_var_list;
87unsigned long gomp_bind_var_list_len;
88void **gomp_places_list;
89unsigned long gomp_places_list_len;
800bcc8c 90uintptr_t gomp_def_allocator = omp_default_mem_alloc;
630e3c3a
AM
91int gomp_debug_var;
92unsigned int gomp_num_teams_var;
07dd3bcd
JJ
93int gomp_nteams_var;
94int gomp_teams_thread_limit_var;
28567c40
JJ
95bool gomp_display_affinity_var;
96char *gomp_affinity_format_var = "level %L thread %i affinity %A";
97size_t gomp_affinity_format_len;
630e3c3a
AM
98char *goacc_device_type;
99int goacc_device_num;
ec00d3fa 100int goacc_default_dims[GOMP_DIM_MAX];
630e3c3a
AM
101
102#ifndef LIBGOMP_OFFLOADED_ONLY
953ff289 103
7123ae24
UD
104static int wait_policy;
105static unsigned long stacksize = GOMP_DEFAULT_STACKSIZE;
106
953ff289
DN
107/* Parse the OMP_SCHEDULE environment variable. */
108
109static void
110parse_schedule (void)
111{
112 char *env, *end;
6acf0b38 113 unsigned long value;
28567c40 114 int monotonic = 0;
953ff289
DN
115
116 env = getenv ("OMP_SCHEDULE");
117 if (env == NULL)
118 return;
119
89b3e3cd
JJ
120 while (isspace ((unsigned char) *env))
121 ++env;
28567c40
JJ
122 if (strncasecmp (env, "monotonic", 9) == 0)
123 {
124 monotonic = 1;
125 env += 9;
126 }
127 else if (strncasecmp (env, "nonmonotonic", 12) == 0)
128 {
129 monotonic = -1;
130 env += 12;
131 }
132 if (monotonic)
133 {
134 while (isspace ((unsigned char) *env))
135 ++env;
136 if (*env != ':')
137 goto unknown;
138 ++env;
139 while (isspace ((unsigned char) *env))
140 ++env;
141 }
89b3e3cd 142 if (strncasecmp (env, "static", 6) == 0)
953ff289 143 {
a68ab351 144 gomp_global_icv.run_sched_var = GFS_STATIC;
953ff289
DN
145 env += 6;
146 }
89b3e3cd 147 else if (strncasecmp (env, "dynamic", 7) == 0)
953ff289 148 {
a68ab351 149 gomp_global_icv.run_sched_var = GFS_DYNAMIC;
953ff289
DN
150 env += 7;
151 }
89b3e3cd 152 else if (strncasecmp (env, "guided", 6) == 0)
953ff289 153 {
a68ab351 154 gomp_global_icv.run_sched_var = GFS_GUIDED;
953ff289
DN
155 env += 6;
156 }
a68ab351
JJ
157 else if (strncasecmp (env, "auto", 4) == 0)
158 {
159 gomp_global_icv.run_sched_var = GFS_AUTO;
160 env += 4;
161 }
953ff289
DN
162 else
163 goto unknown;
164
28567c40
JJ
165 if (monotonic == 1
166 || (monotonic == 0 && gomp_global_icv.run_sched_var == GFS_STATIC))
167 gomp_global_icv.run_sched_var |= GFS_MONOTONIC;
168
89b3e3cd
JJ
169 while (isspace ((unsigned char) *env))
170 ++env;
953ff289 171 if (*env == '\0')
fb79f500 172 {
d9a6bd32 173 gomp_global_icv.run_sched_chunk_size
28567c40 174 = (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC;
fb79f500
JJ
175 return;
176 }
89b3e3cd 177 if (*env++ != ',')
953ff289 178 goto unknown;
89b3e3cd
JJ
179 while (isspace ((unsigned char) *env))
180 ++env;
953ff289 181 if (*env == '\0')
953ff289
DN
182 goto invalid;
183
6acf0b38
UB
184 errno = 0;
185 value = strtoul (env, &end, 10);
186 if (errno)
187 goto invalid;
188
89b3e3cd
JJ
189 while (isspace ((unsigned char) *end))
190 ++end;
953ff289
DN
191 if (*end != '\0')
192 goto invalid;
6acf0b38 193
a68ab351
JJ
194 if ((int)value != value)
195 goto invalid;
196
28567c40
JJ
197 if (value == 0
198 && (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC)
fb79f500 199 value = 1;
d9a6bd32 200 gomp_global_icv.run_sched_chunk_size = value;
953ff289
DN
201 return;
202
203 unknown:
204 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
205 return;
206
207 invalid:
208 gomp_error ("Invalid value for chunk size in "
209 "environment variable OMP_SCHEDULE");
953ff289
DN
210 return;
211}
212
a68ab351 213/* Parse an unsigned long environment variable. Return true if one was
22f1a037
TV
214 present and it was successfully parsed. If SECURE, use secure_getenv to the
215 environment variable. */
953ff289
DN
216
217static bool
22f1a037
TV
218parse_unsigned_long_1 (const char *name, unsigned long *pvalue, bool allow_zero,
219 bool secure)
953ff289
DN
220{
221 char *env, *end;
d0d1b24d 222 unsigned long value;
953ff289 223
22f1a037 224 env = (secure ? secure_getenv (name) : getenv (name));
953ff289
DN
225 if (env == NULL)
226 return false;
227
89b3e3cd
JJ
228 while (isspace ((unsigned char) *env))
229 ++env;
953ff289
DN
230 if (*env == '\0')
231 goto invalid;
232
6acf0b38 233 errno = 0;
d0d1b24d 234 value = strtoul (env, &end, 10);
80f046cc 235 if (errno || (long) value <= 0 - allow_zero)
6acf0b38
UB
236 goto invalid;
237
89b3e3cd
JJ
238 while (isspace ((unsigned char) *end))
239 ++end;
953ff289
DN
240 if (*end != '\0')
241 goto invalid;
d0d1b24d
RH
242
243 *pvalue = value;
953ff289
DN
244 return true;
245
246 invalid:
d0d1b24d 247 gomp_error ("Invalid value for environment variable %s", name);
953ff289
DN
248 return false;
249}
250
22f1a037
TV
251/* As parse_unsigned_long_1, but always use getenv. */
252
253static bool
254parse_unsigned_long (const char *name, unsigned long *pvalue, bool allow_zero)
255{
256 return parse_unsigned_long_1 (name, pvalue, allow_zero, false);
257}
258
acf0174b 259/* Parse a positive int environment variable. Return true if one was
22f1a037
TV
260 present and it was successfully parsed. If SECURE, use secure_getenv to the
261 environment variable. */
acf0174b
JJ
262
263static bool
22f1a037 264parse_int_1 (const char *name, int *pvalue, bool allow_zero, bool secure)
acf0174b
JJ
265{
266 unsigned long value;
22f1a037 267 if (!parse_unsigned_long_1 (name, &value, allow_zero, secure))
acf0174b
JJ
268 return false;
269 if (value > INT_MAX)
270 {
271 gomp_error ("Invalid value for environment variable %s", name);
272 return false;
273 }
274 *pvalue = (int) value;
275 return true;
276}
277
22f1a037
TV
278/* As parse_int_1, but use getenv. */
279
280static bool
281parse_int (const char *name, int *pvalue, bool allow_zero)
282{
283 return parse_int_1 (name, pvalue, allow_zero, false);
284}
285
286/* As parse_int_1, but use getenv_secure. */
287
288static bool
289parse_int_secure (const char *name, int *pvalue, bool allow_zero)
290{
291 return parse_int_1 (name, pvalue, allow_zero, true);
292}
293
20906c66
JJ
294/* Parse an unsigned long list environment variable. Return true if one was
295 present and it was successfully parsed. */
296
297static bool
298parse_unsigned_long_list (const char *name, unsigned long *p1stvalue,
299 unsigned long **pvalues,
300 unsigned long *pnvalues)
301{
302 char *env, *end;
303 unsigned long value, *values = NULL;
304
305 env = getenv (name);
306 if (env == NULL)
307 return false;
308
309 while (isspace ((unsigned char) *env))
310 ++env;
311 if (*env == '\0')
312 goto invalid;
313
314 errno = 0;
315 value = strtoul (env, &end, 10);
316 if (errno || (long) value <= 0)
317 goto invalid;
318
319 while (isspace ((unsigned char) *end))
320 ++end;
321 if (*end != '\0')
322 {
323 if (*end == ',')
324 {
325 unsigned long nvalues = 0, nalloced = 0;
326
327 do
328 {
329 env = end + 1;
330 if (nvalues == nalloced)
331 {
332 unsigned long *n;
333 nalloced = nalloced ? nalloced * 2 : 16;
334 n = realloc (values, nalloced * sizeof (unsigned long));
335 if (n == NULL)
336 {
337 free (values);
338 gomp_error ("Out of memory while trying to parse"
339 " environment variable %s", name);
340 return false;
341 }
342 values = n;
343 if (nvalues == 0)
344 values[nvalues++] = value;
345 }
346
347 while (isspace ((unsigned char) *env))
348 ++env;
349 if (*env == '\0')
350 goto invalid;
351
352 errno = 0;
353 value = strtoul (env, &end, 10);
354 if (errno || (long) value <= 0)
355 goto invalid;
356
357 values[nvalues++] = value;
358 while (isspace ((unsigned char) *end))
359 ++end;
360 if (*end == '\0')
361 break;
362 if (*end != ',')
363 goto invalid;
364 }
365 while (1);
366 *p1stvalue = values[0];
367 *pvalues = values;
368 *pnvalues = nvalues;
369 return true;
370 }
371 goto invalid;
372 }
373
374 *p1stvalue = value;
375 return true;
376
377 invalid:
378 free (values);
379 gomp_error ("Invalid value for environment variable %s", name);
380 return false;
381}
382
1bfc07d1
KCY
383static void
384parse_target_offload (const char *name, enum gomp_target_offload_t *offload)
385{
386 const char *env;
121a8812 387 int new_offload = -1;
1bfc07d1
KCY
388
389 env = getenv (name);
390 if (env == NULL)
391 return;
392
393 while (isspace ((unsigned char) *env))
394 ++env;
395 if (strncasecmp (env, "default", 7) == 0)
396 {
397 env += 7;
1bfc07d1
KCY
398 new_offload = GOMP_TARGET_OFFLOAD_DEFAULT;
399 }
400 else if (strncasecmp (env, "mandatory", 9) == 0)
401 {
402 env += 9;
1bfc07d1
KCY
403 new_offload = GOMP_TARGET_OFFLOAD_MANDATORY;
404 }
405 else if (strncasecmp (env, "disabled", 8) == 0)
406 {
407 env += 8;
1bfc07d1
KCY
408 new_offload = GOMP_TARGET_OFFLOAD_DISABLED;
409 }
410 while (isspace ((unsigned char) *env))
411 ++env;
121a8812 412 if (new_offload != -1 && *env == '\0')
1bfc07d1
KCY
413 {
414 *offload = new_offload;
415 return;
416 }
417
418 gomp_error ("Invalid value for environment variable OMP_TARGET_OFFLOAD");
419}
420
acf0174b
JJ
421/* Parse environment variable set to a boolean or list of omp_proc_bind_t
422 enum values. Return true if one was present and it was successfully
423 parsed. */
424
425static bool
426parse_bind_var (const char *name, char *p1stvalue,
427 char **pvalues, unsigned long *pnvalues)
428{
429 char *env;
c8673881 430 char value = omp_proc_bind_false, *values = NULL;
acf0174b
JJ
431 int i;
432 static struct proc_bind_kinds
433 {
434 const char name[7];
435 const char len;
436 omp_proc_bind_t kind;
437 } kinds[] =
438 {
439 { "false", 5, omp_proc_bind_false },
440 { "true", 4, omp_proc_bind_true },
441 { "master", 6, omp_proc_bind_master },
432de084 442 { "primary", 7, omp_proc_bind_primary },
acf0174b
JJ
443 { "close", 5, omp_proc_bind_close },
444 { "spread", 6, omp_proc_bind_spread }
445 };
446
447 env = getenv (name);
448 if (env == NULL)
449 return false;
450
451 while (isspace ((unsigned char) *env))
452 ++env;
453 if (*env == '\0')
454 goto invalid;
455
432de084 456 for (i = 0; i < 6; i++)
acf0174b
JJ
457 if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
458 {
459 value = kinds[i].kind;
460 env += kinds[i].len;
461 break;
462 }
432de084 463 if (i == 6)
acf0174b
JJ
464 goto invalid;
465
466 while (isspace ((unsigned char) *env))
467 ++env;
468 if (*env != '\0')
469 {
470 if (*env == ',')
471 {
472 unsigned long nvalues = 0, nalloced = 0;
473
474 if (value == omp_proc_bind_false
475 || value == omp_proc_bind_true)
476 goto invalid;
477
478 do
479 {
480 env++;
481 if (nvalues == nalloced)
482 {
483 char *n;
484 nalloced = nalloced ? nalloced * 2 : 16;
485 n = realloc (values, nalloced);
486 if (n == NULL)
487 {
488 free (values);
489 gomp_error ("Out of memory while trying to parse"
490 " environment variable %s", name);
491 return false;
492 }
493 values = n;
494 if (nvalues == 0)
495 values[nvalues++] = value;
496 }
497
498 while (isspace ((unsigned char) *env))
499 ++env;
500 if (*env == '\0')
501 goto invalid;
502
432de084 503 for (i = 2; i < 6; i++)
acf0174b
JJ
504 if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
505 {
506 value = kinds[i].kind;
507 env += kinds[i].len;
508 break;
509 }
432de084 510 if (i == 6)
acf0174b
JJ
511 goto invalid;
512
513 values[nvalues++] = value;
514 while (isspace ((unsigned char) *env))
515 ++env;
516 if (*env == '\0')
517 break;
518 if (*env != ',')
519 goto invalid;
520 }
521 while (1);
522 *p1stvalue = values[0];
523 *pvalues = values;
524 *pnvalues = nvalues;
525 return true;
526 }
527 goto invalid;
528 }
529
530 *p1stvalue = value;
531 return true;
532
533 invalid:
534 free (values);
535 gomp_error ("Invalid value for environment variable %s", name);
536 return false;
537}
538
539static bool
540parse_one_place (char **envp, bool *negatep, unsigned long *lenp,
541 long *stridep)
542{
543 char *env = *envp, *start;
544 void *p = gomp_places_list ? gomp_places_list[gomp_places_list_len] : NULL;
545 unsigned long len = 1;
546 long stride = 1;
547 int pass;
548 bool any_negate = false;
549 *negatep = false;
550 while (isspace ((unsigned char) *env))
551 ++env;
552 if (*env == '!')
553 {
554 *negatep = true;
555 ++env;
556 while (isspace ((unsigned char) *env))
557 ++env;
558 }
559 if (*env != '{')
560 return false;
561 ++env;
562 while (isspace ((unsigned char) *env))
563 ++env;
564 start = env;
565 for (pass = 0; pass < (any_negate ? 2 : 1); pass++)
566 {
567 env = start;
568 do
569 {
570 unsigned long this_num, this_len = 1;
571 long this_stride = 1;
572 bool this_negate = (*env == '!');
573 if (this_negate)
574 {
575 if (gomp_places_list)
576 any_negate = true;
577 ++env;
578 while (isspace ((unsigned char) *env))
579 ++env;
580 }
581
582 errno = 0;
583 this_num = strtoul (env, &env, 10);
584 if (errno)
585 return false;
586 while (isspace ((unsigned char) *env))
587 ++env;
588 if (*env == ':')
589 {
590 ++env;
591 while (isspace ((unsigned char) *env))
592 ++env;
593 errno = 0;
594 this_len = strtoul (env, &env, 10);
595 if (errno || this_len == 0)
596 return false;
597 while (isspace ((unsigned char) *env))
598 ++env;
599 if (*env == ':')
600 {
601 ++env;
602 while (isspace ((unsigned char) *env))
603 ++env;
604 errno = 0;
605 this_stride = strtol (env, &env, 10);
606 if (errno)
607 return false;
608 while (isspace ((unsigned char) *env))
609 ++env;
610 }
611 }
612 if (this_negate && this_len != 1)
613 return false;
614 if (gomp_places_list && pass == this_negate)
615 {
616 if (this_negate)
617 {
618 if (!gomp_affinity_remove_cpu (p, this_num))
619 return false;
620 }
621 else if (!gomp_affinity_add_cpus (p, this_num, this_len,
622 this_stride, false))
623 return false;
624 }
625 if (*env == '}')
626 break;
627 if (*env != ',')
628 return false;
629 ++env;
630 }
631 while (1);
632 }
633
634 ++env;
635 while (isspace ((unsigned char) *env))
636 ++env;
637 if (*env == ':')
638 {
639 ++env;
640 while (isspace ((unsigned char) *env))
641 ++env;
642 errno = 0;
643 len = strtoul (env, &env, 10);
644 if (errno || len == 0 || len >= 65536)
645 return false;
646 while (isspace ((unsigned char) *env))
647 ++env;
648 if (*env == ':')
649 {
650 ++env;
651 while (isspace ((unsigned char) *env))
652 ++env;
653 errno = 0;
654 stride = strtol (env, &env, 10);
655 if (errno)
656 return false;
657 while (isspace ((unsigned char) *env))
658 ++env;
659 }
660 }
661 if (*negatep && len != 1)
662 return false;
663 *envp = env;
664 *lenp = len;
665 *stridep = stride;
666 return true;
667}
668
669static bool
f89163fd 670parse_places_var (const char *name, bool ignore)
acf0174b
JJ
671{
672 char *env = getenv (name), *end;
673 bool any_negate = false;
674 int level = 0;
675 unsigned long count = 0;
676 if (env == NULL)
677 return false;
678
679 while (isspace ((unsigned char) *env))
680 ++env;
681 if (*env == '\0')
682 goto invalid;
683
684 if (strncasecmp (env, "threads", 7) == 0)
685 {
686 env += 7;
687 level = 1;
688 }
689 else if (strncasecmp (env, "cores", 5) == 0)
690 {
691 env += 5;
692 level = 2;
693 }
694 else if (strncasecmp (env, "sockets", 7) == 0)
695 {
696 env += 7;
697 level = 3;
698 }
5809be05
JJ
699 else if (strncasecmp (env, "ll_caches", 9) == 0)
700 {
701 env += 9;
702 level = 4;
703 }
e7ce32c7
JJ
704 else if (strncasecmp (env, "numa_domains", 12) == 0)
705 {
706 env += 12;
707 level = 5;
708 }
acf0174b
JJ
709 if (level)
710 {
711 count = ULONG_MAX;
712 while (isspace ((unsigned char) *env))
713 ++env;
714 if (*env != '\0')
715 {
716 if (*env++ != '(')
717 goto invalid;
718 while (isspace ((unsigned char) *env))
719 ++env;
720
721 errno = 0;
722 count = strtoul (env, &end, 10);
723 if (errno)
724 goto invalid;
725 env = end;
726 while (isspace ((unsigned char) *env))
727 ++env;
728 if (*env != ')')
729 goto invalid;
730 ++env;
731 while (isspace ((unsigned char) *env))
732 ++env;
733 if (*env != '\0')
734 goto invalid;
735 }
f89163fd
JJ
736
737 if (ignore)
738 return false;
739
acf0174b
JJ
740 return gomp_affinity_init_level (level, count, false);
741 }
742
743 count = 0;
744 end = env;
745 do
746 {
747 bool negate;
748 unsigned long len;
749 long stride;
750 if (!parse_one_place (&end, &negate, &len, &stride))
751 goto invalid;
752 if (negate)
753 {
754 if (!any_negate)
755 count++;
756 any_negate = true;
757 }
758 else
759 count += len;
760 if (count > 65536)
761 goto invalid;
762 if (*end == '\0')
763 break;
764 if (*end != ',')
765 goto invalid;
766 end++;
767 }
768 while (1);
769
f89163fd 770 if (ignore)
acf0174b
JJ
771 return false;
772
773 gomp_places_list_len = 0;
774 gomp_places_list = gomp_affinity_alloc (count, false);
775 if (gomp_places_list == NULL)
776 return false;
777
778 do
779 {
780 bool negate;
781 unsigned long len;
782 long stride;
783 gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
784 if (!parse_one_place (&env, &negate, &len, &stride))
785 goto invalid;
786 if (negate)
787 {
788 void *p;
789 for (count = 0; count < gomp_places_list_len; count++)
790 if (gomp_affinity_same_place
791 (gomp_places_list[count],
792 gomp_places_list[gomp_places_list_len]))
793 break;
794 if (count == gomp_places_list_len)
795 {
796 gomp_error ("Trying to remove a non-existing place from list "
797 "of places");
798 goto invalid;
799 }
800 p = gomp_places_list[count];
801 memmove (&gomp_places_list[count],
802 &gomp_places_list[count + 1],
803 (gomp_places_list_len - count - 1) * sizeof (void *));
804 --gomp_places_list_len;
805 gomp_places_list[gomp_places_list_len] = p;
806 }
807 else if (len == 1)
808 ++gomp_places_list_len;
809 else
810 {
811 for (count = 0; count < len - 1; count++)
812 if (!gomp_affinity_copy_place
813 (gomp_places_list[gomp_places_list_len + count + 1],
814 gomp_places_list[gomp_places_list_len + count],
815 stride))
816 goto invalid;
817 gomp_places_list_len += len;
818 }
819 if (*env == '\0')
820 break;
821 env++;
822 }
823 while (1);
824
825 if (gomp_places_list_len == 0)
826 {
827 gomp_error ("All places have been removed");
828 goto invalid;
829 }
830 if (!gomp_affinity_finalize_place_list (false))
831 goto invalid;
832 return true;
833
834 invalid:
835 free (gomp_places_list);
836 gomp_places_list = NULL;
837 gomp_places_list_len = 0;
838 gomp_error ("Invalid value for environment variable %s", name);
839 return false;
840}
841
a68ab351
JJ
842/* Parse the OMP_STACKSIZE environment varible. Return true if one was
843 present and it was successfully parsed. */
844
845static bool
846parse_stacksize (const char *name, unsigned long *pvalue)
847{
848 char *env, *end;
849 unsigned long value, shift = 10;
850
851 env = getenv (name);
852 if (env == NULL)
853 return false;
854
855 while (isspace ((unsigned char) *env))
856 ++env;
857 if (*env == '\0')
858 goto invalid;
859
860 errno = 0;
861 value = strtoul (env, &end, 10);
862 if (errno)
863 goto invalid;
864
865 while (isspace ((unsigned char) *end))
866 ++end;
867 if (*end != '\0')
868 {
323ff903 869 switch (tolower ((unsigned char) *end))
a68ab351
JJ
870 {
871 case 'b':
872 shift = 0;
873 break;
874 case 'k':
875 break;
876 case 'm':
877 shift = 20;
878 break;
879 case 'g':
880 shift = 30;
881 break;
882 default:
883 goto invalid;
884 }
885 ++end;
886 while (isspace ((unsigned char) *end))
887 ++end;
888 if (*end != '\0')
889 goto invalid;
890 }
891
892 if (((value << shift) >> shift) != value)
893 goto invalid;
894
895 *pvalue = value << shift;
896 return true;
897
898 invalid:
899 gomp_error ("Invalid value for environment variable %s", name);
900 return false;
901}
902
903/* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
904 present and it was successfully parsed. */
905
906static bool
907parse_spincount (const char *name, unsigned long long *pvalue)
908{
909 char *env, *end;
910 unsigned long long value, mult = 1;
911
912 env = getenv (name);
913 if (env == NULL)
914 return false;
915
916 while (isspace ((unsigned char) *env))
917 ++env;
918 if (*env == '\0')
919 goto invalid;
920
921 if (strncasecmp (env, "infinite", 8) == 0
922 || strncasecmp (env, "infinity", 8) == 0)
923 {
924 value = ~0ULL;
925 end = env + 8;
926 goto check_tail;
927 }
928
929 errno = 0;
930 value = strtoull (env, &end, 10);
931 if (errno)
932 goto invalid;
933
934 while (isspace ((unsigned char) *end))
935 ++end;
936 if (*end != '\0')
937 {
323ff903 938 switch (tolower ((unsigned char) *end))
a68ab351
JJ
939 {
940 case 'k':
941 mult = 1000LL;
942 break;
943 case 'm':
944 mult = 1000LL * 1000LL;
945 break;
946 case 'g':
947 mult = 1000LL * 1000LL * 1000LL;
948 break;
949 case 't':
950 mult = 1000LL * 1000LL * 1000LL * 1000LL;
951 break;
952 default:
953 goto invalid;
954 }
955 ++end;
956 check_tail:
957 while (isspace ((unsigned char) *end))
958 ++end;
959 if (*end != '\0')
960 goto invalid;
961 }
962
963 if (value > ~0ULL / mult)
964 value = ~0ULL;
965 else
966 value *= mult;
967
968 *pvalue = value;
969 return true;
970
971 invalid:
972 gomp_error ("Invalid value for environment variable %s", name);
973 return false;
974}
975
976/* Parse a boolean value for environment variable NAME and store the
6fae7eda
KCY
977 result in VALUE. Return true if one was present and it was
978 successfully parsed. */
953ff289 979
6fae7eda 980static bool
953ff289
DN
981parse_boolean (const char *name, bool *value)
982{
983 const char *env;
984
985 env = getenv (name);
986 if (env == NULL)
6fae7eda 987 return false;
953ff289 988
89b3e3cd
JJ
989 while (isspace ((unsigned char) *env))
990 ++env;
991 if (strncasecmp (env, "true", 4) == 0)
992 {
993 *value = true;
994 env += 4;
995 }
996 else if (strncasecmp (env, "false", 5) == 0)
997 {
998 *value = false;
999 env += 5;
1000 }
953ff289 1001 else
89b3e3cd
JJ
1002 env = "X";
1003 while (isspace ((unsigned char) *env))
1004 ++env;
1005 if (*env != '\0')
6fae7eda
KCY
1006 {
1007 gomp_error ("Invalid value for environment variable %s", name);
1008 return false;
1009 }
1010 return true;
953ff289
DN
1011}
1012
800bcc8c 1013/* Parse the OMP_WAIT_POLICY environment variable and return the value. */
a68ab351
JJ
1014
1015static int
1016parse_wait_policy (void)
1017{
1018 const char *env;
1019 int ret = -1;
1020
1021 env = getenv ("OMP_WAIT_POLICY");
1022 if (env == NULL)
1023 return -1;
1024
1025 while (isspace ((unsigned char) *env))
1026 ++env;
1027 if (strncasecmp (env, "active", 6) == 0)
1028 {
1029 ret = 1;
1030 env += 6;
1031 }
1032 else if (strncasecmp (env, "passive", 7) == 0)
1033 {
1034 ret = 0;
1035 env += 7;
1036 }
1037 else
1038 env = "X";
1039 while (isspace ((unsigned char) *env))
1040 ++env;
1041 if (*env == '\0')
1042 return ret;
1043 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
1044 return -1;
1045}
1046
a0884cf0
JJ
1047/* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1048 present and it was successfully parsed. */
1049
1050static bool
f89163fd 1051parse_affinity (bool ignore)
a0884cf0 1052{
acf0174b
JJ
1053 char *env, *end, *start;
1054 int pass;
a0884cf0 1055 unsigned long cpu_beg, cpu_end, cpu_stride;
acf0174b 1056 size_t count = 0, needed;
a0884cf0
JJ
1057
1058 env = getenv ("GOMP_CPU_AFFINITY");
1059 if (env == NULL)
1060 return false;
1061
acf0174b
JJ
1062 start = env;
1063 for (pass = 0; pass < 2; pass++)
a0884cf0 1064 {
acf0174b
JJ
1065 env = start;
1066 if (pass == 1)
a0884cf0 1067 {
f89163fd
JJ
1068 if (ignore)
1069 return false;
1070
acf0174b
JJ
1071 gomp_places_list_len = 0;
1072 gomp_places_list = gomp_affinity_alloc (count, true);
1073 if (gomp_places_list == NULL)
1074 return false;
1075 }
1076 do
1077 {
1078 while (isspace ((unsigned char) *env))
1079 ++env;
1080
1081 errno = 0;
1082 cpu_beg = strtoul (env, &end, 0);
1083 if (errno || cpu_beg >= 65536)
a0884cf0 1084 goto invalid;
acf0174b
JJ
1085 cpu_end = cpu_beg;
1086 cpu_stride = 1;
a0884cf0
JJ
1087
1088 env = end;
acf0174b 1089 if (*env == '-')
a0884cf0 1090 {
acf0174b
JJ
1091 errno = 0;
1092 cpu_end = strtoul (++env, &end, 0);
1093 if (errno || cpu_end >= 65536 || cpu_end < cpu_beg)
a0884cf0
JJ
1094 goto invalid;
1095
1096 env = end;
acf0174b
JJ
1097 if (*env == ':')
1098 {
1099 errno = 0;
1100 cpu_stride = strtoul (++env, &end, 0);
1101 if (errno || cpu_stride == 0 || cpu_stride >= 65536)
1102 goto invalid;
a0884cf0 1103
acf0174b
JJ
1104 env = end;
1105 }
1106 }
a0884cf0 1107
acf0174b
JJ
1108 needed = (cpu_end - cpu_beg) / cpu_stride + 1;
1109 if (pass == 0)
1110 count += needed;
a0884cf0 1111 else
a0884cf0 1112 {
acf0174b
JJ
1113 while (needed--)
1114 {
1115 void *p = gomp_places_list[gomp_places_list_len];
1116 gomp_affinity_init_place (p);
1117 if (gomp_affinity_add_cpus (p, cpu_beg, 1, 0, true))
1118 ++gomp_places_list_len;
1119 cpu_beg += cpu_stride;
1120 }
a0884cf0
JJ
1121 }
1122
acf0174b
JJ
1123 while (isspace ((unsigned char) *env))
1124 ++env;
a0884cf0 1125
acf0174b
JJ
1126 if (*env == ',')
1127 env++;
1128 else if (*env == '\0')
1129 break;
a0884cf0 1130 }
acf0174b 1131 while (1);
a0884cf0 1132 }
a0884cf0 1133
acf0174b
JJ
1134 if (gomp_places_list_len == 0)
1135 {
1136 free (gomp_places_list);
1137 gomp_places_list = NULL;
f89163fd 1138 return false;
acf0174b 1139 }
a0884cf0
JJ
1140 return true;
1141
1142 invalid:
1143 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1144 return false;
1145}
1146
800bcc8c
JJ
1147/* Parse the OMP_ALLOCATOR environment variable and return the value. */
1148
1149static uintptr_t
1150parse_allocator (void)
1151{
1152 const char *env;
1153 uintptr_t ret = omp_default_mem_alloc;
1154
1155 env = getenv ("OMP_ALLOCATOR");
1156 if (env == NULL)
1157 return ret;
1158
1159 while (isspace ((unsigned char) *env))
1160 ++env;
1161 if (0)
1162 ;
1163#define C(v) \
1164 else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
1165 { \
1166 ret = v; \
1167 env += sizeof (#v) - 1; \
1168 }
1169 C (omp_default_mem_alloc)
1170 C (omp_large_cap_mem_alloc)
1171 C (omp_const_mem_alloc)
1172 C (omp_high_bw_mem_alloc)
1173 C (omp_low_lat_mem_alloc)
1174 C (omp_cgroup_mem_alloc)
1175 C (omp_pteam_mem_alloc)
1176 C (omp_thread_mem_alloc)
1177#undef C
1178 else
1179 env = "X";
1180 while (isspace ((unsigned char) *env))
1181 ++env;
1182 if (*env == '\0')
1183 return ret;
1184 gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
1185 return omp_default_mem_alloc;
1186}
1187
41dbbb37
TS
1188static void
1189parse_acc_device_type (void)
1190{
1191 const char *env = getenv ("ACC_DEVICE_TYPE");
1192
1193 if (env && *env != '\0')
1194 goacc_device_type = strdup (env);
1195 else
1196 goacc_device_type = NULL;
1197}
acf0174b 1198
ec00d3fa
TV
1199static void
1200parse_gomp_openacc_dim (void)
1201{
1202 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1203 const char *var_name = "GOMP_OPENACC_DIM";
1204 const char *env_var = getenv (var_name);
1205 if (!env_var)
1206 return;
1207
1208 const char *pos = env_var;
1209 int i;
1210 for (i = 0; *pos && i != GOMP_DIM_MAX; i++)
1211 {
1212 if (i && *pos++ != ':')
1213 break;
1214
1215 if (*pos == ':')
1216 continue;
1217
1218 const char *eptr;
1219 errno = 0;
1220 long val = strtol (pos, (char **)&eptr, 10);
1221 if (errno || val < 0 || (unsigned)val != val)
1222 break;
1223
1224 goacc_default_dims[i] = (int)val;
1225 pos = eptr;
1226 }
1227}
1228
7123ae24
UD
1229void
1230omp_display_env (int verbose)
acf0174b 1231{
acf0174b
JJ
1232 int i;
1233
acf0174b
JJ
1234 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr);
1235
d9a6bd32 1236 fputs (" _OPENMP = '201511'\n", stderr);
acf0174b
JJ
1237 fprintf (stderr, " OMP_DYNAMIC = '%s'\n",
1238 gomp_global_icv.dyn_var ? "TRUE" : "FALSE");
1239 fprintf (stderr, " OMP_NESTED = '%s'\n",
6fae7eda 1240 gomp_global_icv.max_active_levels_var > 1 ? "TRUE" : "FALSE");
acf0174b
JJ
1241
1242 fprintf (stderr, " OMP_NUM_THREADS = '%lu", gomp_global_icv.nthreads_var);
1243 for (i = 1; i < gomp_nthreads_var_list_len; i++)
1244 fprintf (stderr, ",%lu", gomp_nthreads_var_list[i]);
1245 fputs ("'\n", stderr);
1246
1247 fprintf (stderr, " OMP_SCHEDULE = '");
28567c40
JJ
1248 if ((gomp_global_icv.run_sched_var & GFS_MONOTONIC))
1249 {
1250 if (gomp_global_icv.run_sched_var != (GFS_MONOTONIC | GFS_STATIC))
1251 fputs ("MONOTONIC:", stderr);
1252 }
1253 else if (gomp_global_icv.run_sched_var == GFS_STATIC)
1254 fputs ("NONMONOTONIC:", stderr);
1255 switch (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC)
acf0174b
JJ
1256 {
1257 case GFS_RUNTIME:
1258 fputs ("RUNTIME", stderr);
28567c40
JJ
1259 if (gomp_global_icv.run_sched_chunk_size != 1)
1260 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1261 break;
1262 case GFS_STATIC:
1263 fputs ("STATIC", stderr);
28567c40
JJ
1264 if (gomp_global_icv.run_sched_chunk_size != 0)
1265 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1266 break;
1267 case GFS_DYNAMIC:
1268 fputs ("DYNAMIC", stderr);
28567c40
JJ
1269 if (gomp_global_icv.run_sched_chunk_size != 1)
1270 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1271 break;
1272 case GFS_GUIDED:
1273 fputs ("GUIDED", stderr);
28567c40
JJ
1274 if (gomp_global_icv.run_sched_chunk_size != 1)
1275 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1276 break;
1277 case GFS_AUTO:
1278 fputs ("AUTO", stderr);
1279 break;
1280 }
1281 fputs ("'\n", stderr);
1282
1283 fputs (" OMP_PROC_BIND = '", stderr);
1284 switch (gomp_global_icv.bind_var)
1285 {
1286 case omp_proc_bind_false:
1287 fputs ("FALSE", stderr);
1288 break;
1289 case omp_proc_bind_true:
1290 fputs ("TRUE", stderr);
1291 break;
1292 case omp_proc_bind_master:
432de084 1293 fputs ("MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1294 break;
1295 case omp_proc_bind_close:
1296 fputs ("CLOSE", stderr);
1297 break;
1298 case omp_proc_bind_spread:
1299 fputs ("SPREAD", stderr);
1300 break;
1301 }
1302 for (i = 1; i < gomp_bind_var_list_len; i++)
1303 switch (gomp_bind_var_list[i])
1304 {
1305 case omp_proc_bind_master:
432de084 1306 fputs (",MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1307 break;
1308 case omp_proc_bind_close:
1309 fputs (",CLOSE", stderr);
1310 break;
1311 case omp_proc_bind_spread:
1312 fputs (",SPREAD", stderr);
1313 break;
1314 }
1315 fputs ("'\n", stderr);
1316 fputs (" OMP_PLACES = '", stderr);
1317 for (i = 0; i < gomp_places_list_len; i++)
1318 {
1319 fputs ("{", stderr);
1320 gomp_affinity_print_place (gomp_places_list[i]);
1321 fputs (i + 1 == gomp_places_list_len ? "}" : "},", stderr);
1322 }
1323 fputs ("'\n", stderr);
1324
1325 fprintf (stderr, " OMP_STACKSIZE = '%lu'\n", stacksize);
1326
1327 /* GOMP's default value is actually neither active nor passive. */
1328 fprintf (stderr, " OMP_WAIT_POLICY = '%s'\n",
1329 wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1330 fprintf (stderr, " OMP_THREAD_LIMIT = '%u'\n",
1331 gomp_global_icv.thread_limit_var);
6fae7eda
KCY
1332 fprintf (stderr, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1333 gomp_global_icv.max_active_levels_var);
07dd3bcd
JJ
1334 fprintf (stderr, " OMP_NUM_TEAMS = '%u'\n", gomp_nteams_var);
1335 fprintf (stderr, " OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1336 gomp_teams_thread_limit_var);
acf0174b
JJ
1337
1338 fprintf (stderr, " OMP_CANCELLATION = '%s'\n",
1339 gomp_cancel_var ? "TRUE" : "FALSE");
1340 fprintf (stderr, " OMP_DEFAULT_DEVICE = '%d'\n",
1341 gomp_global_icv.default_device_var);
d9a6bd32
JJ
1342 fprintf (stderr, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1343 gomp_max_task_priority_var);
28567c40
JJ
1344 fprintf (stderr, " OMP_DISPLAY_AFFINITY = '%s'\n",
1345 gomp_display_affinity_var ? "TRUE" : "FALSE");
1346 fprintf (stderr, " OMP_AFFINITY_FORMAT = '%s'\n",
1347 gomp_affinity_format_var);
800bcc8c
JJ
1348 fprintf (stderr, " OMP_ALLOCATOR = '");
1349 switch (gomp_def_allocator)
1350 {
1351#define C(v) case v: fputs (#v, stderr); break;
1352 C (omp_default_mem_alloc)
1353 C (omp_large_cap_mem_alloc)
1354 C (omp_const_mem_alloc)
1355 C (omp_high_bw_mem_alloc)
1356 C (omp_low_lat_mem_alloc)
1357 C (omp_cgroup_mem_alloc)
1358 C (omp_pteam_mem_alloc)
1359 C (omp_thread_mem_alloc)
1360#undef C
1361 default: break;
1362 }
1363 fputs ("'\n", stderr);
acf0174b 1364
1bfc07d1
KCY
1365 fputs (" OMP_TARGET_OFFLOAD = '", stderr);
1366 switch (gomp_target_offload_var)
1367 {
1368 case GOMP_TARGET_OFFLOAD_DEFAULT:
1369 fputs ("DEFAULT", stderr);
1370 break;
1371 case GOMP_TARGET_OFFLOAD_MANDATORY:
1372 fputs ("MANDATORY", stderr);
1373 break;
1374 case GOMP_TARGET_OFFLOAD_DISABLED:
1375 fputs ("DISABLED", stderr);
1376 break;
1377 }
1378 fputs ("'\n", stderr);
1379
acf0174b
JJ
1380 if (verbose)
1381 {
1382 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr);
1383 fprintf (stderr, " GOMP_STACKSIZE = '%lu'\n", stacksize);
1384#ifdef HAVE_INTTYPES_H
1385 fprintf (stderr, " GOMP_SPINCOUNT = '%"PRIu64"'\n",
1386 (uint64_t) gomp_spin_count_var);
1387#else
1388 fprintf (stderr, " GOMP_SPINCOUNT = '%lu'\n",
1389 (unsigned long) gomp_spin_count_var);
1390#endif
1391 }
1392
1393 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr);
1394}
7123ae24
UD
1395ialias (omp_display_env)
1396
1397static void
1398handle_omp_display_env (void)
1399{
1400 const char *env;
1401 bool display = false;
1402 bool verbose = false;
1403
1404 env = getenv ("OMP_DISPLAY_ENV");
1405 if (env == NULL)
1406 return;
1407
1408 while (isspace ((unsigned char) *env))
1409 ++env;
1410 if (strncasecmp (env, "true", 4) == 0)
1411 {
1412 display = true;
1413 env += 4;
1414 }
1415 else if (strncasecmp (env, "false", 5) == 0)
1416 {
1417 display = false;
1418 env += 5;
1419 }
1420 else if (strncasecmp (env, "verbose", 7) == 0)
1421 {
1422 display = true;
1423 verbose = true;
1424 env += 7;
1425 }
1426 else
1427 env = "X";
1428 while (isspace ((unsigned char) *env))
1429 ++env;
1430 if (*env != '\0')
1431 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1432
1433 if (display)
3749c3af 1434 ialias_call (omp_display_env) (verbose);
7123ae24 1435}
acf0174b
JJ
1436
1437
953ff289
DN
1438static void __attribute__((constructor))
1439initialize_env (void)
1440{
7123ae24 1441 unsigned long thread_limit_var;
6fae7eda 1442 unsigned long max_active_levels_var;
d0d1b24d 1443
953ff289
DN
1444 /* Do a compile time check that mkomp_h.pl did good job. */
1445 omp_check_defines ();
1446
1447 parse_schedule ();
a68ab351 1448 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
acf0174b 1449 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
28567c40 1450 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var);
acf0174b 1451 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
1bfc07d1 1452 parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var);
d9a6bd32 1453 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
800bcc8c 1454 gomp_def_allocator = parse_allocator ();
acf0174b
JJ
1455 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false))
1456 {
1457 gomp_global_icv.thread_limit_var
1458 = thread_limit_var > INT_MAX ? UINT_MAX : thread_limit_var;
1459 }
22f1a037 1460 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var, true);
a68ab351 1461#ifndef HAVE_SYNC_BUILTINS
acf0174b 1462 gomp_mutex_init (&gomp_managed_threads_lock);
a68ab351 1463#endif
a68ab351
JJ
1464 gomp_init_num_threads ();
1465 gomp_available_cpus = gomp_global_icv.nthreads_var;
20906c66
JJ
1466 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1467 &gomp_global_icv.nthreads_var,
1468 &gomp_nthreads_var_list,
1469 &gomp_nthreads_var_list_len))
a68ab351 1470 gomp_global_icv.nthreads_var = gomp_available_cpus;
07dd3bcd
JJ
1471 parse_int ("OMP_NUM_TEAMS", &gomp_nteams_var, false);
1472 parse_int ("OMP_TEAMS_THREAD_LIMIT", &gomp_teams_thread_limit_var, false);
f89163fd
JJ
1473 bool ignore = false;
1474 if (parse_bind_var ("OMP_PROC_BIND",
1475 &gomp_global_icv.bind_var,
1476 &gomp_bind_var_list,
1477 &gomp_bind_var_list_len)
1478 && gomp_global_icv.bind_var == omp_proc_bind_false)
1479 ignore = true;
6fae7eda
KCY
1480 if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
1481 &max_active_levels_var, true))
1482 gomp_global_icv.max_active_levels_var
1483 = (max_active_levels_var > gomp_supported_active_levels)
1484 ? gomp_supported_active_levels : max_active_levels_var;
1485 else
1486 {
1487 bool nested = true;
1488
1489 /* OMP_NESTED is deprecated in OpenMP 5.0. */
1490 if (parse_boolean ("OMP_NESTED", &nested))
1491 gomp_global_icv.max_active_levels_var
1492 = nested ? gomp_supported_active_levels : 1;
1493 else if (gomp_nthreads_var_list_len > 1 || gomp_bind_var_list_len > 1)
1494 gomp_global_icv.max_active_levels_var = gomp_supported_active_levels;
1495 }
f89163fd
JJ
1496 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1497 parsed if present in the environment. If OMP_PROC_BIND was set
93d90219 1498 explicitly to false, don't populate places list though. If places
f89163fd
JJ
1499 list was successfully set from OMP_PLACES, only parse but don't process
1500 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1501 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1502 was successfully parsed into a places list, otherwise to
1503 OMP_PROC_BIND=false. */
1504 if (parse_places_var ("OMP_PLACES", ignore))
1505 {
1506 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1507 gomp_global_icv.bind_var = true;
1508 ignore = true;
1509 }
1510 if (parse_affinity (ignore))
1511 {
1512 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1513 gomp_global_icv.bind_var = true;
1514 ignore = true;
1515 }
1516 if (gomp_global_icv.bind_var != omp_proc_bind_false)
a0884cf0 1517 gomp_init_affinity ();
28567c40
JJ
1518
1519 {
1520 const char *env = getenv ("OMP_AFFINITY_FORMAT");
1521 if (env != NULL)
1522 gomp_set_affinity_format (env, strlen (env));
1523 }
1524
a68ab351
JJ
1525 wait_policy = parse_wait_policy ();
1526 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
1527 {
1528 /* Using a rough estimation of 100000 spins per msec,
1529 use 5 min blocking for OMP_WAIT_POLICY=active,
4c698cf8 1530 3 msec blocking when OMP_WAIT_POLICY is not specificed
a68ab351
JJ
1531 and 0 when OMP_WAIT_POLICY=passive.
1532 Depending on the CPU speed, this can be e.g. 5 times longer
1533 or 5 times shorter. */
1534 if (wait_policy > 0)
1535 gomp_spin_count_var = 30000000000LL;
1536 else if (wait_policy < 0)
4c698cf8 1537 gomp_spin_count_var = 300000LL;
a68ab351
JJ
1538 }
1539 /* gomp_throttled_spin_count_var is used when there are more libgomp
1540 managed threads than available CPUs. Use very short spinning. */
1541 if (wait_policy > 0)
1542 gomp_throttled_spin_count_var = 1000LL;
1543 else if (wait_policy < 0)
1544 gomp_throttled_spin_count_var = 100LL;
1545 if (gomp_throttled_spin_count_var > gomp_spin_count_var)
1546 gomp_throttled_spin_count_var = gomp_spin_count_var;
d0d1b24d
RH
1547
1548 /* Not strictly environment related, but ordering constructors is tricky. */
1549 pthread_attr_init (&gomp_thread_attr);
d0d1b24d 1550
a68ab351 1551 if (parse_stacksize ("OMP_STACKSIZE", &stacksize)
c4060df4
JJ
1552 || parse_stacksize ("GOMP_STACKSIZE", &stacksize)
1553 || GOMP_DEFAULT_STACKSIZE)
d0d1b24d 1554 {
c3b11a40
RH
1555 int err;
1556
c3b11a40
RH
1557 err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
1558
1559#ifdef PTHREAD_STACK_MIN
1560 if (err == EINVAL)
d0d1b24d 1561 {
c3b11a40
RH
1562 if (stacksize < PTHREAD_STACK_MIN)
1563 gomp_error ("Stack size less than minimum of %luk",
1564 PTHREAD_STACK_MIN / 1024ul
1565 + (PTHREAD_STACK_MIN % 1024 != 0));
1566 else
d0d1b24d 1567 gomp_error ("Stack size larger than system limit");
d0d1b24d 1568 }
c3b11a40
RH
1569 else
1570#endif
1571 if (err != 0)
1572 gomp_error ("Stack size change failed: %s", strerror (err));
d0d1b24d 1573 }
acf0174b 1574
7123ae24 1575 handle_omp_display_env ();
41dbbb37
TS
1576
1577 /* OpenACC. */
1578
1579 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num, true))
1580 goacc_device_num = 0;
1581
1582 parse_acc_device_type ();
ec00d3fa 1583 parse_gomp_openacc_dim ();
41dbbb37
TS
1584
1585 goacc_runtime_initialize ();
5fae049d
TS
1586
1587 goacc_profiling_initialize ();
953ff289 1588}
630e3c3a 1589#endif /* LIBGOMP_OFFLOADED_ONLY */