1 /* Copyright (C) 2005-2019 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 bool gomp_display_affinity_var
;
92 char *gomp_affinity_format_var
= "level %L thread %i affinity %A";
93 size_t gomp_affinity_format_len
;
94 char *goacc_device_type
;
96 int goacc_default_dims
[GOMP_DIM_MAX
];
98 #ifndef LIBGOMP_OFFLOADED_ONLY
100 /* Parse the OMP_SCHEDULE environment variable. */
103 parse_schedule (void)
109 env
= getenv ("OMP_SCHEDULE");
113 while (isspace ((unsigned char) *env
))
115 if (strncasecmp (env
, "monotonic", 9) == 0)
120 else if (strncasecmp (env
, "nonmonotonic", 12) == 0)
127 while (isspace ((unsigned char) *env
))
132 while (isspace ((unsigned char) *env
))
135 if (strncasecmp (env
, "static", 6) == 0)
137 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
140 else if (strncasecmp (env
, "dynamic", 7) == 0)
142 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
145 else if (strncasecmp (env
, "guided", 6) == 0)
147 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
150 else if (strncasecmp (env
, "auto", 4) == 0)
152 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
159 || (monotonic
== 0 && gomp_global_icv
.run_sched_var
== GFS_STATIC
))
160 gomp_global_icv
.run_sched_var
|= GFS_MONOTONIC
;
162 while (isspace ((unsigned char) *env
))
166 gomp_global_icv
.run_sched_chunk_size
167 = (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
;
172 while (isspace ((unsigned char) *env
))
178 value
= strtoul (env
, &end
, 10);
182 while (isspace ((unsigned char) *end
))
187 if ((int)value
!= value
)
191 && (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
) != GFS_STATIC
)
193 gomp_global_icv
.run_sched_chunk_size
= value
;
197 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
201 gomp_error ("Invalid value for chunk size in "
202 "environment variable OMP_SCHEDULE");
206 /* Parse an unsigned long environment variable. Return true if one was
207 present and it was successfully parsed. If SECURE, use secure_getenv to the
208 environment variable. */
211 parse_unsigned_long_1 (const char *name
, unsigned long *pvalue
, bool allow_zero
,
217 env
= (secure
? secure_getenv (name
) : getenv (name
));
221 while (isspace ((unsigned char) *env
))
227 value
= strtoul (env
, &end
, 10);
228 if (errno
|| (long) value
<= 0 - allow_zero
)
231 while (isspace ((unsigned char) *end
))
240 gomp_error ("Invalid value for environment variable %s", name
);
244 /* As parse_unsigned_long_1, but always use getenv. */
247 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
249 return parse_unsigned_long_1 (name
, pvalue
, allow_zero
, false);
252 /* Parse a positive int environment variable. Return true if one was
253 present and it was successfully parsed. If SECURE, use secure_getenv to the
254 environment variable. */
257 parse_int_1 (const char *name
, int *pvalue
, bool allow_zero
, bool secure
)
260 if (!parse_unsigned_long_1 (name
, &value
, allow_zero
, secure
))
264 gomp_error ("Invalid value for environment variable %s", name
);
267 *pvalue
= (int) value
;
271 /* As parse_int_1, but use getenv. */
274 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
276 return parse_int_1 (name
, pvalue
, allow_zero
, false);
279 /* As parse_int_1, but use getenv_secure. */
282 parse_int_secure (const char *name
, int *pvalue
, bool allow_zero
)
284 return parse_int_1 (name
, pvalue
, allow_zero
, true);
287 /* Parse an unsigned long list environment variable. Return true if one was
288 present and it was successfully parsed. */
291 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
292 unsigned long **pvalues
,
293 unsigned long *pnvalues
)
296 unsigned long value
, *values
= NULL
;
302 while (isspace ((unsigned char) *env
))
308 value
= strtoul (env
, &end
, 10);
309 if (errno
|| (long) value
<= 0)
312 while (isspace ((unsigned char) *end
))
318 unsigned long nvalues
= 0, nalloced
= 0;
323 if (nvalues
== nalloced
)
326 nalloced
= nalloced
? nalloced
* 2 : 16;
327 n
= realloc (values
, nalloced
* sizeof (unsigned long));
331 gomp_error ("Out of memory while trying to parse"
332 " environment variable %s", name
);
337 values
[nvalues
++] = value
;
340 while (isspace ((unsigned char) *env
))
346 value
= strtoul (env
, &end
, 10);
347 if (errno
|| (long) value
<= 0)
350 values
[nvalues
++] = value
;
351 while (isspace ((unsigned char) *end
))
359 *p1stvalue
= values
[0];
372 gomp_error ("Invalid value for environment variable %s", name
);
376 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
377 enum values. Return true if one was present and it was successfully
381 parse_bind_var (const char *name
, char *p1stvalue
,
382 char **pvalues
, unsigned long *pnvalues
)
385 char value
= omp_proc_bind_false
, *values
= NULL
;
387 static struct proc_bind_kinds
391 omp_proc_bind_t kind
;
394 { "false", 5, omp_proc_bind_false
},
395 { "true", 4, omp_proc_bind_true
},
396 { "master", 6, omp_proc_bind_master
},
397 { "close", 5, omp_proc_bind_close
},
398 { "spread", 6, omp_proc_bind_spread
}
405 while (isspace ((unsigned char) *env
))
410 for (i
= 0; i
< 5; i
++)
411 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
413 value
= kinds
[i
].kind
;
420 while (isspace ((unsigned char) *env
))
426 unsigned long nvalues
= 0, nalloced
= 0;
428 if (value
== omp_proc_bind_false
429 || value
== omp_proc_bind_true
)
435 if (nvalues
== nalloced
)
438 nalloced
= nalloced
? nalloced
* 2 : 16;
439 n
= realloc (values
, nalloced
);
443 gomp_error ("Out of memory while trying to parse"
444 " environment variable %s", name
);
449 values
[nvalues
++] = value
;
452 while (isspace ((unsigned char) *env
))
457 for (i
= 2; i
< 5; i
++)
458 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
460 value
= kinds
[i
].kind
;
467 values
[nvalues
++] = value
;
468 while (isspace ((unsigned char) *env
))
476 *p1stvalue
= values
[0];
489 gomp_error ("Invalid value for environment variable %s", name
);
494 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
497 char *env
= *envp
, *start
;
498 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
499 unsigned long len
= 1;
502 bool any_negate
= false;
504 while (isspace ((unsigned char) *env
))
510 while (isspace ((unsigned char) *env
))
516 while (isspace ((unsigned char) *env
))
519 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
524 unsigned long this_num
, this_len
= 1;
525 long this_stride
= 1;
526 bool this_negate
= (*env
== '!');
529 if (gomp_places_list
)
532 while (isspace ((unsigned char) *env
))
537 this_num
= strtoul (env
, &env
, 10);
540 while (isspace ((unsigned char) *env
))
545 while (isspace ((unsigned char) *env
))
548 this_len
= strtoul (env
, &env
, 10);
549 if (errno
|| this_len
== 0)
551 while (isspace ((unsigned char) *env
))
556 while (isspace ((unsigned char) *env
))
559 this_stride
= strtol (env
, &env
, 10);
562 while (isspace ((unsigned char) *env
))
566 if (this_negate
&& this_len
!= 1)
568 if (gomp_places_list
&& pass
== this_negate
)
572 if (!gomp_affinity_remove_cpu (p
, this_num
))
575 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
589 while (isspace ((unsigned char) *env
))
594 while (isspace ((unsigned char) *env
))
597 len
= strtoul (env
, &env
, 10);
598 if (errno
|| len
== 0 || len
>= 65536)
600 while (isspace ((unsigned char) *env
))
605 while (isspace ((unsigned char) *env
))
608 stride
= strtol (env
, &env
, 10);
611 while (isspace ((unsigned char) *env
))
615 if (*negatep
&& len
!= 1)
624 parse_places_var (const char *name
, bool ignore
)
626 char *env
= getenv (name
), *end
;
627 bool any_negate
= false;
629 unsigned long count
= 0;
633 while (isspace ((unsigned char) *env
))
638 if (strncasecmp (env
, "threads", 7) == 0)
643 else if (strncasecmp (env
, "cores", 5) == 0)
648 else if (strncasecmp (env
, "sockets", 7) == 0)
656 while (isspace ((unsigned char) *env
))
662 while (isspace ((unsigned char) *env
))
666 count
= strtoul (env
, &end
, 10);
670 while (isspace ((unsigned char) *env
))
675 while (isspace ((unsigned char) *env
))
684 return gomp_affinity_init_level (level
, count
, false);
694 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
717 gomp_places_list_len
= 0;
718 gomp_places_list
= gomp_affinity_alloc (count
, false);
719 if (gomp_places_list
== NULL
)
727 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
728 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
733 for (count
= 0; count
< gomp_places_list_len
; count
++)
734 if (gomp_affinity_same_place
735 (gomp_places_list
[count
],
736 gomp_places_list
[gomp_places_list_len
]))
738 if (count
== gomp_places_list_len
)
740 gomp_error ("Trying to remove a non-existing place from list "
744 p
= gomp_places_list
[count
];
745 memmove (&gomp_places_list
[count
],
746 &gomp_places_list
[count
+ 1],
747 (gomp_places_list_len
- count
- 1) * sizeof (void *));
748 --gomp_places_list_len
;
749 gomp_places_list
[gomp_places_list_len
] = p
;
752 ++gomp_places_list_len
;
755 for (count
= 0; count
< len
- 1; count
++)
756 if (!gomp_affinity_copy_place
757 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
758 gomp_places_list
[gomp_places_list_len
+ count
],
761 gomp_places_list_len
+= len
;
769 if (gomp_places_list_len
== 0)
771 gomp_error ("All places have been removed");
774 if (!gomp_affinity_finalize_place_list (false))
779 free (gomp_places_list
);
780 gomp_places_list
= NULL
;
781 gomp_places_list_len
= 0;
782 gomp_error ("Invalid value for environment variable %s", name
);
786 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
787 present and it was successfully parsed. */
790 parse_stacksize (const char *name
, unsigned long *pvalue
)
793 unsigned long value
, shift
= 10;
799 while (isspace ((unsigned char) *env
))
805 value
= strtoul (env
, &end
, 10);
809 while (isspace ((unsigned char) *end
))
813 switch (tolower ((unsigned char) *end
))
830 while (isspace ((unsigned char) *end
))
836 if (((value
<< shift
) >> shift
) != value
)
839 *pvalue
= value
<< shift
;
843 gomp_error ("Invalid value for environment variable %s", name
);
847 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
848 present and it was successfully parsed. */
851 parse_spincount (const char *name
, unsigned long long *pvalue
)
854 unsigned long long value
, mult
= 1;
860 while (isspace ((unsigned char) *env
))
865 if (strncasecmp (env
, "infinite", 8) == 0
866 || strncasecmp (env
, "infinity", 8) == 0)
874 value
= strtoull (env
, &end
, 10);
878 while (isspace ((unsigned char) *end
))
882 switch (tolower ((unsigned char) *end
))
888 mult
= 1000LL * 1000LL;
891 mult
= 1000LL * 1000LL * 1000LL;
894 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
901 while (isspace ((unsigned char) *end
))
907 if (value
> ~0ULL / mult
)
916 gomp_error ("Invalid value for environment variable %s", name
);
920 /* Parse a boolean value for environment variable NAME and store the
924 parse_boolean (const char *name
, bool *value
)
932 while (isspace ((unsigned char) *env
))
934 if (strncasecmp (env
, "true", 4) == 0)
939 else if (strncasecmp (env
, "false", 5) == 0)
946 while (isspace ((unsigned char) *env
))
949 gomp_error ("Invalid value for environment variable %s", name
);
952 /* Parse the OMP_WAIT_POLICY environment variable and store the
953 result in gomp_active_wait_policy. */
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");
1088 parse_acc_device_type (void)
1090 const char *env
= getenv ("ACC_DEVICE_TYPE");
1092 if (env
&& *env
!= '\0')
1093 goacc_device_type
= strdup (env
);
1095 goacc_device_type
= NULL
;
1099 parse_gomp_openacc_dim (void)
1101 /* The syntax is the same as for the -fopenacc-dim compilation option. */
1102 const char *var_name
= "GOMP_OPENACC_DIM";
1103 const char *env_var
= getenv (var_name
);
1107 const char *pos
= env_var
;
1109 for (i
= 0; *pos
&& i
!= GOMP_DIM_MAX
; i
++)
1111 if (i
&& *pos
++ != ':')
1119 long val
= strtol (pos
, (char **)&eptr
, 10);
1120 if (errno
|| val
< 0 || (unsigned)val
!= val
)
1123 goacc_default_dims
[i
] = (int)val
;
1129 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1132 bool display
= false;
1133 bool verbose
= false;
1136 env
= getenv ("OMP_DISPLAY_ENV");
1140 while (isspace ((unsigned char) *env
))
1142 if (strncasecmp (env
, "true", 4) == 0)
1147 else if (strncasecmp (env
, "false", 5) == 0)
1152 else if (strncasecmp (env
, "verbose", 7) == 0)
1160 while (isspace ((unsigned char) *env
))
1163 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1168 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1170 fputs (" _OPENMP = '201511'\n", stderr
);
1171 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1172 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1173 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1174 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1176 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1177 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1178 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1179 fputs ("'\n", stderr
);
1181 fprintf (stderr
, " OMP_SCHEDULE = '");
1182 if ((gomp_global_icv
.run_sched_var
& GFS_MONOTONIC
))
1184 if (gomp_global_icv
.run_sched_var
!= (GFS_MONOTONIC
| GFS_STATIC
))
1185 fputs ("MONOTONIC:", stderr
);
1187 else if (gomp_global_icv
.run_sched_var
== GFS_STATIC
)
1188 fputs ("NONMONOTONIC:", stderr
);
1189 switch (gomp_global_icv
.run_sched_var
& ~GFS_MONOTONIC
)
1192 fputs ("RUNTIME", stderr
);
1193 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1194 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1197 fputs ("STATIC", stderr
);
1198 if (gomp_global_icv
.run_sched_chunk_size
!= 0)
1199 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1202 fputs ("DYNAMIC", stderr
);
1203 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1204 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1207 fputs ("GUIDED", stderr
);
1208 if (gomp_global_icv
.run_sched_chunk_size
!= 1)
1209 fprintf (stderr
, ",%d", gomp_global_icv
.run_sched_chunk_size
);
1212 fputs ("AUTO", stderr
);
1215 fputs ("'\n", stderr
);
1217 fputs (" OMP_PROC_BIND = '", stderr
);
1218 switch (gomp_global_icv
.bind_var
)
1220 case omp_proc_bind_false
:
1221 fputs ("FALSE", stderr
);
1223 case omp_proc_bind_true
:
1224 fputs ("TRUE", stderr
);
1226 case omp_proc_bind_master
:
1227 fputs ("MASTER", stderr
);
1229 case omp_proc_bind_close
:
1230 fputs ("CLOSE", stderr
);
1232 case omp_proc_bind_spread
:
1233 fputs ("SPREAD", stderr
);
1236 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1237 switch (gomp_bind_var_list
[i
])
1239 case omp_proc_bind_master
:
1240 fputs (",MASTER", stderr
);
1242 case omp_proc_bind_close
:
1243 fputs (",CLOSE", stderr
);
1245 case omp_proc_bind_spread
:
1246 fputs (",SPREAD", stderr
);
1249 fputs ("'\n", stderr
);
1250 fputs (" OMP_PLACES = '", stderr
);
1251 for (i
= 0; i
< gomp_places_list_len
; i
++)
1253 fputs ("{", stderr
);
1254 gomp_affinity_print_place (gomp_places_list
[i
]);
1255 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1257 fputs ("'\n", stderr
);
1259 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1261 /* GOMP's default value is actually neither active nor passive. */
1262 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1263 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1264 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1265 gomp_global_icv
.thread_limit_var
);
1266 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1267 gomp_max_active_levels_var
);
1269 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1270 gomp_cancel_var
? "TRUE" : "FALSE");
1271 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1272 gomp_global_icv
.default_device_var
);
1273 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1274 gomp_max_task_priority_var
);
1275 fprintf (stderr
, " OMP_DISPLAY_AFFINITY = '%s'\n",
1276 gomp_display_affinity_var
? "TRUE" : "FALSE");
1277 fprintf (stderr
, " OMP_AFFINITY_FORMAT = '%s'\n",
1278 gomp_affinity_format_var
);
1282 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1283 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1284 #ifdef HAVE_INTTYPES_H
1285 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1286 (uint64_t) gomp_spin_count_var
);
1288 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1289 (unsigned long) gomp_spin_count_var
);
1293 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1297 static void __attribute__((constructor
))
1298 initialize_env (void)
1300 unsigned long thread_limit_var
, stacksize
= GOMP_DEFAULT_STACKSIZE
;
1303 /* Do a compile time check that mkomp_h.pl did good job. */
1304 omp_check_defines ();
1307 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1308 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1309 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1310 parse_boolean ("OMP_DISPLAY_AFFINITY", &gomp_display_affinity_var
);
1311 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1312 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1313 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1315 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1317 gomp_global_icv
.thread_limit_var
1318 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1320 parse_int_secure ("GOMP_DEBUG", &gomp_debug_var
, true);
1321 #ifndef HAVE_SYNC_BUILTINS
1322 gomp_mutex_init (&gomp_managed_threads_lock
);
1324 gomp_init_num_threads ();
1325 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1326 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1327 &gomp_global_icv
.nthreads_var
,
1328 &gomp_nthreads_var_list
,
1329 &gomp_nthreads_var_list_len
))
1330 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1331 bool ignore
= false;
1332 if (parse_bind_var ("OMP_PROC_BIND",
1333 &gomp_global_icv
.bind_var
,
1334 &gomp_bind_var_list
,
1335 &gomp_bind_var_list_len
)
1336 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1338 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1339 parsed if present in the environment. If OMP_PROC_BIND was set
1340 explictly to false, don't populate places list though. If places
1341 list was successfully set from OMP_PLACES, only parse but don't process
1342 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1343 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1344 was successfully parsed into a places list, otherwise to
1345 OMP_PROC_BIND=false. */
1346 if (parse_places_var ("OMP_PLACES", ignore
))
1348 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1349 gomp_global_icv
.bind_var
= true;
1352 if (parse_affinity (ignore
))
1354 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1355 gomp_global_icv
.bind_var
= true;
1358 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1359 gomp_init_affinity ();
1362 const char *env
= getenv ("OMP_AFFINITY_FORMAT");
1364 gomp_set_affinity_format (env
, strlen (env
));
1367 wait_policy
= parse_wait_policy ();
1368 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1370 /* Using a rough estimation of 100000 spins per msec,
1371 use 5 min blocking for OMP_WAIT_POLICY=active,
1372 3 msec blocking when OMP_WAIT_POLICY is not specificed
1373 and 0 when OMP_WAIT_POLICY=passive.
1374 Depending on the CPU speed, this can be e.g. 5 times longer
1375 or 5 times shorter. */
1376 if (wait_policy
> 0)
1377 gomp_spin_count_var
= 30000000000LL;
1378 else if (wait_policy
< 0)
1379 gomp_spin_count_var
= 300000LL;
1381 /* gomp_throttled_spin_count_var is used when there are more libgomp
1382 managed threads than available CPUs. Use very short spinning. */
1383 if (wait_policy
> 0)
1384 gomp_throttled_spin_count_var
= 1000LL;
1385 else if (wait_policy
< 0)
1386 gomp_throttled_spin_count_var
= 100LL;
1387 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1388 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1390 /* Not strictly environment related, but ordering constructors is tricky. */
1391 pthread_attr_init (&gomp_thread_attr
);
1393 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1394 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
)
1395 || GOMP_DEFAULT_STACKSIZE
)
1399 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1401 #ifdef PTHREAD_STACK_MIN
1404 if (stacksize
< PTHREAD_STACK_MIN
)
1405 gomp_error ("Stack size less than minimum of %luk",
1406 PTHREAD_STACK_MIN
/ 1024ul
1407 + (PTHREAD_STACK_MIN
% 1024 != 0));
1409 gomp_error ("Stack size larger than system limit");
1414 gomp_error ("Stack size change failed: %s", strerror (err
));
1417 handle_omp_display_env (stacksize
, wait_policy
);
1421 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1422 goacc_device_num
= 0;
1424 parse_acc_device_type ();
1425 parse_gomp_openacc_dim ();
1427 goacc_runtime_initialize ();
1429 goacc_profiling_initialize ();
1431 #endif /* LIBGOMP_OFFLOADED_ONLY */