]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgomp/env.c
Fix argument to pthread_join
[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
953ff289
DN
102/* Parse the OMP_SCHEDULE environment variable. */
103
104static void
105parse_schedule (void)
106{
107 char *env, *end;
6acf0b38 108 unsigned long value;
28567c40 109 int monotonic = 0;
953ff289
DN
110
111 env = getenv ("OMP_SCHEDULE");
112 if (env == NULL)
113 return;
114
89b3e3cd
JJ
115 while (isspace ((unsigned char) *env))
116 ++env;
28567c40
JJ
117 if (strncasecmp (env, "monotonic", 9) == 0)
118 {
119 monotonic = 1;
120 env += 9;
121 }
122 else if (strncasecmp (env, "nonmonotonic", 12) == 0)
123 {
124 monotonic = -1;
125 env += 12;
126 }
127 if (monotonic)
128 {
129 while (isspace ((unsigned char) *env))
130 ++env;
131 if (*env != ':')
132 goto unknown;
133 ++env;
134 while (isspace ((unsigned char) *env))
135 ++env;
136 }
89b3e3cd 137 if (strncasecmp (env, "static", 6) == 0)
953ff289 138 {
a68ab351 139 gomp_global_icv.run_sched_var = GFS_STATIC;
953ff289
DN
140 env += 6;
141 }
89b3e3cd 142 else if (strncasecmp (env, "dynamic", 7) == 0)
953ff289 143 {
a68ab351 144 gomp_global_icv.run_sched_var = GFS_DYNAMIC;
953ff289
DN
145 env += 7;
146 }
89b3e3cd 147 else if (strncasecmp (env, "guided", 6) == 0)
953ff289 148 {
a68ab351 149 gomp_global_icv.run_sched_var = GFS_GUIDED;
953ff289
DN
150 env += 6;
151 }
a68ab351
JJ
152 else if (strncasecmp (env, "auto", 4) == 0)
153 {
154 gomp_global_icv.run_sched_var = GFS_AUTO;
155 env += 4;
156 }
953ff289
DN
157 else
158 goto unknown;
159
28567c40
JJ
160 if (monotonic == 1
161 || (monotonic == 0 && gomp_global_icv.run_sched_var == GFS_STATIC))
162 gomp_global_icv.run_sched_var |= GFS_MONOTONIC;
163
89b3e3cd
JJ
164 while (isspace ((unsigned char) *env))
165 ++env;
953ff289 166 if (*env == '\0')
fb79f500 167 {
d9a6bd32 168 gomp_global_icv.run_sched_chunk_size
28567c40 169 = (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC;
fb79f500
JJ
170 return;
171 }
89b3e3cd 172 if (*env++ != ',')
953ff289 173 goto unknown;
89b3e3cd
JJ
174 while (isspace ((unsigned char) *env))
175 ++env;
953ff289 176 if (*env == '\0')
953ff289
DN
177 goto invalid;
178
6acf0b38
UB
179 errno = 0;
180 value = strtoul (env, &end, 10);
181 if (errno)
182 goto invalid;
183
89b3e3cd
JJ
184 while (isspace ((unsigned char) *end))
185 ++end;
953ff289
DN
186 if (*end != '\0')
187 goto invalid;
6acf0b38 188
a68ab351
JJ
189 if ((int)value != value)
190 goto invalid;
191
28567c40
JJ
192 if (value == 0
193 && (gomp_global_icv.run_sched_var & ~GFS_MONOTONIC) != GFS_STATIC)
fb79f500 194 value = 1;
d9a6bd32 195 gomp_global_icv.run_sched_chunk_size = value;
953ff289
DN
196 return;
197
198 unknown:
199 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
200 return;
201
202 invalid:
203 gomp_error ("Invalid value for chunk size in "
204 "environment variable OMP_SCHEDULE");
953ff289
DN
205 return;
206}
207
a68ab351 208/* Parse an unsigned long environment variable. Return true if one was
22f1a037
TV
209 present and it was successfully parsed. If SECURE, use secure_getenv to the
210 environment variable. */
953ff289
DN
211
212static bool
22f1a037
TV
213parse_unsigned_long_1 (const char *name, unsigned long *pvalue, bool allow_zero,
214 bool secure)
953ff289
DN
215{
216 char *env, *end;
d0d1b24d 217 unsigned long value;
953ff289 218
22f1a037 219 env = (secure ? secure_getenv (name) : getenv (name));
953ff289
DN
220 if (env == NULL)
221 return false;
222
89b3e3cd
JJ
223 while (isspace ((unsigned char) *env))
224 ++env;
953ff289
DN
225 if (*env == '\0')
226 goto invalid;
227
6acf0b38 228 errno = 0;
d0d1b24d 229 value = strtoul (env, &end, 10);
80f046cc 230 if (errno || (long) value <= 0 - allow_zero)
6acf0b38
UB
231 goto invalid;
232
89b3e3cd
JJ
233 while (isspace ((unsigned char) *end))
234 ++end;
953ff289
DN
235 if (*end != '\0')
236 goto invalid;
d0d1b24d
RH
237
238 *pvalue = value;
953ff289
DN
239 return true;
240
241 invalid:
d0d1b24d 242 gomp_error ("Invalid value for environment variable %s", name);
953ff289
DN
243 return false;
244}
245
22f1a037
TV
246/* As parse_unsigned_long_1, but always use getenv. */
247
248static bool
249parse_unsigned_long (const char *name, unsigned long *pvalue, bool allow_zero)
250{
251 return parse_unsigned_long_1 (name, pvalue, allow_zero, false);
252}
253
acf0174b 254/* Parse a positive int environment variable. Return true if one was
22f1a037
TV
255 present and it was successfully parsed. If SECURE, use secure_getenv to the
256 environment variable. */
acf0174b
JJ
257
258static bool
22f1a037 259parse_int_1 (const char *name, int *pvalue, bool allow_zero, bool secure)
acf0174b
JJ
260{
261 unsigned long value;
22f1a037 262 if (!parse_unsigned_long_1 (name, &value, allow_zero, secure))
acf0174b
JJ
263 return false;
264 if (value > INT_MAX)
265 {
266 gomp_error ("Invalid value for environment variable %s", name);
267 return false;
268 }
269 *pvalue = (int) value;
270 return true;
271}
272
22f1a037
TV
273/* As parse_int_1, but use getenv. */
274
275static bool
276parse_int (const char *name, int *pvalue, bool allow_zero)
277{
278 return parse_int_1 (name, pvalue, allow_zero, false);
279}
280
281/* As parse_int_1, but use getenv_secure. */
282
283static bool
284parse_int_secure (const char *name, int *pvalue, bool allow_zero)
285{
286 return parse_int_1 (name, pvalue, allow_zero, true);
287}
288
20906c66
JJ
289/* Parse an unsigned long list environment variable. Return true if one was
290 present and it was successfully parsed. */
291
292static bool
293parse_unsigned_long_list (const char *name, unsigned long *p1stvalue,
294 unsigned long **pvalues,
295 unsigned long *pnvalues)
296{
297 char *env, *end;
298 unsigned long value, *values = NULL;
299
300 env = getenv (name);
301 if (env == NULL)
302 return false;
303
304 while (isspace ((unsigned char) *env))
305 ++env;
306 if (*env == '\0')
307 goto invalid;
308
309 errno = 0;
310 value = strtoul (env, &end, 10);
311 if (errno || (long) value <= 0)
312 goto invalid;
313
314 while (isspace ((unsigned char) *end))
315 ++end;
316 if (*end != '\0')
317 {
318 if (*end == ',')
319 {
320 unsigned long nvalues = 0, nalloced = 0;
321
322 do
323 {
324 env = end + 1;
325 if (nvalues == nalloced)
326 {
327 unsigned long *n;
328 nalloced = nalloced ? nalloced * 2 : 16;
329 n = realloc (values, nalloced * sizeof (unsigned long));
330 if (n == NULL)
331 {
332 free (values);
333 gomp_error ("Out of memory while trying to parse"
334 " environment variable %s", name);
335 return false;
336 }
337 values = n;
338 if (nvalues == 0)
339 values[nvalues++] = value;
340 }
341
342 while (isspace ((unsigned char) *env))
343 ++env;
344 if (*env == '\0')
345 goto invalid;
346
347 errno = 0;
348 value = strtoul (env, &end, 10);
349 if (errno || (long) value <= 0)
350 goto invalid;
351
352 values[nvalues++] = value;
353 while (isspace ((unsigned char) *end))
354 ++end;
355 if (*end == '\0')
356 break;
357 if (*end != ',')
358 goto invalid;
359 }
360 while (1);
361 *p1stvalue = values[0];
362 *pvalues = values;
363 *pnvalues = nvalues;
364 return true;
365 }
366 goto invalid;
367 }
368
369 *p1stvalue = value;
370 return true;
371
372 invalid:
373 free (values);
374 gomp_error ("Invalid value for environment variable %s", name);
375 return false;
376}
377
1bfc07d1
KCY
378static void
379parse_target_offload (const char *name, enum gomp_target_offload_t *offload)
380{
381 const char *env;
121a8812 382 int new_offload = -1;
1bfc07d1
KCY
383
384 env = getenv (name);
385 if (env == NULL)
386 return;
387
388 while (isspace ((unsigned char) *env))
389 ++env;
390 if (strncasecmp (env, "default", 7) == 0)
391 {
392 env += 7;
1bfc07d1
KCY
393 new_offload = GOMP_TARGET_OFFLOAD_DEFAULT;
394 }
395 else if (strncasecmp (env, "mandatory", 9) == 0)
396 {
397 env += 9;
1bfc07d1
KCY
398 new_offload = GOMP_TARGET_OFFLOAD_MANDATORY;
399 }
400 else if (strncasecmp (env, "disabled", 8) == 0)
401 {
402 env += 8;
1bfc07d1
KCY
403 new_offload = GOMP_TARGET_OFFLOAD_DISABLED;
404 }
405 while (isspace ((unsigned char) *env))
406 ++env;
121a8812 407 if (new_offload != -1 && *env == '\0')
1bfc07d1
KCY
408 {
409 *offload = new_offload;
410 return;
411 }
412
413 gomp_error ("Invalid value for environment variable OMP_TARGET_OFFLOAD");
414}
415
acf0174b
JJ
416/* Parse environment variable set to a boolean or list of omp_proc_bind_t
417 enum values. Return true if one was present and it was successfully
418 parsed. */
419
420static bool
421parse_bind_var (const char *name, char *p1stvalue,
422 char **pvalues, unsigned long *pnvalues)
423{
424 char *env;
c8673881 425 char value = omp_proc_bind_false, *values = NULL;
acf0174b
JJ
426 int i;
427 static struct proc_bind_kinds
428 {
429 const char name[7];
430 const char len;
431 omp_proc_bind_t kind;
432 } kinds[] =
433 {
434 { "false", 5, omp_proc_bind_false },
435 { "true", 4, omp_proc_bind_true },
436 { "master", 6, omp_proc_bind_master },
437 { "close", 5, omp_proc_bind_close },
438 { "spread", 6, omp_proc_bind_spread }
439 };
440
441 env = getenv (name);
442 if (env == NULL)
443 return false;
444
445 while (isspace ((unsigned char) *env))
446 ++env;
447 if (*env == '\0')
448 goto invalid;
449
450 for (i = 0; i < 5; i++)
451 if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
452 {
453 value = kinds[i].kind;
454 env += kinds[i].len;
455 break;
456 }
457 if (i == 5)
458 goto invalid;
459
460 while (isspace ((unsigned char) *env))
461 ++env;
462 if (*env != '\0')
463 {
464 if (*env == ',')
465 {
466 unsigned long nvalues = 0, nalloced = 0;
467
468 if (value == omp_proc_bind_false
469 || value == omp_proc_bind_true)
470 goto invalid;
471
472 do
473 {
474 env++;
475 if (nvalues == nalloced)
476 {
477 char *n;
478 nalloced = nalloced ? nalloced * 2 : 16;
479 n = realloc (values, nalloced);
480 if (n == NULL)
481 {
482 free (values);
483 gomp_error ("Out of memory while trying to parse"
484 " environment variable %s", name);
485 return false;
486 }
487 values = n;
488 if (nvalues == 0)
489 values[nvalues++] = value;
490 }
491
492 while (isspace ((unsigned char) *env))
493 ++env;
494 if (*env == '\0')
495 goto invalid;
496
497 for (i = 2; i < 5; i++)
498 if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
499 {
500 value = kinds[i].kind;
501 env += kinds[i].len;
502 break;
503 }
504 if (i == 5)
505 goto invalid;
506
507 values[nvalues++] = value;
508 while (isspace ((unsigned char) *env))
509 ++env;
510 if (*env == '\0')
511 break;
512 if (*env != ',')
513 goto invalid;
514 }
515 while (1);
516 *p1stvalue = values[0];
517 *pvalues = values;
518 *pnvalues = nvalues;
519 return true;
520 }
521 goto invalid;
522 }
523
524 *p1stvalue = value;
525 return true;
526
527 invalid:
528 free (values);
529 gomp_error ("Invalid value for environment variable %s", name);
530 return false;
531}
532
533static bool
534parse_one_place (char **envp, bool *negatep, unsigned long *lenp,
535 long *stridep)
536{
537 char *env = *envp, *start;
538 void *p = gomp_places_list ? gomp_places_list[gomp_places_list_len] : NULL;
539 unsigned long len = 1;
540 long stride = 1;
541 int pass;
542 bool any_negate = false;
543 *negatep = false;
544 while (isspace ((unsigned char) *env))
545 ++env;
546 if (*env == '!')
547 {
548 *negatep = true;
549 ++env;
550 while (isspace ((unsigned char) *env))
551 ++env;
552 }
553 if (*env != '{')
554 return false;
555 ++env;
556 while (isspace ((unsigned char) *env))
557 ++env;
558 start = env;
559 for (pass = 0; pass < (any_negate ? 2 : 1); pass++)
560 {
561 env = start;
562 do
563 {
564 unsigned long this_num, this_len = 1;
565 long this_stride = 1;
566 bool this_negate = (*env == '!');
567 if (this_negate)
568 {
569 if (gomp_places_list)
570 any_negate = true;
571 ++env;
572 while (isspace ((unsigned char) *env))
573 ++env;
574 }
575
576 errno = 0;
577 this_num = strtoul (env, &env, 10);
578 if (errno)
579 return false;
580 while (isspace ((unsigned char) *env))
581 ++env;
582 if (*env == ':')
583 {
584 ++env;
585 while (isspace ((unsigned char) *env))
586 ++env;
587 errno = 0;
588 this_len = strtoul (env, &env, 10);
589 if (errno || this_len == 0)
590 return false;
591 while (isspace ((unsigned char) *env))
592 ++env;
593 if (*env == ':')
594 {
595 ++env;
596 while (isspace ((unsigned char) *env))
597 ++env;
598 errno = 0;
599 this_stride = strtol (env, &env, 10);
600 if (errno)
601 return false;
602 while (isspace ((unsigned char) *env))
603 ++env;
604 }
605 }
606 if (this_negate && this_len != 1)
607 return false;
608 if (gomp_places_list && pass == this_negate)
609 {
610 if (this_negate)
611 {
612 if (!gomp_affinity_remove_cpu (p, this_num))
613 return false;
614 }
615 else if (!gomp_affinity_add_cpus (p, this_num, this_len,
616 this_stride, false))
617 return false;
618 }
619 if (*env == '}')
620 break;
621 if (*env != ',')
622 return false;
623 ++env;
624 }
625 while (1);
626 }
627
628 ++env;
629 while (isspace ((unsigned char) *env))
630 ++env;
631 if (*env == ':')
632 {
633 ++env;
634 while (isspace ((unsigned char) *env))
635 ++env;
636 errno = 0;
637 len = strtoul (env, &env, 10);
638 if (errno || len == 0 || len >= 65536)
639 return false;
640 while (isspace ((unsigned char) *env))
641 ++env;
642 if (*env == ':')
643 {
644 ++env;
645 while (isspace ((unsigned char) *env))
646 ++env;
647 errno = 0;
648 stride = strtol (env, &env, 10);
649 if (errno)
650 return false;
651 while (isspace ((unsigned char) *env))
652 ++env;
653 }
654 }
655 if (*negatep && len != 1)
656 return false;
657 *envp = env;
658 *lenp = len;
659 *stridep = stride;
660 return true;
661}
662
663static bool
f89163fd 664parse_places_var (const char *name, bool ignore)
acf0174b
JJ
665{
666 char *env = getenv (name), *end;
667 bool any_negate = false;
668 int level = 0;
669 unsigned long count = 0;
670 if (env == NULL)
671 return false;
672
673 while (isspace ((unsigned char) *env))
674 ++env;
675 if (*env == '\0')
676 goto invalid;
677
678 if (strncasecmp (env, "threads", 7) == 0)
679 {
680 env += 7;
681 level = 1;
682 }
683 else if (strncasecmp (env, "cores", 5) == 0)
684 {
685 env += 5;
686 level = 2;
687 }
688 else if (strncasecmp (env, "sockets", 7) == 0)
689 {
690 env += 7;
691 level = 3;
692 }
693 if (level)
694 {
695 count = ULONG_MAX;
696 while (isspace ((unsigned char) *env))
697 ++env;
698 if (*env != '\0')
699 {
700 if (*env++ != '(')
701 goto invalid;
702 while (isspace ((unsigned char) *env))
703 ++env;
704
705 errno = 0;
706 count = strtoul (env, &end, 10);
707 if (errno)
708 goto invalid;
709 env = end;
710 while (isspace ((unsigned char) *env))
711 ++env;
712 if (*env != ')')
713 goto invalid;
714 ++env;
715 while (isspace ((unsigned char) *env))
716 ++env;
717 if (*env != '\0')
718 goto invalid;
719 }
f89163fd
JJ
720
721 if (ignore)
722 return false;
723
acf0174b
JJ
724 return gomp_affinity_init_level (level, count, false);
725 }
726
727 count = 0;
728 end = env;
729 do
730 {
731 bool negate;
732 unsigned long len;
733 long stride;
734 if (!parse_one_place (&end, &negate, &len, &stride))
735 goto invalid;
736 if (negate)
737 {
738 if (!any_negate)
739 count++;
740 any_negate = true;
741 }
742 else
743 count += len;
744 if (count > 65536)
745 goto invalid;
746 if (*end == '\0')
747 break;
748 if (*end != ',')
749 goto invalid;
750 end++;
751 }
752 while (1);
753
f89163fd 754 if (ignore)
acf0174b
JJ
755 return false;
756
757 gomp_places_list_len = 0;
758 gomp_places_list = gomp_affinity_alloc (count, false);
759 if (gomp_places_list == NULL)
760 return false;
761
762 do
763 {
764 bool negate;
765 unsigned long len;
766 long stride;
767 gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
768 if (!parse_one_place (&env, &negate, &len, &stride))
769 goto invalid;
770 if (negate)
771 {
772 void *p;
773 for (count = 0; count < gomp_places_list_len; count++)
774 if (gomp_affinity_same_place
775 (gomp_places_list[count],
776 gomp_places_list[gomp_places_list_len]))
777 break;
778 if (count == gomp_places_list_len)
779 {
780 gomp_error ("Trying to remove a non-existing place from list "
781 "of places");
782 goto invalid;
783 }
784 p = gomp_places_list[count];
785 memmove (&gomp_places_list[count],
786 &gomp_places_list[count + 1],
787 (gomp_places_list_len - count - 1) * sizeof (void *));
788 --gomp_places_list_len;
789 gomp_places_list[gomp_places_list_len] = p;
790 }
791 else if (len == 1)
792 ++gomp_places_list_len;
793 else
794 {
795 for (count = 0; count < len - 1; count++)
796 if (!gomp_affinity_copy_place
797 (gomp_places_list[gomp_places_list_len + count + 1],
798 gomp_places_list[gomp_places_list_len + count],
799 stride))
800 goto invalid;
801 gomp_places_list_len += len;
802 }
803 if (*env == '\0')
804 break;
805 env++;
806 }
807 while (1);
808
809 if (gomp_places_list_len == 0)
810 {
811 gomp_error ("All places have been removed");
812 goto invalid;
813 }
814 if (!gomp_affinity_finalize_place_list (false))
815 goto invalid;
816 return true;
817
818 invalid:
819 free (gomp_places_list);
820 gomp_places_list = NULL;
821 gomp_places_list_len = 0;
822 gomp_error ("Invalid value for environment variable %s", name);
823 return false;
824}
825
a68ab351
JJ
826/* Parse the OMP_STACKSIZE environment varible. Return true if one was
827 present and it was successfully parsed. */
828
829static bool
830parse_stacksize (const char *name, unsigned long *pvalue)
831{
832 char *env, *end;
833 unsigned long value, shift = 10;
834
835 env = getenv (name);
836 if (env == NULL)
837 return false;
838
839 while (isspace ((unsigned char) *env))
840 ++env;
841 if (*env == '\0')
842 goto invalid;
843
844 errno = 0;
845 value = strtoul (env, &end, 10);
846 if (errno)
847 goto invalid;
848
849 while (isspace ((unsigned char) *end))
850 ++end;
851 if (*end != '\0')
852 {
323ff903 853 switch (tolower ((unsigned char) *end))
a68ab351
JJ
854 {
855 case 'b':
856 shift = 0;
857 break;
858 case 'k':
859 break;
860 case 'm':
861 shift = 20;
862 break;
863 case 'g':
864 shift = 30;
865 break;
866 default:
867 goto invalid;
868 }
869 ++end;
870 while (isspace ((unsigned char) *end))
871 ++end;
872 if (*end != '\0')
873 goto invalid;
874 }
875
876 if (((value << shift) >> shift) != value)
877 goto invalid;
878
879 *pvalue = value << shift;
880 return true;
881
882 invalid:
883 gomp_error ("Invalid value for environment variable %s", name);
884 return false;
885}
886
887/* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
888 present and it was successfully parsed. */
889
890static bool
891parse_spincount (const char *name, unsigned long long *pvalue)
892{
893 char *env, *end;
894 unsigned long long value, mult = 1;
895
896 env = getenv (name);
897 if (env == NULL)
898 return false;
899
900 while (isspace ((unsigned char) *env))
901 ++env;
902 if (*env == '\0')
903 goto invalid;
904
905 if (strncasecmp (env, "infinite", 8) == 0
906 || strncasecmp (env, "infinity", 8) == 0)
907 {
908 value = ~0ULL;
909 end = env + 8;
910 goto check_tail;
911 }
912
913 errno = 0;
914 value = strtoull (env, &end, 10);
915 if (errno)
916 goto invalid;
917
918 while (isspace ((unsigned char) *end))
919 ++end;
920 if (*end != '\0')
921 {
323ff903 922 switch (tolower ((unsigned char) *end))
a68ab351
JJ
923 {
924 case 'k':
925 mult = 1000LL;
926 break;
927 case 'm':
928 mult = 1000LL * 1000LL;
929 break;
930 case 'g':
931 mult = 1000LL * 1000LL * 1000LL;
932 break;
933 case 't':
934 mult = 1000LL * 1000LL * 1000LL * 1000LL;
935 break;
936 default:
937 goto invalid;
938 }
939 ++end;
940 check_tail:
941 while (isspace ((unsigned char) *end))
942 ++end;
943 if (*end != '\0')
944 goto invalid;
945 }
946
947 if (value > ~0ULL / mult)
948 value = ~0ULL;
949 else
950 value *= mult;
951
952 *pvalue = value;
953 return true;
954
955 invalid:
956 gomp_error ("Invalid value for environment variable %s", name);
957 return false;
958}
959
960/* Parse a boolean value for environment variable NAME and store the
6fae7eda
KCY
961 result in VALUE. Return true if one was present and it was
962 successfully parsed. */
953ff289 963
6fae7eda 964static bool
953ff289
DN
965parse_boolean (const char *name, bool *value)
966{
967 const char *env;
968
969 env = getenv (name);
970 if (env == NULL)
6fae7eda 971 return false;
953ff289 972
89b3e3cd
JJ
973 while (isspace ((unsigned char) *env))
974 ++env;
975 if (strncasecmp (env, "true", 4) == 0)
976 {
977 *value = true;
978 env += 4;
979 }
980 else if (strncasecmp (env, "false", 5) == 0)
981 {
982 *value = false;
983 env += 5;
984 }
953ff289 985 else
89b3e3cd
JJ
986 env = "X";
987 while (isspace ((unsigned char) *env))
988 ++env;
989 if (*env != '\0')
6fae7eda
KCY
990 {
991 gomp_error ("Invalid value for environment variable %s", name);
992 return false;
993 }
994 return true;
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",
6fae7eda 1259 gomp_global_icv.max_active_levels_var > 1 ? "TRUE" : "FALSE");
acf0174b
JJ
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);
6fae7eda
KCY
1351 fprintf (stderr, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1352 gomp_global_icv.max_active_levels_var);
acf0174b
JJ
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;
6fae7eda 1417 unsigned long max_active_levels_var;
a68ab351 1418 int wait_policy;
d0d1b24d 1419
953ff289
DN
1420 /* Do a compile time check that mkomp_h.pl did good job. */
1421 omp_check_defines ();
1422
1423 parse_schedule ();
a68ab351 1424 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_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);
800bcc8c 1430 gomp_def_allocator = parse_allocator ();
acf0174b
JJ
1431 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false))
1432 {
1433 gomp_global_icv.thread_limit_var
1434 = thread_limit_var > INT_MAX ? UINT_MAX : thread_limit_var;
1435 }
22f1a037 1436 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var, true);
a68ab351 1437#ifndef HAVE_SYNC_BUILTINS
acf0174b 1438 gomp_mutex_init (&gomp_managed_threads_lock);
a68ab351 1439#endif
a68ab351
JJ
1440 gomp_init_num_threads ();
1441 gomp_available_cpus = gomp_global_icv.nthreads_var;
20906c66
JJ
1442 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1443 &gomp_global_icv.nthreads_var,
1444 &gomp_nthreads_var_list,
1445 &gomp_nthreads_var_list_len))
a68ab351 1446 gomp_global_icv.nthreads_var = gomp_available_cpus;
f89163fd
JJ
1447 bool ignore = false;
1448 if (parse_bind_var ("OMP_PROC_BIND",
1449 &gomp_global_icv.bind_var,
1450 &gomp_bind_var_list,
1451 &gomp_bind_var_list_len)
1452 && gomp_global_icv.bind_var == omp_proc_bind_false)
1453 ignore = true;
6fae7eda
KCY
1454 if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
1455 &max_active_levels_var, true))
1456 gomp_global_icv.max_active_levels_var
1457 = (max_active_levels_var > gomp_supported_active_levels)
1458 ? gomp_supported_active_levels : max_active_levels_var;
1459 else
1460 {
1461 bool nested = true;
1462
1463 /* OMP_NESTED is deprecated in OpenMP 5.0. */
1464 if (parse_boolean ("OMP_NESTED", &nested))
1465 gomp_global_icv.max_active_levels_var
1466 = nested ? gomp_supported_active_levels : 1;
1467 else if (gomp_nthreads_var_list_len > 1 || gomp_bind_var_list_len > 1)
1468 gomp_global_icv.max_active_levels_var = gomp_supported_active_levels;
1469 }
f89163fd
JJ
1470 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1471 parsed if present in the environment. If OMP_PROC_BIND was set
93d90219 1472 explicitly to false, don't populate places list though. If places
f89163fd
JJ
1473 list was successfully set from OMP_PLACES, only parse but don't process
1474 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1475 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1476 was successfully parsed into a places list, otherwise to
1477 OMP_PROC_BIND=false. */
1478 if (parse_places_var ("OMP_PLACES", ignore))
1479 {
1480 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1481 gomp_global_icv.bind_var = true;
1482 ignore = true;
1483 }
1484 if (parse_affinity (ignore))
1485 {
1486 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1487 gomp_global_icv.bind_var = true;
1488 ignore = true;
1489 }
1490 if (gomp_global_icv.bind_var != omp_proc_bind_false)
a0884cf0 1491 gomp_init_affinity ();
28567c40
JJ
1492
1493 {
1494 const char *env = getenv ("OMP_AFFINITY_FORMAT");
1495 if (env != NULL)
1496 gomp_set_affinity_format (env, strlen (env));
1497 }
1498
a68ab351
JJ
1499 wait_policy = parse_wait_policy ();
1500 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
1501 {
1502 /* Using a rough estimation of 100000 spins per msec,
1503 use 5 min blocking for OMP_WAIT_POLICY=active,
4c698cf8 1504 3 msec blocking when OMP_WAIT_POLICY is not specificed
a68ab351
JJ
1505 and 0 when OMP_WAIT_POLICY=passive.
1506 Depending on the CPU speed, this can be e.g. 5 times longer
1507 or 5 times shorter. */
1508 if (wait_policy > 0)
1509 gomp_spin_count_var = 30000000000LL;
1510 else if (wait_policy < 0)
4c698cf8 1511 gomp_spin_count_var = 300000LL;
a68ab351
JJ
1512 }
1513 /* gomp_throttled_spin_count_var is used when there are more libgomp
1514 managed threads than available CPUs. Use very short spinning. */
1515 if (wait_policy > 0)
1516 gomp_throttled_spin_count_var = 1000LL;
1517 else if (wait_policy < 0)
1518 gomp_throttled_spin_count_var = 100LL;
1519 if (gomp_throttled_spin_count_var > gomp_spin_count_var)
1520 gomp_throttled_spin_count_var = gomp_spin_count_var;
d0d1b24d
RH
1521
1522 /* Not strictly environment related, but ordering constructors is tricky. */
1523 pthread_attr_init (&gomp_thread_attr);
d0d1b24d 1524
a68ab351 1525 if (parse_stacksize ("OMP_STACKSIZE", &stacksize)
c4060df4
JJ
1526 || parse_stacksize ("GOMP_STACKSIZE", &stacksize)
1527 || GOMP_DEFAULT_STACKSIZE)
d0d1b24d 1528 {
c3b11a40
RH
1529 int err;
1530
c3b11a40
RH
1531 err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
1532
1533#ifdef PTHREAD_STACK_MIN
1534 if (err == EINVAL)
d0d1b24d 1535 {
c3b11a40
RH
1536 if (stacksize < PTHREAD_STACK_MIN)
1537 gomp_error ("Stack size less than minimum of %luk",
1538 PTHREAD_STACK_MIN / 1024ul
1539 + (PTHREAD_STACK_MIN % 1024 != 0));
1540 else
d0d1b24d 1541 gomp_error ("Stack size larger than system limit");
d0d1b24d 1542 }
c3b11a40
RH
1543 else
1544#endif
1545 if (err != 0)
1546 gomp_error ("Stack size change failed: %s", strerror (err));
d0d1b24d 1547 }
acf0174b
JJ
1548
1549 handle_omp_display_env (stacksize, wait_policy);
41dbbb37
TS
1550
1551 /* OpenACC. */
1552
1553 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num, true))
1554 goacc_device_num = 0;
1555
1556 parse_acc_device_type ();
ec00d3fa 1557 parse_gomp_openacc_dim ();
41dbbb37
TS
1558
1559 goacc_runtime_initialize ();
5fae049d
TS
1560
1561 goacc_profiling_initialize ();
953ff289 1562}
630e3c3a 1563#endif /* LIBGOMP_OFFLOADED_ONLY */