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