1 /* Copyright (C) 2005-2022 Free Software Foundation, Inc.
2 Contributed by Richard Henderson <rth@redhat.com>.
4 This file is part of the GNU Offloading and Multi Processing Library
7 Libgomp is free software; you can redistribute it and/or modify it
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)
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
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
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.
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/>. */
26 /* This file defines the OpenMP internal control variables and arranges
27 for them to be initialized from environment variables at startup. */
31 #include "gomp-constants.h"
33 #ifndef LIBGOMP_OFFLOADED_ONLY
34 #include "libgomp_f.h"
39 #ifdef HAVE_INTTYPES_H
40 # include <inttypes.h> /* For PRIu64. */
42 #ifdef STRING_WITH_STRINGS
49 # ifdef HAVE_STRINGS_H
55 #include "thread-stacksize.h"
58 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
60 #endif /* LIBGOMP_OFFLOADED_ONLY */
62 #include "secure_getenv.h"
64 struct gomp_task_icv gomp_global_icv
= {
66 .thread_limit_var
= UINT_MAX
,
67 .run_sched_var
= GFS_DYNAMIC
,
68 .run_sched_chunk_size
= 1,
69 .default_device_var
= 0,
71 .max_active_levels_var
= 1,
72 .bind_var
= omp_proc_bind_false
,
76 bool gomp_cancel_var
= false;
77 enum gomp_target_offload_t gomp_target_offload_var
78 = GOMP_TARGET_OFFLOAD_DEFAULT
;
79 int gomp_max_task_priority_var
= 0;
80 #ifndef HAVE_SYNC_BUILTINS
81 gomp_mutex_t gomp_managed_threads_lock
;
83 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
84 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
85 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
86 char *gomp_bind_var_list
;
87 unsigned long gomp_bind_var_list_len
;
88 void **gomp_places_list
;
89 unsigned long gomp_places_list_len
;
90 uintptr_t gomp_def_allocator
= omp_default_mem_alloc
;
92 unsigned int gomp_num_teams_var
;
94 int gomp_teams_thread_limit_var
;
95 bool gomp_display_affinity_var
;
96 char *gomp_affinity_format_var
= "level %L thread %i affinity %A";
97 size_t gomp_affinity_format_len
;
98 char *goacc_device_type
;
100 int goacc_default_dims
[GOMP_DIM_MAX
];
102 #ifndef LIBGOMP_OFFLOADED_ONLY
104 static int wait_policy
;
105 static unsigned long stacksize
= GOMP_DEFAULT_STACKSIZE
;
107 /* Parse the OMP_SCHEDULE environment variable. */
110 parse_schedule (void)
116 env
= getenv ("OMP_SCHEDULE");
120 while (isspace ((unsigned char) *env
))
122 if (strncasecmp (env
, "monotonic", 9) == 0)
127 else if (strncasecmp (env
, "nonmonotonic", 12) == 0)
134 while (isspace ((unsigned char) *env
))
139 while (isspace ((unsigned char) *env
))
142 if (strncasecmp (env
, "static", 6) == 0)
144 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
147 else if (strncasecmp (env
, "dynamic", 7) == 0)
149 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
152 else if (strncasecmp (env
, "guided", 6) == 0)
154 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
157 else if (strncasecmp (env
, "auto", 4) == 0)
159 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
166 || (monotonic
== 0 && gomp_global_icv
.run_sched_var
== GFS_STATIC
))
167 gomp_global_icv
.run_sched_var
|= GFS_MONOTONIC
;
169 while (isspace ((unsigned char) *env
))
173 gomp_global_icv
.run_sched_chunk_size
174 = (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
;
179 while (isspace ((unsigned char) *env
))
185 value
= strtoul (env
, &end
, 10);
186 if (errno
|| end
== env
)
189 while (isspace ((unsigned char) *end
))
194 if ((int)value
!= value
)
198 && (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
)
200 gomp_global_icv
.run_sched_chunk_size
= value
;
204 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
208 gomp_error ("Invalid value for chunk size in "
209 "environment variable OMP_SCHEDULE");
213 /* Parse an unsigned long environment variable. Return true if one was
214 present and it was successfully parsed. If SECURE, use secure_getenv to the
215 environment variable. */
218 parse_unsigned_long_1 (const char *name
, unsigned long *pvalue
, bool allow_zero
,
224 env
= (secure
? secure_getenv (name
) : getenv (name
));
228 while (isspace ((unsigned char) *env
))
234 value
= strtoul (env
, &end
, 10);
235 if (errno
|| end
== env
|| (long) value
<= 0 - allow_zero
)
238 while (isspace ((unsigned char) *end
))
247 gomp_error ("Invalid value for environment variable %s", name
);
251 /* As parse_unsigned_long_1, but always use getenv. */
254 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
256 return parse_unsigned_long_1 (name
, pvalue
, allow_zero
, false);
259 /* Parse a positive int environment variable. Return true if one was
260 present and it was successfully parsed. If SECURE, use secure_getenv to the
261 environment variable. */
264 parse_int_1 (const char *name
, int *pvalue
, bool allow_zero
, bool secure
)
267 if (!parse_unsigned_long_1 (name
, &value
, allow_zero
, secure
))
271 gomp_error ("Invalid value for environment variable %s", name
);
274 *pvalue
= (int) value
;
278 /* As parse_int_1, but use getenv. */
281 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
283 return parse_int_1 (name
, pvalue
, allow_zero
, false);
286 /* As parse_int_1, but use getenv_secure. */
289 parse_int_secure (const char *name
, int *pvalue
, bool allow_zero
)
291 return parse_int_1 (name
, pvalue
, allow_zero
, true);
294 /* Parse an unsigned long list environment variable. Return true if one was
295 present and it was successfully parsed. */
298 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
299 unsigned long **pvalues
,
300 unsigned long *pnvalues
)
303 unsigned long value
, *values
= NULL
;
309 while (isspace ((unsigned char) *env
))
315 value
= strtoul (env
, &end
, 10);
316 if (errno
|| (long) value
<= 0)
319 while (isspace ((unsigned char) *end
))
325 unsigned long nvalues
= 0, nalloced
= 0;
330 if (nvalues
== nalloced
)
333 nalloced
= nalloced
? nalloced
* 2 : 16;
334 n
= realloc (values
, nalloced
* sizeof (unsigned long));
338 gomp_error ("Out of memory while trying to parse"
339 " environment variable %s", name
);
344 values
[nvalues
++] = value
;
347 while (isspace ((unsigned char) *env
))
353 value
= strtoul (env
, &end
, 10);
354 if (errno
|| (long) value
<= 0)
357 values
[nvalues
++] = value
;
358 while (isspace ((unsigned char) *end
))
366 *p1stvalue
= values
[0];
379 gomp_error ("Invalid value for environment variable %s", name
);
384 parse_target_offload (const char *name
, enum gomp_target_offload_t
*offload
)
387 int new_offload
= -1;
393 while (isspace ((unsigned char) *env
))
395 if (strncasecmp (env
, "default", 7) == 0)
398 new_offload
= GOMP_TARGET_OFFLOAD_DEFAULT
;
400 else if (strncasecmp (env
, "mandatory", 9) == 0)
403 new_offload
= GOMP_TARGET_OFFLOAD_MANDATORY
;
405 else if (strncasecmp (env
, "disabled", 8) == 0)
408 new_offload
= GOMP_TARGET_OFFLOAD_DISABLED
;
410 while (isspace ((unsigned char) *env
))
412 if (new_offload
!= -1 && *env
== '\0')
414 *offload
= new_offload
;
418 gomp_error ("Invalid value for environment variable OMP_TARGET_OFFLOAD");
421 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
422 enum values. Return true if one was present and it was successfully
426 parse_bind_var (const char *name
, char *p1stvalue
,
427 char **pvalues
, unsigned long *pnvalues
)
430 char value
= omp_proc_bind_false
, *values
= NULL
;
432 static struct proc_bind_kinds
436 omp_proc_bind_t kind
;
439 { "false", 5, omp_proc_bind_false
},
440 { "true", 4, omp_proc_bind_true
},
441 { "master", 6, omp_proc_bind_master
},
442 { "primary", 7, omp_proc_bind_primary
},
443 { "close", 5, omp_proc_bind_close
},
444 { "spread", 6, omp_proc_bind_spread
}
451 while (isspace ((unsigned char) *env
))
456 for (i
= 0; i
< 6; i
++)
457 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
459 value
= kinds
[i
].kind
;
466 while (isspace ((unsigned char) *env
))
472 unsigned long nvalues
= 0, nalloced
= 0;
474 if (value
== omp_proc_bind_false
475 || value
== omp_proc_bind_true
)
481 if (nvalues
== nalloced
)
484 nalloced
= nalloced
? nalloced
* 2 : 16;
485 n
= realloc (values
, nalloced
);
489 gomp_error ("Out of memory while trying to parse"
490 " environment variable %s", name
);
495 values
[nvalues
++] = value
;
498 while (isspace ((unsigned char) *env
))
503 for (i
= 2; i
< 6; i
++)
504 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
506 value
= kinds
[i
].kind
;
513 values
[nvalues
++] = value
;
514 while (isspace ((unsigned char) *env
))
522 *p1stvalue
= values
[0];
535 gomp_error ("Invalid value for environment variable %s", name
);
540 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
543 char *env
= *envp
, *start
;
544 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
545 unsigned long len
= 1;
548 bool any_negate
= false;
549 bool has_braces
= true;
551 while (isspace ((unsigned char) *env
))
557 while (isspace ((unsigned char) *env
))
563 unsigned long this_num
;
566 this_num
= strtoul (env
, &end
, 10);
567 if (errno
|| end
== env
)
572 && !gomp_affinity_add_cpus (p
, this_num
, 1, 1, false))
578 while (isspace ((unsigned char) *env
))
582 for (pass
= 0; pass
< (any_negate
? 2 : has_braces
); pass
++)
587 unsigned long this_num
, this_len
= 1;
588 long this_stride
= 1;
589 bool this_negate
= (*env
== '!');
593 if (gomp_places_list
)
596 while (isspace ((unsigned char) *env
))
601 this_num
= strtoul (env
, &end
, 10);
602 if (errno
|| end
== env
)
605 while (isspace ((unsigned char) *env
))
612 while (isspace ((unsigned char) *env
))
615 this_len
= strtoul (env
, &env
, 10);
616 if (errno
|| this_len
== 0)
618 while (isspace ((unsigned char) *env
))
623 while (isspace ((unsigned char) *env
))
626 this_stride
= strtol (env
, &end
, 10);
627 if (errno
|| end
== env
)
630 while (isspace ((unsigned char) *env
))
634 if (gomp_places_list
&& pass
== this_negate
)
638 if (!gomp_affinity_remove_cpu (p
, this_num
))
641 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
655 while (isspace ((unsigned char) *env
))
663 while (isspace ((unsigned char) *env
))
666 len
= strtoul (env
, &env
, 10);
667 if (errno
|| len
== 0 || len
>= 65536)
669 while (isspace ((unsigned char) *env
))
674 while (isspace ((unsigned char) *env
))
677 stride
= strtol (env
, &end
, 10);
678 if (errno
|| end
== env
)
681 while (isspace ((unsigned char) *env
))
692 parse_places_var (const char *name
, bool ignore
)
694 char *env
= getenv (name
), *end
;
695 bool any_negate
= false;
697 unsigned long count
= 0;
701 while (isspace ((unsigned char) *env
))
706 if (strncasecmp (env
, "threads", 7) == 0)
711 else if (strncasecmp (env
, "cores", 5) == 0)
716 else if (strncasecmp (env
, "sockets", 7) == 0)
721 else if (strncasecmp (env
, "ll_caches", 9) == 0)
726 else if (strncasecmp (env
, "numa_domains", 12) == 0)
734 while (isspace ((unsigned char) *env
))
740 while (isspace ((unsigned char) *env
))
744 count
= strtoul (env
, &end
, 10);
745 if (errno
|| end
== env
)
748 while (isspace ((unsigned char) *env
))
753 while (isspace ((unsigned char) *env
))
762 return gomp_affinity_init_level (level
, count
, false);
772 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
795 gomp_places_list_len
= 0;
796 gomp_places_list
= gomp_affinity_alloc (count
, false);
797 if (gomp_places_list
== NULL
)
805 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
806 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
811 for (count
= 0; count
< gomp_places_list_len
; count
++)
812 if (gomp_affinity_same_place
813 (gomp_places_list
[count
],
814 gomp_places_list
[gomp_places_list_len
]))
816 if (count
== gomp_places_list_len
)
818 gomp_error ("Trying to remove a non-existing place from list "
822 p
= gomp_places_list
[count
];
823 memmove (&gomp_places_list
[count
],
824 &gomp_places_list
[count
+ 1],
825 (gomp_places_list_len
- count
- 1) * sizeof (void *));
826 --gomp_places_list_len
;
827 gomp_places_list
[gomp_places_list_len
] = p
;
830 ++gomp_places_list_len
;
833 for (count
= 0; count
< len
- 1; count
++)
834 if (!gomp_affinity_copy_place
835 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
836 gomp_places_list
[gomp_places_list_len
+ count
],
839 gomp_places_list_len
+= len
;
847 if (gomp_places_list_len
== 0)
849 gomp_error ("All places have been removed");
852 if (!gomp_affinity_finalize_place_list (false))
857 free (gomp_places_list
);
858 gomp_places_list
= NULL
;
859 gomp_places_list_len
= 0;
860 gomp_error ("Invalid value for environment variable %s", name
);
864 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
865 present and it was successfully parsed. */
868 parse_stacksize (const char *name
, unsigned long *pvalue
)
871 unsigned long value
, shift
= 10;
877 while (isspace ((unsigned char) *env
))
883 value
= strtoul (env
, &end
, 10);
884 if (errno
|| end
== env
)
887 while (isspace ((unsigned char) *end
))
891 switch (tolower ((unsigned char) *end
))
908 while (isspace ((unsigned char) *end
))
914 if (((value
<< shift
) >> shift
) != value
)
917 *pvalue
= value
<< shift
;
921 gomp_error ("Invalid value for environment variable %s", name
);
925 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
926 present and it was successfully parsed. */
929 parse_spincount (const char *name
, unsigned long long *pvalue
)
932 unsigned long long value
, mult
= 1;
938 while (isspace ((unsigned char) *env
))
943 if (strncasecmp (env
, "infinite", 8) == 0
944 || strncasecmp (env
, "infinity", 8) == 0)
952 value
= strtoull (env
, &end
, 10);
953 if (errno
|| end
== env
)
956 while (isspace ((unsigned char) *end
))
960 switch (tolower ((unsigned char) *end
))
966 mult
= 1000LL * 1000LL;
969 mult
= 1000LL * 1000LL * 1000LL;
972 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
979 while (isspace ((unsigned char) *end
))
985 if (value
> ~0ULL / mult
)
994 gomp_error ("Invalid value for environment variable %s", name
);
998 /* Parse a boolean value for environment variable NAME and store the
999 result in VALUE. Return true if one was present and it was
1000 successfully parsed. */
1003 parse_boolean (const char *name
, bool *value
)
1007 env
= getenv (name
);
1011 while (isspace ((unsigned char) *env
))
1013 if (strncasecmp (env
, "true", 4) == 0)
1018 else if (strncasecmp (env
, "false", 5) == 0)
1025 while (isspace ((unsigned char) *env
))
1029 gomp_error ("Invalid value for environment variable %s", name
);
1035 /* Parse the OMP_WAIT_POLICY environment variable and return the value. */
1038 parse_wait_policy (void)
1043 env
= getenv ("OMP_WAIT_POLICY");
1047 while (isspace ((unsigned char) *env
))
1049 if (strncasecmp (env
, "active", 6) == 0)
1054 else if (strncasecmp (env
, "passive", 7) == 0)
1061 while (isspace ((unsigned char) *env
))
1065 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
1069 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1070 present and it was successfully parsed. */
1073 parse_affinity (bool ignore
)
1075 char *env
, *end
, *start
;
1077 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
1078 size_t count
= 0, needed
;
1080 env
= getenv ("GOMP_CPU_AFFINITY");
1085 for (pass
= 0; pass
< 2; pass
++)
1093 gomp_places_list_len
= 0;
1094 gomp_places_list
= gomp_affinity_alloc (count
, true);
1095 if (gomp_places_list
== NULL
)
1100 while (isspace ((unsigned char) *env
))
1104 cpu_beg
= strtoul (env
, &end
, 0);
1105 if (errno
|| end
== env
|| cpu_beg
>= 65536)
1114 cpu_end
= strtoul (++env
, &end
, 0);
1115 if (errno
|| end
== env
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
1122 cpu_stride
= strtoul (++env
, &end
, 0);
1123 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
1130 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
1137 void *p
= gomp_places_list
[gomp_places_list_len
];
1138 gomp_affinity_init_place (p
);
1139 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
1140 ++gomp_places_list_len
;
1141 cpu_beg
+= cpu_stride
;
1145 while (isspace ((unsigned char) *env
))
1150 else if (*env
== '\0')
1156 if (gomp_places_list_len
== 0)
1158 free (gomp_places_list
);
1159 gomp_places_list
= NULL
;
1165 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1169 /* Parse the OMP_ALLOCATOR environment variable and return the value. */
1172 parse_allocator (void)
1175 uintptr_t ret
= omp_default_mem_alloc
;
1177 env
= getenv ("OMP_ALLOCATOR");
1181 while (isspace ((unsigned char) *env
))
1186 else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
1189 env += sizeof (#v) - 1; \
1191 C (omp_default_mem_alloc
)
1192 C (omp_large_cap_mem_alloc
)
1193 C (omp_const_mem_alloc
)
1194 C (omp_high_bw_mem_alloc
)
1195 C (omp_low_lat_mem_alloc
)
1196 C (omp_cgroup_mem_alloc
)
1197 C (omp_pteam_mem_alloc
)
1198 C (omp_thread_mem_alloc
)
1202 while (isspace ((unsigned char) *env
))
1206 gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
1207 return omp_default_mem_alloc
;
1211 parse_acc_device_type (void)
1213 const char *env
= getenv ("ACC_DEVICE_TYPE");
1215 if (env
&& *env
!= '\0')
1216 goacc_device_type
= strdup (env
);
1218 goacc_device_type
= NULL
;
1222 parse_gomp_openacc_dim (void)
1224 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1225 const char *var_name
= "GOMP_OPENACC_DIM";
1226 const char *env_var
= getenv (var_name
);
1227 const char *pos
= env_var
;
1233 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1238 if (i
&& *pos
++ != ':')
1245 val
= strtol (pos
, &eptr
, 10);
1246 if (errno
|| eptr
== pos
|| val
< 0 || (unsigned)val
!= val
)
1249 goacc_default_dims
[i
] = (int)val
;
1250 pos
= (const char *) eptr
;
1255 omp_display_env (int verbose
)
1259 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1261 fputs (" _OPENMP = '201511'\n", stderr
);
1262 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1263 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1264 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1265 gomp_global_icv
.max_active_levels_var
> 1 ? "TRUE" : "FALSE");
1267 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1268 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1269 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1270 fputs ("'\n", stderr
);
1272 fprintf (stderr
, " OMP_SCHEDULE = '");
1273 if ((gomp_global_icv
.run_sched_var
& GFS_MONOTONIC
))
1275 if (gomp_global_icv
.run_sched_var
!= (GFS_MONOTONIC
| GFS_STATIC
))
1276 fputs ("MONOTONIC:", stderr
);
1278 else if (gomp_global_icv
.run_sched_var
== GFS_STATIC
)
1279 fputs ("NONMONOTONIC:", stderr
);
1280 switch (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
)
1283 fputs ("RUNTIME", stderr
);
1284 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1285 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1288 fputs ("STATIC", stderr
);
1289 if (gomp_global_icv
.run_sched_chunk_size
!= 0)
1290 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1293 fputs ("DYNAMIC", stderr
);
1294 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1295 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1298 fputs ("GUIDED", stderr
);
1299 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1300 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1303 fputs ("AUTO", stderr
);
1306 fputs ("'\n", stderr
);
1308 fputs (" OMP_PROC_BIND = '", stderr
);
1309 switch (gomp_global_icv
.bind_var
)
1311 case omp_proc_bind_false
:
1312 fputs ("FALSE", stderr
);
1314 case omp_proc_bind_true
:
1315 fputs ("TRUE", stderr
);
1317 case omp_proc_bind_master
:
1318 fputs ("MASTER", stderr
); /* TODO: Change to PRIMARY for OpenMP 5.1. */
1320 case omp_proc_bind_close
:
1321 fputs ("CLOSE", stderr
);
1323 case omp_proc_bind_spread
:
1324 fputs ("SPREAD", stderr
);
1327 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1328 switch (gomp_bind_var_list
[i
])
1330 case omp_proc_bind_master
:
1331 fputs (",MASTER", stderr
); /* TODO: Change to PRIMARY for OpenMP 5.1. */
1333 case omp_proc_bind_close
:
1334 fputs (",CLOSE", stderr
);
1336 case omp_proc_bind_spread
:
1337 fputs (",SPREAD", stderr
);
1340 fputs ("'\n", stderr
);
1341 fputs (" OMP_PLACES = '", stderr
);
1342 for (i
= 0; i
< gomp_places_list_len
; i
++)
1344 fputs ("{", stderr
);
1345 gomp_affinity_print_place (gomp_places_list
[i
]);
1346 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1348 fputs ("'\n", stderr
);
1350 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1352 /* GOMP's default value is actually neither active nor passive. */
1353 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1354 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1355 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1356 gomp_global_icv
.thread_limit_var
);
1357 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1358 gomp_global_icv
.max_active_levels_var
);
1359 fprintf (stderr
, " OMP_NUM_TEAMS = '%u'\n", gomp_nteams_var
);
1360 fprintf (stderr
, " OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1361 gomp_teams_thread_limit_var
);
1363 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1364 gomp_cancel_var
? "TRUE" : "FALSE");
1365 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1366 gomp_global_icv
.default_device_var
);
1367 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1368 gomp_max_task_priority_var
);
1369 fprintf (stderr
, " OMP_DISPLAY_AFFINITY = '%s'\n",
1370 gomp_display_affinity_var
? "TRUE" : "FALSE");
1371 fprintf (stderr
, " OMP_AFFINITY_FORMAT = '%s'\n",
1372 gomp_affinity_format_var
);
1373 fprintf (stderr
, " OMP_ALLOCATOR = '");
1374 switch (gomp_def_allocator
)
1376 #define C(v) case v: fputs (#v, stderr); break;
1377 C (omp_default_mem_alloc
)
1378 C (omp_large_cap_mem_alloc
)
1379 C (omp_const_mem_alloc
)
1380 C (omp_high_bw_mem_alloc
)
1381 C (omp_low_lat_mem_alloc
)
1382 C (omp_cgroup_mem_alloc
)
1383 C (omp_pteam_mem_alloc
)
1384 C (omp_thread_mem_alloc
)
1388 fputs ("'\n", stderr
);
1390 fputs (" OMP_TARGET_OFFLOAD = '", stderr
);
1391 switch (gomp_target_offload_var
)
1393 case GOMP_TARGET_OFFLOAD_DEFAULT
:
1394 fputs ("DEFAULT", stderr
);
1396 case GOMP_TARGET_OFFLOAD_MANDATORY
:
1397 fputs ("MANDATORY", stderr
);
1399 case GOMP_TARGET_OFFLOAD_DISABLED
:
1400 fputs ("DISABLED", stderr
);
1403 fputs ("'\n", stderr
);
1407 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1408 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1409 #ifdef HAVE_INTTYPES_H
1410 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1411 (uint64_t) gomp_spin_count_var
);
1413 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1414 (unsigned long) gomp_spin_count_var
);
1418 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1420 ialias (omp_display_env
)
1423 handle_omp_display_env (void)
1426 bool display
= false;
1427 bool verbose
= false;
1429 env
= getenv ("OMP_DISPLAY_ENV");
1433 while (isspace ((unsigned char) *env
))
1435 if (strncasecmp (env
, "true", 4) == 0)
1440 else if (strncasecmp (env
, "false", 5) == 0)
1445 else if (strncasecmp (env
, "verbose", 7) == 0)
1453 while (isspace ((unsigned char) *env
))
1456 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1459 ialias_call (omp_display_env
) (verbose
);
1463 static void __attribute__((constructor
))
1464 initialize_env (void)
1466 unsigned long thread_limit_var
;
1467 unsigned long max_active_levels_var
;
1469 /* Do a compile time check that mkomp_h.pl did good job. */
1470 omp_check_defines ();
1473 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1474 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1475 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var
);
1476 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1477 parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var
);
1478 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1479 gomp_def_allocator
= parse_allocator ();
1480 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1482 gomp_global_icv
.thread_limit_var
1483 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1485 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var
, true);
1486 #ifndef HAVE_SYNC_BUILTINS
1487 gomp_mutex_init (&gomp_managed_threads_lock
);
1489 gomp_init_num_threads ();
1490 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1491 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1492 &gomp_global_icv
.nthreads_var
,
1493 &gomp_nthreads_var_list
,
1494 &gomp_nthreads_var_list_len
))
1495 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1496 parse_int ("OMP_NUM_TEAMS", &gomp_nteams_var
, false);
1497 parse_int ("OMP_TEAMS_THREAD_LIMIT", &gomp_teams_thread_limit_var
, false);
1498 bool ignore
= false;
1499 if (parse_bind_var ("OMP_PROC_BIND",
1500 &gomp_global_icv
.bind_var
,
1501 &gomp_bind_var_list
,
1502 &gomp_bind_var_list_len
)
1503 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1505 if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
1506 &max_active_levels_var
, true))
1507 gomp_global_icv
.max_active_levels_var
1508 = (max_active_levels_var
> gomp_supported_active_levels
)
1509 ? gomp_supported_active_levels
: max_active_levels_var
;
1514 /* OMP_NESTED is deprecated in OpenMP 5.0. */
1515 if (parse_boolean ("OMP_NESTED", &nested
))
1516 gomp_global_icv
.max_active_levels_var
1517 = nested
? gomp_supported_active_levels
: 1;
1518 else if (gomp_nthreads_var_list_len
> 1 || gomp_bind_var_list_len
> 1)
1519 gomp_global_icv
.max_active_levels_var
= gomp_supported_active_levels
;
1521 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1522 parsed if present in the environment. If OMP_PROC_BIND was set
1523 explicitly to false, don't populate places list though. If places
1524 list was successfully set from OMP_PLACES, only parse but don't process
1525 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1526 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1527 was successfully parsed into a places list, otherwise to
1528 OMP_PROC_BIND=false. */
1529 if (parse_places_var ("OMP_PLACES", ignore
))
1531 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1532 gomp_global_icv
.bind_var
= true;
1535 if (parse_affinity (ignore
))
1537 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1538 gomp_global_icv
.bind_var
= true;
1541 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1542 gomp_init_affinity ();
1545 const char *env
= getenv ("OMP_AFFINITY_FORMAT");
1547 gomp_set_affinity_format (env
, strlen (env
));
1550 wait_policy
= parse_wait_policy ();
1551 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1553 /* Using a rough estimation of 100000 spins per msec,
1554 use 5 min blocking for OMP_WAIT_POLICY=active,
1555 3 msec blocking when OMP_WAIT_POLICY is not specificed
1556 and 0 when OMP_WAIT_POLICY=passive.
1557 Depending on the CPU speed, this can be e.g. 5 times longer
1558 or 5 times shorter. */
1559 if (wait_policy
> 0)
1560 gomp_spin_count_var
= 30000000000LL;
1561 else if (wait_policy
< 0)
1562 gomp_spin_count_var
= 300000LL;
1564 /* gomp_throttled_spin_count_var is used when there are more libgomp
1565 managed threads than available CPUs. Use very short spinning. */
1566 if (wait_policy
> 0)
1567 gomp_throttled_spin_count_var
= 1000LL;
1568 else if (wait_policy
< 0)
1569 gomp_throttled_spin_count_var
= 100LL;
1570 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1571 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1573 /* Not strictly environment related, but ordering constructors is tricky. */
1574 pthread_attr_init (&gomp_thread_attr
);
1576 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1577 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
)
1578 || GOMP_DEFAULT_STACKSIZE
)
1582 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1584 #ifdef PTHREAD_STACK_MIN
1587 if (stacksize
< PTHREAD_STACK_MIN
)
1588 gomp_error ("Stack size less than minimum of %luk",
1589 PTHREAD_STACK_MIN
/ 1024ul
1590 + (PTHREAD_STACK_MIN
% 1024 != 0));
1592 gomp_error ("Stack size larger than system limit");
1597 gomp_error ("Stack size change failed: %s", strerror (err
));
1600 handle_omp_display_env ();
1604 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1605 goacc_device_num
= 0;
1607 parse_acc_device_type ();
1608 parse_gomp_openacc_dim ();
1610 goacc_runtime_initialize ();
1612 goacc_profiling_initialize ();
1614 #endif /* LIBGOMP_OFFLOADED_ONLY */