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