]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgomp/env.c
Merge IPA solution with local one in ipa-modref
[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);
c057ed9c 186 if (errno || end == env)
6acf0b38
UB
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);
c057ed9c 235 if (errno || end == env || (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;
4a0fed0c 549 bool has_braces = true;
acf0174b
JJ
550 *negatep = false;
551 while (isspace ((unsigned char) *env))
552 ++env;
553 if (*env == '!')
554 {
555 *negatep = true;
556 ++env;
557 while (isspace ((unsigned char) *env))
558 ++env;
559 }
560 if (*env != '{')
4a0fed0c
JJ
561 {
562 char *end;
563 unsigned long this_num;
564
565 errno = 0;
566 this_num = strtoul (env, &end, 10);
567 if (errno || end == env)
568 return false;
569 env = end - 1;
570 has_braces = false;
571 if (gomp_places_list
572 && !gomp_affinity_add_cpus (p, this_num, 1, 1, false))
573 return false;
574 }
575 else
576 {
577 ++env;
578 while (isspace ((unsigned char) *env))
579 ++env;
580 }
acf0174b 581 start = env;
4a0fed0c 582 for (pass = 0; pass < (any_negate ? 2 : has_braces); pass++)
acf0174b
JJ
583 {
584 env = start;
585 do
586 {
587 unsigned long this_num, this_len = 1;
588 long this_stride = 1;
589 bool this_negate = (*env == '!');
c057ed9c 590 char *end;
acf0174b
JJ
591 if (this_negate)
592 {
593 if (gomp_places_list)
594 any_negate = true;
595 ++env;
596 while (isspace ((unsigned char) *env))
597 ++env;
598 }
599
600 errno = 0;
c057ed9c
JJ
601 this_num = strtoul (env, &end, 10);
602 if (errno || end == env)
acf0174b 603 return false;
c057ed9c 604 env = end;
acf0174b
JJ
605 while (isspace ((unsigned char) *env))
606 ++env;
607 if (*env == ':')
608 {
609 ++env;
4a0fed0c
JJ
610 if (this_negate)
611 return false;
acf0174b
JJ
612 while (isspace ((unsigned char) *env))
613 ++env;
614 errno = 0;
615 this_len = strtoul (env, &env, 10);
616 if (errno || this_len == 0)
617 return false;
618 while (isspace ((unsigned char) *env))
619 ++env;
620 if (*env == ':')
621 {
622 ++env;
623 while (isspace ((unsigned char) *env))
624 ++env;
625 errno = 0;
c057ed9c
JJ
626 this_stride = strtol (env, &end, 10);
627 if (errno || end == env)
acf0174b 628 return false;
c057ed9c 629 env = end;
acf0174b
JJ
630 while (isspace ((unsigned char) *env))
631 ++env;
632 }
633 }
acf0174b
JJ
634 if (gomp_places_list && pass == this_negate)
635 {
636 if (this_negate)
637 {
638 if (!gomp_affinity_remove_cpu (p, this_num))
639 return false;
640 }
641 else if (!gomp_affinity_add_cpus (p, this_num, this_len,
642 this_stride, false))
643 return false;
644 }
645 if (*env == '}')
646 break;
647 if (*env != ',')
648 return false;
649 ++env;
650 }
651 while (1);
652 }
653
654 ++env;
655 while (isspace ((unsigned char) *env))
656 ++env;
657 if (*env == ':')
658 {
c057ed9c 659 char *end;
4a0fed0c
JJ
660 if (*negatep)
661 return false;
acf0174b
JJ
662 ++env;
663 while (isspace ((unsigned char) *env))
664 ++env;
665 errno = 0;
666 len = strtoul (env, &env, 10);
667 if (errno || len == 0 || len >= 65536)
668 return false;
669 while (isspace ((unsigned char) *env))
670 ++env;
671 if (*env == ':')
672 {
673 ++env;
674 while (isspace ((unsigned char) *env))
675 ++env;
676 errno = 0;
c057ed9c
JJ
677 stride = strtol (env, &end, 10);
678 if (errno || end == env)
acf0174b 679 return false;
c057ed9c 680 env = end;
acf0174b
JJ
681 while (isspace ((unsigned char) *env))
682 ++env;
683 }
684 }
acf0174b
JJ
685 *envp = env;
686 *lenp = len;
687 *stridep = stride;
688 return true;
689}
690
691static bool
f89163fd 692parse_places_var (const char *name, bool ignore)
acf0174b
JJ
693{
694 char *env = getenv (name), *end;
695 bool any_negate = false;
696 int level = 0;
697 unsigned long count = 0;
698 if (env == NULL)
699 return false;
700
701 while (isspace ((unsigned char) *env))
702 ++env;
703 if (*env == '\0')
704 goto invalid;
705
706 if (strncasecmp (env, "threads", 7) == 0)
707 {
708 env += 7;
709 level = 1;
710 }
711 else if (strncasecmp (env, "cores", 5) == 0)
712 {
713 env += 5;
714 level = 2;
715 }
716 else if (strncasecmp (env, "sockets", 7) == 0)
717 {
718 env += 7;
719 level = 3;
720 }
5809be05
JJ
721 else if (strncasecmp (env, "ll_caches", 9) == 0)
722 {
723 env += 9;
724 level = 4;
725 }
e7ce32c7
JJ
726 else if (strncasecmp (env, "numa_domains", 12) == 0)
727 {
728 env += 12;
729 level = 5;
730 }
acf0174b
JJ
731 if (level)
732 {
733 count = ULONG_MAX;
734 while (isspace ((unsigned char) *env))
735 ++env;
736 if (*env != '\0')
737 {
738 if (*env++ != '(')
739 goto invalid;
740 while (isspace ((unsigned char) *env))
741 ++env;
742
743 errno = 0;
744 count = strtoul (env, &end, 10);
c057ed9c 745 if (errno || end == env)
acf0174b
JJ
746 goto invalid;
747 env = end;
748 while (isspace ((unsigned char) *env))
749 ++env;
750 if (*env != ')')
751 goto invalid;
752 ++env;
753 while (isspace ((unsigned char) *env))
754 ++env;
755 if (*env != '\0')
756 goto invalid;
757 }
f89163fd
JJ
758
759 if (ignore)
760 return false;
761
acf0174b
JJ
762 return gomp_affinity_init_level (level, count, false);
763 }
764
765 count = 0;
766 end = env;
767 do
768 {
769 bool negate;
770 unsigned long len;
771 long stride;
772 if (!parse_one_place (&end, &negate, &len, &stride))
773 goto invalid;
774 if (negate)
775 {
776 if (!any_negate)
777 count++;
778 any_negate = true;
779 }
780 else
781 count += len;
782 if (count > 65536)
783 goto invalid;
784 if (*end == '\0')
785 break;
786 if (*end != ',')
787 goto invalid;
788 end++;
789 }
790 while (1);
791
f89163fd 792 if (ignore)
acf0174b
JJ
793 return false;
794
795 gomp_places_list_len = 0;
796 gomp_places_list = gomp_affinity_alloc (count, false);
797 if (gomp_places_list == NULL)
798 return false;
799
800 do
801 {
802 bool negate;
803 unsigned long len;
804 long stride;
805 gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
806 if (!parse_one_place (&env, &negate, &len, &stride))
807 goto invalid;
808 if (negate)
809 {
810 void *p;
811 for (count = 0; count < gomp_places_list_len; count++)
812 if (gomp_affinity_same_place
813 (gomp_places_list[count],
814 gomp_places_list[gomp_places_list_len]))
815 break;
816 if (count == gomp_places_list_len)
817 {
818 gomp_error ("Trying to remove a non-existing place from list "
819 "of places");
820 goto invalid;
821 }
822 p = gomp_places_list[count];
823 memmove (&gomp_places_list[count],
824 &gomp_places_list[count + 1],
825 (gomp_places_list_len - count - 1) * sizeof (void *));
826 --gomp_places_list_len;
827 gomp_places_list[gomp_places_list_len] = p;
828 }
829 else if (len == 1)
830 ++gomp_places_list_len;
831 else
832 {
833 for (count = 0; count < len - 1; count++)
834 if (!gomp_affinity_copy_place
835 (gomp_places_list[gomp_places_list_len + count + 1],
836 gomp_places_list[gomp_places_list_len + count],
837 stride))
838 goto invalid;
839 gomp_places_list_len += len;
840 }
841 if (*env == '\0')
842 break;
843 env++;
844 }
845 while (1);
846
847 if (gomp_places_list_len == 0)
848 {
849 gomp_error ("All places have been removed");
850 goto invalid;
851 }
852 if (!gomp_affinity_finalize_place_list (false))
853 goto invalid;
854 return true;
855
856 invalid:
857 free (gomp_places_list);
858 gomp_places_list = NULL;
859 gomp_places_list_len = 0;
860 gomp_error ("Invalid value for environment variable %s", name);
861 return false;
862}
863
a68ab351
JJ
864/* Parse the OMP_STACKSIZE environment varible. Return true if one was
865 present and it was successfully parsed. */
866
867static bool
868parse_stacksize (const char *name, unsigned long *pvalue)
869{
870 char *env, *end;
871 unsigned long value, shift = 10;
872
873 env = getenv (name);
874 if (env == NULL)
875 return false;
876
877 while (isspace ((unsigned char) *env))
878 ++env;
879 if (*env == '\0')
880 goto invalid;
881
882 errno = 0;
883 value = strtoul (env, &end, 10);
c057ed9c 884 if (errno || end == env)
a68ab351
JJ
885 goto invalid;
886
887 while (isspace ((unsigned char) *end))
888 ++end;
889 if (*end != '\0')
890 {
323ff903 891 switch (tolower ((unsigned char) *end))
a68ab351
JJ
892 {
893 case 'b':
894 shift = 0;
895 break;
896 case 'k':
897 break;
898 case 'm':
899 shift = 20;
900 break;
901 case 'g':
902 shift = 30;
903 break;
904 default:
905 goto invalid;
906 }
907 ++end;
908 while (isspace ((unsigned char) *end))
909 ++end;
910 if (*end != '\0')
911 goto invalid;
912 }
913
914 if (((value << shift) >> shift) != value)
915 goto invalid;
916
917 *pvalue = value << shift;
918 return true;
919
920 invalid:
921 gomp_error ("Invalid value for environment variable %s", name);
922 return false;
923}
924
925/* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
926 present and it was successfully parsed. */
927
928static bool
929parse_spincount (const char *name, unsigned long long *pvalue)
930{
931 char *env, *end;
932 unsigned long long value, mult = 1;
933
934 env = getenv (name);
935 if (env == NULL)
936 return false;
937
938 while (isspace ((unsigned char) *env))
939 ++env;
940 if (*env == '\0')
941 goto invalid;
942
943 if (strncasecmp (env, "infinite", 8) == 0
944 || strncasecmp (env, "infinity", 8) == 0)
945 {
946 value = ~0ULL;
947 end = env + 8;
948 goto check_tail;
949 }
950
951 errno = 0;
952 value = strtoull (env, &end, 10);
c057ed9c 953 if (errno || end == env)
a68ab351
JJ
954 goto invalid;
955
956 while (isspace ((unsigned char) *end))
957 ++end;
958 if (*end != '\0')
959 {
323ff903 960 switch (tolower ((unsigned char) *end))
a68ab351
JJ
961 {
962 case 'k':
963 mult = 1000LL;
964 break;
965 case 'm':
966 mult = 1000LL * 1000LL;
967 break;
968 case 'g':
969 mult = 1000LL * 1000LL * 1000LL;
970 break;
971 case 't':
972 mult = 1000LL * 1000LL * 1000LL * 1000LL;
973 break;
974 default:
975 goto invalid;
976 }
977 ++end;
978 check_tail:
979 while (isspace ((unsigned char) *end))
980 ++end;
981 if (*end != '\0')
982 goto invalid;
983 }
984
985 if (value > ~0ULL / mult)
986 value = ~0ULL;
987 else
988 value *= mult;
989
990 *pvalue = value;
991 return true;
992
993 invalid:
994 gomp_error ("Invalid value for environment variable %s", name);
995 return false;
996}
997
998/* Parse a boolean value for environment variable NAME and store the
6fae7eda
KCY
999 result in VALUE. Return true if one was present and it was
1000 successfully parsed. */
953ff289 1001
6fae7eda 1002static bool
953ff289
DN
1003parse_boolean (const char *name, bool *value)
1004{
1005 const char *env;
1006
1007 env = getenv (name);
1008 if (env == NULL)
6fae7eda 1009 return false;
953ff289 1010
89b3e3cd
JJ
1011 while (isspace ((unsigned char) *env))
1012 ++env;
1013 if (strncasecmp (env, "true", 4) == 0)
1014 {
1015 *value = true;
1016 env += 4;
1017 }
1018 else if (strncasecmp (env, "false", 5) == 0)
1019 {
1020 *value = false;
1021 env += 5;
1022 }
953ff289 1023 else
89b3e3cd
JJ
1024 env = "X";
1025 while (isspace ((unsigned char) *env))
1026 ++env;
1027 if (*env != '\0')
6fae7eda
KCY
1028 {
1029 gomp_error ("Invalid value for environment variable %s", name);
1030 return false;
1031 }
1032 return true;
953ff289
DN
1033}
1034
800bcc8c 1035/* Parse the OMP_WAIT_POLICY environment variable and return the value. */
a68ab351
JJ
1036
1037static int
1038parse_wait_policy (void)
1039{
1040 const char *env;
1041 int ret = -1;
1042
1043 env = getenv ("OMP_WAIT_POLICY");
1044 if (env == NULL)
1045 return -1;
1046
1047 while (isspace ((unsigned char) *env))
1048 ++env;
1049 if (strncasecmp (env, "active", 6) == 0)
1050 {
1051 ret = 1;
1052 env += 6;
1053 }
1054 else if (strncasecmp (env, "passive", 7) == 0)
1055 {
1056 ret = 0;
1057 env += 7;
1058 }
1059 else
1060 env = "X";
1061 while (isspace ((unsigned char) *env))
1062 ++env;
1063 if (*env == '\0')
1064 return ret;
1065 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
1066 return -1;
1067}
1068
a0884cf0
JJ
1069/* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1070 present and it was successfully parsed. */
1071
1072static bool
f89163fd 1073parse_affinity (bool ignore)
a0884cf0 1074{
acf0174b
JJ
1075 char *env, *end, *start;
1076 int pass;
a0884cf0 1077 unsigned long cpu_beg, cpu_end, cpu_stride;
acf0174b 1078 size_t count = 0, needed;
a0884cf0
JJ
1079
1080 env = getenv ("GOMP_CPU_AFFINITY");
1081 if (env == NULL)
1082 return false;
1083
acf0174b
JJ
1084 start = env;
1085 for (pass = 0; pass < 2; pass++)
a0884cf0 1086 {
acf0174b
JJ
1087 env = start;
1088 if (pass == 1)
a0884cf0 1089 {
f89163fd
JJ
1090 if (ignore)
1091 return false;
1092
acf0174b
JJ
1093 gomp_places_list_len = 0;
1094 gomp_places_list = gomp_affinity_alloc (count, true);
1095 if (gomp_places_list == NULL)
1096 return false;
1097 }
1098 do
1099 {
1100 while (isspace ((unsigned char) *env))
1101 ++env;
1102
1103 errno = 0;
1104 cpu_beg = strtoul (env, &end, 0);
c057ed9c 1105 if (errno || end == env || cpu_beg >= 65536)
a0884cf0 1106 goto invalid;
acf0174b
JJ
1107 cpu_end = cpu_beg;
1108 cpu_stride = 1;
a0884cf0
JJ
1109
1110 env = end;
acf0174b 1111 if (*env == '-')
a0884cf0 1112 {
acf0174b
JJ
1113 errno = 0;
1114 cpu_end = strtoul (++env, &end, 0);
c057ed9c 1115 if (errno || end == env || cpu_end >= 65536 || cpu_end < cpu_beg)
a0884cf0
JJ
1116 goto invalid;
1117
1118 env = end;
acf0174b
JJ
1119 if (*env == ':')
1120 {
1121 errno = 0;
1122 cpu_stride = strtoul (++env, &end, 0);
1123 if (errno || cpu_stride == 0 || cpu_stride >= 65536)
1124 goto invalid;
a0884cf0 1125
acf0174b
JJ
1126 env = end;
1127 }
1128 }
a0884cf0 1129
acf0174b
JJ
1130 needed = (cpu_end - cpu_beg) / cpu_stride + 1;
1131 if (pass == 0)
1132 count += needed;
a0884cf0 1133 else
a0884cf0 1134 {
acf0174b
JJ
1135 while (needed--)
1136 {
1137 void *p = gomp_places_list[gomp_places_list_len];
1138 gomp_affinity_init_place (p);
1139 if (gomp_affinity_add_cpus (p, cpu_beg, 1, 0, true))
1140 ++gomp_places_list_len;
1141 cpu_beg += cpu_stride;
1142 }
a0884cf0
JJ
1143 }
1144
acf0174b
JJ
1145 while (isspace ((unsigned char) *env))
1146 ++env;
a0884cf0 1147
acf0174b
JJ
1148 if (*env == ',')
1149 env++;
1150 else if (*env == '\0')
1151 break;
a0884cf0 1152 }
acf0174b 1153 while (1);
a0884cf0 1154 }
a0884cf0 1155
acf0174b
JJ
1156 if (gomp_places_list_len == 0)
1157 {
1158 free (gomp_places_list);
1159 gomp_places_list = NULL;
f89163fd 1160 return false;
acf0174b 1161 }
a0884cf0
JJ
1162 return true;
1163
1164 invalid:
1165 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1166 return false;
1167}
1168
800bcc8c
JJ
1169/* Parse the OMP_ALLOCATOR environment variable and return the value. */
1170
1171static uintptr_t
1172parse_allocator (void)
1173{
1174 const char *env;
1175 uintptr_t ret = omp_default_mem_alloc;
1176
1177 env = getenv ("OMP_ALLOCATOR");
1178 if (env == NULL)
1179 return ret;
1180
1181 while (isspace ((unsigned char) *env))
1182 ++env;
1183 if (0)
1184 ;
1185#define C(v) \
1186 else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
1187 { \
1188 ret = v; \
1189 env += sizeof (#v) - 1; \
1190 }
1191 C (omp_default_mem_alloc)
1192 C (omp_large_cap_mem_alloc)
1193 C (omp_const_mem_alloc)
1194 C (omp_high_bw_mem_alloc)
1195 C (omp_low_lat_mem_alloc)
1196 C (omp_cgroup_mem_alloc)
1197 C (omp_pteam_mem_alloc)
1198 C (omp_thread_mem_alloc)
1199#undef C
1200 else
1201 env = "X";
1202 while (isspace ((unsigned char) *env))
1203 ++env;
1204 if (*env == '\0')
1205 return ret;
1206 gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
1207 return omp_default_mem_alloc;
1208}
1209
41dbbb37
TS
1210static void
1211parse_acc_device_type (void)
1212{
1213 const char *env = getenv ("ACC_DEVICE_TYPE");
1214
1215 if (env && *env != '\0')
1216 goacc_device_type = strdup (env);
1217 else
1218 goacc_device_type = NULL;
1219}
acf0174b 1220
ec00d3fa
TV
1221static void
1222parse_gomp_openacc_dim (void)
1223{
1224 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1225 const char *var_name = "GOMP_OPENACC_DIM";
1226 const char *env_var = getenv (var_name);
c057ed9c
JJ
1227 const char *pos = env_var;
1228 int i;
1229
ec00d3fa
TV
1230 if (!env_var)
1231 return;
1232
ec00d3fa
TV
1233 for (i = 0; *pos && i != GOMP_DIM_MAX; i++)
1234 {
c057ed9c
JJ
1235 char *eptr;
1236 long val;
1237
ec00d3fa
TV
1238 if (i && *pos++ != ':')
1239 break;
1240
1241 if (*pos == ':')
1242 continue;
1243
ec00d3fa 1244 errno = 0;
c057ed9c
JJ
1245 val = strtol (pos, &eptr, 10);
1246 if (errno || eptr != pos || val < 0 || (unsigned)val != val)
ec00d3fa
TV
1247 break;
1248
1249 goacc_default_dims[i] = (int)val;
c057ed9c 1250 pos = (const char *) eptr;
ec00d3fa
TV
1251 }
1252}
1253
7123ae24
UD
1254void
1255omp_display_env (int verbose)
acf0174b 1256{
acf0174b
JJ
1257 int i;
1258
acf0174b
JJ
1259 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr);
1260
d9a6bd32 1261 fputs (" _OPENMP = '201511'\n", stderr);
acf0174b
JJ
1262 fprintf (stderr, " OMP_DYNAMIC = '%s'\n",
1263 gomp_global_icv.dyn_var ? "TRUE" : "FALSE");
1264 fprintf (stderr, " OMP_NESTED = '%s'\n",
6fae7eda 1265 gomp_global_icv.max_active_levels_var > 1 ? "TRUE" : "FALSE");
acf0174b
JJ
1266
1267 fprintf (stderr, " OMP_NUM_THREADS = '%lu", gomp_global_icv.nthreads_var);
1268 for (i = 1; i < gomp_nthreads_var_list_len; i++)
1269 fprintf (stderr, ",%lu", gomp_nthreads_var_list[i]);
1270 fputs ("'\n", stderr);
1271
1272 fprintf (stderr, " OMP_SCHEDULE = '");
28567c40
JJ
1273 if ((gomp_global_icv.run_sched_var & GFS_MONOTONIC))
1274 {
1275 if (gomp_global_icv.run_sched_var != (GFS_MONOTONIC | GFS_STATIC))
1276 fputs ("MONOTONIC:", stderr);
1277 }
1278 else if (gomp_global_icv.run_sched_var == GFS_STATIC)
1279 fputs ("NONMONOTONIC:", stderr);
1280 switch (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC)
acf0174b
JJ
1281 {
1282 case GFS_RUNTIME:
1283 fputs ("RUNTIME", stderr);
28567c40
JJ
1284 if (gomp_global_icv.run_sched_chunk_size != 1)
1285 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1286 break;
1287 case GFS_STATIC:
1288 fputs ("STATIC", stderr);
28567c40
JJ
1289 if (gomp_global_icv.run_sched_chunk_size != 0)
1290 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1291 break;
1292 case GFS_DYNAMIC:
1293 fputs ("DYNAMIC", stderr);
28567c40
JJ
1294 if (gomp_global_icv.run_sched_chunk_size != 1)
1295 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1296 break;
1297 case GFS_GUIDED:
1298 fputs ("GUIDED", stderr);
28567c40
JJ
1299 if (gomp_global_icv.run_sched_chunk_size != 1)
1300 fprintf (stderr, ",%d", gomp_global_icv.run_sched_chunk_size);
acf0174b
JJ
1301 break;
1302 case GFS_AUTO:
1303 fputs ("AUTO", stderr);
1304 break;
1305 }
1306 fputs ("'\n", stderr);
1307
1308 fputs (" OMP_PROC_BIND = '", stderr);
1309 switch (gomp_global_icv.bind_var)
1310 {
1311 case omp_proc_bind_false:
1312 fputs ("FALSE", stderr);
1313 break;
1314 case omp_proc_bind_true:
1315 fputs ("TRUE", stderr);
1316 break;
1317 case omp_proc_bind_master:
432de084 1318 fputs ("MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1319 break;
1320 case omp_proc_bind_close:
1321 fputs ("CLOSE", stderr);
1322 break;
1323 case omp_proc_bind_spread:
1324 fputs ("SPREAD", stderr);
1325 break;
1326 }
1327 for (i = 1; i < gomp_bind_var_list_len; i++)
1328 switch (gomp_bind_var_list[i])
1329 {
1330 case omp_proc_bind_master:
432de084 1331 fputs (",MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1332 break;
1333 case omp_proc_bind_close:
1334 fputs (",CLOSE", stderr);
1335 break;
1336 case omp_proc_bind_spread:
1337 fputs (",SPREAD", stderr);
1338 break;
1339 }
1340 fputs ("'\n", stderr);
1341 fputs (" OMP_PLACES = '", stderr);
1342 for (i = 0; i < gomp_places_list_len; i++)
1343 {
1344 fputs ("{", stderr);
1345 gomp_affinity_print_place (gomp_places_list[i]);
1346 fputs (i + 1 == gomp_places_list_len ? "}" : "},", stderr);
1347 }
1348 fputs ("'\n", stderr);
1349
1350 fprintf (stderr, " OMP_STACKSIZE = '%lu'\n", stacksize);
1351
1352 /* GOMP's default value is actually neither active nor passive. */
1353 fprintf (stderr, " OMP_WAIT_POLICY = '%s'\n",
1354 wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1355 fprintf (stderr, " OMP_THREAD_LIMIT = '%u'\n",
1356 gomp_global_icv.thread_limit_var);
6fae7eda
KCY
1357 fprintf (stderr, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1358 gomp_global_icv.max_active_levels_var);
07dd3bcd
JJ
1359 fprintf (stderr, " OMP_NUM_TEAMS = '%u'\n", gomp_nteams_var);
1360 fprintf (stderr, " OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1361 gomp_teams_thread_limit_var);
acf0174b
JJ
1362
1363 fprintf (stderr, " OMP_CANCELLATION = '%s'\n",
1364 gomp_cancel_var ? "TRUE" : "FALSE");
1365 fprintf (stderr, " OMP_DEFAULT_DEVICE = '%d'\n",
1366 gomp_global_icv.default_device_var);
d9a6bd32
JJ
1367 fprintf (stderr, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1368 gomp_max_task_priority_var);
28567c40
JJ
1369 fprintf (stderr, " OMP_DISPLAY_AFFINITY = '%s'\n",
1370 gomp_display_affinity_var ? "TRUE" : "FALSE");
1371 fprintf (stderr, " OMP_AFFINITY_FORMAT = '%s'\n",
1372 gomp_affinity_format_var);
800bcc8c
JJ
1373 fprintf (stderr, " OMP_ALLOCATOR = '");
1374 switch (gomp_def_allocator)
1375 {
1376#define C(v) case v: fputs (#v, stderr); break;
1377 C (omp_default_mem_alloc)
1378 C (omp_large_cap_mem_alloc)
1379 C (omp_const_mem_alloc)
1380 C (omp_high_bw_mem_alloc)
1381 C (omp_low_lat_mem_alloc)
1382 C (omp_cgroup_mem_alloc)
1383 C (omp_pteam_mem_alloc)
1384 C (omp_thread_mem_alloc)
1385#undef C
1386 default: break;
1387 }
1388 fputs ("'\n", stderr);
acf0174b 1389
1bfc07d1
KCY
1390 fputs (" OMP_TARGET_OFFLOAD = '", stderr);
1391 switch (gomp_target_offload_var)
1392 {
1393 case GOMP_TARGET_OFFLOAD_DEFAULT:
1394 fputs ("DEFAULT", stderr);
1395 break;
1396 case GOMP_TARGET_OFFLOAD_MANDATORY:
1397 fputs ("MANDATORY", stderr);
1398 break;
1399 case GOMP_TARGET_OFFLOAD_DISABLED:
1400 fputs ("DISABLED", stderr);
1401 break;
1402 }
1403 fputs ("'\n", stderr);
1404
acf0174b
JJ
1405 if (verbose)
1406 {
1407 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr);
1408 fprintf (stderr, " GOMP_STACKSIZE = '%lu'\n", stacksize);
1409#ifdef HAVE_INTTYPES_H
1410 fprintf (stderr, " GOMP_SPINCOUNT = '%"PRIu64"'\n",
1411 (uint64_t) gomp_spin_count_var);
1412#else
1413 fprintf (stderr, " GOMP_SPINCOUNT = '%lu'\n",
1414 (unsigned long) gomp_spin_count_var);
1415#endif
1416 }
1417
1418 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr);
1419}
7123ae24
UD
1420ialias (omp_display_env)
1421
1422static void
1423handle_omp_display_env (void)
1424{
1425 const char *env;
1426 bool display = false;
1427 bool verbose = false;
1428
1429 env = getenv ("OMP_DISPLAY_ENV");
1430 if (env == NULL)
1431 return;
1432
1433 while (isspace ((unsigned char) *env))
1434 ++env;
1435 if (strncasecmp (env, "true", 4) == 0)
1436 {
1437 display = true;
1438 env += 4;
1439 }
1440 else if (strncasecmp (env, "false", 5) == 0)
1441 {
1442 display = false;
1443 env += 5;
1444 }
1445 else if (strncasecmp (env, "verbose", 7) == 0)
1446 {
1447 display = true;
1448 verbose = true;
1449 env += 7;
1450 }
1451 else
1452 env = "X";
1453 while (isspace ((unsigned char) *env))
1454 ++env;
1455 if (*env != '\0')
1456 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1457
1458 if (display)
3749c3af 1459 ialias_call (omp_display_env) (verbose);
7123ae24 1460}
acf0174b
JJ
1461
1462
953ff289
DN
1463static void __attribute__((constructor))
1464initialize_env (void)
1465{
7123ae24 1466 unsigned long thread_limit_var;
6fae7eda 1467 unsigned long max_active_levels_var;
d0d1b24d 1468
953ff289
DN
1469 /* Do a compile time check that mkomp_h.pl did good job. */
1470 omp_check_defines ();
1471
1472 parse_schedule ();
a68ab351 1473 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
acf0174b 1474 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
28567c40 1475 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var);
acf0174b 1476 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
1bfc07d1 1477 parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var);
d9a6bd32 1478 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
800bcc8c 1479 gomp_def_allocator = parse_allocator ();
acf0174b
JJ
1480 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false))
1481 {
1482 gomp_global_icv.thread_limit_var
1483 = thread_limit_var > INT_MAX ? UINT_MAX : thread_limit_var;
1484 }
22f1a037 1485 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var, true);
a68ab351 1486#ifndef HAVE_SYNC_BUILTINS
acf0174b 1487 gomp_mutex_init (&gomp_managed_threads_lock);
a68ab351 1488#endif
a68ab351
JJ
1489 gomp_init_num_threads ();
1490 gomp_available_cpus = gomp_global_icv.nthreads_var;
20906c66
JJ
1491 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1492 &gomp_global_icv.nthreads_var,
1493 &gomp_nthreads_var_list,
1494 &gomp_nthreads_var_list_len))
a68ab351 1495 gomp_global_icv.nthreads_var = gomp_available_cpus;
07dd3bcd
JJ
1496 parse_int ("OMP_NUM_TEAMS", &gomp_nteams_var, false);
1497 parse_int ("OMP_TEAMS_THREAD_LIMIT", &gomp_teams_thread_limit_var, false);
f89163fd
JJ
1498 bool ignore = false;
1499 if (parse_bind_var ("OMP_PROC_BIND",
1500 &gomp_global_icv.bind_var,
1501 &gomp_bind_var_list,
1502 &gomp_bind_var_list_len)
1503 && gomp_global_icv.bind_var == omp_proc_bind_false)
1504 ignore = true;
6fae7eda
KCY
1505 if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
1506 &max_active_levels_var, true))
1507 gomp_global_icv.max_active_levels_var
1508 = (max_active_levels_var > gomp_supported_active_levels)
1509 ? gomp_supported_active_levels : max_active_levels_var;
1510 else
1511 {
1512 bool nested = true;
1513
1514 /* OMP_NESTED is deprecated in OpenMP 5.0. */
1515 if (parse_boolean ("OMP_NESTED", &nested))
1516 gomp_global_icv.max_active_levels_var
1517 = nested ? gomp_supported_active_levels : 1;
1518 else if (gomp_nthreads_var_list_len > 1 || gomp_bind_var_list_len > 1)
1519 gomp_global_icv.max_active_levels_var = gomp_supported_active_levels;
1520 }
f89163fd
JJ
1521 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1522 parsed if present in the environment. If OMP_PROC_BIND was set
93d90219 1523 explicitly to false, don't populate places list though. If places
f89163fd
JJ
1524 list was successfully set from OMP_PLACES, only parse but don't process
1525 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1526 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1527 was successfully parsed into a places list, otherwise to
1528 OMP_PROC_BIND=false. */
1529 if (parse_places_var ("OMP_PLACES", ignore))
1530 {
1531 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1532 gomp_global_icv.bind_var = true;
1533 ignore = true;
1534 }
1535 if (parse_affinity (ignore))
1536 {
1537 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1538 gomp_global_icv.bind_var = true;
1539 ignore = true;
1540 }
1541 if (gomp_global_icv.bind_var != omp_proc_bind_false)
a0884cf0 1542 gomp_init_affinity ();
28567c40
JJ
1543
1544 {
1545 const char *env = getenv ("OMP_AFFINITY_FORMAT");
1546 if (env != NULL)
1547 gomp_set_affinity_format (env, strlen (env));
1548 }
1549
a68ab351
JJ
1550 wait_policy = parse_wait_policy ();
1551 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
1552 {
1553 /* Using a rough estimation of 100000 spins per msec,
1554 use 5 min blocking for OMP_WAIT_POLICY=active,
4c698cf8 1555 3 msec blocking when OMP_WAIT_POLICY is not specificed
a68ab351
JJ
1556 and 0 when OMP_WAIT_POLICY=passive.
1557 Depending on the CPU speed, this can be e.g. 5 times longer
1558 or 5 times shorter. */
1559 if (wait_policy > 0)
1560 gomp_spin_count_var = 30000000000LL;
1561 else if (wait_policy < 0)
4c698cf8 1562 gomp_spin_count_var = 300000LL;
a68ab351
JJ
1563 }
1564 /* gomp_throttled_spin_count_var is used when there are more libgomp
1565 managed threads than available CPUs. Use very short spinning. */
1566 if (wait_policy > 0)
1567 gomp_throttled_spin_count_var = 1000LL;
1568 else if (wait_policy < 0)
1569 gomp_throttled_spin_count_var = 100LL;
1570 if (gomp_throttled_spin_count_var > gomp_spin_count_var)
1571 gomp_throttled_spin_count_var = gomp_spin_count_var;
d0d1b24d
RH
1572
1573 /* Not strictly environment related, but ordering constructors is tricky. */
1574 pthread_attr_init (&gomp_thread_attr);
d0d1b24d 1575
a68ab351 1576 if (parse_stacksize ("OMP_STACKSIZE", &stacksize)
c4060df4
JJ
1577 || parse_stacksize ("GOMP_STACKSIZE", &stacksize)
1578 || GOMP_DEFAULT_STACKSIZE)
d0d1b24d 1579 {
c3b11a40
RH
1580 int err;
1581
c3b11a40
RH
1582 err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
1583
1584#ifdef PTHREAD_STACK_MIN
1585 if (err == EINVAL)
d0d1b24d 1586 {
c3b11a40
RH
1587 if (stacksize < PTHREAD_STACK_MIN)
1588 gomp_error ("Stack size less than minimum of %luk",
1589 PTHREAD_STACK_MIN / 1024ul
1590 + (PTHREAD_STACK_MIN % 1024 != 0));
1591 else
d0d1b24d 1592 gomp_error ("Stack size larger than system limit");
d0d1b24d 1593 }
c3b11a40
RH
1594 else
1595#endif
1596 if (err != 0)
1597 gomp_error ("Stack size change failed: %s", strerror (err));
d0d1b24d 1598 }
acf0174b 1599
7123ae24 1600 handle_omp_display_env ();
41dbbb37
TS
1601
1602 /* OpenACC. */
1603
1604 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num, true))
1605 goacc_device_num = 0;
1606
1607 parse_acc_device_type ();
ec00d3fa 1608 parse_gomp_openacc_dim ();
41dbbb37
TS
1609
1610 goacc_runtime_initialize ();
5fae049d
TS
1611
1612 goacc_profiling_initialize ();
953ff289 1613}
630e3c3a 1614#endif /* LIBGOMP_OFFLOADED_ONLY */