1 /* Copyright (C) 2005-2021 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
;
93 bool gomp_display_affinity_var
;
94 char *gomp_affinity_format_var
= "level %L thread %i affinity %A";
95 size_t gomp_affinity_format_len
;
96 char *goacc_device_type
;
98 int goacc_default_dims
[GOMP_DIM_MAX
];
100 #ifndef LIBGOMP_OFFLOADED_ONLY
102 /* Parse the OMP_SCHEDULE environment variable. */
105 parse_schedule (void)
111 env
= getenv ("OMP_SCHEDULE");
115 while (isspace ((unsigned char) *env
))
117 if (strncasecmp (env
, "monotonic", 9) == 0)
122 else if (strncasecmp (env
, "nonmonotonic", 12) == 0)
129 while (isspace ((unsigned char) *env
))
134 while (isspace ((unsigned char) *env
))
137 if (strncasecmp (env
, "static", 6) == 0)
139 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
142 else if (strncasecmp (env
, "dynamic", 7) == 0)
144 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
147 else if (strncasecmp (env
, "guided", 6) == 0)
149 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
152 else if (strncasecmp (env
, "auto", 4) == 0)
154 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
161 || (monotonic
== 0 && gomp_global_icv
.run_sched_var
== GFS_STATIC
))
162 gomp_global_icv
.run_sched_var
|= GFS_MONOTONIC
;
164 while (isspace ((unsigned char) *env
))
168 gomp_global_icv
.run_sched_chunk_size
169 = (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
;
174 while (isspace ((unsigned char) *env
))
180 value
= strtoul (env
, &end
, 10);
184 while (isspace ((unsigned char) *end
))
189 if ((int)value
!= value
)
193 && (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
)
195 gomp_global_icv
.run_sched_chunk_size
= value
;
199 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
203 gomp_error ("Invalid value for chunk size in "
204 "environment variable OMP_SCHEDULE");
208 /* Parse an unsigned long environment variable. Return true if one was
209 present and it was successfully parsed. If SECURE, use secure_getenv to the
210 environment variable. */
213 parse_unsigned_long_1 (const char *name
, unsigned long *pvalue
, bool allow_zero
,
219 env
= (secure
? secure_getenv (name
) : getenv (name
));
223 while (isspace ((unsigned char) *env
))
229 value
= strtoul (env
, &end
, 10);
230 if (errno
|| (long) value
<= 0 - allow_zero
)
233 while (isspace ((unsigned char) *end
))
242 gomp_error ("Invalid value for environment variable %s", name
);
246 /* As parse_unsigned_long_1, but always use getenv. */
249 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
251 return parse_unsigned_long_1 (name
, pvalue
, allow_zero
, false);
254 /* Parse a positive int environment variable. Return true if one was
255 present and it was successfully parsed. If SECURE, use secure_getenv to the
256 environment variable. */
259 parse_int_1 (const char *name
, int *pvalue
, bool allow_zero
, bool secure
)
262 if (!parse_unsigned_long_1 (name
, &value
, allow_zero
, secure
))
266 gomp_error ("Invalid value for environment variable %s", name
);
269 *pvalue
= (int) value
;
273 /* As parse_int_1, but use getenv. */
276 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
278 return parse_int_1 (name
, pvalue
, allow_zero
, false);
281 /* As parse_int_1, but use getenv_secure. */
284 parse_int_secure (const char *name
, int *pvalue
, bool allow_zero
)
286 return parse_int_1 (name
, pvalue
, allow_zero
, true);
289 /* Parse an unsigned long list environment variable. Return true if one was
290 present and it was successfully parsed. */
293 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
294 unsigned long **pvalues
,
295 unsigned long *pnvalues
)
298 unsigned long value
, *values
= NULL
;
304 while (isspace ((unsigned char) *env
))
310 value
= strtoul (env
, &end
, 10);
311 if (errno
|| (long) value
<= 0)
314 while (isspace ((unsigned char) *end
))
320 unsigned long nvalues
= 0, nalloced
= 0;
325 if (nvalues
== nalloced
)
328 nalloced
= nalloced
? nalloced
* 2 : 16;
329 n
= realloc (values
, nalloced
* sizeof (unsigned long));
333 gomp_error ("Out of memory while trying to parse"
334 " environment variable %s", name
);
339 values
[nvalues
++] = value
;
342 while (isspace ((unsigned char) *env
))
348 value
= strtoul (env
, &end
, 10);
349 if (errno
|| (long) value
<= 0)
352 values
[nvalues
++] = value
;
353 while (isspace ((unsigned char) *end
))
361 *p1stvalue
= values
[0];
374 gomp_error ("Invalid value for environment variable %s", name
);
379 parse_target_offload (const char *name
, enum gomp_target_offload_t
*offload
)
382 int new_offload
= -1;
388 while (isspace ((unsigned char) *env
))
390 if (strncasecmp (env
, "default", 7) == 0)
393 new_offload
= GOMP_TARGET_OFFLOAD_DEFAULT
;
395 else if (strncasecmp (env
, "mandatory", 9) == 0)
398 new_offload
= GOMP_TARGET_OFFLOAD_MANDATORY
;
400 else if (strncasecmp (env
, "disabled", 8) == 0)
403 new_offload
= GOMP_TARGET_OFFLOAD_DISABLED
;
405 while (isspace ((unsigned char) *env
))
407 if (new_offload
!= -1 && *env
== '\0')
409 *offload
= new_offload
;
413 gomp_error ("Invalid value for environment variable OMP_TARGET_OFFLOAD");
416 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
417 enum values. Return true if one was present and it was successfully
421 parse_bind_var (const char *name
, char *p1stvalue
,
422 char **pvalues
, unsigned long *pnvalues
)
425 char value
= omp_proc_bind_false
, *values
= NULL
;
427 static struct proc_bind_kinds
431 omp_proc_bind_t kind
;
434 { "false", 5, omp_proc_bind_false
},
435 { "true", 4, omp_proc_bind_true
},
436 { "master", 6, omp_proc_bind_master
},
437 { "close", 5, omp_proc_bind_close
},
438 { "spread", 6, omp_proc_bind_spread
}
445 while (isspace ((unsigned char) *env
))
450 for (i
= 0; i
< 5; i
++)
451 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
453 value
= kinds
[i
].kind
;
460 while (isspace ((unsigned char) *env
))
466 unsigned long nvalues
= 0, nalloced
= 0;
468 if (value
== omp_proc_bind_false
469 || value
== omp_proc_bind_true
)
475 if (nvalues
== nalloced
)
478 nalloced
= nalloced
? nalloced
* 2 : 16;
479 n
= realloc (values
, nalloced
);
483 gomp_error ("Out of memory while trying to parse"
484 " environment variable %s", name
);
489 values
[nvalues
++] = value
;
492 while (isspace ((unsigned char) *env
))
497 for (i
= 2; i
< 5; i
++)
498 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
500 value
= kinds
[i
].kind
;
507 values
[nvalues
++] = value
;
508 while (isspace ((unsigned char) *env
))
516 *p1stvalue
= values
[0];
529 gomp_error ("Invalid value for environment variable %s", name
);
534 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
537 char *env
= *envp
, *start
;
538 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
539 unsigned long len
= 1;
542 bool any_negate
= false;
544 while (isspace ((unsigned char) *env
))
550 while (isspace ((unsigned char) *env
))
556 while (isspace ((unsigned char) *env
))
559 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
564 unsigned long this_num
, this_len
= 1;
565 long this_stride
= 1;
566 bool this_negate
= (*env
== '!');
569 if (gomp_places_list
)
572 while (isspace ((unsigned char) *env
))
577 this_num
= strtoul (env
, &env
, 10);
580 while (isspace ((unsigned char) *env
))
585 while (isspace ((unsigned char) *env
))
588 this_len
= strtoul (env
, &env
, 10);
589 if (errno
|| this_len
== 0)
591 while (isspace ((unsigned char) *env
))
596 while (isspace ((unsigned char) *env
))
599 this_stride
= strtol (env
, &env
, 10);
602 while (isspace ((unsigned char) *env
))
606 if (this_negate
&& this_len
!= 1)
608 if (gomp_places_list
&& pass
== this_negate
)
612 if (!gomp_affinity_remove_cpu (p
, this_num
))
615 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
629 while (isspace ((unsigned char) *env
))
634 while (isspace ((unsigned char) *env
))
637 len
= strtoul (env
, &env
, 10);
638 if (errno
|| len
== 0 || len
>= 65536)
640 while (isspace ((unsigned char) *env
))
645 while (isspace ((unsigned char) *env
))
648 stride
= strtol (env
, &env
, 10);
651 while (isspace ((unsigned char) *env
))
655 if (*negatep
&& len
!= 1)
664 parse_places_var (const char *name
, bool ignore
)
666 char *env
= getenv (name
), *end
;
667 bool any_negate
= false;
669 unsigned long count
= 0;
673 while (isspace ((unsigned char) *env
))
678 if (strncasecmp (env
, "threads", 7) == 0)
683 else if (strncasecmp (env
, "cores", 5) == 0)
688 else if (strncasecmp (env
, "sockets", 7) == 0)
696 while (isspace ((unsigned char) *env
))
702 while (isspace ((unsigned char) *env
))
706 count
= strtoul (env
, &end
, 10);
710 while (isspace ((unsigned char) *env
))
715 while (isspace ((unsigned char) *env
))
724 return gomp_affinity_init_level (level
, count
, false);
734 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
757 gomp_places_list_len
= 0;
758 gomp_places_list
= gomp_affinity_alloc (count
, false);
759 if (gomp_places_list
== NULL
)
767 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
768 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
773 for (count
= 0; count
< gomp_places_list_len
; count
++)
774 if (gomp_affinity_same_place
775 (gomp_places_list
[count
],
776 gomp_places_list
[gomp_places_list_len
]))
778 if (count
== gomp_places_list_len
)
780 gomp_error ("Trying to remove a non-existing place from list "
784 p
= gomp_places_list
[count
];
785 memmove (&gomp_places_list
[count
],
786 &gomp_places_list
[count
+ 1],
787 (gomp_places_list_len
- count
- 1) * sizeof (void *));
788 --gomp_places_list_len
;
789 gomp_places_list
[gomp_places_list_len
] = p
;
792 ++gomp_places_list_len
;
795 for (count
= 0; count
< len
- 1; count
++)
796 if (!gomp_affinity_copy_place
797 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
798 gomp_places_list
[gomp_places_list_len
+ count
],
801 gomp_places_list_len
+= len
;
809 if (gomp_places_list_len
== 0)
811 gomp_error ("All places have been removed");
814 if (!gomp_affinity_finalize_place_list (false))
819 free (gomp_places_list
);
820 gomp_places_list
= NULL
;
821 gomp_places_list_len
= 0;
822 gomp_error ("Invalid value for environment variable %s", name
);
826 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
827 present and it was successfully parsed. */
830 parse_stacksize (const char *name
, unsigned long *pvalue
)
833 unsigned long value
, shift
= 10;
839 while (isspace ((unsigned char) *env
))
845 value
= strtoul (env
, &end
, 10);
849 while (isspace ((unsigned char) *end
))
853 switch (tolower ((unsigned char) *end
))
870 while (isspace ((unsigned char) *end
))
876 if (((value
<< shift
) >> shift
) != value
)
879 *pvalue
= value
<< shift
;
883 gomp_error ("Invalid value for environment variable %s", name
);
887 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
888 present and it was successfully parsed. */
891 parse_spincount (const char *name
, unsigned long long *pvalue
)
894 unsigned long long value
, mult
= 1;
900 while (isspace ((unsigned char) *env
))
905 if (strncasecmp (env
, "infinite", 8) == 0
906 || strncasecmp (env
, "infinity", 8) == 0)
914 value
= strtoull (env
, &end
, 10);
918 while (isspace ((unsigned char) *end
))
922 switch (tolower ((unsigned char) *end
))
928 mult
= 1000LL * 1000LL;
931 mult
= 1000LL * 1000LL * 1000LL;
934 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
941 while (isspace ((unsigned char) *end
))
947 if (value
> ~0ULL / mult
)
956 gomp_error ("Invalid value for environment variable %s", name
);
960 /* Parse a boolean value for environment variable NAME and store the
961 result in VALUE. Return true if one was present and it was
962 successfully parsed. */
965 parse_boolean (const char *name
, bool *value
)
973 while (isspace ((unsigned char) *env
))
975 if (strncasecmp (env
, "true", 4) == 0)
980 else if (strncasecmp (env
, "false", 5) == 0)
987 while (isspace ((unsigned char) *env
))
991 gomp_error ("Invalid value for environment variable %s", name
);
997 /* Parse the OMP_WAIT_POLICY environment variable and return the value. */
1000 parse_wait_policy (void)
1005 env
= getenv ("OMP_WAIT_POLICY");
1009 while (isspace ((unsigned char) *env
))
1011 if (strncasecmp (env
, "active", 6) == 0)
1016 else if (strncasecmp (env
, "passive", 7) == 0)
1023 while (isspace ((unsigned char) *env
))
1027 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
1031 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1032 present and it was successfully parsed. */
1035 parse_affinity (bool ignore
)
1037 char *env
, *end
, *start
;
1039 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
1040 size_t count
= 0, needed
;
1042 env
= getenv ("GOMP_CPU_AFFINITY");
1047 for (pass
= 0; pass
< 2; pass
++)
1055 gomp_places_list_len
= 0;
1056 gomp_places_list
= gomp_affinity_alloc (count
, true);
1057 if (gomp_places_list
== NULL
)
1062 while (isspace ((unsigned char) *env
))
1066 cpu_beg
= strtoul (env
, &end
, 0);
1067 if (errno
|| cpu_beg
>= 65536)
1076 cpu_end
= strtoul (++env
, &end
, 0);
1077 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
1084 cpu_stride
= strtoul (++env
, &end
, 0);
1085 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
1092 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
1099 void *p
= gomp_places_list
[gomp_places_list_len
];
1100 gomp_affinity_init_place (p
);
1101 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
1102 ++gomp_places_list_len
;
1103 cpu_beg
+= cpu_stride
;
1107 while (isspace ((unsigned char) *env
))
1112 else if (*env
== '\0')
1118 if (gomp_places_list_len
== 0)
1120 free (gomp_places_list
);
1121 gomp_places_list
= NULL
;
1127 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1131 /* Parse the OMP_ALLOCATOR environment variable and return the value. */
1134 parse_allocator (void)
1137 uintptr_t ret
= omp_default_mem_alloc
;
1139 env
= getenv ("OMP_ALLOCATOR");
1143 while (isspace ((unsigned char) *env
))
1148 else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
1151 env += sizeof (#v) - 1; \
1153 C (omp_default_mem_alloc
)
1154 C (omp_large_cap_mem_alloc
)
1155 C (omp_const_mem_alloc
)
1156 C (omp_high_bw_mem_alloc
)
1157 C (omp_low_lat_mem_alloc
)
1158 C (omp_cgroup_mem_alloc
)
1159 C (omp_pteam_mem_alloc
)
1160 C (omp_thread_mem_alloc
)
1164 while (isspace ((unsigned char) *env
))
1168 gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
1169 return omp_default_mem_alloc
;
1173 parse_acc_device_type (void)
1175 const char *env
= getenv ("ACC_DEVICE_TYPE");
1177 if (env
&& *env
!= '\0')
1178 goacc_device_type
= strdup (env
);
1180 goacc_device_type
= NULL
;
1184 parse_gomp_openacc_dim (void)
1186 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1187 const char *var_name
= "GOMP_OPENACC_DIM";
1188 const char *env_var
= getenv (var_name
);
1192 const char *pos
= env_var
;
1194 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1196 if (i
&& *pos
++ != ':')
1204 long val
= strtol (pos
, (char **)&eptr
, 10);
1205 if (errno
|| val
< 0 || (unsigned)val
!= val
)
1208 goacc_default_dims
[i
] = (int)val
;
1214 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1217 bool display
= false;
1218 bool verbose
= false;
1221 env
= getenv ("OMP_DISPLAY_ENV");
1225 while (isspace ((unsigned char) *env
))
1227 if (strncasecmp (env
, "true", 4) == 0)
1232 else if (strncasecmp (env
, "false", 5) == 0)
1237 else if (strncasecmp (env
, "verbose", 7) == 0)
1245 while (isspace ((unsigned char) *env
))
1248 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1253 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1255 fputs (" _OPENMP = '201511'\n", stderr
);
1256 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1257 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1258 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1259 gomp_global_icv
.max_active_levels_var
> 1 ? "TRUE" : "FALSE");
1261 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1262 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1263 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1264 fputs ("'\n", stderr
);
1266 fprintf (stderr
, " OMP_SCHEDULE = '");
1267 if ((gomp_global_icv
.run_sched_var
& GFS_MONOTONIC
))
1269 if (gomp_global_icv
.run_sched_var
!= (GFS_MONOTONIC
| GFS_STATIC
))
1270 fputs ("MONOTONIC:", stderr
);
1272 else if (gomp_global_icv
.run_sched_var
== GFS_STATIC
)
1273 fputs ("NONMONOTONIC:", stderr
);
1274 switch (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
)
1277 fputs ("RUNTIME", stderr
);
1278 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1279 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1282 fputs ("STATIC", stderr
);
1283 if (gomp_global_icv
.run_sched_chunk_size
!= 0)
1284 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1287 fputs ("DYNAMIC", stderr
);
1288 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1289 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1292 fputs ("GUIDED", stderr
);
1293 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1294 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1297 fputs ("AUTO", stderr
);
1300 fputs ("'\n", stderr
);
1302 fputs (" OMP_PROC_BIND = '", stderr
);
1303 switch (gomp_global_icv
.bind_var
)
1305 case omp_proc_bind_false
:
1306 fputs ("FALSE", stderr
);
1308 case omp_proc_bind_true
:
1309 fputs ("TRUE", stderr
);
1311 case omp_proc_bind_master
:
1312 fputs ("MASTER", stderr
);
1314 case omp_proc_bind_close
:
1315 fputs ("CLOSE", stderr
);
1317 case omp_proc_bind_spread
:
1318 fputs ("SPREAD", stderr
);
1321 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1322 switch (gomp_bind_var_list
[i
])
1324 case omp_proc_bind_master
:
1325 fputs (",MASTER", stderr
);
1327 case omp_proc_bind_close
:
1328 fputs (",CLOSE", stderr
);
1330 case omp_proc_bind_spread
:
1331 fputs (",SPREAD", stderr
);
1334 fputs ("'\n", stderr
);
1335 fputs (" OMP_PLACES = '", stderr
);
1336 for (i
= 0; i
< gomp_places_list_len
; i
++)
1338 fputs ("{", stderr
);
1339 gomp_affinity_print_place (gomp_places_list
[i
]);
1340 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1342 fputs ("'\n", stderr
);
1344 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1346 /* GOMP's default value is actually neither active nor passive. */
1347 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1348 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1349 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1350 gomp_global_icv
.thread_limit_var
);
1351 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1352 gomp_global_icv
.max_active_levels_var
);
1354 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1355 gomp_cancel_var
? "TRUE" : "FALSE");
1356 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1357 gomp_global_icv
.default_device_var
);
1358 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1359 gomp_max_task_priority_var
);
1360 fprintf (stderr
, " OMP_DISPLAY_AFFINITY = '%s'\n",
1361 gomp_display_affinity_var
? "TRUE" : "FALSE");
1362 fprintf (stderr
, " OMP_AFFINITY_FORMAT = '%s'\n",
1363 gomp_affinity_format_var
);
1364 fprintf (stderr
, " OMP_ALLOCATOR = '");
1365 switch (gomp_def_allocator
)
1367 #define C(v) case v: fputs (#v, stderr); break;
1368 C (omp_default_mem_alloc
)
1369 C (omp_large_cap_mem_alloc
)
1370 C (omp_const_mem_alloc
)
1371 C (omp_high_bw_mem_alloc
)
1372 C (omp_low_lat_mem_alloc
)
1373 C (omp_cgroup_mem_alloc
)
1374 C (omp_pteam_mem_alloc
)
1375 C (omp_thread_mem_alloc
)
1379 fputs ("'\n", stderr
);
1381 fputs (" OMP_TARGET_OFFLOAD = '", stderr
);
1382 switch (gomp_target_offload_var
)
1384 case GOMP_TARGET_OFFLOAD_DEFAULT
:
1385 fputs ("DEFAULT", stderr
);
1387 case GOMP_TARGET_OFFLOAD_MANDATORY
:
1388 fputs ("MANDATORY", stderr
);
1390 case GOMP_TARGET_OFFLOAD_DISABLED
:
1391 fputs ("DISABLED", stderr
);
1394 fputs ("'\n", stderr
);
1398 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1399 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1400 #ifdef HAVE_INTTYPES_H
1401 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1402 (uint64_t) gomp_spin_count_var
);
1404 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1405 (unsigned long) gomp_spin_count_var
);
1409 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1413 static void __attribute__((constructor
))
1414 initialize_env (void)
1416 unsigned long thread_limit_var
, stacksize
= GOMP_DEFAULT_STACKSIZE
;
1417 unsigned long max_active_levels_var
;
1420 /* Do a compile time check that mkomp_h.pl did good job. */
1421 omp_check_defines ();
1424 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1425 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1426 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var
);
1427 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1428 parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var
);
1429 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1430 gomp_def_allocator
= parse_allocator ();
1431 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1433 gomp_global_icv
.thread_limit_var
1434 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1436 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var
, true);
1437 #ifndef HAVE_SYNC_BUILTINS
1438 gomp_mutex_init (&gomp_managed_threads_lock
);
1440 gomp_init_num_threads ();
1441 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1442 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1443 &gomp_global_icv
.nthreads_var
,
1444 &gomp_nthreads_var_list
,
1445 &gomp_nthreads_var_list_len
))
1446 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1447 bool ignore
= false;
1448 if (parse_bind_var ("OMP_PROC_BIND",
1449 &gomp_global_icv
.bind_var
,
1450 &gomp_bind_var_list
,
1451 &gomp_bind_var_list_len
)
1452 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1454 if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
1455 &max_active_levels_var
, true))
1456 gomp_global_icv
.max_active_levels_var
1457 = (max_active_levels_var
> gomp_supported_active_levels
)
1458 ? gomp_supported_active_levels
: max_active_levels_var
;
1463 /* OMP_NESTED is deprecated in OpenMP 5.0. */
1464 if (parse_boolean ("OMP_NESTED", &nested
))
1465 gomp_global_icv
.max_active_levels_var
1466 = nested
? gomp_supported_active_levels
: 1;
1467 else if (gomp_nthreads_var_list_len
> 1 || gomp_bind_var_list_len
> 1)
1468 gomp_global_icv
.max_active_levels_var
= gomp_supported_active_levels
;
1470 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1471 parsed if present in the environment. If OMP_PROC_BIND was set
1472 explicitly to false, don't populate places list though. If places
1473 list was successfully set from OMP_PLACES, only parse but don't process
1474 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1475 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1476 was successfully parsed into a places list, otherwise to
1477 OMP_PROC_BIND=false. */
1478 if (parse_places_var ("OMP_PLACES", ignore
))
1480 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1481 gomp_global_icv
.bind_var
= true;
1484 if (parse_affinity (ignore
))
1486 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1487 gomp_global_icv
.bind_var
= true;
1490 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1491 gomp_init_affinity ();
1494 const char *env
= getenv ("OMP_AFFINITY_FORMAT");
1496 gomp_set_affinity_format (env
, strlen (env
));
1499 wait_policy
= parse_wait_policy ();
1500 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1502 /* Using a rough estimation of 100000 spins per msec,
1503 use 5 min blocking for OMP_WAIT_POLICY=active,
1504 3 msec blocking when OMP_WAIT_POLICY is not specificed
1505 and 0 when OMP_WAIT_POLICY=passive.
1506 Depending on the CPU speed, this can be e.g. 5 times longer
1507 or 5 times shorter. */
1508 if (wait_policy
> 0)
1509 gomp_spin_count_var
= 30000000000LL;
1510 else if (wait_policy
< 0)
1511 gomp_spin_count_var
= 300000LL;
1513 /* gomp_throttled_spin_count_var is used when there are more libgomp
1514 managed threads than available CPUs. Use very short spinning. */
1515 if (wait_policy
> 0)
1516 gomp_throttled_spin_count_var
= 1000LL;
1517 else if (wait_policy
< 0)
1518 gomp_throttled_spin_count_var
= 100LL;
1519 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1520 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1522 /* Not strictly environment related, but ordering constructors is tricky. */
1523 pthread_attr_init (&gomp_thread_attr
);
1525 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1526 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
)
1527 || GOMP_DEFAULT_STACKSIZE
)
1531 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1533 #ifdef PTHREAD_STACK_MIN
1536 if (stacksize
< PTHREAD_STACK_MIN
)
1537 gomp_error ("Stack size less than minimum of %luk",
1538 PTHREAD_STACK_MIN
/ 1024ul
1539 + (PTHREAD_STACK_MIN
% 1024 != 0));
1541 gomp_error ("Stack size larger than system limit");
1546 gomp_error ("Stack size change failed: %s", strerror (err
));
1549 handle_omp_display_env (stacksize
, wait_policy
);
1553 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1554 goacc_device_num
= 0;
1556 parse_acc_device_type ();
1557 parse_gomp_openacc_dim ();
1559 goacc_runtime_initialize ();
1561 goacc_profiling_initialize ();
1563 #endif /* LIBGOMP_OFFLOADED_ONLY */