]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgomp/env.c
[testsuite][aarch64] Adjust vect_copy_lane_1.c for new code-gen.
[thirdparty/gcc.git] / libgomp / env.c
CommitLineData
83ffe9cd 1/* Copyright (C) 2005-2023 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 62#include "secure_getenv.h"
7d37c7f6 63#include "environ.h"
22f1a037 64
18c8b56c
TB
65/* Default values of ICVs according to the OpenMP standard,
66 except for default-device-var. */
9f2fca56 67const struct gomp_default_icv gomp_default_icv_values = {
630e3c3a
AM
68 .nthreads_var = 1,
69 .thread_limit_var = UINT_MAX,
70 .run_sched_var = GFS_DYNAMIC,
71 .run_sched_chunk_size = 1,
18c8b56c 72 .default_device_var = INT_MIN,
6fae7eda 73 .max_active_levels_var = 1,
630e3c3a 74 .bind_var = omp_proc_bind_false,
9f2fca56
MV
75 .nteams_var = 0,
76 .teams_thread_limit_var = 0,
77 .dyn_var = false
78};
79
80struct gomp_task_icv gomp_global_icv = {
81 .nthreads_var = gomp_default_icv_values.nthreads_var,
82 .thread_limit_var = gomp_default_icv_values.thread_limit_var,
83 .run_sched_var = gomp_default_icv_values.run_sched_var,
84 .run_sched_chunk_size = gomp_default_icv_values.run_sched_chunk_size,
85 .default_device_var = gomp_default_icv_values.default_device_var,
86 .dyn_var = gomp_default_icv_values.dyn_var,
87 .max_active_levels_var = gomp_default_icv_values.max_active_levels_var,
88 .bind_var = gomp_default_icv_values.bind_var,
630e3c3a
AM
89 .target_data = NULL
90};
91
9f2fca56
MV
92/* List for initial "_DEV", "_ALL", and "_DEV_X" ICVs like OMP_NUM_TEAMS_DEV,
93 OMP_NUM_TEAMS_ALL, or OMP_NUM_TEAMS_DEV_42. */
94struct gomp_icv_list *gomp_initial_icv_list = NULL;
95
96/* List for "_DEV_X" ICVs like OMP_NUM_TEAMS_DEV_42. This list contains all
97 device-specific ICVs that are copied from host to device and back. */
98struct gomp_offload_icv_list *gomp_offload_icv_list = NULL;
99
630e3c3a 100bool gomp_cancel_var = false;
1bfc07d1
KCY
101enum gomp_target_offload_t gomp_target_offload_var
102 = GOMP_TARGET_OFFLOAD_DEFAULT;
630e3c3a
AM
103int gomp_max_task_priority_var = 0;
104#ifndef HAVE_SYNC_BUILTINS
105gomp_mutex_t gomp_managed_threads_lock;
106#endif
107unsigned long gomp_available_cpus = 1, gomp_managed_threads = 1;
108unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
109unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len;
110char *gomp_bind_var_list;
111unsigned long gomp_bind_var_list_len;
112void **gomp_places_list;
113unsigned long gomp_places_list_len;
800bcc8c 114uintptr_t gomp_def_allocator = omp_default_mem_alloc;
73a0d3bf 115char *gomp_def_allocator_envvar = NULL;
630e3c3a
AM
116int gomp_debug_var;
117unsigned int gomp_num_teams_var;
07dd3bcd
JJ
118int gomp_nteams_var;
119int gomp_teams_thread_limit_var;
28567c40
JJ
120bool gomp_display_affinity_var;
121char *gomp_affinity_format_var = "level %L thread %i affinity %A";
122size_t gomp_affinity_format_len;
630e3c3a
AM
123char *goacc_device_type;
124int goacc_device_num;
ec00d3fa 125int goacc_default_dims[GOMP_DIM_MAX];
630e3c3a
AM
126
127#ifndef LIBGOMP_OFFLOADED_ONLY
953ff289 128
288bc7b5 129static int wait_policy = -1;
7123ae24
UD
130static unsigned long stacksize = GOMP_DEFAULT_STACKSIZE;
131
953ff289 132static void
9f2fca56 133print_env_var_error (const char *env, const char *val)
953ff289 134{
9f2fca56
MV
135 gomp_error ("Invalid value for environment variable %.*s: %s",
136 (int) (val - env - 1), env, val);
137}
138
139/* Parse the OMP_SCHEDULE environment variable. */
140static bool
141parse_schedule (const char *env, const char *val, void *const params[])
142{
143 enum gomp_schedule_type *schedule = (enum gomp_schedule_type *) params[0];
144 int *chunk_size = (int *) params[1];
145 char *end;
6acf0b38 146 unsigned long value;
28567c40 147 int monotonic = 0;
953ff289 148
9f2fca56
MV
149 if (val == NULL)
150 return false;
953ff289 151
9f2fca56
MV
152 while (isspace ((unsigned char) *val))
153 ++val;
154 if (strncasecmp (val, "monotonic", 9) == 0)
28567c40
JJ
155 {
156 monotonic = 1;
9f2fca56 157 val += 9;
28567c40 158 }
9f2fca56 159 else if (strncasecmp (val, "nonmonotonic", 12) == 0)
28567c40
JJ
160 {
161 monotonic = -1;
9f2fca56 162 val += 12;
28567c40
JJ
163 }
164 if (monotonic)
165 {
9f2fca56
MV
166 while (isspace ((unsigned char) *val))
167 ++val;
168 if (*val != ':')
28567c40 169 goto unknown;
9f2fca56
MV
170 ++val;
171 while (isspace ((unsigned char) *val))
172 ++val;
28567c40 173 }
9f2fca56 174 if (strncasecmp (val, "static", 6) == 0)
953ff289 175 {
9f2fca56
MV
176 *schedule = GFS_STATIC;
177 val += 6;
953ff289 178 }
9f2fca56 179 else if (strncasecmp (val, "dynamic", 7) == 0)
953ff289 180 {
9f2fca56
MV
181 *schedule = GFS_DYNAMIC;
182 val += 7;
953ff289 183 }
9f2fca56 184 else if (strncasecmp (val, "guided", 6) == 0)
953ff289 185 {
9f2fca56
MV
186 *schedule = GFS_GUIDED;
187 val += 6;
953ff289 188 }
9f2fca56 189 else if (strncasecmp (val, "auto", 4) == 0)
a68ab351 190 {
9f2fca56
MV
191 *schedule = GFS_AUTO;
192 val += 4;
a68ab351 193 }
953ff289
DN
194 else
195 goto unknown;
196
28567c40 197 if (monotonic == 1
9f2fca56
MV
198 || (monotonic == 0 && *schedule == GFS_STATIC))
199 *schedule |= GFS_MONOTONIC;
28567c40 200
9f2fca56
MV
201 while (isspace ((unsigned char) *val))
202 ++val;
203 if (*val == '\0')
fb79f500 204 {
9f2fca56
MV
205 *chunk_size = (*schedule & ~GFS_MONOTONIC) != GFS_STATIC;
206 return true;
fb79f500 207 }
9f2fca56 208 if (*val++ != ',')
953ff289 209 goto unknown;
9f2fca56
MV
210 while (isspace ((unsigned char) *val))
211 ++val;
212 if (*val == '\0')
953ff289
DN
213 goto invalid;
214
6acf0b38 215 errno = 0;
9f2fca56
MV
216 value = strtoul (val, &end, 10);
217 if (errno || end == val)
6acf0b38
UB
218 goto invalid;
219
89b3e3cd
JJ
220 while (isspace ((unsigned char) *end))
221 ++end;
953ff289
DN
222 if (*end != '\0')
223 goto invalid;
6acf0b38 224
a68ab351
JJ
225 if ((int)value != value)
226 goto invalid;
227
9f2fca56 228 if (value == 0 && (*schedule & ~GFS_MONOTONIC) != GFS_STATIC)
fb79f500 229 value = 1;
9f2fca56
MV
230 *chunk_size = value;
231 return true;
953ff289
DN
232
233 unknown:
9f2fca56
MV
234 print_env_var_error (env, val);
235 return false;
953ff289
DN
236
237 invalid:
9f2fca56
MV
238 char name[val - env];
239 memcpy (name, env, val - env - 1);
240 name[val - env - 1] = '\0';
953ff289 241 gomp_error ("Invalid value for chunk size in "
9f2fca56
MV
242 "environment variable %s: %s", name, val);
243 return false;
953ff289
DN
244}
245
a68ab351 246/* Parse an unsigned long environment variable. Return true if one was
22f1a037
TV
247 present and it was successfully parsed. If SECURE, use secure_getenv to the
248 environment variable. */
953ff289
DN
249
250static bool
9f2fca56
MV
251parse_unsigned_long_1 (const char *env, const char *val, unsigned long *pvalue,
252 bool allow_zero)
953ff289 253{
9f2fca56 254 char *end;
d0d1b24d 255 unsigned long value;
953ff289 256
9f2fca56 257 if (val == NULL)
953ff289
DN
258 return false;
259
9f2fca56
MV
260 while (isspace ((unsigned char) *val))
261 ++val;
262 if (*val == '\0')
953ff289
DN
263 goto invalid;
264
6acf0b38 265 errno = 0;
9f2fca56
MV
266 value = strtoul (val, &end, 10);
267 if (errno || end == val || (long) value <= 0 - allow_zero)
6acf0b38
UB
268 goto invalid;
269
89b3e3cd
JJ
270 while (isspace ((unsigned char) *end))
271 ++end;
953ff289
DN
272 if (*end != '\0')
273 goto invalid;
d0d1b24d
RH
274
275 *pvalue = value;
953ff289
DN
276 return true;
277
278 invalid:
9f2fca56 279 print_env_var_error (env, val);
953ff289
DN
280 return false;
281}
282
22f1a037
TV
283/* As parse_unsigned_long_1, but always use getenv. */
284
285static bool
9f2fca56 286parse_unsigned_long (const char *env, const char *val, void *const params[])
22f1a037 287{
2a193e9d 288 unsigned long upper = (uintptr_t) params[2];
9f2fca56
MV
289 unsigned long pvalue = 0;
290 bool ret = parse_unsigned_long_1 (env, val, &pvalue, (bool) params[1]);
291 if (!ret)
292 return false;
293
294 if (upper == 0)
295 *(unsigned long *) params[0] = pvalue;
296 else
297 {
298 if (pvalue > upper)
299 pvalue = upper;
300 if (upper <= UCHAR_MAX)
301 *(unsigned char *) params[0] = pvalue;
302 else if (upper <= UINT_MAX)
303 *(unsigned int *) params[0] = pvalue;
304 else
305 *(unsigned long *) params[0] = pvalue;
306 }
307
308 return ret;
22f1a037
TV
309}
310
acf0174b 311/* Parse a positive int environment variable. Return true if one was
22f1a037
TV
312 present and it was successfully parsed. If SECURE, use secure_getenv to the
313 environment variable. */
acf0174b
JJ
314
315static bool
9f2fca56 316parse_int_1 (const char *env, const char *val, int *pvalue, bool allow_zero)
acf0174b
JJ
317{
318 unsigned long value;
9f2fca56 319 if (!parse_unsigned_long_1 (env, val, &value, allow_zero))
acf0174b
JJ
320 return false;
321 if (value > INT_MAX)
322 {
9f2fca56 323 print_env_var_error (env, val);
acf0174b
JJ
324 return false;
325 }
326 *pvalue = (int) value;
327 return true;
328}
329
22f1a037 330static bool
9f2fca56 331parse_int (const char *env, const char *val, void *const params[])
22f1a037 332{
9f2fca56 333 return parse_int_1 (env, val, (int *) params[0], (bool) params[1]);
22f1a037
TV
334}
335
336/* As parse_int_1, but use getenv_secure. */
337
338static bool
9f2fca56 339parse_int_secure (const char *env, int *pvalue, bool allow_zero)
22f1a037 340{
9f2fca56 341 return parse_int_1 (env, secure_getenv (env), pvalue, allow_zero);
22f1a037
TV
342}
343
20906c66
JJ
344/* Parse an unsigned long list environment variable. Return true if one was
345 present and it was successfully parsed. */
346
347static bool
9f2fca56
MV
348parse_unsigned_long_list (const char *env, const char *val,
349 void *const params[])
20906c66 350{
9f2fca56
MV
351 unsigned long *p1stvalue = (unsigned long *) params[0];
352 unsigned long **pvalues = (unsigned long **) params[1];
353 unsigned long *pnvalues = (unsigned long *) params[2];
354 char *end;
20906c66
JJ
355 unsigned long value, *values = NULL;
356
9f2fca56 357 if (val == NULL)
20906c66
JJ
358 return false;
359
9f2fca56
MV
360 while (isspace ((unsigned char) *val))
361 ++val;
362 if (*val == '\0')
20906c66
JJ
363 goto invalid;
364
365 errno = 0;
9f2fca56 366 value = strtoul (val, &end, 10);
20906c66
JJ
367 if (errno || (long) value <= 0)
368 goto invalid;
369
370 while (isspace ((unsigned char) *end))
371 ++end;
372 if (*end != '\0')
373 {
374 if (*end == ',')
375 {
376 unsigned long nvalues = 0, nalloced = 0;
377
378 do
379 {
9f2fca56 380 val = end + 1;
20906c66
JJ
381 if (nvalues == nalloced)
382 {
383 unsigned long *n;
384 nalloced = nalloced ? nalloced * 2 : 16;
385 n = realloc (values, nalloced * sizeof (unsigned long));
386 if (n == NULL)
387 {
388 free (values);
9f2fca56
MV
389 char name[val - env];
390 memcpy (name, env, val - env - 1);
391 name[val - env - 1] = '\0';
20906c66
JJ
392 gomp_error ("Out of memory while trying to parse"
393 " environment variable %s", name);
394 return false;
395 }
396 values = n;
397 if (nvalues == 0)
398 values[nvalues++] = value;
399 }
400
9f2fca56
MV
401 while (isspace ((unsigned char) *val))
402 ++val;
403 if (*val == '\0')
20906c66
JJ
404 goto invalid;
405
406 errno = 0;
9f2fca56 407 value = strtoul (val, &end, 10);
20906c66
JJ
408 if (errno || (long) value <= 0)
409 goto invalid;
410
411 values[nvalues++] = value;
412 while (isspace ((unsigned char) *end))
413 ++end;
414 if (*end == '\0')
415 break;
416 if (*end != ',')
417 goto invalid;
418 }
419 while (1);
420 *p1stvalue = values[0];
421 *pvalues = values;
422 *pnvalues = nvalues;
423 return true;
424 }
425 goto invalid;
426 }
9f2fca56
MV
427 else
428 {
429 *pnvalues = 0;
430 *pvalues = NULL;
431 }
20906c66
JJ
432
433 *p1stvalue = value;
434 return true;
435
436 invalid:
437 free (values);
9f2fca56 438 print_env_var_error (env, val);
20906c66
JJ
439 return false;
440}
441
9f2fca56
MV
442static bool
443parse_target_offload (const char *env, const char *val, void *const params[])
1bfc07d1 444{
121a8812 445 int new_offload = -1;
1bfc07d1 446
9f2fca56
MV
447 if (val == NULL)
448 return false;
1bfc07d1 449
9f2fca56
MV
450 while (isspace ((unsigned char) *val))
451 ++val;
452 if (strncasecmp (val, "default", 7) == 0)
1bfc07d1 453 {
9f2fca56 454 val += 7;
1bfc07d1
KCY
455 new_offload = GOMP_TARGET_OFFLOAD_DEFAULT;
456 }
9f2fca56 457 else if (strncasecmp (val, "mandatory", 9) == 0)
1bfc07d1 458 {
9f2fca56 459 val += 9;
1bfc07d1
KCY
460 new_offload = GOMP_TARGET_OFFLOAD_MANDATORY;
461 }
9f2fca56 462 else if (strncasecmp (val, "disabled", 8) == 0)
1bfc07d1 463 {
9f2fca56 464 val += 8;
1bfc07d1
KCY
465 new_offload = GOMP_TARGET_OFFLOAD_DISABLED;
466 }
9f2fca56
MV
467 while (isspace ((unsigned char) *val))
468 ++val;
469 if (new_offload != -1 && *val == '\0')
1bfc07d1 470 {
9f2fca56
MV
471 *(enum gomp_target_offload_t *) params[0] = new_offload;
472 return true;
1bfc07d1
KCY
473 }
474
9f2fca56
MV
475 print_env_var_error (env, val);
476 return false;
1bfc07d1
KCY
477}
478
acf0174b
JJ
479/* Parse environment variable set to a boolean or list of omp_proc_bind_t
480 enum values. Return true if one was present and it was successfully
481 parsed. */
482
483static bool
9f2fca56 484parse_bind_var (const char *env, const char *val, void *const params[])
acf0174b 485{
9f2fca56
MV
486 char *p1stvalue = (char *) params[0];
487 char **pvalues = (char **) params[1];
488 unsigned long *pnvalues = (unsigned long *) params[2];
c8673881 489 char value = omp_proc_bind_false, *values = NULL;
acf0174b
JJ
490 int i;
491 static struct proc_bind_kinds
492 {
493 const char name[7];
494 const char len;
495 omp_proc_bind_t kind;
496 } kinds[] =
497 {
498 { "false", 5, omp_proc_bind_false },
499 { "true", 4, omp_proc_bind_true },
500 { "master", 6, omp_proc_bind_master },
432de084 501 { "primary", 7, omp_proc_bind_primary },
acf0174b
JJ
502 { "close", 5, omp_proc_bind_close },
503 { "spread", 6, omp_proc_bind_spread }
504 };
505
9f2fca56 506 if (val == NULL)
acf0174b
JJ
507 return false;
508
9f2fca56
MV
509 while (isspace ((unsigned char) *val))
510 ++val;
511 if (*val == '\0')
acf0174b
JJ
512 goto invalid;
513
432de084 514 for (i = 0; i < 6; i++)
9f2fca56 515 if (strncasecmp (val, kinds[i].name, kinds[i].len) == 0)
acf0174b
JJ
516 {
517 value = kinds[i].kind;
9f2fca56 518 val += kinds[i].len;
acf0174b
JJ
519 break;
520 }
432de084 521 if (i == 6)
acf0174b
JJ
522 goto invalid;
523
9f2fca56
MV
524 while (isspace ((unsigned char) *val))
525 ++val;
526 if (*val != '\0')
acf0174b 527 {
9f2fca56 528 if (*val == ',')
acf0174b
JJ
529 {
530 unsigned long nvalues = 0, nalloced = 0;
531
532 if (value == omp_proc_bind_false
533 || value == omp_proc_bind_true)
534 goto invalid;
535
536 do
537 {
9f2fca56 538 val++;
acf0174b
JJ
539 if (nvalues == nalloced)
540 {
541 char *n;
542 nalloced = nalloced ? nalloced * 2 : 16;
543 n = realloc (values, nalloced);
544 if (n == NULL)
545 {
546 free (values);
9f2fca56
MV
547 char name[val - env];
548 memcpy (name, env, val - env - 1);
549 name[val - env - 1] = '\0';
acf0174b
JJ
550 gomp_error ("Out of memory while trying to parse"
551 " environment variable %s", name);
552 return false;
553 }
554 values = n;
555 if (nvalues == 0)
556 values[nvalues++] = value;
557 }
558
9f2fca56
MV
559 while (isspace ((unsigned char) *val))
560 ++val;
561 if (*val == '\0')
acf0174b
JJ
562 goto invalid;
563
432de084 564 for (i = 2; i < 6; i++)
9f2fca56 565 if (strncasecmp (val, kinds[i].name, kinds[i].len) == 0)
acf0174b
JJ
566 {
567 value = kinds[i].kind;
9f2fca56 568 val += kinds[i].len;
acf0174b
JJ
569 break;
570 }
432de084 571 if (i == 6)
acf0174b
JJ
572 goto invalid;
573
574 values[nvalues++] = value;
9f2fca56
MV
575 while (isspace ((unsigned char) *val))
576 ++val;
577 if (*val == '\0')
acf0174b 578 break;
9f2fca56 579 if (*val != ',')
acf0174b
JJ
580 goto invalid;
581 }
582 while (1);
583 *p1stvalue = values[0];
584 *pvalues = values;
585 *pnvalues = nvalues;
586 return true;
587 }
588 goto invalid;
589 }
590
591 *p1stvalue = value;
592 return true;
593
594 invalid:
595 free (values);
9f2fca56 596 print_env_var_error (env, val);
acf0174b
JJ
597 return false;
598}
599
600static bool
601parse_one_place (char **envp, bool *negatep, unsigned long *lenp,
602 long *stridep)
603{
604 char *env = *envp, *start;
605 void *p = gomp_places_list ? gomp_places_list[gomp_places_list_len] : NULL;
606 unsigned long len = 1;
607 long stride = 1;
608 int pass;
609 bool any_negate = false;
4a0fed0c 610 bool has_braces = true;
acf0174b
JJ
611 *negatep = false;
612 while (isspace ((unsigned char) *env))
613 ++env;
614 if (*env == '!')
615 {
616 *negatep = true;
617 ++env;
618 while (isspace ((unsigned char) *env))
619 ++env;
620 }
621 if (*env != '{')
4a0fed0c
JJ
622 {
623 char *end;
624 unsigned long this_num;
625
626 errno = 0;
627 this_num = strtoul (env, &end, 10);
628 if (errno || end == env)
629 return false;
630 env = end - 1;
631 has_braces = false;
632 if (gomp_places_list
633 && !gomp_affinity_add_cpus (p, this_num, 1, 1, false))
634 return false;
635 }
636 else
637 {
638 ++env;
639 while (isspace ((unsigned char) *env))
640 ++env;
641 }
acf0174b 642 start = env;
4a0fed0c 643 for (pass = 0; pass < (any_negate ? 2 : has_braces); pass++)
acf0174b
JJ
644 {
645 env = start;
646 do
647 {
648 unsigned long this_num, this_len = 1;
649 long this_stride = 1;
650 bool this_negate = (*env == '!');
c057ed9c 651 char *end;
acf0174b
JJ
652 if (this_negate)
653 {
654 if (gomp_places_list)
655 any_negate = true;
656 ++env;
657 while (isspace ((unsigned char) *env))
658 ++env;
659 }
660
661 errno = 0;
c057ed9c
JJ
662 this_num = strtoul (env, &end, 10);
663 if (errno || end == env)
acf0174b 664 return false;
c057ed9c 665 env = end;
acf0174b
JJ
666 while (isspace ((unsigned char) *env))
667 ++env;
668 if (*env == ':')
669 {
670 ++env;
4a0fed0c
JJ
671 if (this_negate)
672 return false;
acf0174b
JJ
673 while (isspace ((unsigned char) *env))
674 ++env;
675 errno = 0;
676 this_len = strtoul (env, &env, 10);
677 if (errno || this_len == 0)
678 return false;
679 while (isspace ((unsigned char) *env))
680 ++env;
681 if (*env == ':')
682 {
683 ++env;
684 while (isspace ((unsigned char) *env))
685 ++env;
686 errno = 0;
c057ed9c
JJ
687 this_stride = strtol (env, &end, 10);
688 if (errno || end == env)
acf0174b 689 return false;
c057ed9c 690 env = end;
acf0174b
JJ
691 while (isspace ((unsigned char) *env))
692 ++env;
693 }
694 }
acf0174b
JJ
695 if (gomp_places_list && pass == this_negate)
696 {
697 if (this_negate)
698 {
699 if (!gomp_affinity_remove_cpu (p, this_num))
700 return false;
701 }
702 else if (!gomp_affinity_add_cpus (p, this_num, this_len,
703 this_stride, false))
704 return false;
705 }
706 if (*env == '}')
707 break;
708 if (*env != ',')
709 return false;
710 ++env;
711 }
712 while (1);
713 }
714
715 ++env;
716 while (isspace ((unsigned char) *env))
717 ++env;
718 if (*env == ':')
719 {
c057ed9c 720 char *end;
4a0fed0c
JJ
721 if (*negatep)
722 return false;
acf0174b
JJ
723 ++env;
724 while (isspace ((unsigned char) *env))
725 ++env;
726 errno = 0;
727 len = strtoul (env, &env, 10);
728 if (errno || len == 0 || len >= 65536)
729 return false;
730 while (isspace ((unsigned char) *env))
731 ++env;
732 if (*env == ':')
733 {
734 ++env;
735 while (isspace ((unsigned char) *env))
736 ++env;
737 errno = 0;
c057ed9c
JJ
738 stride = strtol (env, &end, 10);
739 if (errno || end == env)
acf0174b 740 return false;
c057ed9c 741 env = end;
acf0174b
JJ
742 while (isspace ((unsigned char) *env))
743 ++env;
744 }
745 }
acf0174b
JJ
746 *envp = env;
747 *lenp = len;
748 *stridep = stride;
749 return true;
750}
751
752static bool
f89163fd 753parse_places_var (const char *name, bool ignore)
acf0174b
JJ
754{
755 char *env = getenv (name), *end;
756 bool any_negate = false;
757 int level = 0;
758 unsigned long count = 0;
759 if (env == NULL)
760 return false;
761
762 while (isspace ((unsigned char) *env))
763 ++env;
764 if (*env == '\0')
765 goto invalid;
766
767 if (strncasecmp (env, "threads", 7) == 0)
768 {
769 env += 7;
770 level = 1;
771 }
772 else if (strncasecmp (env, "cores", 5) == 0)
773 {
774 env += 5;
775 level = 2;
776 }
777 else if (strncasecmp (env, "sockets", 7) == 0)
778 {
779 env += 7;
780 level = 3;
781 }
5809be05
JJ
782 else if (strncasecmp (env, "ll_caches", 9) == 0)
783 {
784 env += 9;
785 level = 4;
786 }
e7ce32c7
JJ
787 else if (strncasecmp (env, "numa_domains", 12) == 0)
788 {
789 env += 12;
790 level = 5;
791 }
acf0174b
JJ
792 if (level)
793 {
794 count = ULONG_MAX;
795 while (isspace ((unsigned char) *env))
796 ++env;
797 if (*env != '\0')
798 {
799 if (*env++ != '(')
800 goto invalid;
801 while (isspace ((unsigned char) *env))
802 ++env;
803
804 errno = 0;
805 count = strtoul (env, &end, 10);
c057ed9c 806 if (errno || end == env)
acf0174b
JJ
807 goto invalid;
808 env = end;
809 while (isspace ((unsigned char) *env))
810 ++env;
811 if (*env != ')')
812 goto invalid;
813 ++env;
814 while (isspace ((unsigned char) *env))
815 ++env;
816 if (*env != '\0')
817 goto invalid;
818 }
f89163fd
JJ
819
820 if (ignore)
821 return false;
822
acf0174b
JJ
823 return gomp_affinity_init_level (level, count, false);
824 }
825
826 count = 0;
827 end = env;
828 do
829 {
830 bool negate;
831 unsigned long len;
832 long stride;
833 if (!parse_one_place (&end, &negate, &len, &stride))
834 goto invalid;
835 if (negate)
836 {
837 if (!any_negate)
838 count++;
839 any_negate = true;
840 }
841 else
842 count += len;
843 if (count > 65536)
844 goto invalid;
845 if (*end == '\0')
846 break;
847 if (*end != ',')
848 goto invalid;
849 end++;
850 }
851 while (1);
852
f89163fd 853 if (ignore)
acf0174b
JJ
854 return false;
855
856 gomp_places_list_len = 0;
857 gomp_places_list = gomp_affinity_alloc (count, false);
858 if (gomp_places_list == NULL)
859 return false;
860
861 do
862 {
863 bool negate;
864 unsigned long len;
865 long stride;
866 gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
867 if (!parse_one_place (&env, &negate, &len, &stride))
868 goto invalid;
869 if (negate)
870 {
871 void *p;
872 for (count = 0; count < gomp_places_list_len; count++)
873 if (gomp_affinity_same_place
874 (gomp_places_list[count],
875 gomp_places_list[gomp_places_list_len]))
876 break;
877 if (count == gomp_places_list_len)
878 {
879 gomp_error ("Trying to remove a non-existing place from list "
880 "of places");
881 goto invalid;
882 }
883 p = gomp_places_list[count];
884 memmove (&gomp_places_list[count],
885 &gomp_places_list[count + 1],
886 (gomp_places_list_len - count - 1) * sizeof (void *));
887 --gomp_places_list_len;
888 gomp_places_list[gomp_places_list_len] = p;
889 }
890 else if (len == 1)
891 ++gomp_places_list_len;
892 else
893 {
894 for (count = 0; count < len - 1; count++)
895 if (!gomp_affinity_copy_place
896 (gomp_places_list[gomp_places_list_len + count + 1],
897 gomp_places_list[gomp_places_list_len + count],
898 stride))
899 goto invalid;
900 gomp_places_list_len += len;
901 }
902 if (*env == '\0')
903 break;
904 env++;
905 }
906 while (1);
907
908 if (gomp_places_list_len == 0)
909 {
910 gomp_error ("All places have been removed");
911 goto invalid;
912 }
913 if (!gomp_affinity_finalize_place_list (false))
914 goto invalid;
915 return true;
916
917 invalid:
918 free (gomp_places_list);
919 gomp_places_list = NULL;
920 gomp_places_list_len = 0;
921 gomp_error ("Invalid value for environment variable %s", name);
922 return false;
923}
924
a68ab351
JJ
925/* Parse the OMP_STACKSIZE environment varible. Return true if one was
926 present and it was successfully parsed. */
927
928static bool
9f2fca56 929parse_stacksize (const char *env, const char *val, void *const params[])
a68ab351 930{
9f2fca56 931 char *end;
a68ab351
JJ
932 unsigned long value, shift = 10;
933
9f2fca56 934 if (val == NULL)
a68ab351
JJ
935 return false;
936
9f2fca56
MV
937 while (isspace ((unsigned char) *val))
938 ++val;
939 if (*val == '\0')
a68ab351
JJ
940 goto invalid;
941
942 errno = 0;
9f2fca56
MV
943 value = strtoul (val, &end, 10);
944 if (errno || end == val)
a68ab351
JJ
945 goto invalid;
946
947 while (isspace ((unsigned char) *end))
948 ++end;
949 if (*end != '\0')
950 {
323ff903 951 switch (tolower ((unsigned char) *end))
a68ab351
JJ
952 {
953 case 'b':
954 shift = 0;
955 break;
956 case 'k':
957 break;
958 case 'm':
959 shift = 20;
960 break;
961 case 'g':
962 shift = 30;
963 break;
964 default:
965 goto invalid;
966 }
967 ++end;
968 while (isspace ((unsigned char) *end))
969 ++end;
970 if (*end != '\0')
971 goto invalid;
972 }
973
974 if (((value << shift) >> shift) != value)
975 goto invalid;
976
9f2fca56 977 *(unsigned long *) params[0] = value << shift;
a68ab351
JJ
978 return true;
979
980 invalid:
9f2fca56 981 print_env_var_error (env, val);
a68ab351
JJ
982 return false;
983}
984
985/* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
986 present and it was successfully parsed. */
987
988static bool
989parse_spincount (const char *name, unsigned long long *pvalue)
990{
991 char *env, *end;
992 unsigned long long value, mult = 1;
993
994 env = getenv (name);
995 if (env == NULL)
996 return false;
997
998 while (isspace ((unsigned char) *env))
999 ++env;
1000 if (*env == '\0')
1001 goto invalid;
1002
1003 if (strncasecmp (env, "infinite", 8) == 0
1004 || strncasecmp (env, "infinity", 8) == 0)
1005 {
1006 value = ~0ULL;
1007 end = env + 8;
1008 goto check_tail;
1009 }
1010
1011 errno = 0;
1012 value = strtoull (env, &end, 10);
c057ed9c 1013 if (errno || end == env)
a68ab351
JJ
1014 goto invalid;
1015
1016 while (isspace ((unsigned char) *end))
1017 ++end;
1018 if (*end != '\0')
1019 {
323ff903 1020 switch (tolower ((unsigned char) *end))
a68ab351
JJ
1021 {
1022 case 'k':
1023 mult = 1000LL;
1024 break;
1025 case 'm':
1026 mult = 1000LL * 1000LL;
1027 break;
1028 case 'g':
1029 mult = 1000LL * 1000LL * 1000LL;
1030 break;
1031 case 't':
1032 mult = 1000LL * 1000LL * 1000LL * 1000LL;
1033 break;
1034 default:
1035 goto invalid;
1036 }
1037 ++end;
1038 check_tail:
1039 while (isspace ((unsigned char) *end))
1040 ++end;
1041 if (*end != '\0')
1042 goto invalid;
1043 }
1044
1045 if (value > ~0ULL / mult)
1046 value = ~0ULL;
1047 else
1048 value *= mult;
1049
1050 *pvalue = value;
1051 return true;
1052
1053 invalid:
1054 gomp_error ("Invalid value for environment variable %s", name);
1055 return false;
1056}
1057
1058/* Parse a boolean value for environment variable NAME and store the
6fae7eda
KCY
1059 result in VALUE. Return true if one was present and it was
1060 successfully parsed. */
6fae7eda 1061static bool
9f2fca56 1062parse_boolean (const char *env, const char *val, void *const params[])
953ff289 1063{
9f2fca56 1064 bool *value = (bool *) params[0];
953ff289 1065
9f2fca56 1066 if (val == NULL)
6fae7eda 1067 return false;
953ff289 1068
9f2fca56
MV
1069 while (isspace ((unsigned char) *val))
1070 ++val;
1071 if (strncasecmp (val, "true", 4) == 0)
89b3e3cd
JJ
1072 {
1073 *value = true;
9f2fca56 1074 val += 4;
89b3e3cd 1075 }
9f2fca56 1076 else if (strncasecmp (val, "false", 5) == 0)
89b3e3cd
JJ
1077 {
1078 *value = false;
9f2fca56 1079 val += 5;
89b3e3cd 1080 }
953ff289 1081 else
9f2fca56
MV
1082 val = "X";
1083 while (isspace ((unsigned char) *val))
1084 ++val;
1085 if (*val != '\0')
6fae7eda 1086 {
9f2fca56 1087 print_env_var_error (env, val);
6fae7eda
KCY
1088 return false;
1089 }
1090 return true;
953ff289
DN
1091}
1092
800bcc8c 1093/* Parse the OMP_WAIT_POLICY environment variable and return the value. */
a68ab351 1094
9f2fca56
MV
1095static bool
1096parse_wait_policy (const char *env, const char *val, void *const params[])
a68ab351 1097{
9f2fca56 1098 int *pvalue = (int *) params[0];
a68ab351
JJ
1099 int ret = -1;
1100
9f2fca56
MV
1101 if (val == NULL)
1102 {
1103 *pvalue = -1;
1104 return false;
1105 }
a68ab351 1106
9f2fca56
MV
1107 while (isspace ((unsigned char) *val))
1108 ++val;
1109 if (strncasecmp (val, "active", 6) == 0)
a68ab351
JJ
1110 {
1111 ret = 1;
9f2fca56 1112 val += 6;
a68ab351 1113 }
9f2fca56 1114 else if (strncasecmp (val, "passive", 7) == 0)
a68ab351
JJ
1115 {
1116 ret = 0;
9f2fca56 1117 val += 7;
a68ab351
JJ
1118 }
1119 else
9f2fca56
MV
1120 val = "X";
1121 while (isspace ((unsigned char) *val))
1122 ++val;
1123 if (*val == '\0')
1124 {
1125 *pvalue = ret;
1126 return true;
1127 }
1128 print_env_var_error (env, val);
1129 *pvalue = -1;
1130 return false;
a68ab351
JJ
1131}
1132
a0884cf0
JJ
1133/* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1134 present and it was successfully parsed. */
1135
1136static bool
f89163fd 1137parse_affinity (bool ignore)
a0884cf0 1138{
acf0174b
JJ
1139 char *env, *end, *start;
1140 int pass;
a0884cf0 1141 unsigned long cpu_beg, cpu_end, cpu_stride;
acf0174b 1142 size_t count = 0, needed;
a0884cf0
JJ
1143
1144 env = getenv ("GOMP_CPU_AFFINITY");
1145 if (env == NULL)
1146 return false;
1147
acf0174b
JJ
1148 start = env;
1149 for (pass = 0; pass < 2; pass++)
a0884cf0 1150 {
acf0174b
JJ
1151 env = start;
1152 if (pass == 1)
a0884cf0 1153 {
f89163fd
JJ
1154 if (ignore)
1155 return false;
1156
acf0174b
JJ
1157 gomp_places_list_len = 0;
1158 gomp_places_list = gomp_affinity_alloc (count, true);
1159 if (gomp_places_list == NULL)
1160 return false;
1161 }
1162 do
1163 {
1164 while (isspace ((unsigned char) *env))
1165 ++env;
1166
1167 errno = 0;
1168 cpu_beg = strtoul (env, &end, 0);
c057ed9c 1169 if (errno || end == env || cpu_beg >= 65536)
a0884cf0 1170 goto invalid;
acf0174b
JJ
1171 cpu_end = cpu_beg;
1172 cpu_stride = 1;
a0884cf0
JJ
1173
1174 env = end;
acf0174b 1175 if (*env == '-')
a0884cf0 1176 {
acf0174b
JJ
1177 errno = 0;
1178 cpu_end = strtoul (++env, &end, 0);
c057ed9c 1179 if (errno || end == env || cpu_end >= 65536 || cpu_end < cpu_beg)
a0884cf0
JJ
1180 goto invalid;
1181
1182 env = end;
acf0174b
JJ
1183 if (*env == ':')
1184 {
1185 errno = 0;
1186 cpu_stride = strtoul (++env, &end, 0);
1187 if (errno || cpu_stride == 0 || cpu_stride >= 65536)
1188 goto invalid;
a0884cf0 1189
acf0174b
JJ
1190 env = end;
1191 }
1192 }
a0884cf0 1193
acf0174b
JJ
1194 needed = (cpu_end - cpu_beg) / cpu_stride + 1;
1195 if (pass == 0)
1196 count += needed;
a0884cf0 1197 else
a0884cf0 1198 {
acf0174b
JJ
1199 while (needed--)
1200 {
1201 void *p = gomp_places_list[gomp_places_list_len];
1202 gomp_affinity_init_place (p);
1203 if (gomp_affinity_add_cpus (p, cpu_beg, 1, 0, true))
1204 ++gomp_places_list_len;
1205 cpu_beg += cpu_stride;
1206 }
a0884cf0
JJ
1207 }
1208
acf0174b
JJ
1209 while (isspace ((unsigned char) *env))
1210 ++env;
a0884cf0 1211
acf0174b
JJ
1212 if (*env == ',')
1213 env++;
1214 else if (*env == '\0')
1215 break;
a0884cf0 1216 }
acf0174b 1217 while (1);
a0884cf0 1218 }
a0884cf0 1219
acf0174b
JJ
1220 if (gomp_places_list_len == 0)
1221 {
1222 free (gomp_places_list);
1223 gomp_places_list = NULL;
f89163fd 1224 return false;
acf0174b 1225 }
a0884cf0
JJ
1226 return true;
1227
1228 invalid:
1229 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1230 return false;
1231}
1232
800bcc8c 1233/* Parse the OMP_ALLOCATOR environment variable and return the value. */
9f2fca56
MV
1234static bool
1235parse_allocator (const char *env, const char *val, void *const params[])
800bcc8c 1236{
73a0d3bf 1237 const char *orig_val = val;
9f2fca56
MV
1238 uintptr_t *ret = (uintptr_t *) params[0];
1239 *ret = omp_default_mem_alloc;
73a0d3bf
TB
1240 bool memspace = false;
1241 size_t ntraits = 0;
1242 omp_alloctrait_t *traits;
800bcc8c 1243
9f2fca56
MV
1244 if (val == NULL)
1245 return false;
800bcc8c 1246
9f2fca56
MV
1247 while (isspace ((unsigned char) *val))
1248 ++val;
800bcc8c
JJ
1249 if (0)
1250 ;
73a0d3bf 1251#define C(v, m) \
9f2fca56 1252 else if (strncasecmp (val, #v, sizeof (#v) - 1) == 0) \
800bcc8c 1253 { \
9f2fca56
MV
1254 *ret = v; \
1255 val += sizeof (#v) - 1; \
73a0d3bf 1256 memspace = m; \
800bcc8c 1257 }
73a0d3bf
TB
1258 C (omp_default_mem_alloc, false)
1259 C (omp_large_cap_mem_alloc, false)
1260 C (omp_const_mem_alloc, false)
1261 C (omp_high_bw_mem_alloc, false)
1262 C (omp_low_lat_mem_alloc, false)
1263 C (omp_cgroup_mem_alloc, false)
1264 C (omp_pteam_mem_alloc, false)
1265 C (omp_thread_mem_alloc, false)
1266 C (omp_default_mem_space, true)
1267 C (omp_large_cap_mem_space, true)
1268 C (omp_const_mem_space, true)
1269 C (omp_high_bw_mem_space, true)
1270 C (omp_low_lat_mem_space, true)
800bcc8c
JJ
1271#undef C
1272 else
73a0d3bf
TB
1273 goto invalid;
1274 if (memspace && *val == ':')
1275 {
1276 ++val;
1277 const char *cp = val;
1278 while (*cp != '\0')
1279 {
1280 if (*cp == '=')
1281 ++ntraits;
1282 ++cp;
1283 }
1284 traits = gomp_alloca (ntraits * sizeof (omp_alloctrait_t));
1285 size_t n = 0;
1286 while (*val != '\0')
1287 {
1288#define C(v) \
1289 else if (strncasecmp (val, #v "=", sizeof (#v)) == 0) \
1290 { \
1291 val += sizeof (#v); \
1292 traits[n].key = omp_atk_ ## v;
1293#define V(v) \
1294 else if (strncasecmp (val, #v, sizeof (#v) - 1) == 0) \
1295 { \
1296 val += sizeof (#v) - 1; \
1297 traits[n].value = omp_atv_ ## v; \
1298 }
1299 if (0)
1300 ;
1301 C (sync_hint)
1302 if (0)
1303 ;
1304 V (contended)
1305 V (uncontended)
1306 V (serialized)
1307 V (private)
1308 else
1309 goto invalid;
1310 }
1311 C (alignment)
1312 char *end;
1313 errno = 0;
1314 traits[n].value = strtol (val, &end, 10);
1315 if (errno || end == val || traits[n].value <= 0)
1316 goto invalid;
1317 val = end;
1318 }
1319 C (access)
1320 if (0)
1321 ;
1322 V (all)
1323 V (cgroup)
1324 V (pteam)
1325 V (thread)
1326 else
1327 goto invalid;
1328 }
1329 C (pool_size)
1330 char *end;
1331 errno = 0;
1332 traits[n].value = strtol (val, &end, 10);
1333 if (errno || end == val || traits[n].value <= 0)
1334 goto invalid;
1335 val = end;
1336 }
1337 C (fallback)
1338 if (0)
1339 ;
1340 V (default_mem_fb)
1341 V (null_fb)
1342 V (abort_fb)
1343 V (allocator_fb)
1344 else
1345 goto invalid;
1346 }
1347 /* Ignore fb_data, which expects an allocator handle. */
1348 C (pinned)
1349 if (0)
1350 ;
1351 V (true)
1352 V (false)
1353 else
1354 goto invalid;
1355 }
1356 C (partition)
1357 if (0)
1358 ;
1359 V (environment)
1360 V (nearest)
1361 V (blocked)
1362 V (interleaved)
1363 else
1364 goto invalid;
1365 }
1366 else
1367 goto invalid;
1368 if (*val != ',')
1369 break;
1370 ++val;
1371 ++n;
1372 if (*val == '\0')
1373 goto invalid;
1374 }
1375#undef C
1376#undef V
1377 }
1378 else if (memspace)
1379 switch (*ret)
1380 {
1381 case omp_default_mem_space: *ret = omp_default_mem_alloc; break;
1382 case omp_large_cap_mem_space: *ret = omp_large_cap_mem_alloc; break;
1383 case omp_const_mem_space: *ret = omp_const_mem_alloc; break;
1384 case omp_high_bw_mem_space: *ret = omp_high_bw_mem_alloc; break;
1385 case omp_low_lat_mem_space: *ret = omp_low_lat_mem_alloc; break;
1386 default: __builtin_unreachable ();
1387 }
9f2fca56
MV
1388 while (isspace ((unsigned char) *val))
1389 ++val;
1390 if (*val == '\0')
73a0d3bf
TB
1391 {
1392 if (ntraits)
1393 {
1394 *ret = omp_init_allocator (*ret, ntraits, traits);
1395 if (*ret == omp_null_allocator)
1396 {
1397 gomp_error ("Allocator of environment variable %.*s cannot be "
1398 "created, using omp_default_mem_alloc instead",
1399 (int) (orig_val - env - 1), env);
1400 *ret = omp_default_mem_alloc;
1401 }
1402 else
1403 gomp_def_allocator_envvar = strdup (orig_val);
1404 }
1405 return true;
1406 }
1407invalid:
1408 int len = (orig_val - env - 1);
1409 if (*val == '\0')
1410 gomp_error ("Missing value at the end of environment variable %s", env);
1411 else
1412 gomp_error ("Invalid value for environment variable %.*s when parsing: %s",
1413 len, env, val);
9f2fca56
MV
1414 *ret = omp_default_mem_alloc;
1415 return false;
800bcc8c
JJ
1416}
1417
41dbbb37
TS
1418static void
1419parse_acc_device_type (void)
1420{
1421 const char *env = getenv ("ACC_DEVICE_TYPE");
1422
1423 if (env && *env != '\0')
1424 goacc_device_type = strdup (env);
1425 else
1426 goacc_device_type = NULL;
1427}
acf0174b 1428
ec00d3fa
TV
1429static void
1430parse_gomp_openacc_dim (void)
1431{
1432 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1433 const char *var_name = "GOMP_OPENACC_DIM";
1434 const char *env_var = getenv (var_name);
c057ed9c
JJ
1435 const char *pos = env_var;
1436 int i;
1437
ec00d3fa
TV
1438 if (!env_var)
1439 return;
1440
ec00d3fa
TV
1441 for (i = 0; *pos && i != GOMP_DIM_MAX; i++)
1442 {
c057ed9c
JJ
1443 char *eptr;
1444 long val;
1445
ec00d3fa
TV
1446 if (i && *pos++ != ':')
1447 break;
1448
1449 if (*pos == ':')
1450 continue;
1451
ec00d3fa 1452 errno = 0;
c057ed9c 1453 val = strtol (pos, &eptr, 10);
00c9ce13 1454 if (errno || eptr == pos || val < 0 || (unsigned)val != val)
ec00d3fa
TV
1455 break;
1456
1457 goacc_default_dims[i] = (int)val;
c057ed9c 1458 pos = (const char *) eptr;
ec00d3fa
TV
1459 }
1460}
1461
9f2fca56
MV
1462/* Helper function for omp_display_env which prints the values of run_sched_var.
1463 'device' can be 'host', 'dev', 'all' or a particular device number. */
acf0174b 1464
9f2fca56
MV
1465static void
1466print_schedule (enum gomp_schedule_type run_sched_var, int run_sched_chunk_size,
1467 const char *device)
1468{
1469 fprintf (stderr, " [%s] OMP_SCHEDULE = '", device);
1470 if ((run_sched_var & GFS_MONOTONIC))
28567c40 1471 {
9f2fca56 1472 if (run_sched_var != (GFS_MONOTONIC | GFS_STATIC))
28567c40
JJ
1473 fputs ("MONOTONIC:", stderr);
1474 }
9f2fca56 1475 else if (run_sched_var == GFS_STATIC)
28567c40 1476 fputs ("NONMONOTONIC:", stderr);
9f2fca56 1477 switch (run_sched_var & ~GFS_MONOTONIC)
acf0174b
JJ
1478 {
1479 case GFS_RUNTIME:
1480 fputs ("RUNTIME", stderr);
9f2fca56
MV
1481 if (run_sched_chunk_size != 1)
1482 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1483 break;
1484 case GFS_STATIC:
1485 fputs ("STATIC", stderr);
9f2fca56
MV
1486 if (run_sched_chunk_size != 0)
1487 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1488 break;
1489 case GFS_DYNAMIC:
1490 fputs ("DYNAMIC", stderr);
9f2fca56
MV
1491 if (run_sched_chunk_size != 1)
1492 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1493 break;
1494 case GFS_GUIDED:
1495 fputs ("GUIDED", stderr);
9f2fca56
MV
1496 if (run_sched_chunk_size != 1)
1497 fprintf (stderr, ",%d", run_sched_chunk_size);
acf0174b
JJ
1498 break;
1499 case GFS_AUTO:
1500 fputs ("AUTO", stderr);
1501 break;
1502 }
1503 fputs ("'\n", stderr);
9f2fca56
MV
1504}
1505
1506/* Helper function for omp_display_env which prints the values of proc_bind_var.
1507 'device' can be 'host', 'dev', 'all', or a particular device number. */
acf0174b 1508
9f2fca56
MV
1509static void
1510print_proc_bind (char proc_bind_var, unsigned long len, char **list,
1511 const char *device)
1512{
1513 fprintf (stderr, " [%s] OMP_PROC_BIND = '", device);
1514 switch (proc_bind_var)
acf0174b
JJ
1515 {
1516 case omp_proc_bind_false:
1517 fputs ("FALSE", stderr);
1518 break;
1519 case omp_proc_bind_true:
1520 fputs ("TRUE", stderr);
1521 break;
1522 case omp_proc_bind_master:
432de084 1523 fputs ("MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1524 break;
1525 case omp_proc_bind_close:
1526 fputs ("CLOSE", stderr);
1527 break;
1528 case omp_proc_bind_spread:
1529 fputs ("SPREAD", stderr);
1530 break;
1531 }
9f2fca56
MV
1532 for (int i = 1; i < len; i++)
1533 switch ((*list)[i])
acf0174b
JJ
1534 {
1535 case omp_proc_bind_master:
432de084 1536 fputs (",MASTER", stderr); /* TODO: Change to PRIMARY for OpenMP 5.1. */
acf0174b
JJ
1537 break;
1538 case omp_proc_bind_close:
1539 fputs (",CLOSE", stderr);
1540 break;
1541 case omp_proc_bind_spread:
1542 fputs (",SPREAD", stderr);
1543 break;
1544 }
1545 fputs ("'\n", stderr);
9f2fca56
MV
1546}
1547
1548enum gomp_parse_type
1549{
1550 PARSE_INT = 1,
1551 PARSE_BOOL = 2,
1552 PARSE_UINT = 3,
1553 PARSE_ULONG = 4,
1554 PARSE_UCHAR = 5,
1555 PARSE_SCHEDULE =6,
1556 PARSE_BIND = 7
1557};
1558
1559/* The following table contains items that help parsing environment variables
1560 and fill corresponding ICVs with values. FLAG_VARS contain all ICVS which
1561 are affected by the environment variable. FLAGS determine what variant of
1562 environment variable is allowed. */
1563
1564#define ENTRY(NAME) NAME, sizeof (NAME) - 1
1565static const struct envvar
1566{
1567 const char *name;
1568 int name_len;
1569 uint8_t flag_vars[3];
1570 uint8_t flag;
1571 bool (*parse_func) (const char *, const char *, void *const[]);
1572} envvars[] = {
1573 { ENTRY ("SCHEDULE"),
1574 { GOMP_ICV_SCHEDULE, GOMP_ICV_SCHEDULE_CHUNK_SIZE },
1575 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1576 &parse_schedule },
1577 { ENTRY ("NUM_TEAMS"),
1578 { GOMP_ICV_NTEAMS },
1579 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1580 &parse_int },
1581 { ENTRY ("DYNAMIC"),
1582 { GOMP_ICV_DYNAMIC },
1583 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1584 &parse_boolean },
1585 { ENTRY ("TEAMS_THREAD_LIMIT"),
1586 { GOMP_ICV_TEAMS_THREAD_LIMIT },
1587 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1588 &parse_int },
1589 { ENTRY ("THREAD_LIMIT"),
1590 { GOMP_ICV_THREAD_LIMIT },
1591 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1592 &parse_unsigned_long },
1593 { ENTRY ("NUM_THREADS"),
1594 { GOMP_ICV_NTHREADS, GOMP_ICV_NTHREADS_LIST, GOMP_ICV_NTHREADS_LIST_LEN },
1595 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1596 &parse_unsigned_long_list },
1597 { ENTRY ("PROC_BIND"),
1598 { GOMP_ICV_BIND, GOMP_ICV_BIND_LIST, GOMP_ICV_BIND_LIST_LEN },
1599 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1600 &parse_bind_var },
1601 { ENTRY ("MAX_ACTIVE_LEVELS"),
1602 { GOMP_ICV_MAX_ACTIVE_LEVELS },
1603 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1604 &parse_unsigned_long },
1605 { ENTRY ("WAIT_POLICY"),
1606 { GOMP_ICV_WAIT_POLICY },
1607 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1608 &parse_wait_policy },
1609 { ENTRY ("STACKSIZE"),
1610 { GOMP_ICV_STACKSIZE },
1611 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1612 &parse_stacksize },
1613 { ENTRY ("CANCELLATION"), { GOMP_ICV_CANCELLATION }, 0, &parse_boolean },
1614 { ENTRY ("DISPLAY_AFFINITY"), { GOMP_ICV_DISPLAY_AFFINITY }, 0,
1615 &parse_boolean },
1616 { ENTRY ("TARGET_OFFLOAD"), { GOMP_ICV_TARGET_OFFLOAD }, 0,
1617 &parse_target_offload },
1618 { ENTRY ("MAX_TASK_PRIORITY"), { GOMP_ICV_MAX_TASK_PRIORITY }, 0,
1619 &parse_int },
1620 { ENTRY ("ALLOCATOR"), { GOMP_ICV_ALLOCATOR }, 0, &parse_allocator },
1621 { ENTRY ("DEFAULT_DEVICE"), { GOMP_ICV_DEFAULT_DEVICE },
1622 GOMP_ENV_SUFFIX_DEV | GOMP_ENV_SUFFIX_ALL | GOMP_ENV_SUFFIX_DEV_X,
1623 &parse_int }
1624};
1625#undef ENTRY
1626#define OMP_VAR_CNT (sizeof (envvars) / sizeof (envvars[0]))
1627
1628/* The following table is used to apply the hierarchy of ICV variants for host
1629 variables, e.g. nteams_var is set to OMP_NUM_TEAMS_ALL if OMP_NUM_TEAMS is
1630 undefined. */
1631
1632static const struct host_envvar
1633{
1634 unsigned char flag_var;
1635 void *dest[3];
1636 int type_code;
1637} host_envvars[] = {
1638 { GOMP_ICV_NTEAMS, { &gomp_nteams_var }, PARSE_INT },
1639 { GOMP_ICV_DYNAMIC, { &gomp_global_icv.dyn_var }, PARSE_BOOL },
1640 { GOMP_ICV_DEFAULT_DEVICE, { &gomp_global_icv.default_device_var },
1641 PARSE_INT },
1642 { GOMP_ICV_TEAMS_THREAD_LIMIT, { &gomp_teams_thread_limit_var }, PARSE_INT },
1643 { GOMP_ICV_SCHEDULE,
1644 { &gomp_global_icv.run_sched_var, &gomp_global_icv.run_sched_chunk_size },
1645 PARSE_SCHEDULE },
1646 { GOMP_ICV_THREAD_LIMIT, { &gomp_global_icv.thread_limit_var }, PARSE_UINT },
1647 { GOMP_ICV_NTHREADS,
1648 { &gomp_global_icv.nthreads_var, &gomp_nthreads_var_list,
1649 &gomp_nthreads_var_list_len }, PARSE_ULONG },
1650 { GOMP_ICV_BIND,
1651 { &gomp_global_icv.bind_var, &gomp_bind_var_list, &gomp_bind_var_list_len },
1652 PARSE_BIND },
1653 { GOMP_ICV_MAX_ACTIVE_LEVELS, { &gomp_global_icv.max_active_levels_var },
1654 PARSE_UCHAR },
1655};
1656#define OMP_HOST_VAR_CNT (sizeof (host_envvars) / sizeof (host_envvars[0]))
1657
1658#define INT_MAX_STR_LEN 10
1659
1660bool
1661gomp_get_icv_flag (uint32_t value, enum gomp_icvs icv)
1662{
1663 return value & (1 << (icv - 1));
1664}
1665
1666static void
1667gomp_set_icv_flag (uint32_t *value, enum gomp_icvs icv)
1668{
1669 *value |= 1 << (icv - 1);
1670}
1671
1672static void
1673print_device_specific_icvs (int icv_code)
1674{
1675 struct gomp_icv_list *list = gomp_initial_icv_list;
1676 int i;
1677 char dev_num[INT_MAX_STR_LEN + 1];
1678
1679 while (list != NULL)
1680 {
1681 if (list->device_num < 0)
1682 {
1683 list = list->next;
1684 continue;
1685 }
1686
1687 switch (icv_code)
1688 {
1689 case GOMP_ICV_NTEAMS:
1690 if (gomp_get_icv_flag (list->flags, GOMP_ICV_NTEAMS))
1691 fprintf (stderr, " [%d] OMP_NUM_TEAMS = '%d'\n",
1692 list->device_num, list->icvs.nteams_var);
1693 break;
1694 case GOMP_ICV_DYNAMIC:
1695 if (gomp_get_icv_flag (list->flags, GOMP_ICV_DYNAMIC))
1696 fprintf (stderr, " [%d] OMP_DYNAMIC = '%s'\n",
1697 list->device_num, list->icvs.dyn_var ? "TRUE" : "FALSE");
1698 break;
1699 case GOMP_ICV_TEAMS_THREAD_LIMIT:
1700 if (gomp_get_icv_flag (list->flags, GOMP_ICV_TEAMS_THREAD_LIMIT))
1701 fprintf (stderr, " [%d] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1702 list->device_num, list->icvs.teams_thread_limit_var);
1703 break;
1704 case GOMP_ICV_SCHEDULE:
1705 if (!(gomp_get_icv_flag (list->flags, GOMP_ICV_SCHEDULE)))
1706 break;
1707 sprintf (dev_num, "%d", list->device_num);
1708 print_schedule (list->icvs.run_sched_var,
1709 list->icvs.run_sched_chunk_size,
1710 dev_num);
1711 break;
1712 case GOMP_ICV_THREAD_LIMIT:
1713 if (gomp_get_icv_flag (list->flags, GOMP_ICV_THREAD_LIMIT))
1714 fprintf (stderr, " [%d] OMP_THREAD_LIMIT = '%d'\n",
1715 list->device_num, list->icvs.thread_limit_var);
1716 break;
1717 case GOMP_ICV_NTHREADS:
1718 if (!(gomp_get_icv_flag (list->flags, GOMP_ICV_NTHREADS)))
1719 break;
1720 fprintf (stderr, " [%d] OMP_NUM_THREADS = '%lu", list->device_num,
1721 list->icvs.nthreads_var);
1722 for (i = 1; i < list->icvs.nthreads_var_list_len; i++)
1723 fprintf (stderr, ",%lu", list->icvs.nthreads_var_list[i]);
1724 fputs ("'\n", stderr);
1725 break;
1726 case GOMP_ICV_MAX_ACTIVE_LEVELS:
1727 fprintf (stderr, " [%d] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1728 list->device_num, list->icvs.max_active_levels_var);
1729 break;
1730 case GOMP_ICV_BIND:
1731 if (!(gomp_get_icv_flag (list->flags, GOMP_ICV_BIND)))
1732 break;
1733 sprintf (dev_num, "%d", list->device_num);
1734 print_proc_bind (list->icvs.bind_var, list->icvs.bind_var_list_len,
1735 &list->icvs.bind_var_list, dev_num);
1736 break;
1737 case GOMP_ICV_WAIT_POLICY:
1738 if (gomp_get_icv_flag (list->flags, GOMP_ICV_WAIT_POLICY))
1739 fprintf (stderr, " [%d] OMP_WAIT_POLICY = '%s'\n",
1740 list->device_num,
1741 list->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1742 break;
1743 case GOMP_ICV_STACKSIZE:
1744 if (gomp_get_icv_flag (list->flags, GOMP_ICV_STACKSIZE))
1745 fprintf (stderr, " [%d] OMP_STACKSIZE = '%lu'\n",
1746 list->device_num, list->icvs.stacksize);
1747 break;
1748 }
1749 list = list->next;
1750 }
1751}
1752
1753void
1754omp_display_env (int verbose)
1755{
1756 int i;
1757 struct gomp_icv_list *dev
1758 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_DEV);
1759 struct gomp_icv_list *all
1760 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_ALL);
1761 struct gomp_icv_list *none
1762 = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX);
1763
18c8b56c
TB
1764 if (none->icvs.default_device_var == INT_MIN)
1765 /* This implies OMP_TARGET_OFFLOAD=mandatory. */
1766 gomp_init_targets_once ();
1767
9f2fca56
MV
1768 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr);
1769
1770 fputs (" _OPENMP = '201511'\n", stderr);
1771
1772 fprintf (stderr, " [host] OMP_DYNAMIC = '%s'\n",
1773 none->icvs.dyn_var ? "TRUE" : "FALSE");
1774 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_DYNAMIC))
1775 fprintf (stderr, " [all] OMP_DYNAMIC = '%s'\n",
1776 all->icvs.dyn_var ? "TRUE" : "FALSE");
1777 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_DYNAMIC))
1778 fprintf (stderr, " [device] OMP_DYNAMIC = '%s'\n",
1779 dev->icvs.dyn_var ? "TRUE" : "FALSE");
1780 print_device_specific_icvs (GOMP_ICV_DYNAMIC);
1781
1782 /* The OMP_NESTED environment variable has been deprecated. */
1783 fprintf (stderr, " [host] OMP_NESTED = '%s'\n",
1784 none->icvs.max_active_levels_var > 1 ? "TRUE" : "FALSE");
1785
1786 fprintf (stderr, " [host] OMP_NUM_THREADS = '%lu",
1787 none->icvs.nthreads_var);
1788 for (i = 1; i < none->icvs.nthreads_var_list_len; i++)
1789 fprintf (stderr, ",%lu", none->icvs.nthreads_var_list[i]);
1790 fputs ("'\n", stderr);
1791 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_NTHREADS))
1792 {
1793 fprintf (stderr, " [all] OMP_NUM_THREADS = '%lu",
1794 all->icvs.nthreads_var);
1795 for (i = 1; i < all->icvs.nthreads_var_list_len; i++)
1796 fprintf (stderr, ",%lu", all->icvs.nthreads_var_list[i]);
1797 fputs ("'\n", stderr);
1798 }
1799 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_NTHREADS))
1800 {
1801 fprintf (stderr, " [device] OMP_NUM_THREADS = '%lu",
1802 dev->icvs.nthreads_var);
1803 for (i = 1; i < dev->icvs.nthreads_var_list_len; i++)
1804 fprintf (stderr, ",%lu", dev->icvs.nthreads_var_list[i]);
1805 fputs ("'\n", stderr);
1806 }
1807 print_device_specific_icvs (GOMP_ICV_NTHREADS);
1808
1809
1810 print_schedule (none->icvs.run_sched_var,
1811 none->icvs.run_sched_chunk_size, "host");
1812 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_SCHEDULE))
1813 print_schedule (all->icvs.run_sched_var,
1814 all->icvs.run_sched_chunk_size, "all");
1815 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_SCHEDULE))
1816 print_schedule (dev->icvs.run_sched_var,
1817 dev->icvs.run_sched_chunk_size, "device");
1818 print_device_specific_icvs (GOMP_ICV_SCHEDULE);
1819
1820 print_proc_bind (none->icvs.bind_var,
1821 none->icvs.bind_var_list_len,
1822 &none->icvs.bind_var_list, "host");
1823 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_BIND))
1824 print_proc_bind (all->icvs.bind_var,
1825 all->icvs.bind_var_list_len,
1826 &all->icvs.bind_var_list, "all");
1827 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_BIND))
1828 print_proc_bind (dev->icvs.bind_var,
1829 dev->icvs.bind_var_list_len,
1830 &dev->icvs.bind_var_list, "device");
1831 print_device_specific_icvs (GOMP_ICV_BIND);
1832
1833 fputs (" [host] OMP_PLACES = '", stderr);
acf0174b
JJ
1834 for (i = 0; i < gomp_places_list_len; i++)
1835 {
1836 fputs ("{", stderr);
1837 gomp_affinity_print_place (gomp_places_list[i]);
1838 fputs (i + 1 == gomp_places_list_len ? "}" : "},", stderr);
1839 }
1840 fputs ("'\n", stderr);
1841
9f2fca56
MV
1842 fprintf (stderr, " [host] OMP_STACKSIZE = '%lu'\n",
1843 none->icvs.stacksize);
1844 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_STACKSIZE))
1845 fprintf (stderr, " [all] OMP_STACKSIZE = '%lu'\n",
1846 all->icvs.stacksize);
1847 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_STACKSIZE))
1848 fprintf (stderr, " [device] OMP_STACKSIZE = '%lu'\n",
1849 dev->icvs.stacksize);
1850 print_device_specific_icvs (GOMP_ICV_STACKSIZE);
acf0174b
JJ
1851
1852 /* GOMP's default value is actually neither active nor passive. */
9f2fca56
MV
1853 fprintf (stderr, " [host] OMP_WAIT_POLICY = '%s'\n",
1854 none->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1855 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_WAIT_POLICY))
1856 fprintf (stderr, " [all] OMP_WAIT_POLICY = '%s'\n",
1857 all->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1858 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_WAIT_POLICY))
1859 fprintf (stderr, " [device] OMP_WAIT_POLICY = '%s'\n",
1860 dev->icvs.wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1861 print_device_specific_icvs (GOMP_ICV_WAIT_POLICY);
1862
1863 fprintf (stderr, " [host] OMP_THREAD_LIMIT = '%u'\n",
1864 none->icvs.thread_limit_var);
1865 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_THREAD_LIMIT))
1866 fprintf (stderr, " [all] OMP_THREAD_LIMIT = '%d'\n",
1867 all->icvs.thread_limit_var);
1868 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_THREAD_LIMIT))
1869 fprintf (stderr, " [device] OMP_THREAD_LIMIT = '%d'\n",
1870 dev->icvs.thread_limit_var);
1871 print_device_specific_icvs (GOMP_ICV_THREAD_LIMIT);
1872
1873 fprintf (stderr, " [host] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1874 none->icvs.max_active_levels_var);
1875 if (all != NULL && gomp_get_icv_flag (all->flags,
1876 GOMP_ICV_MAX_ACTIVE_LEVELS))
1877 fprintf (stderr, " [all] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1878 all->icvs.max_active_levels_var);
1879 if (dev != NULL && gomp_get_icv_flag (dev->flags,
1880 GOMP_ICV_MAX_ACTIVE_LEVELS))
1881 fprintf (stderr, " [device] OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1882 dev->icvs.max_active_levels_var);
1883 print_device_specific_icvs (GOMP_ICV_MAX_ACTIVE_LEVELS);
1884
1885
1886 fprintf (stderr, " [host] OMP_NUM_TEAMS = '%d'\n",
1887 none->icvs.nteams_var);
1888 if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_NTEAMS))
1889 fprintf (stderr, " [all] OMP_NUM_TEAMS = '%d'\n",
1890 all->icvs.nteams_var);
1891 if (dev != NULL && gomp_get_icv_flag (dev->flags, GOMP_ICV_NTEAMS))
1892 fprintf (stderr, " [device] OMP_NUM_TEAMS = '%d'\n",
1893 dev->icvs.nteams_var);
1894 print_device_specific_icvs (GOMP_ICV_NTEAMS);
1895
1896 fprintf (stderr, " [host] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1897 none->icvs.teams_thread_limit_var);
1898 if (all != NULL && gomp_get_icv_flag (all->flags,
1899 GOMP_ICV_TEAMS_THREAD_LIMIT))
1900 fprintf (stderr, " [all] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1901 all->icvs.teams_thread_limit_var);
1902 if (dev != NULL && gomp_get_icv_flag (dev->flags,
1903 GOMP_ICV_TEAMS_THREAD_LIMIT))
1904 fprintf (stderr, " [device] OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1905 dev->icvs.teams_thread_limit_var);
1906 print_device_specific_icvs (GOMP_ICV_TEAMS_THREAD_LIMIT);
1907
1908 fprintf (stderr, " [all] OMP_CANCELLATION = '%s'\n",
acf0174b 1909 gomp_cancel_var ? "TRUE" : "FALSE");
9f2fca56
MV
1910
1911 fprintf (stderr, " [all] OMP_DEFAULT_DEVICE = '%d'\n",
1912 none->icvs.default_device_var);
1913
1914 fprintf (stderr, " [all] OMP_MAX_TASK_PRIORITY = '%d'\n",
d9a6bd32 1915 gomp_max_task_priority_var);
9f2fca56 1916 fprintf (stderr, " [all] OMP_DISPLAY_AFFINITY = '%s'\n",
28567c40 1917 gomp_display_affinity_var ? "TRUE" : "FALSE");
9f2fca56 1918 fprintf (stderr, " [host] OMP_AFFINITY_FORMAT = '%s'\n",
28567c40 1919 gomp_affinity_format_var);
9f2fca56 1920 fprintf (stderr, " [host] OMP_ALLOCATOR = '");
800bcc8c
JJ
1921 switch (gomp_def_allocator)
1922 {
1923#define C(v) case v: fputs (#v, stderr); break;
1924 C (omp_default_mem_alloc)
1925 C (omp_large_cap_mem_alloc)
1926 C (omp_const_mem_alloc)
1927 C (omp_high_bw_mem_alloc)
1928 C (omp_low_lat_mem_alloc)
1929 C (omp_cgroup_mem_alloc)
1930 C (omp_pteam_mem_alloc)
1931 C (omp_thread_mem_alloc)
1932#undef C
73a0d3bf
TB
1933 /* For an OMP_ALLOCATOR with traits, '' will be output. */
1934 default:
1935 if (gomp_def_allocator_envvar)
1936 fputs (gomp_def_allocator_envvar, stderr);
1937 break;
800bcc8c
JJ
1938 }
1939 fputs ("'\n", stderr);
acf0174b 1940
9f2fca56 1941 fputs (" [all] OMP_TARGET_OFFLOAD = '", stderr);
1bfc07d1
KCY
1942 switch (gomp_target_offload_var)
1943 {
1944 case GOMP_TARGET_OFFLOAD_DEFAULT:
1945 fputs ("DEFAULT", stderr);
1946 break;
1947 case GOMP_TARGET_OFFLOAD_MANDATORY:
1948 fputs ("MANDATORY", stderr);
1949 break;
1950 case GOMP_TARGET_OFFLOAD_DISABLED:
1951 fputs ("DISABLED", stderr);
1952 break;
1953 }
1954 fputs ("'\n", stderr);
1955
acf0174b
JJ
1956 if (verbose)
1957 {
9f2fca56
MV
1958 fputs (" [host] GOMP_CPU_AFFINITY = ''\n", stderr);
1959 fprintf (stderr, " [host] GOMP_STACKSIZE = '%lu'\n", stacksize);
acf0174b 1960#ifdef HAVE_INTTYPES_H
9f2fca56 1961 fprintf (stderr, " [host] GOMP_SPINCOUNT = '%"PRIu64"'\n",
acf0174b
JJ
1962 (uint64_t) gomp_spin_count_var);
1963#else
9f2fca56 1964 fprintf (stderr, " [host] GOMP_SPINCOUNT = '%lu'\n",
acf0174b
JJ
1965 (unsigned long) gomp_spin_count_var);
1966#endif
1967 }
1968
1969 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr);
1970}
7123ae24
UD
1971ialias (omp_display_env)
1972
1973static void
1974handle_omp_display_env (void)
1975{
1976 const char *env;
1977 bool display = false;
1978 bool verbose = false;
1979
1980 env = getenv ("OMP_DISPLAY_ENV");
1981 if (env == NULL)
1982 return;
1983
1984 while (isspace ((unsigned char) *env))
1985 ++env;
1986 if (strncasecmp (env, "true", 4) == 0)
1987 {
1988 display = true;
1989 env += 4;
1990 }
1991 else if (strncasecmp (env, "false", 5) == 0)
1992 {
1993 display = false;
1994 env += 5;
1995 }
1996 else if (strncasecmp (env, "verbose", 7) == 0)
1997 {
1998 display = true;
1999 verbose = true;
2000 env += 7;
2001 }
2002 else
2003 env = "X";
2004 while (isspace ((unsigned char) *env))
2005 ++env;
2006 if (*env != '\0')
2007 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
2008
2009 if (display)
3749c3af 2010 ialias_call (omp_display_env) (verbose);
7123ae24 2011}
acf0174b 2012
9f2fca56
MV
2013/* Helper function for initialize_env. Extracts the device number from
2014 an environment variable name. ENV is the complete environment variable.
2015 DEV_NUM_PTR points to the start of the device number in the environment
2016 variable string. DEV_NUM_LEN is the returned length of the device num
2017 string. */
2018
2019static bool
2020get_device_num (char *env, char *dev_num_ptr, int *dev_num, int *dev_num_len)
2021{
2022 char *end;
2023 unsigned long val = strtoul (dev_num_ptr, &end, 10);
2024 if (val > INT_MAX
2025 || *end != '='
2026 || (dev_num_ptr[0] == '0' && end != dev_num_ptr + 1)
2027 || (dev_num_ptr[0] < '0' || dev_num_ptr[0] > '9'))
2028 {
2029 gomp_error ("Invalid device number in %s", env);
2030 return false;
2031 }
2032 *dev_num = val;
2033 *dev_num_len = end - dev_num_ptr;
2034 return true;
2035}
2036
2037static void
2038get_icv_member_addr (struct gomp_initial_icvs *icvs, int icv_code,
2039 void *icv_addr[3])
2040{
2041 if (icv_code == 0 || icv_addr == NULL)
2042 return;
2043
2044 icv_addr[0] = icv_addr[1] = icv_addr[2] = NULL;
2045
2046 switch (icv_code)
2047 {
2048 case GOMP_ICV_NTEAMS:
2049 icv_addr[0] = &icvs->nteams_var;
e11babbf 2050 /* icv_addr[1] = (void *) false; */
9f2fca56
MV
2051 break;
2052 case GOMP_ICV_DYNAMIC:
2053 icv_addr[0] = &(*icvs).dyn_var;
2054 break;
2055 case GOMP_ICV_TEAMS_THREAD_LIMIT:
2056 icv_addr[0] = &icvs->teams_thread_limit_var;
e11babbf 2057 /* icv_addr[1] = (void *) false; */
9f2fca56
MV
2058 break;
2059 case GOMP_ICV_SCHEDULE:
2060 icv_addr[0] = &icvs->run_sched_var;
2061 icv_addr[1] = &icvs->run_sched_chunk_size;
2062 break;
2063 case GOMP_ICV_THREAD_LIMIT:
2064 icv_addr[0] = &icvs->thread_limit_var;
e11babbf 2065 /* icv_addr[1] = (void *) false; */
9f2fca56
MV
2066 icv_addr[2] = (void *) UINT_MAX;
2067 break;
2068 case GOMP_ICV_NTHREADS:
2069 icv_addr[0] = &icvs->nthreads_var;
2070 icv_addr[1] = &icvs->nthreads_var_list;
2071 icv_addr[2] = &icvs->nthreads_var_list_len;
2072 break;
2073 case GOMP_ICV_MAX_ACTIVE_LEVELS:
2074 icv_addr[0] = &icvs->max_active_levels_var;
2075 icv_addr[1] = (void *) true;
2076 icv_addr[2] = (void *) gomp_supported_active_levels;
2077 break;
2078 case GOMP_ICV_BIND:
2079 icv_addr[0] = &icvs->bind_var;
2080 icv_addr[1] = &icvs->bind_var_list;
2081 icv_addr[2] = &icvs->bind_var_list_len;
2082 break;
2083 case GOMP_ICV_WAIT_POLICY:
2084 icv_addr[0] = &icvs->wait_policy;
2085 break;
2086 case GOMP_ICV_STACKSIZE:
2087 icv_addr[0] = &icvs->stacksize;
2088 break;
2089 case GOMP_ICV_CANCELLATION:
2090 icv_addr[0] = &gomp_cancel_var;
2091 break;
2092 case GOMP_ICV_DISPLAY_AFFINITY:
2093 icv_addr[0] = &gomp_display_affinity_var;
2094 break;
2095 case GOMP_ICV_TARGET_OFFLOAD:
2096 icv_addr[0] = &gomp_target_offload_var;
2097 break;
2098 case GOMP_ICV_MAX_TASK_PRIORITY:
2099 icv_addr[0] = &gomp_max_task_priority_var;
2100 break;
2101 case GOMP_ICV_ALLOCATOR:
2102 icv_addr[0] = &gomp_def_allocator;
2103 break;
2104 case GOMP_ICV_DEFAULT_DEVICE:
2105 icv_addr[0] = &icvs->default_device_var;
2106 icv_addr[1] = (void *) true;
2107 break;
2108 }
2109}
2110
2111struct gomp_icv_list *
2112gomp_get_initial_icv_item (int dev_num)
2113{
2114 struct gomp_icv_list *l = gomp_initial_icv_list;
2115 while (l != NULL && l->device_num != dev_num)
2116 l = l->next;
2117
2118 return l;
2119}
2120
2121static void
2122initialize_icvs (struct gomp_initial_icvs *icvs)
2123{
2124 icvs->nthreads_var_list = NULL;
2125 icvs->bind_var_list = NULL;
2126 icvs->nthreads_var = gomp_default_icv_values.nthreads_var;
2127 icvs->nthreads_var_list_len = 0;
2128 icvs->bind_var_list_len = 0;
2129 icvs->stacksize = 0;
2130 icvs->thread_limit_var = gomp_default_icv_values.thread_limit_var;
2131 icvs->run_sched_var = gomp_default_icv_values.run_sched_var;
2132 icvs->run_sched_chunk_size = gomp_default_icv_values.run_sched_chunk_size;
2133 icvs->default_device_var = gomp_default_icv_values.default_device_var;
2134 icvs->dyn_var = gomp_default_icv_values.dyn_var;
2135 icvs->max_active_levels_var = gomp_default_icv_values.max_active_levels_var;
2136 icvs->bind_var = gomp_default_icv_values.bind_var;
2137 icvs->nteams_var = gomp_default_icv_values.nteams_var;
2138 icvs->teams_thread_limit_var = gomp_default_icv_values.teams_thread_limit_var;
288bc7b5 2139 icvs->wait_policy = -1;
9f2fca56
MV
2140}
2141
2142/* Helper function for initialize_env to add a device specific ICV value
2143 to gomp_initial_icv_list. */
2144
2145static uint32_t *
2146add_initial_icv_to_list (int dev_num, int icv_code, void *icv_addr[3])
2147{
2148 struct gomp_icv_list *last = NULL, *l = gomp_initial_icv_list;
2149 while (l != NULL && l->device_num != dev_num)
2150 {
2151 last = l;
2152 l = l->next;
2153 }
2154
2155 if (l == NULL)
2156 {
2157 l = ((struct gomp_icv_list *)
2158 gomp_malloc_cleared (sizeof (struct gomp_icv_list)));
2159 l->device_num = dev_num;
2160 initialize_icvs (&l->icvs);
2161 if (dev_num < 0)
2162 {
2163 l->next = gomp_initial_icv_list;
2164 gomp_initial_icv_list = l;
2165 }
2166 else
2167 {
2168 l->next = NULL;
2169 if (last == NULL)
2170 gomp_initial_icv_list = l;
2171 else
2172 last->next = l;
2173 }
2174 }
2175
2176 get_icv_member_addr (&l->icvs, icv_code, icv_addr);
2177
2178 return &l->flags;
2179}
2180
2181/* Return true if STR string starts with PREFIX. */
2182
2183static inline bool
2184startswith (const char *str, const char *prefix)
2185{
2186 return strncmp (str, prefix, strlen (prefix)) == 0;
2187}
acf0174b 2188
73a0d3bf
TB
2189static void __attribute__((destructor))
2190cleanup_env (void)
2191{
2192 if (gomp_def_allocator_envvar != NULL)
2193 {
2194 free (gomp_def_allocator_envvar);
2195 omp_destroy_allocator (gomp_def_allocator);
2196 }
2197}
2198
953ff289
DN
2199static void __attribute__((constructor))
2200initialize_env (void)
2201{
9f2fca56
MV
2202 char **env;
2203 int omp_var, dev_num = 0, dev_num_len = 0, i;
2204 bool ignore = false;
2205 char *env_val;
2206 void *params[3];
2207 uint32_t *flag_var_addr = NULL;
2208 unsigned pos;
2209 struct gomp_icv_list *all, *none;
d0d1b24d 2210
953ff289
DN
2211 /* Do a compile time check that mkomp_h.pl did good job. */
2212 omp_check_defines ();
2213
a68ab351 2214#ifndef HAVE_SYNC_BUILTINS
acf0174b 2215 gomp_mutex_init (&gomp_managed_threads_lock);
a68ab351 2216#endif
a68ab351
JJ
2217 gomp_init_num_threads ();
2218 gomp_available_cpus = gomp_global_icv.nthreads_var;
9f2fca56
MV
2219
2220 /* Initial values for host environment variables should always exist even if
2221 there is no explicitly set host environment variable. Moreover, they are
2222 set to the initial global values. */
2223 add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX, 0, NULL);
2224 none = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_NO_SUFFIX);
2225 initialize_icvs (&none->icvs);
2226
2227 for (env = environ; *env != 0; env++)
2228 {
2229 if (!startswith (*env, "OMP_"))
2230 continue;
2231
2232 /* Name of the environment variable without suffix "OMP_". */
2233 char *name = *env + sizeof ("OMP_") - 1;
2234 for (omp_var = 0; omp_var < OMP_VAR_CNT; omp_var++)
2235 {
2236 if (startswith (name, envvars[omp_var].name))
2237 {
2238 pos = envvars[omp_var].name_len;
2239 if (name[pos] == '=')
2240 {
2241 pos++;
2242 flag_var_addr
2243 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_NO_SUFFIX,
2244 envvars[omp_var].flag_vars[0],
2245 params);
2246 }
2247 else if (startswith (&name[pos], "_DEV=")
2248 && envvars[omp_var].flag & GOMP_ENV_SUFFIX_DEV)
2249 {
2250 pos += 5;
2251 flag_var_addr
2252 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_DEV,
2253 envvars[omp_var].flag_vars[0],
2254 params);
2255 }
2256 else if (startswith (&name[pos], "_ALL=")
2257 && envvars[omp_var].flag & GOMP_ENV_SUFFIX_ALL)
2258 {
2259 pos += 5;
2260 flag_var_addr
2261 = add_initial_icv_to_list (GOMP_DEVICE_NUM_FOR_ALL,
2262 envvars[omp_var].flag_vars[0],
2263 params);
2264 }
2265 else if (startswith (&name[pos], "_DEV_")
2266 && envvars[omp_var].flag & GOMP_ENV_SUFFIX_DEV_X)
2267 {
2268 pos += 5;
2269 if (!get_device_num (*env, &name[pos], &dev_num,
2270 &dev_num_len))
2271 break;
2272
2273 pos += dev_num_len + 1;
2274 flag_var_addr
2275 = add_initial_icv_to_list (dev_num,
2276 envvars[omp_var].flag_vars[0],
2277 params);
2278 }
2279 else
2280 {
2281 gomp_error ("Invalid environment variable in %s", *env);
2282 break;
2283 }
2284 env_val = &name[pos];
2285
2286 if (envvars[omp_var].parse_func (*env, env_val, params))
2287 {
2288 for (i = 0; i < 3; ++i)
2289 if (envvars[omp_var].flag_vars[i])
2290 gomp_set_icv_flag (flag_var_addr,
2291 envvars[omp_var].flag_vars[i]);
2292 else
2293 break;
2294 }
2295
2296 break;
2297 }
2298 }
2299 }
2300
2301 all = gomp_get_initial_icv_item (GOMP_DEVICE_NUM_FOR_ALL);
2302 for (omp_var = 0; omp_var < OMP_HOST_VAR_CNT; omp_var++)
2303 {
2304 if (none != NULL
2305 && gomp_get_icv_flag (none->flags, host_envvars[omp_var].flag_var))
2306 get_icv_member_addr (&none->icvs,
2307 host_envvars[omp_var].flag_var, params);
2308 else if (all != NULL
2309 && gomp_get_icv_flag (all->flags,
2310 host_envvars[omp_var].flag_var))
2311 get_icv_member_addr (&all->icvs, host_envvars[omp_var].flag_var,
2312 params);
2313 else
2314 continue;
2315
2316 switch (host_envvars[omp_var].type_code)
2317 {
2318 case PARSE_INT:
2319 for (i = 0; i < 3; ++i)
2320 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2321 *(int *) (host_envvars[omp_var].dest[i]) = *(int *) params[i];
2322 break;
2323 case PARSE_BOOL:
2324 for (i = 0; i < 3; ++i)
2325 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2326 *(bool *) (host_envvars[omp_var].dest[i]) = *(bool *) params[i];
2327 break;
2328 case PARSE_UINT:
2329 for (i = 0; i < 3; ++i)
2330 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2331 *(unsigned int *) (host_envvars[omp_var].dest[i])
2332 = *(unsigned int *) params[i];
2333 break;
2334 case PARSE_ULONG:
2335 for (i = 0; i < 3; ++i)
2336 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2337 *(unsigned long *) (host_envvars[omp_var].dest[i])
2338 = *(unsigned long *) params[i];
2339 break;
2340 case PARSE_UCHAR:
2341 for (i = 0; i < 3; ++i)
2342 if (host_envvars[omp_var].dest[i] != NULL && params[i] != NULL)
2343 *(unsigned char *) (host_envvars[omp_var].dest[i])
2344 = *(unsigned char *) params[i];
2345 break;
2346 case PARSE_SCHEDULE:
2347 *(enum gomp_schedule_type *) (host_envvars[omp_var].dest[0])
2348 = *(enum gomp_schedule_type *) params[0];
2349 *(int *) (host_envvars[omp_var].dest[1]) = *(int *) params[1];
2350 break;
2351 case PARSE_BIND:
26a1f4fc
JJ
2352 *(char *) (host_envvars[omp_var].dest[0]) = *(char *) params[0];
2353 *(char **) (host_envvars[omp_var].dest[1]) = *(char **) params[1];
9f2fca56 2354 *(unsigned long *) (host_envvars[omp_var].dest[2])
26a1f4fc 2355 = *(unsigned long *) params[2];
9f2fca56
MV
2356 break;
2357 }
2358 }
2359
2360 if (((none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_BIND))
2361 || (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_BIND)))
f89163fd
JJ
2362 && gomp_global_icv.bind_var == omp_proc_bind_false)
2363 ignore = true;
9f2fca56
MV
2364
2365 if (!((none != NULL
2366 && gomp_get_icv_flag (none->flags, GOMP_ICV_MAX_ACTIVE_LEVELS))
2367 || (all != NULL
2368 && gomp_get_icv_flag (all->flags, GOMP_ICV_MAX_ACTIVE_LEVELS))))
6fae7eda
KCY
2369 {
2370 bool nested = true;
9f2fca56 2371 const char *env = getenv ("OMP_NESTED");
6fae7eda
KCY
2372
2373 /* OMP_NESTED is deprecated in OpenMP 5.0. */
9f2fca56 2374 if (parse_boolean ("OMP_NESTED", env, (void *[]) {&nested}))
6fae7eda
KCY
2375 gomp_global_icv.max_active_levels_var
2376 = nested ? gomp_supported_active_levels : 1;
2377 else if (gomp_nthreads_var_list_len > 1 || gomp_bind_var_list_len > 1)
2378 gomp_global_icv.max_active_levels_var = gomp_supported_active_levels;
2379 }
9f2fca56 2380
18c8b56c
TB
2381 if (gomp_global_icv.default_device_var == INT_MIN
2382 && gomp_target_offload_var != GOMP_TARGET_OFFLOAD_MANDATORY)
2383 none->icvs.default_device_var = gomp_global_icv.default_device_var = 0;
2384
9f2fca56
MV
2385 /* Process GOMP_* variables and dependencies between parsed ICVs. */
2386 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var, true);
2387
f89163fd
JJ
2388 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
2389 parsed if present in the environment. If OMP_PROC_BIND was set
93d90219 2390 explicitly to false, don't populate places list though. If places
f89163fd
JJ
2391 list was successfully set from OMP_PLACES, only parse but don't process
2392 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
2393 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
2394 was successfully parsed into a places list, otherwise to
2395 OMP_PROC_BIND=false. */
2396 if (parse_places_var ("OMP_PLACES", ignore))
2397 {
2398 if (gomp_global_icv.bind_var == omp_proc_bind_false)
2399 gomp_global_icv.bind_var = true;
2400 ignore = true;
2401 }
2402 if (parse_affinity (ignore))
2403 {
2404 if (gomp_global_icv.bind_var == omp_proc_bind_false)
2405 gomp_global_icv.bind_var = true;
2406 ignore = true;
2407 }
2408 if (gomp_global_icv.bind_var != omp_proc_bind_false)
a0884cf0 2409 gomp_init_affinity ();
28567c40
JJ
2410
2411 {
2412 const char *env = getenv ("OMP_AFFINITY_FORMAT");
2413 if (env != NULL)
2414 gomp_set_affinity_format (env, strlen (env));
2415 }
2416
9f2fca56
MV
2417 if (none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_WAIT_POLICY))
2418 wait_policy = none->icvs.wait_policy;
2419 else if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_WAIT_POLICY))
2420 wait_policy = all->icvs.wait_policy;
2421
a68ab351
JJ
2422 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
2423 {
2424 /* Using a rough estimation of 100000 spins per msec,
2425 use 5 min blocking for OMP_WAIT_POLICY=active,
4c698cf8 2426 3 msec blocking when OMP_WAIT_POLICY is not specificed
a68ab351
JJ
2427 and 0 when OMP_WAIT_POLICY=passive.
2428 Depending on the CPU speed, this can be e.g. 5 times longer
2429 or 5 times shorter. */
2430 if (wait_policy > 0)
2431 gomp_spin_count_var = 30000000000LL;
2432 else if (wait_policy < 0)
4c698cf8 2433 gomp_spin_count_var = 300000LL;
a68ab351
JJ
2434 }
2435 /* gomp_throttled_spin_count_var is used when there are more libgomp
2436 managed threads than available CPUs. Use very short spinning. */
2437 if (wait_policy > 0)
2438 gomp_throttled_spin_count_var = 1000LL;
2439 else if (wait_policy < 0)
2440 gomp_throttled_spin_count_var = 100LL;
2441 if (gomp_throttled_spin_count_var > gomp_spin_count_var)
2442 gomp_throttled_spin_count_var = gomp_spin_count_var;
d0d1b24d
RH
2443
2444 /* Not strictly environment related, but ordering constructors is tricky. */
2445 pthread_attr_init (&gomp_thread_attr);
d0d1b24d 2446
9f2fca56
MV
2447 if (!(none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_STACKSIZE)))
2448 {
2449 const char *env = getenv ("GOMP_STACKSIZE");
2450 if (env != NULL
2451 && parse_stacksize ("GOMP_STACKSIZE", env,
2452 (void *[3]) {&none->icvs.stacksize}))
2453 gomp_set_icv_flag (&none->flags, GOMP_ICV_STACKSIZE);
2454 }
2455 if (none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_STACKSIZE))
2456 stacksize = none->icvs.stacksize;
2457 else if (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_STACKSIZE))
2458 stacksize = all->icvs.stacksize;
2459
2460 if ((none != NULL && gomp_get_icv_flag (none->flags, GOMP_ICV_STACKSIZE))
2461 || (all != NULL && gomp_get_icv_flag (all->flags, GOMP_ICV_STACKSIZE))
c4060df4 2462 || GOMP_DEFAULT_STACKSIZE)
d0d1b24d 2463 {
c3b11a40
RH
2464 int err;
2465
c3b11a40
RH
2466 err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
2467
2468#ifdef PTHREAD_STACK_MIN
2469 if (err == EINVAL)
d0d1b24d 2470 {
c3b11a40
RH
2471 if (stacksize < PTHREAD_STACK_MIN)
2472 gomp_error ("Stack size less than minimum of %luk",
2473 PTHREAD_STACK_MIN / 1024ul
2474 + (PTHREAD_STACK_MIN % 1024 != 0));
2475 else
d0d1b24d 2476 gomp_error ("Stack size larger than system limit");
d0d1b24d 2477 }
c3b11a40
RH
2478 else
2479#endif
2480 if (err != 0)
2481 gomp_error ("Stack size change failed: %s", strerror (err));
d0d1b24d 2482 }
acf0174b 2483
7123ae24 2484 handle_omp_display_env ();
41dbbb37
TS
2485
2486 /* OpenACC. */
2487
9f2fca56
MV
2488 if (!parse_int ("ACC_DEVICE_NUM", getenv ("ACC_DEVICE_NUM"),
2489 (void *[]) {&goacc_device_num, (void *) true}))
41dbbb37
TS
2490 goacc_device_num = 0;
2491
2492 parse_acc_device_type ();
ec00d3fa 2493 parse_gomp_openacc_dim ();
41dbbb37
TS
2494
2495 goacc_runtime_initialize ();
5fae049d
TS
2496
2497 goacc_profiling_initialize ();
953ff289 2498}
630e3c3a 2499#endif /* LIBGOMP_OFFLOADED_ONLY */