1 /* Copyright (C) 2005-2016 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 arranges for OpenMP internal control variables to be initialized
27 from environment variables at startup. */
30 #include "libgomp_f.h"
32 #include "gomp-constants.h"
36 #ifdef HAVE_INTTYPES_H
37 # include <inttypes.h> /* For PRIu64. */
39 #ifdef STRING_WITH_STRINGS
46 # ifdef HAVE_STRINGS_H
55 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
58 /* Parse the OMP_SCHEDULE environment variable. */
66 env
= getenv ("OMP_SCHEDULE");
70 while (isspace ((unsigned char) *env
))
72 if (strncasecmp (env
, "static", 6) == 0)
74 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
77 else if (strncasecmp (env
, "dynamic", 7) == 0)
79 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
82 else if (strncasecmp (env
, "guided", 6) == 0)
84 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
87 else if (strncasecmp (env
, "auto", 4) == 0)
89 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
95 while (isspace ((unsigned char) *env
))
99 gomp_global_icv
.run_sched_chunk_size
100 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
105 while (isspace ((unsigned char) *env
))
111 value
= strtoul (env
, &end
, 10);
115 while (isspace ((unsigned char) *end
))
120 if ((int)value
!= value
)
123 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
125 gomp_global_icv
.run_sched_chunk_size
= value
;
129 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
133 gomp_error ("Invalid value for chunk size in "
134 "environment variable OMP_SCHEDULE");
138 /* Parse an unsigned long environment variable. Return true if one was
139 present and it was successfully parsed. */
142 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
151 while (isspace ((unsigned char) *env
))
157 value
= strtoul (env
, &end
, 10);
158 if (errno
|| (long) value
<= 0 - allow_zero
)
161 while (isspace ((unsigned char) *end
))
170 gomp_error ("Invalid value for environment variable %s", name
);
174 /* Parse a positive int environment variable. Return true if one was
175 present and it was successfully parsed. */
178 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
181 if (!parse_unsigned_long (name
, &value
, allow_zero
))
185 gomp_error ("Invalid value for environment variable %s", name
);
188 *pvalue
= (int) value
;
192 /* Parse an unsigned long list environment variable. Return true if one was
193 present and it was successfully parsed. */
196 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
197 unsigned long **pvalues
,
198 unsigned long *pnvalues
)
201 unsigned long value
, *values
= NULL
;
207 while (isspace ((unsigned char) *env
))
213 value
= strtoul (env
, &end
, 10);
214 if (errno
|| (long) value
<= 0)
217 while (isspace ((unsigned char) *end
))
223 unsigned long nvalues
= 0, nalloced
= 0;
228 if (nvalues
== nalloced
)
231 nalloced
= nalloced
? nalloced
* 2 : 16;
232 n
= realloc (values
, nalloced
* sizeof (unsigned long));
236 gomp_error ("Out of memory while trying to parse"
237 " environment variable %s", name
);
242 values
[nvalues
++] = value
;
245 while (isspace ((unsigned char) *env
))
251 value
= strtoul (env
, &end
, 10);
252 if (errno
|| (long) value
<= 0)
255 values
[nvalues
++] = value
;
256 while (isspace ((unsigned char) *end
))
264 *p1stvalue
= values
[0];
277 gomp_error ("Invalid value for environment variable %s", name
);
281 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
282 enum values. Return true if one was present and it was successfully
286 parse_bind_var (const char *name
, char *p1stvalue
,
287 char **pvalues
, unsigned long *pnvalues
)
290 char value
= omp_proc_bind_false
, *values
= NULL
;
292 static struct proc_bind_kinds
296 omp_proc_bind_t kind
;
299 { "false", 5, omp_proc_bind_false
},
300 { "true", 4, omp_proc_bind_true
},
301 { "master", 6, omp_proc_bind_master
},
302 { "close", 5, omp_proc_bind_close
},
303 { "spread", 6, omp_proc_bind_spread
}
310 while (isspace ((unsigned char) *env
))
315 for (i
= 0; i
< 5; i
++)
316 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
318 value
= kinds
[i
].kind
;
325 while (isspace ((unsigned char) *env
))
331 unsigned long nvalues
= 0, nalloced
= 0;
333 if (value
== omp_proc_bind_false
334 || value
== omp_proc_bind_true
)
340 if (nvalues
== nalloced
)
343 nalloced
= nalloced
? nalloced
* 2 : 16;
344 n
= realloc (values
, nalloced
);
348 gomp_error ("Out of memory while trying to parse"
349 " environment variable %s", name
);
354 values
[nvalues
++] = value
;
357 while (isspace ((unsigned char) *env
))
362 for (i
= 2; i
< 5; i
++)
363 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
365 value
= kinds
[i
].kind
;
372 values
[nvalues
++] = value
;
373 while (isspace ((unsigned char) *env
))
381 *p1stvalue
= values
[0];
394 gomp_error ("Invalid value for environment variable %s", name
);
399 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
402 char *env
= *envp
, *start
;
403 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
404 unsigned long len
= 1;
407 bool any_negate
= false;
409 while (isspace ((unsigned char) *env
))
415 while (isspace ((unsigned char) *env
))
421 while (isspace ((unsigned char) *env
))
424 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
429 unsigned long this_num
, this_len
= 1;
430 long this_stride
= 1;
431 bool this_negate
= (*env
== '!');
434 if (gomp_places_list
)
437 while (isspace ((unsigned char) *env
))
442 this_num
= strtoul (env
, &env
, 10);
445 while (isspace ((unsigned char) *env
))
450 while (isspace ((unsigned char) *env
))
453 this_len
= strtoul (env
, &env
, 10);
454 if (errno
|| this_len
== 0)
456 while (isspace ((unsigned char) *env
))
461 while (isspace ((unsigned char) *env
))
464 this_stride
= strtol (env
, &env
, 10);
467 while (isspace ((unsigned char) *env
))
471 if (this_negate
&& this_len
!= 1)
473 if (gomp_places_list
&& pass
== this_negate
)
477 if (!gomp_affinity_remove_cpu (p
, this_num
))
480 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
494 while (isspace ((unsigned char) *env
))
499 while (isspace ((unsigned char) *env
))
502 len
= strtoul (env
, &env
, 10);
503 if (errno
|| len
== 0 || len
>= 65536)
505 while (isspace ((unsigned char) *env
))
510 while (isspace ((unsigned char) *env
))
513 stride
= strtol (env
, &env
, 10);
516 while (isspace ((unsigned char) *env
))
520 if (*negatep
&& len
!= 1)
529 parse_places_var (const char *name
, bool ignore
)
531 char *env
= getenv (name
), *end
;
532 bool any_negate
= false;
534 unsigned long count
= 0;
538 while (isspace ((unsigned char) *env
))
543 if (strncasecmp (env
, "threads", 7) == 0)
548 else if (strncasecmp (env
, "cores", 5) == 0)
553 else if (strncasecmp (env
, "sockets", 7) == 0)
561 while (isspace ((unsigned char) *env
))
567 while (isspace ((unsigned char) *env
))
571 count
= strtoul (env
, &end
, 10);
575 while (isspace ((unsigned char) *env
))
580 while (isspace ((unsigned char) *env
))
589 return gomp_affinity_init_level (level
, count
, false);
599 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
622 gomp_places_list_len
= 0;
623 gomp_places_list
= gomp_affinity_alloc (count
, false);
624 if (gomp_places_list
== NULL
)
632 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
633 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
638 for (count
= 0; count
< gomp_places_list_len
; count
++)
639 if (gomp_affinity_same_place
640 (gomp_places_list
[count
],
641 gomp_places_list
[gomp_places_list_len
]))
643 if (count
== gomp_places_list_len
)
645 gomp_error ("Trying to remove a non-existing place from list "
649 p
= gomp_places_list
[count
];
650 memmove (&gomp_places_list
[count
],
651 &gomp_places_list
[count
+ 1],
652 (gomp_places_list_len
- count
- 1) * sizeof (void *));
653 --gomp_places_list_len
;
654 gomp_places_list
[gomp_places_list_len
] = p
;
657 ++gomp_places_list_len
;
660 for (count
= 0; count
< len
- 1; count
++)
661 if (!gomp_affinity_copy_place
662 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
663 gomp_places_list
[gomp_places_list_len
+ count
],
666 gomp_places_list_len
+= len
;
674 if (gomp_places_list_len
== 0)
676 gomp_error ("All places have been removed");
679 if (!gomp_affinity_finalize_place_list (false))
684 free (gomp_places_list
);
685 gomp_places_list
= NULL
;
686 gomp_places_list_len
= 0;
687 gomp_error ("Invalid value for environment variable %s", name
);
691 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
692 present and it was successfully parsed. */
695 parse_stacksize (const char *name
, unsigned long *pvalue
)
698 unsigned long value
, shift
= 10;
704 while (isspace ((unsigned char) *env
))
710 value
= strtoul (env
, &end
, 10);
714 while (isspace ((unsigned char) *end
))
718 switch (tolower ((unsigned char) *end
))
735 while (isspace ((unsigned char) *end
))
741 if (((value
<< shift
) >> shift
) != value
)
744 *pvalue
= value
<< shift
;
748 gomp_error ("Invalid value for environment variable %s", name
);
752 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
753 present and it was successfully parsed. */
756 parse_spincount (const char *name
, unsigned long long *pvalue
)
759 unsigned long long value
, mult
= 1;
765 while (isspace ((unsigned char) *env
))
770 if (strncasecmp (env
, "infinite", 8) == 0
771 || strncasecmp (env
, "infinity", 8) == 0)
779 value
= strtoull (env
, &end
, 10);
783 while (isspace ((unsigned char) *end
))
787 switch (tolower ((unsigned char) *end
))
793 mult
= 1000LL * 1000LL;
796 mult
= 1000LL * 1000LL * 1000LL;
799 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
806 while (isspace ((unsigned char) *end
))
812 if (value
> ~0ULL / mult
)
821 gomp_error ("Invalid value for environment variable %s", name
);
825 /* Parse a boolean value for environment variable NAME and store the
829 parse_boolean (const char *name
, bool *value
)
837 while (isspace ((unsigned char) *env
))
839 if (strncasecmp (env
, "true", 4) == 0)
844 else if (strncasecmp (env
, "false", 5) == 0)
851 while (isspace ((unsigned char) *env
))
854 gomp_error ("Invalid value for environment variable %s", name
);
857 /* Parse the OMP_WAIT_POLICY environment variable and store the
858 result in gomp_active_wait_policy. */
861 parse_wait_policy (void)
866 env
= getenv ("OMP_WAIT_POLICY");
870 while (isspace ((unsigned char) *env
))
872 if (strncasecmp (env
, "active", 6) == 0)
877 else if (strncasecmp (env
, "passive", 7) == 0)
884 while (isspace ((unsigned char) *env
))
888 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
892 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
893 present and it was successfully parsed. */
896 parse_affinity (bool ignore
)
898 char *env
, *end
, *start
;
900 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
901 size_t count
= 0, needed
;
903 env
= getenv ("GOMP_CPU_AFFINITY");
908 for (pass
= 0; pass
< 2; pass
++)
916 gomp_places_list_len
= 0;
917 gomp_places_list
= gomp_affinity_alloc (count
, true);
918 if (gomp_places_list
== NULL
)
923 while (isspace ((unsigned char) *env
))
927 cpu_beg
= strtoul (env
, &end
, 0);
928 if (errno
|| cpu_beg
>= 65536)
937 cpu_end
= strtoul (++env
, &end
, 0);
938 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
945 cpu_stride
= strtoul (++env
, &end
, 0);
946 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
953 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
960 void *p
= gomp_places_list
[gomp_places_list_len
];
961 gomp_affinity_init_place (p
);
962 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
963 ++gomp_places_list_len
;
964 cpu_beg
+= cpu_stride
;
968 while (isspace ((unsigned char) *env
))
973 else if (*env
== '\0')
979 if (gomp_places_list_len
== 0)
981 free (gomp_places_list
);
982 gomp_places_list
= NULL
;
988 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
993 parse_acc_device_type (void)
995 const char *env
= getenv ("ACC_DEVICE_TYPE");
997 if (env
&& *env
!= '\0')
998 goacc_device_type
= strdup (env
);
1000 goacc_device_type
= NULL
;
1004 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1007 bool display
= false;
1008 bool verbose
= false;
1011 env
= getenv ("OMP_DISPLAY_ENV");
1015 while (isspace ((unsigned char) *env
))
1017 if (strncasecmp (env
, "true", 4) == 0)
1022 else if (strncasecmp (env
, "false", 5) == 0)
1027 else if (strncasecmp (env
, "verbose", 7) == 0)
1035 while (isspace ((unsigned char) *env
))
1038 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1043 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1045 fputs (" _OPENMP = '201511'\n", stderr
);
1046 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1047 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1048 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1049 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1051 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1052 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1053 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1054 fputs ("'\n", stderr
);
1056 fprintf (stderr
, " OMP_SCHEDULE = '");
1057 switch (gomp_global_icv
.run_sched_var
)
1060 fputs ("RUNTIME", stderr
);
1063 fputs ("STATIC", stderr
);
1066 fputs ("DYNAMIC", stderr
);
1069 fputs ("GUIDED", stderr
);
1072 fputs ("AUTO", stderr
);
1075 fputs ("'\n", stderr
);
1077 fputs (" OMP_PROC_BIND = '", stderr
);
1078 switch (gomp_global_icv
.bind_var
)
1080 case omp_proc_bind_false
:
1081 fputs ("FALSE", stderr
);
1083 case omp_proc_bind_true
:
1084 fputs ("TRUE", stderr
);
1086 case omp_proc_bind_master
:
1087 fputs ("MASTER", stderr
);
1089 case omp_proc_bind_close
:
1090 fputs ("CLOSE", stderr
);
1092 case omp_proc_bind_spread
:
1093 fputs ("SPREAD", stderr
);
1096 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1097 switch (gomp_bind_var_list
[i
])
1099 case omp_proc_bind_master
:
1100 fputs (",MASTER", stderr
);
1102 case omp_proc_bind_close
:
1103 fputs (",CLOSE", stderr
);
1105 case omp_proc_bind_spread
:
1106 fputs (",SPREAD", stderr
);
1109 fputs ("'\n", stderr
);
1110 fputs (" OMP_PLACES = '", stderr
);
1111 for (i
= 0; i
< gomp_places_list_len
; i
++)
1113 fputs ("{", stderr
);
1114 gomp_affinity_print_place (gomp_places_list
[i
]);
1115 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1117 fputs ("'\n", stderr
);
1119 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1121 /* GOMP's default value is actually neither active nor passive. */
1122 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1123 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1124 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1125 gomp_global_icv
.thread_limit_var
);
1126 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1127 gomp_max_active_levels_var
);
1129 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1130 gomp_cancel_var
? "TRUE" : "FALSE");
1131 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1132 gomp_global_icv
.default_device_var
);
1133 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1134 gomp_max_task_priority_var
);
1138 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1139 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1140 #ifdef HAVE_INTTYPES_H
1141 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1142 (uint64_t) gomp_spin_count_var
);
1144 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1145 (unsigned long) gomp_spin_count_var
);
1149 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1153 static void __attribute__((constructor
))
1154 initialize_env (void)
1156 unsigned long thread_limit_var
, stacksize
;
1159 /* Do a compile time check that mkomp_h.pl did good job. */
1160 omp_check_defines ();
1163 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1164 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1165 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1166 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1167 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1168 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1170 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1172 gomp_global_icv
.thread_limit_var
1173 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1175 parse_int ("GOMP_DEBUG", &gomp_debug_var
, true);
1176 #ifndef HAVE_SYNC_BUILTINS
1177 gomp_mutex_init (&gomp_managed_threads_lock
);
1179 gomp_init_num_threads ();
1180 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1181 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1182 &gomp_global_icv
.nthreads_var
,
1183 &gomp_nthreads_var_list
,
1184 &gomp_nthreads_var_list_len
))
1185 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1186 bool ignore
= false;
1187 if (parse_bind_var ("OMP_PROC_BIND",
1188 &gomp_global_icv
.bind_var
,
1189 &gomp_bind_var_list
,
1190 &gomp_bind_var_list_len
)
1191 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1193 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1194 parsed if present in the environment. If OMP_PROC_BIND was set
1195 explictly to false, don't populate places list though. If places
1196 list was successfully set from OMP_PLACES, only parse but don't process
1197 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1198 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1199 was successfully parsed into a places list, otherwise to
1200 OMP_PROC_BIND=false. */
1201 if (parse_places_var ("OMP_PLACES", ignore
))
1203 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1204 gomp_global_icv
.bind_var
= true;
1207 if (parse_affinity (ignore
))
1209 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1210 gomp_global_icv
.bind_var
= true;
1213 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1214 gomp_init_affinity ();
1215 wait_policy
= parse_wait_policy ();
1216 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1218 /* Using a rough estimation of 100000 spins per msec,
1219 use 5 min blocking for OMP_WAIT_POLICY=active,
1220 3 msec blocking when OMP_WAIT_POLICY is not specificed
1221 and 0 when OMP_WAIT_POLICY=passive.
1222 Depending on the CPU speed, this can be e.g. 5 times longer
1223 or 5 times shorter. */
1224 if (wait_policy
> 0)
1225 gomp_spin_count_var
= 30000000000LL;
1226 else if (wait_policy
< 0)
1227 gomp_spin_count_var
= 300000LL;
1229 /* gomp_throttled_spin_count_var is used when there are more libgomp
1230 managed threads than available CPUs. Use very short spinning. */
1231 if (wait_policy
> 0)
1232 gomp_throttled_spin_count_var
= 1000LL;
1233 else if (wait_policy
< 0)
1234 gomp_throttled_spin_count_var
= 100LL;
1235 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1236 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1238 /* Not strictly environment related, but ordering constructors is tricky. */
1239 pthread_attr_init (&gomp_thread_attr
);
1240 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1242 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1243 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
))
1247 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1249 #ifdef PTHREAD_STACK_MIN
1252 if (stacksize
< PTHREAD_STACK_MIN
)
1253 gomp_error ("Stack size less than minimum of %luk",
1254 PTHREAD_STACK_MIN
/ 1024ul
1255 + (PTHREAD_STACK_MIN
% 1024 != 0));
1257 gomp_error ("Stack size larger than system limit");
1262 gomp_error ("Stack size change failed: %s", strerror (err
));
1265 handle_omp_display_env (stacksize
, wait_policy
);
1269 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1270 goacc_device_num
= 0;
1272 parse_acc_device_type ();
1274 goacc_runtime_initialize ();