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
;
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);
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
|| (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;
550 while (isspace ((unsigned char) *env
))
556 while (isspace ((unsigned char) *env
))
562 while (isspace ((unsigned char) *env
))
565 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
570 unsigned long this_num
, this_len
= 1;
571 long this_stride
= 1;
572 bool this_negate
= (*env
== '!');
575 if (gomp_places_list
)
578 while (isspace ((unsigned char) *env
))
583 this_num
= strtoul (env
, &env
, 10);
586 while (isspace ((unsigned char) *env
))
591 while (isspace ((unsigned char) *env
))
594 this_len
= strtoul (env
, &env
, 10);
595 if (errno
|| this_len
== 0)
597 while (isspace ((unsigned char) *env
))
602 while (isspace ((unsigned char) *env
))
605 this_stride
= strtol (env
, &env
, 10);
608 while (isspace ((unsigned char) *env
))
612 if (this_negate
&& this_len
!= 1)
614 if (gomp_places_list
&& pass
== this_negate
)
618 if (!gomp_affinity_remove_cpu (p
, this_num
))
621 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
635 while (isspace ((unsigned char) *env
))
640 while (isspace ((unsigned char) *env
))
643 len
= strtoul (env
, &env
, 10);
644 if (errno
|| len
== 0 || len
>= 65536)
646 while (isspace ((unsigned char) *env
))
651 while (isspace ((unsigned char) *env
))
654 stride
= strtol (env
, &env
, 10);
657 while (isspace ((unsigned char) *env
))
661 if (*negatep
&& len
!= 1)
670 parse_places_var (const char *name
, bool ignore
)
672 char *env
= getenv (name
), *end
;
673 bool any_negate
= false;
675 unsigned long count
= 0;
679 while (isspace ((unsigned char) *env
))
684 if (strncasecmp (env
, "threads", 7) == 0)
689 else if (strncasecmp (env
, "cores", 5) == 0)
694 else if (strncasecmp (env
, "sockets", 7) == 0)
702 while (isspace ((unsigned char) *env
))
708 while (isspace ((unsigned char) *env
))
712 count
= strtoul (env
, &end
, 10);
716 while (isspace ((unsigned char) *env
))
721 while (isspace ((unsigned char) *env
))
730 return gomp_affinity_init_level (level
, count
, false);
740 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
763 gomp_places_list_len
= 0;
764 gomp_places_list
= gomp_affinity_alloc (count
, false);
765 if (gomp_places_list
== NULL
)
773 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
774 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
779 for (count
= 0; count
< gomp_places_list_len
; count
++)
780 if (gomp_affinity_same_place
781 (gomp_places_list
[count
],
782 gomp_places_list
[gomp_places_list_len
]))
784 if (count
== gomp_places_list_len
)
786 gomp_error ("Trying to remove a non-existing place from list "
790 p
= gomp_places_list
[count
];
791 memmove (&gomp_places_list
[count
],
792 &gomp_places_list
[count
+ 1],
793 (gomp_places_list_len
- count
- 1) * sizeof (void *));
794 --gomp_places_list_len
;
795 gomp_places_list
[gomp_places_list_len
] = p
;
798 ++gomp_places_list_len
;
801 for (count
= 0; count
< len
- 1; count
++)
802 if (!gomp_affinity_copy_place
803 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
804 gomp_places_list
[gomp_places_list_len
+ count
],
807 gomp_places_list_len
+= len
;
815 if (gomp_places_list_len
== 0)
817 gomp_error ("All places have been removed");
820 if (!gomp_affinity_finalize_place_list (false))
825 free (gomp_places_list
);
826 gomp_places_list
= NULL
;
827 gomp_places_list_len
= 0;
828 gomp_error ("Invalid value for environment variable %s", name
);
832 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
833 present and it was successfully parsed. */
836 parse_stacksize (const char *name
, unsigned long *pvalue
)
839 unsigned long value
, shift
= 10;
845 while (isspace ((unsigned char) *env
))
851 value
= strtoul (env
, &end
, 10);
855 while (isspace ((unsigned char) *end
))
859 switch (tolower ((unsigned char) *end
))
876 while (isspace ((unsigned char) *end
))
882 if (((value
<< shift
) >> shift
) != value
)
885 *pvalue
= value
<< shift
;
889 gomp_error ("Invalid value for environment variable %s", name
);
893 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
894 present and it was successfully parsed. */
897 parse_spincount (const char *name
, unsigned long long *pvalue
)
900 unsigned long long value
, mult
= 1;
906 while (isspace ((unsigned char) *env
))
911 if (strncasecmp (env
, "infinite", 8) == 0
912 || strncasecmp (env
, "infinity", 8) == 0)
920 value
= strtoull (env
, &end
, 10);
924 while (isspace ((unsigned char) *end
))
928 switch (tolower ((unsigned char) *end
))
934 mult
= 1000LL * 1000LL;
937 mult
= 1000LL * 1000LL * 1000LL;
940 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
947 while (isspace ((unsigned char) *end
))
953 if (value
> ~0ULL / mult
)
962 gomp_error ("Invalid value for environment variable %s", name
);
966 /* Parse a boolean value for environment variable NAME and store the
967 result in VALUE. Return true if one was present and it was
968 successfully parsed. */
971 parse_boolean (const char *name
, bool *value
)
979 while (isspace ((unsigned char) *env
))
981 if (strncasecmp (env
, "true", 4) == 0)
986 else if (strncasecmp (env
, "false", 5) == 0)
993 while (isspace ((unsigned char) *env
))
997 gomp_error ("Invalid value for environment variable %s", name
);
1003 /* Parse the OMP_WAIT_POLICY environment variable and return the value. */
1006 parse_wait_policy (void)
1011 env
= getenv ("OMP_WAIT_POLICY");
1015 while (isspace ((unsigned char) *env
))
1017 if (strncasecmp (env
, "active", 6) == 0)
1022 else if (strncasecmp (env
, "passive", 7) == 0)
1029 while (isspace ((unsigned char) *env
))
1033 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
1037 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1038 present and it was successfully parsed. */
1041 parse_affinity (bool ignore
)
1043 char *env
, *end
, *start
;
1045 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
1046 size_t count
= 0, needed
;
1048 env
= getenv ("GOMP_CPU_AFFINITY");
1053 for (pass
= 0; pass
< 2; pass
++)
1061 gomp_places_list_len
= 0;
1062 gomp_places_list
= gomp_affinity_alloc (count
, true);
1063 if (gomp_places_list
== NULL
)
1068 while (isspace ((unsigned char) *env
))
1072 cpu_beg
= strtoul (env
, &end
, 0);
1073 if (errno
|| cpu_beg
>= 65536)
1082 cpu_end
= strtoul (++env
, &end
, 0);
1083 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
1090 cpu_stride
= strtoul (++env
, &end
, 0);
1091 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
1098 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
1105 void *p
= gomp_places_list
[gomp_places_list_len
];
1106 gomp_affinity_init_place (p
);
1107 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
1108 ++gomp_places_list_len
;
1109 cpu_beg
+= cpu_stride
;
1113 while (isspace ((unsigned char) *env
))
1118 else if (*env
== '\0')
1124 if (gomp_places_list_len
== 0)
1126 free (gomp_places_list
);
1127 gomp_places_list
= NULL
;
1133 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1137 /* Parse the OMP_ALLOCATOR environment variable and return the value. */
1140 parse_allocator (void)
1143 uintptr_t ret
= omp_default_mem_alloc
;
1145 env
= getenv ("OMP_ALLOCATOR");
1149 while (isspace ((unsigned char) *env
))
1154 else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
1157 env += sizeof (#v) - 1; \
1159 C (omp_default_mem_alloc
)
1160 C (omp_large_cap_mem_alloc
)
1161 C (omp_const_mem_alloc
)
1162 C (omp_high_bw_mem_alloc
)
1163 C (omp_low_lat_mem_alloc
)
1164 C (omp_cgroup_mem_alloc
)
1165 C (omp_pteam_mem_alloc
)
1166 C (omp_thread_mem_alloc
)
1170 while (isspace ((unsigned char) *env
))
1174 gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
1175 return omp_default_mem_alloc
;
1179 parse_acc_device_type (void)
1181 const char *env
= getenv ("ACC_DEVICE_TYPE");
1183 if (env
&& *env
!= '\0')
1184 goacc_device_type
= strdup (env
);
1186 goacc_device_type
= NULL
;
1190 parse_gomp_openacc_dim (void)
1192 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1193 const char *var_name
= "GOMP_OPENACC_DIM";
1194 const char *env_var
= getenv (var_name
);
1198 const char *pos
= env_var
;
1200 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1202 if (i
&& *pos
++ != ':')
1210 long val
= strtol (pos
, (char **)&eptr
, 10);
1211 if (errno
|| val
< 0 || (unsigned)val
!= val
)
1214 goacc_default_dims
[i
] = (int)val
;
1220 omp_display_env (int verbose
)
1224 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1226 fputs (" _OPENMP = '201511'\n", stderr
);
1227 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1228 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1229 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1230 gomp_global_icv
.max_active_levels_var
> 1 ? "TRUE" : "FALSE");
1232 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1233 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1234 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1235 fputs ("'\n", stderr
);
1237 fprintf (stderr
, " OMP_SCHEDULE = '");
1238 if ((gomp_global_icv
.run_sched_var
& GFS_MONOTONIC
))
1240 if (gomp_global_icv
.run_sched_var
!= (GFS_MONOTONIC
| GFS_STATIC
))
1241 fputs ("MONOTONIC:", stderr
);
1243 else if (gomp_global_icv
.run_sched_var
== GFS_STATIC
)
1244 fputs ("NONMONOTONIC:", stderr
);
1245 switch (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
)
1248 fputs ("RUNTIME", stderr
);
1249 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1250 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1253 fputs ("STATIC", stderr
);
1254 if (gomp_global_icv
.run_sched_chunk_size
!= 0)
1255 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1258 fputs ("DYNAMIC", stderr
);
1259 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1260 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1263 fputs ("GUIDED", stderr
);
1264 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1265 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1268 fputs ("AUTO", stderr
);
1271 fputs ("'\n", stderr
);
1273 fputs (" OMP_PROC_BIND = '", stderr
);
1274 switch (gomp_global_icv
.bind_var
)
1276 case omp_proc_bind_false
:
1277 fputs ("FALSE", stderr
);
1279 case omp_proc_bind_true
:
1280 fputs ("TRUE", stderr
);
1282 case omp_proc_bind_master
:
1283 fputs ("MASTER", stderr
); /* TODO: Change to PRIMARY for OpenMP 5.1. */
1285 case omp_proc_bind_close
:
1286 fputs ("CLOSE", stderr
);
1288 case omp_proc_bind_spread
:
1289 fputs ("SPREAD", stderr
);
1292 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1293 switch (gomp_bind_var_list
[i
])
1295 case omp_proc_bind_master
:
1296 fputs (",MASTER", stderr
); /* TODO: Change to PRIMARY for OpenMP 5.1. */
1298 case omp_proc_bind_close
:
1299 fputs (",CLOSE", stderr
);
1301 case omp_proc_bind_spread
:
1302 fputs (",SPREAD", stderr
);
1305 fputs ("'\n", stderr
);
1306 fputs (" OMP_PLACES = '", stderr
);
1307 for (i
= 0; i
< gomp_places_list_len
; i
++)
1309 fputs ("{", stderr
);
1310 gomp_affinity_print_place (gomp_places_list
[i
]);
1311 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1313 fputs ("'\n", stderr
);
1315 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1317 /* GOMP's default value is actually neither active nor passive. */
1318 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1319 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1320 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1321 gomp_global_icv
.thread_limit_var
);
1322 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%u'\n",
1323 gomp_global_icv
.max_active_levels_var
);
1324 fprintf (stderr
, " OMP_NUM_TEAMS = '%u'\n", gomp_nteams_var
);
1325 fprintf (stderr
, " OMP_TEAMS_THREAD_LIMIT = '%u'\n",
1326 gomp_teams_thread_limit_var
);
1328 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1329 gomp_cancel_var
? "TRUE" : "FALSE");
1330 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1331 gomp_global_icv
.default_device_var
);
1332 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1333 gomp_max_task_priority_var
);
1334 fprintf (stderr
, " OMP_DISPLAY_AFFINITY = '%s'\n",
1335 gomp_display_affinity_var
? "TRUE" : "FALSE");
1336 fprintf (stderr
, " OMP_AFFINITY_FORMAT = '%s'\n",
1337 gomp_affinity_format_var
);
1338 fprintf (stderr
, " OMP_ALLOCATOR = '");
1339 switch (gomp_def_allocator
)
1341 #define C(v) case v: fputs (#v, stderr); break;
1342 C (omp_default_mem_alloc
)
1343 C (omp_large_cap_mem_alloc
)
1344 C (omp_const_mem_alloc
)
1345 C (omp_high_bw_mem_alloc
)
1346 C (omp_low_lat_mem_alloc
)
1347 C (omp_cgroup_mem_alloc
)
1348 C (omp_pteam_mem_alloc
)
1349 C (omp_thread_mem_alloc
)
1353 fputs ("'\n", stderr
);
1355 fputs (" OMP_TARGET_OFFLOAD = '", stderr
);
1356 switch (gomp_target_offload_var
)
1358 case GOMP_TARGET_OFFLOAD_DEFAULT
:
1359 fputs ("DEFAULT", stderr
);
1361 case GOMP_TARGET_OFFLOAD_MANDATORY
:
1362 fputs ("MANDATORY", stderr
);
1364 case GOMP_TARGET_OFFLOAD_DISABLED
:
1365 fputs ("DISABLED", stderr
);
1368 fputs ("'\n", stderr
);
1372 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1373 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1374 #ifdef HAVE_INTTYPES_H
1375 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1376 (uint64_t) gomp_spin_count_var
);
1378 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1379 (unsigned long) gomp_spin_count_var
);
1383 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1385 ialias (omp_display_env
)
1388 handle_omp_display_env (void)
1391 bool display
= false;
1392 bool verbose
= false;
1394 env
= getenv ("OMP_DISPLAY_ENV");
1398 while (isspace ((unsigned char) *env
))
1400 if (strncasecmp (env
, "true", 4) == 0)
1405 else if (strncasecmp (env
, "false", 5) == 0)
1410 else if (strncasecmp (env
, "verbose", 7) == 0)
1418 while (isspace ((unsigned char) *env
))
1421 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1424 ialias_call (omp_display_env
) (verbose
);
1428 static void __attribute__((constructor
))
1429 initialize_env (void)
1431 unsigned long thread_limit_var
;
1432 unsigned long max_active_levels_var
;
1434 /* Do a compile time check that mkomp_h.pl did good job. */
1435 omp_check_defines ();
1438 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1439 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1440 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var
);
1441 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1442 parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var
);
1443 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1444 gomp_def_allocator
= parse_allocator ();
1445 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1447 gomp_global_icv
.thread_limit_var
1448 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1450 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var
, true);
1451 #ifndef HAVE_SYNC_BUILTINS
1452 gomp_mutex_init (&gomp_managed_threads_lock
);
1454 gomp_init_num_threads ();
1455 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1456 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1457 &gomp_global_icv
.nthreads_var
,
1458 &gomp_nthreads_var_list
,
1459 &gomp_nthreads_var_list_len
))
1460 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1461 parse_int ("OMP_NUM_TEAMS", &gomp_nteams_var
, false);
1462 parse_int ("OMP_TEAMS_THREAD_LIMIT", &gomp_teams_thread_limit_var
, false);
1463 bool ignore
= false;
1464 if (parse_bind_var ("OMP_PROC_BIND",
1465 &gomp_global_icv
.bind_var
,
1466 &gomp_bind_var_list
,
1467 &gomp_bind_var_list_len
)
1468 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1470 if (parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS",
1471 &max_active_levels_var
, true))
1472 gomp_global_icv
.max_active_levels_var
1473 = (max_active_levels_var
> gomp_supported_active_levels
)
1474 ? gomp_supported_active_levels
: max_active_levels_var
;
1479 /* OMP_NESTED is deprecated in OpenMP 5.0. */
1480 if (parse_boolean ("OMP_NESTED", &nested
))
1481 gomp_global_icv
.max_active_levels_var
1482 = nested
? gomp_supported_active_levels
: 1;
1483 else if (gomp_nthreads_var_list_len
> 1 || gomp_bind_var_list_len
> 1)
1484 gomp_global_icv
.max_active_levels_var
= gomp_supported_active_levels
;
1486 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1487 parsed if present in the environment. If OMP_PROC_BIND was set
1488 explicitly to false, don't populate places list though. If places
1489 list was successfully set from OMP_PLACES, only parse but don't process
1490 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1491 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1492 was successfully parsed into a places list, otherwise to
1493 OMP_PROC_BIND=false. */
1494 if (parse_places_var ("OMP_PLACES", ignore
))
1496 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1497 gomp_global_icv
.bind_var
= true;
1500 if (parse_affinity (ignore
))
1502 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1503 gomp_global_icv
.bind_var
= true;
1506 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1507 gomp_init_affinity ();
1510 const char *env
= getenv ("OMP_AFFINITY_FORMAT");
1512 gomp_set_affinity_format (env
, strlen (env
));
1515 wait_policy
= parse_wait_policy ();
1516 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1518 /* Using a rough estimation of 100000 spins per msec,
1519 use 5 min blocking for OMP_WAIT_POLICY=active,
1520 3 msec blocking when OMP_WAIT_POLICY is not specificed
1521 and 0 when OMP_WAIT_POLICY=passive.
1522 Depending on the CPU speed, this can be e.g. 5 times longer
1523 or 5 times shorter. */
1524 if (wait_policy
> 0)
1525 gomp_spin_count_var
= 30000000000LL;
1526 else if (wait_policy
< 0)
1527 gomp_spin_count_var
= 300000LL;
1529 /* gomp_throttled_spin_count_var is used when there are more libgomp
1530 managed threads than available CPUs. Use very short spinning. */
1531 if (wait_policy
> 0)
1532 gomp_throttled_spin_count_var
= 1000LL;
1533 else if (wait_policy
< 0)
1534 gomp_throttled_spin_count_var
= 100LL;
1535 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1536 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1538 /* Not strictly environment related, but ordering constructors is tricky. */
1539 pthread_attr_init (&gomp_thread_attr
);
1541 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1542 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
)
1543 || GOMP_DEFAULT_STACKSIZE
)
1547 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1549 #ifdef PTHREAD_STACK_MIN
1552 if (stacksize
< PTHREAD_STACK_MIN
)
1553 gomp_error ("Stack size less than minimum of %luk",
1554 PTHREAD_STACK_MIN
/ 1024ul
1555 + (PTHREAD_STACK_MIN
% 1024 != 0));
1557 gomp_error ("Stack size larger than system limit");
1562 gomp_error ("Stack size change failed: %s", strerror (err
));
1565 handle_omp_display_env ();
1569 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1570 goacc_device_num
= 0;
1572 parse_acc_device_type ();
1573 parse_gomp_openacc_dim ();
1575 goacc_runtime_initialize ();
1577 goacc_profiling_initialize ();
1579 #endif /* LIBGOMP_OFFLOADED_ONLY */