1 /* Copyright (C) 2005-2018 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
;
90 unsigned int gomp_num_teams_var
;
91 char *goacc_device_type
;
93 int goacc_default_dims
[GOMP_DIM_MAX
];
95 #ifndef LIBGOMP_OFFLOADED_ONLY
97 /* Parse the OMP_SCHEDULE environment variable. */
100 parse_schedule (void)
105 env
= getenv ("OMP_SCHEDULE");
109 while (isspace ((unsigned char) *env
))
111 if (strncasecmp (env
, "static", 6) == 0)
113 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
116 else if (strncasecmp (env
, "dynamic", 7) == 0)
118 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
121 else if (strncasecmp (env
, "guided", 6) == 0)
123 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
126 else if (strncasecmp (env
, "auto", 4) == 0)
128 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
134 while (isspace ((unsigned char) *env
))
138 gomp_global_icv
.run_sched_chunk_size
139 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
144 while (isspace ((unsigned char) *env
))
150 value
= strtoul (env
, &end
, 10);
154 while (isspace ((unsigned char) *end
))
159 if ((int)value
!= value
)
162 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
164 gomp_global_icv
.run_sched_chunk_size
= value
;
168 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
172 gomp_error ("Invalid value for chunk size in "
173 "environment variable OMP_SCHEDULE");
177 /* Parse an unsigned long environment variable. Return true if one was
178 present and it was successfully parsed. If SECURE, use secure_getenv to the
179 environment variable. */
182 parse_unsigned_long_1 (const char *name
, unsigned long *pvalue
, bool allow_zero
,
188 env
= (secure
? secure_getenv (name
) : getenv (name
));
192 while (isspace ((unsigned char) *env
))
198 value
= strtoul (env
, &end
, 10);
199 if (errno
|| (long) value
<= 0 - allow_zero
)
202 while (isspace ((unsigned char) *end
))
211 gomp_error ("Invalid value for environment variable %s", name
);
215 /* As parse_unsigned_long_1, but always use getenv. */
218 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
220 return parse_unsigned_long_1 (name
, pvalue
, allow_zero
, false);
223 /* Parse a positive int environment variable. Return true if one was
224 present and it was successfully parsed. If SECURE, use secure_getenv to the
225 environment variable. */
228 parse_int_1 (const char *name
, int *pvalue
, bool allow_zero
, bool secure
)
231 if (!parse_unsigned_long_1 (name
, &value
, allow_zero
, secure
))
235 gomp_error ("Invalid value for environment variable %s", name
);
238 *pvalue
= (int) value
;
242 /* As parse_int_1, but use getenv. */
245 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
247 return parse_int_1 (name
, pvalue
, allow_zero
, false);
250 /* As parse_int_1, but use getenv_secure. */
253 parse_int_secure (const char *name
, int *pvalue
, bool allow_zero
)
255 return parse_int_1 (name
, pvalue
, allow_zero
, true);
258 /* Parse an unsigned long list environment variable. Return true if one was
259 present and it was successfully parsed. */
262 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
263 unsigned long **pvalues
,
264 unsigned long *pnvalues
)
267 unsigned long value
, *values
= NULL
;
273 while (isspace ((unsigned char) *env
))
279 value
= strtoul (env
, &end
, 10);
280 if (errno
|| (long) value
<= 0)
283 while (isspace ((unsigned char) *end
))
289 unsigned long nvalues
= 0, nalloced
= 0;
294 if (nvalues
== nalloced
)
297 nalloced
= nalloced
? nalloced
* 2 : 16;
298 n
= realloc (values
, nalloced
* sizeof (unsigned long));
302 gomp_error ("Out of memory while trying to parse"
303 " environment variable %s", name
);
308 values
[nvalues
++] = value
;
311 while (isspace ((unsigned char) *env
))
317 value
= strtoul (env
, &end
, 10);
318 if (errno
|| (long) value
<= 0)
321 values
[nvalues
++] = value
;
322 while (isspace ((unsigned char) *end
))
330 *p1stvalue
= values
[0];
343 gomp_error ("Invalid value for environment variable %s", name
);
347 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
348 enum values. Return true if one was present and it was successfully
352 parse_bind_var (const char *name
, char *p1stvalue
,
353 char **pvalues
, unsigned long *pnvalues
)
356 char value
= omp_proc_bind_false
, *values
= NULL
;
358 static struct proc_bind_kinds
362 omp_proc_bind_t kind
;
365 { "false", 5, omp_proc_bind_false
},
366 { "true", 4, omp_proc_bind_true
},
367 { "master", 6, omp_proc_bind_master
},
368 { "close", 5, omp_proc_bind_close
},
369 { "spread", 6, omp_proc_bind_spread
}
376 while (isspace ((unsigned char) *env
))
381 for (i
= 0; i
< 5; i
++)
382 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
384 value
= kinds
[i
].kind
;
391 while (isspace ((unsigned char) *env
))
397 unsigned long nvalues
= 0, nalloced
= 0;
399 if (value
== omp_proc_bind_false
400 || value
== omp_proc_bind_true
)
406 if (nvalues
== nalloced
)
409 nalloced
= nalloced
? nalloced
* 2 : 16;
410 n
= realloc (values
, nalloced
);
414 gomp_error ("Out of memory while trying to parse"
415 " environment variable %s", name
);
420 values
[nvalues
++] = value
;
423 while (isspace ((unsigned char) *env
))
428 for (i
= 2; i
< 5; i
++)
429 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
431 value
= kinds
[i
].kind
;
438 values
[nvalues
++] = value
;
439 while (isspace ((unsigned char) *env
))
447 *p1stvalue
= values
[0];
460 gomp_error ("Invalid value for environment variable %s", name
);
465 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
468 char *env
= *envp
, *start
;
469 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
470 unsigned long len
= 1;
473 bool any_negate
= false;
475 while (isspace ((unsigned char) *env
))
481 while (isspace ((unsigned char) *env
))
487 while (isspace ((unsigned char) *env
))
490 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
495 unsigned long this_num
, this_len
= 1;
496 long this_stride
= 1;
497 bool this_negate
= (*env
== '!');
500 if (gomp_places_list
)
503 while (isspace ((unsigned char) *env
))
508 this_num
= strtoul (env
, &env
, 10);
511 while (isspace ((unsigned char) *env
))
516 while (isspace ((unsigned char) *env
))
519 this_len
= strtoul (env
, &env
, 10);
520 if (errno
|| this_len
== 0)
522 while (isspace ((unsigned char) *env
))
527 while (isspace ((unsigned char) *env
))
530 this_stride
= strtol (env
, &env
, 10);
533 while (isspace ((unsigned char) *env
))
537 if (this_negate
&& this_len
!= 1)
539 if (gomp_places_list
&& pass
== this_negate
)
543 if (!gomp_affinity_remove_cpu (p
, this_num
))
546 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
560 while (isspace ((unsigned char) *env
))
565 while (isspace ((unsigned char) *env
))
568 len
= strtoul (env
, &env
, 10);
569 if (errno
|| len
== 0 || len
>= 65536)
571 while (isspace ((unsigned char) *env
))
576 while (isspace ((unsigned char) *env
))
579 stride
= strtol (env
, &env
, 10);
582 while (isspace ((unsigned char) *env
))
586 if (*negatep
&& len
!= 1)
595 parse_places_var (const char *name
, bool ignore
)
597 char *env
= getenv (name
), *end
;
598 bool any_negate
= false;
600 unsigned long count
= 0;
604 while (isspace ((unsigned char) *env
))
609 if (strncasecmp (env
, "threads", 7) == 0)
614 else if (strncasecmp (env
, "cores", 5) == 0)
619 else if (strncasecmp (env
, "sockets", 7) == 0)
627 while (isspace ((unsigned char) *env
))
633 while (isspace ((unsigned char) *env
))
637 count
= strtoul (env
, &end
, 10);
641 while (isspace ((unsigned char) *env
))
646 while (isspace ((unsigned char) *env
))
655 return gomp_affinity_init_level (level
, count
, false);
665 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
688 gomp_places_list_len
= 0;
689 gomp_places_list
= gomp_affinity_alloc (count
, false);
690 if (gomp_places_list
== NULL
)
698 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
699 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
704 for (count
= 0; count
< gomp_places_list_len
; count
++)
705 if (gomp_affinity_same_place
706 (gomp_places_list
[count
],
707 gomp_places_list
[gomp_places_list_len
]))
709 if (count
== gomp_places_list_len
)
711 gomp_error ("Trying to remove a non-existing place from list "
715 p
= gomp_places_list
[count
];
716 memmove (&gomp_places_list
[count
],
717 &gomp_places_list
[count
+ 1],
718 (gomp_places_list_len
- count
- 1) * sizeof (void *));
719 --gomp_places_list_len
;
720 gomp_places_list
[gomp_places_list_len
] = p
;
723 ++gomp_places_list_len
;
726 for (count
= 0; count
< len
- 1; count
++)
727 if (!gomp_affinity_copy_place
728 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
729 gomp_places_list
[gomp_places_list_len
+ count
],
732 gomp_places_list_len
+= len
;
740 if (gomp_places_list_len
== 0)
742 gomp_error ("All places have been removed");
745 if (!gomp_affinity_finalize_place_list (false))
750 free (gomp_places_list
);
751 gomp_places_list
= NULL
;
752 gomp_places_list_len
= 0;
753 gomp_error ("Invalid value for environment variable %s", name
);
757 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
758 present and it was successfully parsed. */
761 parse_stacksize (const char *name
, unsigned long *pvalue
)
764 unsigned long value
, shift
= 10;
770 while (isspace ((unsigned char) *env
))
776 value
= strtoul (env
, &end
, 10);
780 while (isspace ((unsigned char) *end
))
784 switch (tolower ((unsigned char) *end
))
801 while (isspace ((unsigned char) *end
))
807 if (((value
<< shift
) >> shift
) != value
)
810 *pvalue
= value
<< shift
;
814 gomp_error ("Invalid value for environment variable %s", name
);
818 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
819 present and it was successfully parsed. */
822 parse_spincount (const char *name
, unsigned long long *pvalue
)
825 unsigned long long value
, mult
= 1;
831 while (isspace ((unsigned char) *env
))
836 if (strncasecmp (env
, "infinite", 8) == 0
837 || strncasecmp (env
, "infinity", 8) == 0)
845 value
= strtoull (env
, &end
, 10);
849 while (isspace ((unsigned char) *end
))
853 switch (tolower ((unsigned char) *end
))
859 mult
= 1000LL * 1000LL;
862 mult
= 1000LL * 1000LL * 1000LL;
865 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
872 while (isspace ((unsigned char) *end
))
878 if (value
> ~0ULL / mult
)
887 gomp_error ("Invalid value for environment variable %s", name
);
891 /* Parse a boolean value for environment variable NAME and store the
895 parse_boolean (const char *name
, bool *value
)
903 while (isspace ((unsigned char) *env
))
905 if (strncasecmp (env
, "true", 4) == 0)
910 else if (strncasecmp (env
, "false", 5) == 0)
917 while (isspace ((unsigned char) *env
))
920 gomp_error ("Invalid value for environment variable %s", name
);
923 /* Parse the OMP_WAIT_POLICY environment variable and store the
924 result in gomp_active_wait_policy. */
927 parse_wait_policy (void)
932 env
= getenv ("OMP_WAIT_POLICY");
936 while (isspace ((unsigned char) *env
))
938 if (strncasecmp (env
, "active", 6) == 0)
943 else if (strncasecmp (env
, "passive", 7) == 0)
950 while (isspace ((unsigned char) *env
))
954 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
958 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
959 present and it was successfully parsed. */
962 parse_affinity (bool ignore
)
964 char *env
, *end
, *start
;
966 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
967 size_t count
= 0, needed
;
969 env
= getenv ("GOMP_CPU_AFFINITY");
974 for (pass
= 0; pass
< 2; pass
++)
982 gomp_places_list_len
= 0;
983 gomp_places_list
= gomp_affinity_alloc (count
, true);
984 if (gomp_places_list
== NULL
)
989 while (isspace ((unsigned char) *env
))
993 cpu_beg
= strtoul (env
, &end
, 0);
994 if (errno
|| cpu_beg
>= 65536)
1003 cpu_end
= strtoul (++env
, &end
, 0);
1004 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
1011 cpu_stride
= strtoul (++env
, &end
, 0);
1012 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
1019 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
1026 void *p
= gomp_places_list
[gomp_places_list_len
];
1027 gomp_affinity_init_place (p
);
1028 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
1029 ++gomp_places_list_len
;
1030 cpu_beg
+= cpu_stride
;
1034 while (isspace ((unsigned char) *env
))
1039 else if (*env
== '\0')
1045 if (gomp_places_list_len
== 0)
1047 free (gomp_places_list
);
1048 gomp_places_list
= NULL
;
1054 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1059 parse_acc_device_type (void)
1061 const char *env
= getenv ("ACC_DEVICE_TYPE");
1063 if (env
&& *env
!= '\0')
1064 goacc_device_type
= strdup (env
);
1066 goacc_device_type
= NULL
;
1070 parse_gomp_openacc_dim (void)
1072 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1073 const char *var_name
= "GOMP_OPENACC_DIM";
1074 const char *env_var
= getenv (var_name
);
1078 const char *pos
= env_var
;
1080 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1082 if (i
&& *pos
++ != ':')
1090 long val
= strtol (pos
, (char **)&eptr
, 10);
1091 if (errno
|| val
< 0 || (unsigned)val
!= val
)
1094 goacc_default_dims
[i
] = (int)val
;
1100 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1103 bool display
= false;
1104 bool verbose
= false;
1107 env
= getenv ("OMP_DISPLAY_ENV");
1111 while (isspace ((unsigned char) *env
))
1113 if (strncasecmp (env
, "true", 4) == 0)
1118 else if (strncasecmp (env
, "false", 5) == 0)
1123 else if (strncasecmp (env
, "verbose", 7) == 0)
1131 while (isspace ((unsigned char) *env
))
1134 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1139 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1141 fputs (" _OPENMP = '201511'\n", stderr
);
1142 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1143 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1144 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1145 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1147 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1148 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1149 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1150 fputs ("'\n", stderr
);
1152 fprintf (stderr
, " OMP_SCHEDULE = '");
1153 switch (gomp_global_icv
.run_sched_var
)
1156 fputs ("RUNTIME", stderr
);
1159 fputs ("STATIC", stderr
);
1162 fputs ("DYNAMIC", stderr
);
1165 fputs ("GUIDED", stderr
);
1168 fputs ("AUTO", stderr
);
1171 fputs ("'\n", stderr
);
1173 fputs (" OMP_PROC_BIND = '", stderr
);
1174 switch (gomp_global_icv
.bind_var
)
1176 case omp_proc_bind_false
:
1177 fputs ("FALSE", stderr
);
1179 case omp_proc_bind_true
:
1180 fputs ("TRUE", stderr
);
1182 case omp_proc_bind_master
:
1183 fputs ("MASTER", stderr
);
1185 case omp_proc_bind_close
:
1186 fputs ("CLOSE", stderr
);
1188 case omp_proc_bind_spread
:
1189 fputs ("SPREAD", stderr
);
1192 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1193 switch (gomp_bind_var_list
[i
])
1195 case omp_proc_bind_master
:
1196 fputs (",MASTER", stderr
);
1198 case omp_proc_bind_close
:
1199 fputs (",CLOSE", stderr
);
1201 case omp_proc_bind_spread
:
1202 fputs (",SPREAD", stderr
);
1205 fputs ("'\n", stderr
);
1206 fputs (" OMP_PLACES = '", stderr
);
1207 for (i
= 0; i
< gomp_places_list_len
; i
++)
1209 fputs ("{", stderr
);
1210 gomp_affinity_print_place (gomp_places_list
[i
]);
1211 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1213 fputs ("'\n", stderr
);
1215 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1217 /* GOMP's default value is actually neither active nor passive. */
1218 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1219 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1220 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1221 gomp_global_icv
.thread_limit_var
);
1222 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1223 gomp_max_active_levels_var
);
1225 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1226 gomp_cancel_var
? "TRUE" : "FALSE");
1227 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1228 gomp_global_icv
.default_device_var
);
1229 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1230 gomp_max_task_priority_var
);
1234 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1235 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1236 #ifdef HAVE_INTTYPES_H
1237 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1238 (uint64_t) gomp_spin_count_var
);
1240 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1241 (unsigned long) gomp_spin_count_var
);
1245 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1249 static void __attribute__((constructor
))
1250 initialize_env (void)
1252 unsigned long thread_limit_var
, stacksize
= GOMP_DEFAULT_STACKSIZE
;
1255 /* Do a compile time check that mkomp_h.pl did good job. */
1256 omp_check_defines ();
1259 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1260 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1261 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1262 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1263 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1264 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1266 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1268 gomp_global_icv
.thread_limit_var
1269 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1271 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var
, true);
1272 #ifndef HAVE_SYNC_BUILTINS
1273 gomp_mutex_init (&gomp_managed_threads_lock
);
1275 gomp_init_num_threads ();
1276 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1277 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1278 &gomp_global_icv
.nthreads_var
,
1279 &gomp_nthreads_var_list
,
1280 &gomp_nthreads_var_list_len
))
1281 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1282 bool ignore
= false;
1283 if (parse_bind_var ("OMP_PROC_BIND",
1284 &gomp_global_icv
.bind_var
,
1285 &gomp_bind_var_list
,
1286 &gomp_bind_var_list_len
)
1287 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1289 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1290 parsed if present in the environment. If OMP_PROC_BIND was set
1291 explictly to false, don't populate places list though. If places
1292 list was successfully set from OMP_PLACES, only parse but don't process
1293 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1294 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1295 was successfully parsed into a places list, otherwise to
1296 OMP_PROC_BIND=false. */
1297 if (parse_places_var ("OMP_PLACES", ignore
))
1299 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1300 gomp_global_icv
.bind_var
= true;
1303 if (parse_affinity (ignore
))
1305 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1306 gomp_global_icv
.bind_var
= true;
1309 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1310 gomp_init_affinity ();
1311 wait_policy
= parse_wait_policy ();
1312 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1314 /* Using a rough estimation of 100000 spins per msec,
1315 use 5 min blocking for OMP_WAIT_POLICY=active,
1316 3 msec blocking when OMP_WAIT_POLICY is not specificed
1317 and 0 when OMP_WAIT_POLICY=passive.
1318 Depending on the CPU speed, this can be e.g. 5 times longer
1319 or 5 times shorter. */
1320 if (wait_policy
> 0)
1321 gomp_spin_count_var
= 30000000000LL;
1322 else if (wait_policy
< 0)
1323 gomp_spin_count_var
= 300000LL;
1325 /* gomp_throttled_spin_count_var is used when there are more libgomp
1326 managed threads than available CPUs. Use very short spinning. */
1327 if (wait_policy
> 0)
1328 gomp_throttled_spin_count_var
= 1000LL;
1329 else if (wait_policy
< 0)
1330 gomp_throttled_spin_count_var
= 100LL;
1331 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1332 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1334 /* Not strictly environment related, but ordering constructors is tricky. */
1335 pthread_attr_init (&gomp_thread_attr
);
1336 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1338 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1339 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
)
1340 || GOMP_DEFAULT_STACKSIZE
)
1344 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1346 #ifdef PTHREAD_STACK_MIN
1349 if (stacksize
< PTHREAD_STACK_MIN
)
1350 gomp_error ("Stack size less than minimum of %luk",
1351 PTHREAD_STACK_MIN
/ 1024ul
1352 + (PTHREAD_STACK_MIN
% 1024 != 0));
1354 gomp_error ("Stack size larger than system limit");
1359 gomp_error ("Stack size change failed: %s", strerror (err
));
1362 handle_omp_display_env (stacksize
, wait_policy
);
1366 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1367 goacc_device_num
= 0;
1369 parse_acc_device_type ();
1370 parse_gomp_openacc_dim ();
1372 goacc_runtime_initialize ();
1374 #endif /* LIBGOMP_OFFLOADED_ONLY */