1 /* Copyright (C) 2005-2020 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,
72 .bind_var
= omp_proc_bind_false
,
76 unsigned long gomp_max_active_levels_var
= INT_MAX
;
77 bool gomp_cancel_var
= false;
78 int gomp_max_task_priority_var
= 0;
79 #ifndef HAVE_SYNC_BUILTINS
80 gomp_mutex_t gomp_managed_threads_lock
;
82 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
83 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
84 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
85 char *gomp_bind_var_list
;
86 unsigned long gomp_bind_var_list_len
;
87 void **gomp_places_list
;
88 unsigned long gomp_places_list_len
;
89 uintptr_t gomp_def_allocator
= omp_default_mem_alloc
;
91 unsigned int gomp_num_teams_var
;
92 bool gomp_display_affinity_var
;
93 char *gomp_affinity_format_var
= "level %L thread %i affinity %A";
94 size_t gomp_affinity_format_len
;
95 char *goacc_device_type
;
97 int goacc_default_dims
[GOMP_DIM_MAX
];
99 #ifndef LIBGOMP_OFFLOADED_ONLY
101 /* Parse the OMP_SCHEDULE environment variable. */
104 parse_schedule (void)
110 env
= getenv ("OMP_SCHEDULE");
114 while (isspace ((unsigned char) *env
))
116 if (strncasecmp (env
, "monotonic", 9) == 0)
121 else if (strncasecmp (env
, "nonmonotonic", 12) == 0)
128 while (isspace ((unsigned char) *env
))
133 while (isspace ((unsigned char) *env
))
136 if (strncasecmp (env
, "static", 6) == 0)
138 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
141 else if (strncasecmp (env
, "dynamic", 7) == 0)
143 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
146 else if (strncasecmp (env
, "guided", 6) == 0)
148 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
151 else if (strncasecmp (env
, "auto", 4) == 0)
153 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
160 || (monotonic
== 0 && gomp_global_icv
.run_sched_var
== GFS_STATIC
))
161 gomp_global_icv
.run_sched_var
|= GFS_MONOTONIC
;
163 while (isspace ((unsigned char) *env
))
167 gomp_global_icv
.run_sched_chunk_size
168 = (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
;
173 while (isspace ((unsigned char) *env
))
179 value
= strtoul (env
, &end
, 10);
183 while (isspace ((unsigned char) *end
))
188 if ((int)value
!= value
)
192 && (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
)
194 gomp_global_icv
.run_sched_chunk_size
= value
;
198 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
202 gomp_error ("Invalid value for chunk size in "
203 "environment variable OMP_SCHEDULE");
207 /* Parse an unsigned long environment variable. Return true if one was
208 present and it was successfully parsed. If SECURE, use secure_getenv to the
209 environment variable. */
212 parse_unsigned_long_1 (const char *name
, unsigned long *pvalue
, bool allow_zero
,
218 env
= (secure
? secure_getenv (name
) : getenv (name
));
222 while (isspace ((unsigned char) *env
))
228 value
= strtoul (env
, &end
, 10);
229 if (errno
|| (long) value
<= 0 - allow_zero
)
232 while (isspace ((unsigned char) *end
))
241 gomp_error ("Invalid value for environment variable %s", name
);
245 /* As parse_unsigned_long_1, but always use getenv. */
248 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
250 return parse_unsigned_long_1 (name
, pvalue
, allow_zero
, false);
253 /* Parse a positive int environment variable. Return true if one was
254 present and it was successfully parsed. If SECURE, use secure_getenv to the
255 environment variable. */
258 parse_int_1 (const char *name
, int *pvalue
, bool allow_zero
, bool secure
)
261 if (!parse_unsigned_long_1 (name
, &value
, allow_zero
, secure
))
265 gomp_error ("Invalid value for environment variable %s", name
);
268 *pvalue
= (int) value
;
272 /* As parse_int_1, but use getenv. */
275 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
277 return parse_int_1 (name
, pvalue
, allow_zero
, false);
280 /* As parse_int_1, but use getenv_secure. */
283 parse_int_secure (const char *name
, int *pvalue
, bool allow_zero
)
285 return parse_int_1 (name
, pvalue
, allow_zero
, true);
288 /* Parse an unsigned long list environment variable. Return true if one was
289 present and it was successfully parsed. */
292 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
293 unsigned long **pvalues
,
294 unsigned long *pnvalues
)
297 unsigned long value
, *values
= NULL
;
303 while (isspace ((unsigned char) *env
))
309 value
= strtoul (env
, &end
, 10);
310 if (errno
|| (long) value
<= 0)
313 while (isspace ((unsigned char) *end
))
319 unsigned long nvalues
= 0, nalloced
= 0;
324 if (nvalues
== nalloced
)
327 nalloced
= nalloced
? nalloced
* 2 : 16;
328 n
= realloc (values
, nalloced
* sizeof (unsigned long));
332 gomp_error ("Out of memory while trying to parse"
333 " environment variable %s", name
);
338 values
[nvalues
++] = value
;
341 while (isspace ((unsigned char) *env
))
347 value
= strtoul (env
, &end
, 10);
348 if (errno
|| (long) value
<= 0)
351 values
[nvalues
++] = value
;
352 while (isspace ((unsigned char) *end
))
360 *p1stvalue
= values
[0];
373 gomp_error ("Invalid value for environment variable %s", name
);
377 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
378 enum values. Return true if one was present and it was successfully
382 parse_bind_var (const char *name
, char *p1stvalue
,
383 char **pvalues
, unsigned long *pnvalues
)
386 char value
= omp_proc_bind_false
, *values
= NULL
;
388 static struct proc_bind_kinds
392 omp_proc_bind_t kind
;
395 { "false", 5, omp_proc_bind_false
},
396 { "true", 4, omp_proc_bind_true
},
397 { "master", 6, omp_proc_bind_master
},
398 { "close", 5, omp_proc_bind_close
},
399 { "spread", 6, omp_proc_bind_spread
}
406 while (isspace ((unsigned char) *env
))
411 for (i
= 0; i
< 5; i
++)
412 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
414 value
= kinds
[i
].kind
;
421 while (isspace ((unsigned char) *env
))
427 unsigned long nvalues
= 0, nalloced
= 0;
429 if (value
== omp_proc_bind_false
430 || value
== omp_proc_bind_true
)
436 if (nvalues
== nalloced
)
439 nalloced
= nalloced
? nalloced
* 2 : 16;
440 n
= realloc (values
, nalloced
);
444 gomp_error ("Out of memory while trying to parse"
445 " environment variable %s", name
);
450 values
[nvalues
++] = value
;
453 while (isspace ((unsigned char) *env
))
458 for (i
= 2; i
< 5; i
++)
459 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
461 value
= kinds
[i
].kind
;
468 values
[nvalues
++] = value
;
469 while (isspace ((unsigned char) *env
))
477 *p1stvalue
= values
[0];
490 gomp_error ("Invalid value for environment variable %s", name
);
495 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
498 char *env
= *envp
, *start
;
499 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
500 unsigned long len
= 1;
503 bool any_negate
= false;
505 while (isspace ((unsigned char) *env
))
511 while (isspace ((unsigned char) *env
))
517 while (isspace ((unsigned char) *env
))
520 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
525 unsigned long this_num
, this_len
= 1;
526 long this_stride
= 1;
527 bool this_negate
= (*env
== '!');
530 if (gomp_places_list
)
533 while (isspace ((unsigned char) *env
))
538 this_num
= strtoul (env
, &env
, 10);
541 while (isspace ((unsigned char) *env
))
546 while (isspace ((unsigned char) *env
))
549 this_len
= strtoul (env
, &env
, 10);
550 if (errno
|| this_len
== 0)
552 while (isspace ((unsigned char) *env
))
557 while (isspace ((unsigned char) *env
))
560 this_stride
= strtol (env
, &env
, 10);
563 while (isspace ((unsigned char) *env
))
567 if (this_negate
&& this_len
!= 1)
569 if (gomp_places_list
&& pass
== this_negate
)
573 if (!gomp_affinity_remove_cpu (p
, this_num
))
576 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
590 while (isspace ((unsigned char) *env
))
595 while (isspace ((unsigned char) *env
))
598 len
= strtoul (env
, &env
, 10);
599 if (errno
|| len
== 0 || len
>= 65536)
601 while (isspace ((unsigned char) *env
))
606 while (isspace ((unsigned char) *env
))
609 stride
= strtol (env
, &env
, 10);
612 while (isspace ((unsigned char) *env
))
616 if (*negatep
&& len
!= 1)
625 parse_places_var (const char *name
, bool ignore
)
627 char *env
= getenv (name
), *end
;
628 bool any_negate
= false;
630 unsigned long count
= 0;
634 while (isspace ((unsigned char) *env
))
639 if (strncasecmp (env
, "threads", 7) == 0)
644 else if (strncasecmp (env
, "cores", 5) == 0)
649 else if (strncasecmp (env
, "sockets", 7) == 0)
657 while (isspace ((unsigned char) *env
))
663 while (isspace ((unsigned char) *env
))
667 count
= strtoul (env
, &end
, 10);
671 while (isspace ((unsigned char) *env
))
676 while (isspace ((unsigned char) *env
))
685 return gomp_affinity_init_level (level
, count
, false);
695 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
718 gomp_places_list_len
= 0;
719 gomp_places_list
= gomp_affinity_alloc (count
, false);
720 if (gomp_places_list
== NULL
)
728 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
729 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
734 for (count
= 0; count
< gomp_places_list_len
; count
++)
735 if (gomp_affinity_same_place
736 (gomp_places_list
[count
],
737 gomp_places_list
[gomp_places_list_len
]))
739 if (count
== gomp_places_list_len
)
741 gomp_error ("Trying to remove a non-existing place from list "
745 p
= gomp_places_list
[count
];
746 memmove (&gomp_places_list
[count
],
747 &gomp_places_list
[count
+ 1],
748 (gomp_places_list_len
- count
- 1) * sizeof (void *));
749 --gomp_places_list_len
;
750 gomp_places_list
[gomp_places_list_len
] = p
;
753 ++gomp_places_list_len
;
756 for (count
= 0; count
< len
- 1; count
++)
757 if (!gomp_affinity_copy_place
758 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
759 gomp_places_list
[gomp_places_list_len
+ count
],
762 gomp_places_list_len
+= len
;
770 if (gomp_places_list_len
== 0)
772 gomp_error ("All places have been removed");
775 if (!gomp_affinity_finalize_place_list (false))
780 free (gomp_places_list
);
781 gomp_places_list
= NULL
;
782 gomp_places_list_len
= 0;
783 gomp_error ("Invalid value for environment variable %s", name
);
787 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
788 present and it was successfully parsed. */
791 parse_stacksize (const char *name
, unsigned long *pvalue
)
794 unsigned long value
, shift
= 10;
800 while (isspace ((unsigned char) *env
))
806 value
= strtoul (env
, &end
, 10);
810 while (isspace ((unsigned char) *end
))
814 switch (tolower ((unsigned char) *end
))
831 while (isspace ((unsigned char) *end
))
837 if (((value
<< shift
) >> shift
) != value
)
840 *pvalue
= value
<< shift
;
844 gomp_error ("Invalid value for environment variable %s", name
);
848 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
849 present and it was successfully parsed. */
852 parse_spincount (const char *name
, unsigned long long *pvalue
)
855 unsigned long long value
, mult
= 1;
861 while (isspace ((unsigned char) *env
))
866 if (strncasecmp (env
, "infinite", 8) == 0
867 || strncasecmp (env
, "infinity", 8) == 0)
875 value
= strtoull (env
, &end
, 10);
879 while (isspace ((unsigned char) *end
))
883 switch (tolower ((unsigned char) *end
))
889 mult
= 1000LL * 1000LL;
892 mult
= 1000LL * 1000LL * 1000LL;
895 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
902 while (isspace ((unsigned char) *end
))
908 if (value
> ~0ULL / mult
)
917 gomp_error ("Invalid value for environment variable %s", name
);
921 /* Parse a boolean value for environment variable NAME and store the
925 parse_boolean (const char *name
, bool *value
)
933 while (isspace ((unsigned char) *env
))
935 if (strncasecmp (env
, "true", 4) == 0)
940 else if (strncasecmp (env
, "false", 5) == 0)
947 while (isspace ((unsigned char) *env
))
950 gomp_error ("Invalid value for environment variable %s", name
);
953 /* Parse the OMP_WAIT_POLICY environment variable and return the value. */
956 parse_wait_policy (void)
961 env
= getenv ("OMP_WAIT_POLICY");
965 while (isspace ((unsigned char) *env
))
967 if (strncasecmp (env
, "active", 6) == 0)
972 else if (strncasecmp (env
, "passive", 7) == 0)
979 while (isspace ((unsigned char) *env
))
983 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
987 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
988 present and it was successfully parsed. */
991 parse_affinity (bool ignore
)
993 char *env
, *end
, *start
;
995 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
996 size_t count
= 0, needed
;
998 env
= getenv ("GOMP_CPU_AFFINITY");
1003 for (pass
= 0; pass
< 2; pass
++)
1011 gomp_places_list_len
= 0;
1012 gomp_places_list
= gomp_affinity_alloc (count
, true);
1013 if (gomp_places_list
== NULL
)
1018 while (isspace ((unsigned char) *env
))
1022 cpu_beg
= strtoul (env
, &end
, 0);
1023 if (errno
|| cpu_beg
>= 65536)
1032 cpu_end
= strtoul (++env
, &end
, 0);
1033 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
1040 cpu_stride
= strtoul (++env
, &end
, 0);
1041 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
1048 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
1055 void *p
= gomp_places_list
[gomp_places_list_len
];
1056 gomp_affinity_init_place (p
);
1057 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
1058 ++gomp_places_list_len
;
1059 cpu_beg
+= cpu_stride
;
1063 while (isspace ((unsigned char) *env
))
1068 else if (*env
== '\0')
1074 if (gomp_places_list_len
== 0)
1076 free (gomp_places_list
);
1077 gomp_places_list
= NULL
;
1083 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1087 /* Parse the OMP_ALLOCATOR environment variable and return the value. */
1090 parse_allocator (void)
1093 uintptr_t ret
= omp_default_mem_alloc
;
1095 env
= getenv ("OMP_ALLOCATOR");
1099 while (isspace ((unsigned char) *env
))
1104 else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
1107 env += sizeof (#v) - 1; \
1109 C (omp_default_mem_alloc
)
1110 C (omp_large_cap_mem_alloc
)
1111 C (omp_const_mem_alloc
)
1112 C (omp_high_bw_mem_alloc
)
1113 C (omp_low_lat_mem_alloc
)
1114 C (omp_cgroup_mem_alloc
)
1115 C (omp_pteam_mem_alloc
)
1116 C (omp_thread_mem_alloc
)
1120 while (isspace ((unsigned char) *env
))
1124 gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
1125 return omp_default_mem_alloc
;
1129 parse_acc_device_type (void)
1131 const char *env
= getenv ("ACC_DEVICE_TYPE");
1133 if (env
&& *env
!= '\0')
1134 goacc_device_type
= strdup (env
);
1136 goacc_device_type
= NULL
;
1140 parse_gomp_openacc_dim (void)
1142 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1143 const char *var_name
= "GOMP_OPENACC_DIM";
1144 const char *env_var
= getenv (var_name
);
1148 const char *pos
= env_var
;
1150 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1152 if (i
&& *pos
++ != ':')
1160 long val
= strtol (pos
, (char **)&eptr
, 10);
1161 if (errno
|| val
< 0 || (unsigned)val
!= val
)
1164 goacc_default_dims
[i
] = (int)val
;
1170 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1173 bool display
= false;
1174 bool verbose
= false;
1177 env
= getenv ("OMP_DISPLAY_ENV");
1181 while (isspace ((unsigned char) *env
))
1183 if (strncasecmp (env
, "true", 4) == 0)
1188 else if (strncasecmp (env
, "false", 5) == 0)
1193 else if (strncasecmp (env
, "verbose", 7) == 0)
1201 while (isspace ((unsigned char) *env
))
1204 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1209 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1211 fputs (" _OPENMP = '201511'\n", stderr
);
1212 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1213 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1214 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1215 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1217 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1218 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1219 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1220 fputs ("'\n", stderr
);
1222 fprintf (stderr
, " OMP_SCHEDULE = '");
1223 if ((gomp_global_icv
.run_sched_var
& GFS_MONOTONIC
))
1225 if (gomp_global_icv
.run_sched_var
!= (GFS_MONOTONIC
| GFS_STATIC
))
1226 fputs ("MONOTONIC:", stderr
);
1228 else if (gomp_global_icv
.run_sched_var
== GFS_STATIC
)
1229 fputs ("NONMONOTONIC:", stderr
);
1230 switch (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
)
1233 fputs ("RUNTIME", stderr
);
1234 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1235 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1238 fputs ("STATIC", stderr
);
1239 if (gomp_global_icv
.run_sched_chunk_size
!= 0)
1240 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1243 fputs ("DYNAMIC", stderr
);
1244 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1245 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1248 fputs ("GUIDED", stderr
);
1249 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1250 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1253 fputs ("AUTO", stderr
);
1256 fputs ("'\n", stderr
);
1258 fputs (" OMP_PROC_BIND = '", stderr
);
1259 switch (gomp_global_icv
.bind_var
)
1261 case omp_proc_bind_false
:
1262 fputs ("FALSE", stderr
);
1264 case omp_proc_bind_true
:
1265 fputs ("TRUE", stderr
);
1267 case omp_proc_bind_master
:
1268 fputs ("MASTER", stderr
);
1270 case omp_proc_bind_close
:
1271 fputs ("CLOSE", stderr
);
1273 case omp_proc_bind_spread
:
1274 fputs ("SPREAD", stderr
);
1277 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1278 switch (gomp_bind_var_list
[i
])
1280 case omp_proc_bind_master
:
1281 fputs (",MASTER", stderr
);
1283 case omp_proc_bind_close
:
1284 fputs (",CLOSE", stderr
);
1286 case omp_proc_bind_spread
:
1287 fputs (",SPREAD", stderr
);
1290 fputs ("'\n", stderr
);
1291 fputs (" OMP_PLACES = '", stderr
);
1292 for (i
= 0; i
< gomp_places_list_len
; i
++)
1294 fputs ("{", stderr
);
1295 gomp_affinity_print_place (gomp_places_list
[i
]);
1296 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1298 fputs ("'\n", stderr
);
1300 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1302 /* GOMP's default value is actually neither active nor passive. */
1303 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1304 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1305 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1306 gomp_global_icv
.thread_limit_var
);
1307 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1308 gomp_max_active_levels_var
);
1310 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1311 gomp_cancel_var
? "TRUE" : "FALSE");
1312 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1313 gomp_global_icv
.default_device_var
);
1314 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1315 gomp_max_task_priority_var
);
1316 fprintf (stderr
, " OMP_DISPLAY_AFFINITY = '%s'\n",
1317 gomp_display_affinity_var
? "TRUE" : "FALSE");
1318 fprintf (stderr
, " OMP_AFFINITY_FORMAT = '%s'\n",
1319 gomp_affinity_format_var
);
1320 fprintf (stderr
, " OMP_ALLOCATOR = '");
1321 switch (gomp_def_allocator
)
1323 #define C(v) case v: fputs (#v, stderr); break;
1324 C (omp_default_mem_alloc
)
1325 C (omp_large_cap_mem_alloc
)
1326 C (omp_const_mem_alloc
)
1327 C (omp_high_bw_mem_alloc
)
1328 C (omp_low_lat_mem_alloc
)
1329 C (omp_cgroup_mem_alloc
)
1330 C (omp_pteam_mem_alloc
)
1331 C (omp_thread_mem_alloc
)
1335 fputs ("'\n", stderr
);
1339 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1340 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1341 #ifdef HAVE_INTTYPES_H
1342 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1343 (uint64_t) gomp_spin_count_var
);
1345 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1346 (unsigned long) gomp_spin_count_var
);
1350 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1354 static void __attribute__((constructor
))
1355 initialize_env (void)
1357 unsigned long thread_limit_var
, stacksize
= GOMP_DEFAULT_STACKSIZE
;
1360 /* Do a compile time check that mkomp_h.pl did good job. */
1361 omp_check_defines ();
1364 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1365 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1366 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1367 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var
);
1368 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1369 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1370 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1372 gomp_def_allocator
= parse_allocator ();
1373 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1375 gomp_global_icv
.thread_limit_var
1376 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1378 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var
, true);
1379 #ifndef HAVE_SYNC_BUILTINS
1380 gomp_mutex_init (&gomp_managed_threads_lock
);
1382 gomp_init_num_threads ();
1383 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1384 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1385 &gomp_global_icv
.nthreads_var
,
1386 &gomp_nthreads_var_list
,
1387 &gomp_nthreads_var_list_len
))
1388 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1389 bool ignore
= false;
1390 if (parse_bind_var ("OMP_PROC_BIND",
1391 &gomp_global_icv
.bind_var
,
1392 &gomp_bind_var_list
,
1393 &gomp_bind_var_list_len
)
1394 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1396 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1397 parsed if present in the environment. If OMP_PROC_BIND was set
1398 explicitly to false, don't populate places list though. If places
1399 list was successfully set from OMP_PLACES, only parse but don't process
1400 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1401 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1402 was successfully parsed into a places list, otherwise to
1403 OMP_PROC_BIND=false. */
1404 if (parse_places_var ("OMP_PLACES", ignore
))
1406 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1407 gomp_global_icv
.bind_var
= true;
1410 if (parse_affinity (ignore
))
1412 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1413 gomp_global_icv
.bind_var
= true;
1416 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1417 gomp_init_affinity ();
1420 const char *env
= getenv ("OMP_AFFINITY_FORMAT");
1422 gomp_set_affinity_format (env
, strlen (env
));
1425 wait_policy
= parse_wait_policy ();
1426 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1428 /* Using a rough estimation of 100000 spins per msec,
1429 use 5 min blocking for OMP_WAIT_POLICY=active,
1430 3 msec blocking when OMP_WAIT_POLICY is not specificed
1431 and 0 when OMP_WAIT_POLICY=passive.
1432 Depending on the CPU speed, this can be e.g. 5 times longer
1433 or 5 times shorter. */
1434 if (wait_policy
> 0)
1435 gomp_spin_count_var
= 30000000000LL;
1436 else if (wait_policy
< 0)
1437 gomp_spin_count_var
= 300000LL;
1439 /* gomp_throttled_spin_count_var is used when there are more libgomp
1440 managed threads than available CPUs. Use very short spinning. */
1441 if (wait_policy
> 0)
1442 gomp_throttled_spin_count_var
= 1000LL;
1443 else if (wait_policy
< 0)
1444 gomp_throttled_spin_count_var
= 100LL;
1445 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1446 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1448 /* Not strictly environment related, but ordering constructors is tricky. */
1449 pthread_attr_init (&gomp_thread_attr
);
1451 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1452 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
)
1453 || GOMP_DEFAULT_STACKSIZE
)
1457 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1459 #ifdef PTHREAD_STACK_MIN
1462 if (stacksize
< PTHREAD_STACK_MIN
)
1463 gomp_error ("Stack size less than minimum of %luk",
1464 PTHREAD_STACK_MIN
/ 1024ul
1465 + (PTHREAD_STACK_MIN
% 1024 != 0));
1467 gomp_error ("Stack size larger than system limit");
1472 gomp_error ("Stack size change failed: %s", strerror (err
));
1475 handle_omp_display_env (stacksize
, wait_policy
);
1479 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1480 goacc_device_num
= 0;
1482 parse_acc_device_type ();
1483 parse_gomp_openacc_dim ();
1485 goacc_runtime_initialize ();
1487 goacc_profiling_initialize ();
1489 #endif /* LIBGOMP_OFFLOADED_ONLY */