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