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