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
= gomp_supported_active_levels
;
77 bool gomp_cancel_var
= false;
78 enum gomp_target_offload_t gomp_target_offload_var
79 = GOMP_TARGET_OFFLOAD_DEFAULT
;
80 int gomp_max_task_priority_var
= 0;
81 #ifndef HAVE_SYNC_BUILTINS
82 gomp_mutex_t gomp_managed_threads_lock
;
84 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
85 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
86 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
87 char *gomp_bind_var_list
;
88 unsigned long gomp_bind_var_list_len
;
89 void **gomp_places_list
;
90 unsigned long gomp_places_list_len
;
91 uintptr_t gomp_def_allocator
= omp_default_mem_alloc
;
93 unsigned int gomp_num_teams_var
;
94 bool gomp_display_affinity_var
;
95 char *gomp_affinity_format_var
= "level %L thread %i affinity %A";
96 size_t gomp_affinity_format_len
;
97 char *goacc_device_type
;
99 int goacc_default_dims
[GOMP_DIM_MAX
];
101 #ifndef LIBGOMP_OFFLOADED_ONLY
103 /* Parse the OMP_SCHEDULE environment variable. */
106 parse_schedule (void)
112 env
= getenv ("OMP_SCHEDULE");
116 while (isspace ((unsigned char) *env
))
118 if (strncasecmp (env
, "monotonic", 9) == 0)
123 else if (strncasecmp (env
, "nonmonotonic", 12) == 0)
130 while (isspace ((unsigned char) *env
))
135 while (isspace ((unsigned char) *env
))
138 if (strncasecmp (env
, "static", 6) == 0)
140 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
143 else if (strncasecmp (env
, "dynamic", 7) == 0)
145 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
148 else if (strncasecmp (env
, "guided", 6) == 0)
150 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
153 else if (strncasecmp (env
, "auto", 4) == 0)
155 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
162 || (monotonic
== 0 && gomp_global_icv
.run_sched_var
== GFS_STATIC
))
163 gomp_global_icv
.run_sched_var
|= GFS_MONOTONIC
;
165 while (isspace ((unsigned char) *env
))
169 gomp_global_icv
.run_sched_chunk_size
170 = (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
;
175 while (isspace ((unsigned char) *env
))
181 value
= strtoul (env
, &end
, 10);
185 while (isspace ((unsigned char) *end
))
190 if ((int)value
!= value
)
194 && (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
)
196 gomp_global_icv
.run_sched_chunk_size
= value
;
200 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
204 gomp_error ("Invalid value for chunk size in "
205 "environment variable OMP_SCHEDULE");
209 /* Parse an unsigned long environment variable. Return true if one was
210 present and it was successfully parsed. If SECURE, use secure_getenv to the
211 environment variable. */
214 parse_unsigned_long_1 (const char *name
, unsigned long *pvalue
, bool allow_zero
,
220 env
= (secure
? secure_getenv (name
) : getenv (name
));
224 while (isspace ((unsigned char) *env
))
230 value
= strtoul (env
, &end
, 10);
231 if (errno
|| (long) value
<= 0 - allow_zero
)
234 while (isspace ((unsigned char) *end
))
243 gomp_error ("Invalid value for environment variable %s", name
);
247 /* As parse_unsigned_long_1, but always use getenv. */
250 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
252 return parse_unsigned_long_1 (name
, pvalue
, allow_zero
, false);
255 /* Parse a positive int environment variable. Return true if one was
256 present and it was successfully parsed. If SECURE, use secure_getenv to the
257 environment variable. */
260 parse_int_1 (const char *name
, int *pvalue
, bool allow_zero
, bool secure
)
263 if (!parse_unsigned_long_1 (name
, &value
, allow_zero
, secure
))
267 gomp_error ("Invalid value for environment variable %s", name
);
270 *pvalue
= (int) value
;
274 /* As parse_int_1, but use getenv. */
277 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
279 return parse_int_1 (name
, pvalue
, allow_zero
, false);
282 /* As parse_int_1, but use getenv_secure. */
285 parse_int_secure (const char *name
, int *pvalue
, bool allow_zero
)
287 return parse_int_1 (name
, pvalue
, allow_zero
, true);
290 /* Parse an unsigned long list environment variable. Return true if one was
291 present and it was successfully parsed. */
294 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
295 unsigned long **pvalues
,
296 unsigned long *pnvalues
)
299 unsigned long value
, *values
= NULL
;
305 while (isspace ((unsigned char) *env
))
311 value
= strtoul (env
, &end
, 10);
312 if (errno
|| (long) value
<= 0)
315 while (isspace ((unsigned char) *end
))
321 unsigned long nvalues
= 0, nalloced
= 0;
326 if (nvalues
== nalloced
)
329 nalloced
= nalloced
? nalloced
* 2 : 16;
330 n
= realloc (values
, nalloced
* sizeof (unsigned long));
334 gomp_error ("Out of memory while trying to parse"
335 " environment variable %s", name
);
340 values
[nvalues
++] = value
;
343 while (isspace ((unsigned char) *env
))
349 value
= strtoul (env
, &end
, 10);
350 if (errno
|| (long) value
<= 0)
353 values
[nvalues
++] = value
;
354 while (isspace ((unsigned char) *end
))
362 *p1stvalue
= values
[0];
375 gomp_error ("Invalid value for environment variable %s", name
);
380 parse_target_offload (const char *name
, enum gomp_target_offload_t
*offload
)
383 int new_offload
= -1;
389 while (isspace ((unsigned char) *env
))
391 if (strncasecmp (env
, "default", 7) == 0)
394 new_offload
= GOMP_TARGET_OFFLOAD_DEFAULT
;
396 else if (strncasecmp (env
, "mandatory", 9) == 0)
399 new_offload
= GOMP_TARGET_OFFLOAD_MANDATORY
;
401 else if (strncasecmp (env
, "disabled", 8) == 0)
404 new_offload
= GOMP_TARGET_OFFLOAD_DISABLED
;
406 while (isspace ((unsigned char) *env
))
408 if (new_offload
!= -1 && *env
== '\0')
410 *offload
= new_offload
;
414 gomp_error ("Invalid value for environment variable OMP_TARGET_OFFLOAD");
417 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
418 enum values. Return true if one was present and it was successfully
422 parse_bind_var (const char *name
, char *p1stvalue
,
423 char **pvalues
, unsigned long *pnvalues
)
426 char value
= omp_proc_bind_false
, *values
= NULL
;
428 static struct proc_bind_kinds
432 omp_proc_bind_t kind
;
435 { "false", 5, omp_proc_bind_false
},
436 { "true", 4, omp_proc_bind_true
},
437 { "master", 6, omp_proc_bind_master
},
438 { "close", 5, omp_proc_bind_close
},
439 { "spread", 6, omp_proc_bind_spread
}
446 while (isspace ((unsigned char) *env
))
451 for (i
= 0; i
< 5; i
++)
452 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
454 value
= kinds
[i
].kind
;
461 while (isspace ((unsigned char) *env
))
467 unsigned long nvalues
= 0, nalloced
= 0;
469 if (value
== omp_proc_bind_false
470 || value
== omp_proc_bind_true
)
476 if (nvalues
== nalloced
)
479 nalloced
= nalloced
? nalloced
* 2 : 16;
480 n
= realloc (values
, nalloced
);
484 gomp_error ("Out of memory while trying to parse"
485 " environment variable %s", name
);
490 values
[nvalues
++] = value
;
493 while (isspace ((unsigned char) *env
))
498 for (i
= 2; i
< 5; i
++)
499 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
501 value
= kinds
[i
].kind
;
508 values
[nvalues
++] = value
;
509 while (isspace ((unsigned char) *env
))
517 *p1stvalue
= values
[0];
530 gomp_error ("Invalid value for environment variable %s", name
);
535 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
538 char *env
= *envp
, *start
;
539 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
540 unsigned long len
= 1;
543 bool any_negate
= false;
545 while (isspace ((unsigned char) *env
))
551 while (isspace ((unsigned char) *env
))
557 while (isspace ((unsigned char) *env
))
560 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
565 unsigned long this_num
, this_len
= 1;
566 long this_stride
= 1;
567 bool this_negate
= (*env
== '!');
570 if (gomp_places_list
)
573 while (isspace ((unsigned char) *env
))
578 this_num
= strtoul (env
, &env
, 10);
581 while (isspace ((unsigned char) *env
))
586 while (isspace ((unsigned char) *env
))
589 this_len
= strtoul (env
, &env
, 10);
590 if (errno
|| this_len
== 0)
592 while (isspace ((unsigned char) *env
))
597 while (isspace ((unsigned char) *env
))
600 this_stride
= strtol (env
, &env
, 10);
603 while (isspace ((unsigned char) *env
))
607 if (this_negate
&& this_len
!= 1)
609 if (gomp_places_list
&& pass
== this_negate
)
613 if (!gomp_affinity_remove_cpu (p
, this_num
))
616 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
630 while (isspace ((unsigned char) *env
))
635 while (isspace ((unsigned char) *env
))
638 len
= strtoul (env
, &env
, 10);
639 if (errno
|| len
== 0 || len
>= 65536)
641 while (isspace ((unsigned char) *env
))
646 while (isspace ((unsigned char) *env
))
649 stride
= strtol (env
, &env
, 10);
652 while (isspace ((unsigned char) *env
))
656 if (*negatep
&& len
!= 1)
665 parse_places_var (const char *name
, bool ignore
)
667 char *env
= getenv (name
), *end
;
668 bool any_negate
= false;
670 unsigned long count
= 0;
674 while (isspace ((unsigned char) *env
))
679 if (strncasecmp (env
, "threads", 7) == 0)
684 else if (strncasecmp (env
, "cores", 5) == 0)
689 else if (strncasecmp (env
, "sockets", 7) == 0)
697 while (isspace ((unsigned char) *env
))
703 while (isspace ((unsigned char) *env
))
707 count
= strtoul (env
, &end
, 10);
711 while (isspace ((unsigned char) *env
))
716 while (isspace ((unsigned char) *env
))
725 return gomp_affinity_init_level (level
, count
, false);
735 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
758 gomp_places_list_len
= 0;
759 gomp_places_list
= gomp_affinity_alloc (count
, false);
760 if (gomp_places_list
== NULL
)
768 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
769 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
774 for (count
= 0; count
< gomp_places_list_len
; count
++)
775 if (gomp_affinity_same_place
776 (gomp_places_list
[count
],
777 gomp_places_list
[gomp_places_list_len
]))
779 if (count
== gomp_places_list_len
)
781 gomp_error ("Trying to remove a non-existing place from list "
785 p
= gomp_places_list
[count
];
786 memmove (&gomp_places_list
[count
],
787 &gomp_places_list
[count
+ 1],
788 (gomp_places_list_len
- count
- 1) * sizeof (void *));
789 --gomp_places_list_len
;
790 gomp_places_list
[gomp_places_list_len
] = p
;
793 ++gomp_places_list_len
;
796 for (count
= 0; count
< len
- 1; count
++)
797 if (!gomp_affinity_copy_place
798 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
799 gomp_places_list
[gomp_places_list_len
+ count
],
802 gomp_places_list_len
+= len
;
810 if (gomp_places_list_len
== 0)
812 gomp_error ("All places have been removed");
815 if (!gomp_affinity_finalize_place_list (false))
820 free (gomp_places_list
);
821 gomp_places_list
= NULL
;
822 gomp_places_list_len
= 0;
823 gomp_error ("Invalid value for environment variable %s", name
);
827 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
828 present and it was successfully parsed. */
831 parse_stacksize (const char *name
, unsigned long *pvalue
)
834 unsigned long value
, shift
= 10;
840 while (isspace ((unsigned char) *env
))
846 value
= strtoul (env
, &end
, 10);
850 while (isspace ((unsigned char) *end
))
854 switch (tolower ((unsigned char) *end
))
871 while (isspace ((unsigned char) *end
))
877 if (((value
<< shift
) >> shift
) != value
)
880 *pvalue
= value
<< shift
;
884 gomp_error ("Invalid value for environment variable %s", name
);
888 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
889 present and it was successfully parsed. */
892 parse_spincount (const char *name
, unsigned long long *pvalue
)
895 unsigned long long value
, mult
= 1;
901 while (isspace ((unsigned char) *env
))
906 if (strncasecmp (env
, "infinite", 8) == 0
907 || strncasecmp (env
, "infinity", 8) == 0)
915 value
= strtoull (env
, &end
, 10);
919 while (isspace ((unsigned char) *end
))
923 switch (tolower ((unsigned char) *end
))
929 mult
= 1000LL * 1000LL;
932 mult
= 1000LL * 1000LL * 1000LL;
935 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
942 while (isspace ((unsigned char) *end
))
948 if (value
> ~0ULL / mult
)
957 gomp_error ("Invalid value for environment variable %s", name
);
961 /* Parse a boolean value for environment variable NAME and store the
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
))
990 gomp_error ("Invalid value for environment variable %s", name
);
993 /* Parse the OMP_WAIT_POLICY environment variable and return the value. */
996 parse_wait_policy (void)
1001 env
= getenv ("OMP_WAIT_POLICY");
1005 while (isspace ((unsigned char) *env
))
1007 if (strncasecmp (env
, "active", 6) == 0)
1012 else if (strncasecmp (env
, "passive", 7) == 0)
1019 while (isspace ((unsigned char) *env
))
1023 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
1027 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
1028 present and it was successfully parsed. */
1031 parse_affinity (bool ignore
)
1033 char *env
, *end
, *start
;
1035 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
1036 size_t count
= 0, needed
;
1038 env
= getenv ("GOMP_CPU_AFFINITY");
1043 for (pass
= 0; pass
< 2; pass
++)
1051 gomp_places_list_len
= 0;
1052 gomp_places_list
= gomp_affinity_alloc (count
, true);
1053 if (gomp_places_list
== NULL
)
1058 while (isspace ((unsigned char) *env
))
1062 cpu_beg
= strtoul (env
, &end
, 0);
1063 if (errno
|| cpu_beg
>= 65536)
1072 cpu_end
= strtoul (++env
, &end
, 0);
1073 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
1080 cpu_stride
= strtoul (++env
, &end
, 0);
1081 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
1088 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
1095 void *p
= gomp_places_list
[gomp_places_list_len
];
1096 gomp_affinity_init_place (p
);
1097 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
1098 ++gomp_places_list_len
;
1099 cpu_beg
+= cpu_stride
;
1103 while (isspace ((unsigned char) *env
))
1108 else if (*env
== '\0')
1114 if (gomp_places_list_len
== 0)
1116 free (gomp_places_list
);
1117 gomp_places_list
= NULL
;
1123 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1127 /* Parse the OMP_ALLOCATOR environment variable and return the value. */
1130 parse_allocator (void)
1133 uintptr_t ret
= omp_default_mem_alloc
;
1135 env
= getenv ("OMP_ALLOCATOR");
1139 while (isspace ((unsigned char) *env
))
1144 else if (strncasecmp (env, #v, sizeof (#v) - 1) == 0) \
1147 env += sizeof (#v) - 1; \
1149 C (omp_default_mem_alloc
)
1150 C (omp_large_cap_mem_alloc
)
1151 C (omp_const_mem_alloc
)
1152 C (omp_high_bw_mem_alloc
)
1153 C (omp_low_lat_mem_alloc
)
1154 C (omp_cgroup_mem_alloc
)
1155 C (omp_pteam_mem_alloc
)
1156 C (omp_thread_mem_alloc
)
1160 while (isspace ((unsigned char) *env
))
1164 gomp_error ("Invalid value for environment variable OMP_ALLOCATOR");
1165 return omp_default_mem_alloc
;
1169 parse_acc_device_type (void)
1171 const char *env
= getenv ("ACC_DEVICE_TYPE");
1173 if (env
&& *env
!= '\0')
1174 goacc_device_type
= strdup (env
);
1176 goacc_device_type
= NULL
;
1180 parse_gomp_openacc_dim (void)
1182 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1183 const char *var_name
= "GOMP_OPENACC_DIM";
1184 const char *env_var
= getenv (var_name
);
1188 const char *pos
= env_var
;
1190 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1192 if (i
&& *pos
++ != ':')
1200 long val
= strtol (pos
, (char **)&eptr
, 10);
1201 if (errno
|| val
< 0 || (unsigned)val
!= val
)
1204 goacc_default_dims
[i
] = (int)val
;
1210 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1213 bool display
= false;
1214 bool verbose
= false;
1217 env
= getenv ("OMP_DISPLAY_ENV");
1221 while (isspace ((unsigned char) *env
))
1223 if (strncasecmp (env
, "true", 4) == 0)
1228 else if (strncasecmp (env
, "false", 5) == 0)
1233 else if (strncasecmp (env
, "verbose", 7) == 0)
1241 while (isspace ((unsigned char) *env
))
1244 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1249 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1251 fputs (" _OPENMP = '201511'\n", stderr
);
1252 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1253 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1254 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1255 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1257 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1258 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1259 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1260 fputs ("'\n", stderr
);
1262 fprintf (stderr
, " OMP_SCHEDULE = '");
1263 if ((gomp_global_icv
.run_sched_var
& GFS_MONOTONIC
))
1265 if (gomp_global_icv
.run_sched_var
!= (GFS_MONOTONIC
| GFS_STATIC
))
1266 fputs ("MONOTONIC:", stderr
);
1268 else if (gomp_global_icv
.run_sched_var
== GFS_STATIC
)
1269 fputs ("NONMONOTONIC:", stderr
);
1270 switch (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
)
1273 fputs ("RUNTIME", stderr
);
1274 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1275 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1278 fputs ("STATIC", stderr
);
1279 if (gomp_global_icv
.run_sched_chunk_size
!= 0)
1280 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1283 fputs ("DYNAMIC", stderr
);
1284 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1285 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1288 fputs ("GUIDED", stderr
);
1289 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1290 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1293 fputs ("AUTO", stderr
);
1296 fputs ("'\n", stderr
);
1298 fputs (" OMP_PROC_BIND = '", stderr
);
1299 switch (gomp_global_icv
.bind_var
)
1301 case omp_proc_bind_false
:
1302 fputs ("FALSE", stderr
);
1304 case omp_proc_bind_true
:
1305 fputs ("TRUE", stderr
);
1307 case omp_proc_bind_master
:
1308 fputs ("MASTER", stderr
);
1310 case omp_proc_bind_close
:
1311 fputs ("CLOSE", stderr
);
1313 case omp_proc_bind_spread
:
1314 fputs ("SPREAD", stderr
);
1317 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1318 switch (gomp_bind_var_list
[i
])
1320 case omp_proc_bind_master
:
1321 fputs (",MASTER", stderr
);
1323 case omp_proc_bind_close
:
1324 fputs (",CLOSE", stderr
);
1326 case omp_proc_bind_spread
:
1327 fputs (",SPREAD", stderr
);
1330 fputs ("'\n", stderr
);
1331 fputs (" OMP_PLACES = '", stderr
);
1332 for (i
= 0; i
< gomp_places_list_len
; i
++)
1334 fputs ("{", stderr
);
1335 gomp_affinity_print_place (gomp_places_list
[i
]);
1336 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1338 fputs ("'\n", stderr
);
1340 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1342 /* GOMP's default value is actually neither active nor passive. */
1343 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1344 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1345 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1346 gomp_global_icv
.thread_limit_var
);
1347 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1348 gomp_max_active_levels_var
);
1350 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1351 gomp_cancel_var
? "TRUE" : "FALSE");
1352 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1353 gomp_global_icv
.default_device_var
);
1354 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1355 gomp_max_task_priority_var
);
1356 fprintf (stderr
, " OMP_DISPLAY_AFFINITY = '%s'\n",
1357 gomp_display_affinity_var
? "TRUE" : "FALSE");
1358 fprintf (stderr
, " OMP_AFFINITY_FORMAT = '%s'\n",
1359 gomp_affinity_format_var
);
1360 fprintf (stderr
, " OMP_ALLOCATOR = '");
1361 switch (gomp_def_allocator
)
1363 #define C(v) case v: fputs (#v, stderr); break;
1364 C (omp_default_mem_alloc
)
1365 C (omp_large_cap_mem_alloc
)
1366 C (omp_const_mem_alloc
)
1367 C (omp_high_bw_mem_alloc
)
1368 C (omp_low_lat_mem_alloc
)
1369 C (omp_cgroup_mem_alloc
)
1370 C (omp_pteam_mem_alloc
)
1371 C (omp_thread_mem_alloc
)
1375 fputs ("'\n", stderr
);
1377 fputs (" OMP_TARGET_OFFLOAD = '", stderr
);
1378 switch (gomp_target_offload_var
)
1380 case GOMP_TARGET_OFFLOAD_DEFAULT
:
1381 fputs ("DEFAULT", stderr
);
1383 case GOMP_TARGET_OFFLOAD_MANDATORY
:
1384 fputs ("MANDATORY", stderr
);
1386 case GOMP_TARGET_OFFLOAD_DISABLED
:
1387 fputs ("DISABLED", stderr
);
1390 fputs ("'\n", stderr
);
1394 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1395 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1396 #ifdef HAVE_INTTYPES_H
1397 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1398 (uint64_t) gomp_spin_count_var
);
1400 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1401 (unsigned long) gomp_spin_count_var
);
1405 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1409 static void __attribute__((constructor
))
1410 initialize_env (void)
1412 unsigned long thread_limit_var
, stacksize
= GOMP_DEFAULT_STACKSIZE
;
1415 /* Do a compile time check that mkomp_h.pl did good job. */
1416 omp_check_defines ();
1419 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1420 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1421 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1422 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var
);
1423 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1424 parse_target_offload ("OMP_TARGET_OFFLOAD", &gomp_target_offload_var
);
1425 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1426 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1428 if (gomp_max_active_levels_var
> gomp_supported_active_levels
)
1429 gomp_max_active_levels_var
= gomp_supported_active_levels
;
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 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1455 parsed if present in the environment. If OMP_PROC_BIND was set
1456 explicitly to false, don't populate places list though. If places
1457 list was successfully set from OMP_PLACES, only parse but don't process
1458 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1459 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1460 was successfully parsed into a places list, otherwise to
1461 OMP_PROC_BIND=false. */
1462 if (parse_places_var ("OMP_PLACES", ignore
))
1464 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1465 gomp_global_icv
.bind_var
= true;
1468 if (parse_affinity (ignore
))
1470 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1471 gomp_global_icv
.bind_var
= true;
1474 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1475 gomp_init_affinity ();
1478 const char *env
= getenv ("OMP_AFFINITY_FORMAT");
1480 gomp_set_affinity_format (env
, strlen (env
));
1483 wait_policy
= parse_wait_policy ();
1484 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1486 /* Using a rough estimation of 100000 spins per msec,
1487 use 5 min blocking for OMP_WAIT_POLICY=active,
1488 3 msec blocking when OMP_WAIT_POLICY is not specificed
1489 and 0 when OMP_WAIT_POLICY=passive.
1490 Depending on the CPU speed, this can be e.g. 5 times longer
1491 or 5 times shorter. */
1492 if (wait_policy
> 0)
1493 gomp_spin_count_var
= 30000000000LL;
1494 else if (wait_policy
< 0)
1495 gomp_spin_count_var
= 300000LL;
1497 /* gomp_throttled_spin_count_var is used when there are more libgomp
1498 managed threads than available CPUs. Use very short spinning. */
1499 if (wait_policy
> 0)
1500 gomp_throttled_spin_count_var
= 1000LL;
1501 else if (wait_policy
< 0)
1502 gomp_throttled_spin_count_var
= 100LL;
1503 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1504 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1506 /* Not strictly environment related, but ordering constructors is tricky. */
1507 pthread_attr_init (&gomp_thread_attr
);
1509 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1510 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
)
1511 || GOMP_DEFAULT_STACKSIZE
)
1515 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1517 #ifdef PTHREAD_STACK_MIN
1520 if (stacksize
< PTHREAD_STACK_MIN
)
1521 gomp_error ("Stack size less than minimum of %luk",
1522 PTHREAD_STACK_MIN
/ 1024ul
1523 + (PTHREAD_STACK_MIN
% 1024 != 0));
1525 gomp_error ("Stack size larger than system limit");
1530 gomp_error ("Stack size change failed: %s", strerror (err
));
1533 handle_omp_display_env (stacksize
, wait_policy
);
1537 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1538 goacc_device_num
= 0;
1540 parse_acc_device_type ();
1541 parse_gomp_openacc_dim ();
1543 goacc_runtime_initialize ();
1545 goacc_profiling_initialize ();
1547 #endif /* LIBGOMP_OFFLOADED_ONLY */