1 /* Copyright (C) 2005-2015 Free Software Foundation, Inc.
2 Contributed by Richard Henderson <rth@redhat.com>.
4 This file is part of the GNU OpenMP Library (libgomp).
6 Libgomp is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
25 /* This file defines the OpenMP internal control variables, and arranges
26 for them to be initialized from environment variables at startup. */
29 #include "libgomp_f.h"
33 #ifdef HAVE_INTTYPES_H
34 # include <inttypes.h> /* For PRIu64. */
36 #ifdef STRING_WITH_STRINGS
43 # ifdef HAVE_STRINGS_H
52 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
55 struct gomp_task_icv gomp_global_icv
= {
57 .thread_limit_var
= UINT_MAX
,
58 .run_sched_var
= GFS_DYNAMIC
,
59 .run_sched_modifier
= 1,
60 .default_device_var
= 0,
63 .bind_var
= omp_proc_bind_false
,
67 unsigned long gomp_max_active_levels_var
= INT_MAX
;
68 bool gomp_cancel_var
= false;
69 #ifndef HAVE_SYNC_BUILTINS
70 gomp_mutex_t gomp_managed_threads_lock
;
72 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
73 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
74 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
75 char *gomp_bind_var_list
;
76 unsigned long gomp_bind_var_list_len
;
77 void **gomp_places_list
;
78 unsigned long gomp_places_list_len
;
80 /* Parse the OMP_SCHEDULE environment variable. */
88 env
= getenv ("OMP_SCHEDULE");
92 while (isspace ((unsigned char) *env
))
94 if (strncasecmp (env
, "static", 6) == 0)
96 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
99 else if (strncasecmp (env
, "dynamic", 7) == 0)
101 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
104 else if (strncasecmp (env
, "guided", 6) == 0)
106 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
109 else if (strncasecmp (env
, "auto", 4) == 0)
111 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
117 while (isspace ((unsigned char) *env
))
121 gomp_global_icv
.run_sched_modifier
122 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
127 while (isspace ((unsigned char) *env
))
133 value
= strtoul (env
, &end
, 10);
137 while (isspace ((unsigned char) *end
))
142 if ((int)value
!= value
)
145 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
147 gomp_global_icv
.run_sched_modifier
= value
;
151 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
155 gomp_error ("Invalid value for chunk size in "
156 "environment variable OMP_SCHEDULE");
160 /* Parse an unsigned long environment variable. Return true if one was
161 present and it was successfully parsed. */
164 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
173 while (isspace ((unsigned char) *env
))
179 value
= strtoul (env
, &end
, 10);
180 if (errno
|| (long) value
<= 0 - allow_zero
)
183 while (isspace ((unsigned char) *end
))
192 gomp_error ("Invalid value for environment variable %s", name
);
196 /* Parse a positive int environment variable. Return true if one was
197 present and it was successfully parsed. */
200 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
203 if (!parse_unsigned_long (name
, &value
, allow_zero
))
207 gomp_error ("Invalid value for environment variable %s", name
);
210 *pvalue
= (int) value
;
214 /* Parse an unsigned long list environment variable. Return true if one was
215 present and it was successfully parsed. */
218 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
219 unsigned long **pvalues
,
220 unsigned long *pnvalues
)
223 unsigned long value
, *values
= NULL
;
229 while (isspace ((unsigned char) *env
))
235 value
= strtoul (env
, &end
, 10);
236 if (errno
|| (long) value
<= 0)
239 while (isspace ((unsigned char) *end
))
245 unsigned long nvalues
= 0, nalloced
= 0;
250 if (nvalues
== nalloced
)
253 nalloced
= nalloced
? nalloced
* 2 : 16;
254 n
= realloc (values
, nalloced
* sizeof (unsigned long));
258 gomp_error ("Out of memory while trying to parse"
259 " environment variable %s", name
);
264 values
[nvalues
++] = value
;
267 while (isspace ((unsigned char) *env
))
273 value
= strtoul (env
, &end
, 10);
274 if (errno
|| (long) value
<= 0)
277 values
[nvalues
++] = value
;
278 while (isspace ((unsigned char) *end
))
286 *p1stvalue
= values
[0];
299 gomp_error ("Invalid value for environment variable %s", name
);
303 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
304 enum values. Return true if one was present and it was successfully
308 parse_bind_var (const char *name
, char *p1stvalue
,
309 char **pvalues
, unsigned long *pnvalues
)
312 char value
= omp_proc_bind_false
, *values
= NULL
;
314 static struct proc_bind_kinds
318 omp_proc_bind_t kind
;
321 { "false", 5, omp_proc_bind_false
},
322 { "true", 4, omp_proc_bind_true
},
323 { "master", 6, omp_proc_bind_master
},
324 { "close", 5, omp_proc_bind_close
},
325 { "spread", 6, omp_proc_bind_spread
}
332 while (isspace ((unsigned char) *env
))
337 for (i
= 0; i
< 5; i
++)
338 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
340 value
= kinds
[i
].kind
;
347 while (isspace ((unsigned char) *env
))
353 unsigned long nvalues
= 0, nalloced
= 0;
355 if (value
== omp_proc_bind_false
356 || value
== omp_proc_bind_true
)
362 if (nvalues
== nalloced
)
365 nalloced
= nalloced
? nalloced
* 2 : 16;
366 n
= realloc (values
, nalloced
);
370 gomp_error ("Out of memory while trying to parse"
371 " environment variable %s", name
);
376 values
[nvalues
++] = value
;
379 while (isspace ((unsigned char) *env
))
384 for (i
= 2; i
< 5; i
++)
385 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
387 value
= kinds
[i
].kind
;
394 values
[nvalues
++] = value
;
395 while (isspace ((unsigned char) *env
))
403 *p1stvalue
= values
[0];
416 gomp_error ("Invalid value for environment variable %s", name
);
421 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
424 char *env
= *envp
, *start
;
425 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
426 unsigned long len
= 1;
429 bool any_negate
= false;
431 while (isspace ((unsigned char) *env
))
437 while (isspace ((unsigned char) *env
))
443 while (isspace ((unsigned char) *env
))
446 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
451 unsigned long this_num
, this_len
= 1;
452 long this_stride
= 1;
453 bool this_negate
= (*env
== '!');
456 if (gomp_places_list
)
459 while (isspace ((unsigned char) *env
))
464 this_num
= strtoul (env
, &env
, 10);
467 while (isspace ((unsigned char) *env
))
472 while (isspace ((unsigned char) *env
))
475 this_len
= strtoul (env
, &env
, 10);
476 if (errno
|| this_len
== 0)
478 while (isspace ((unsigned char) *env
))
483 while (isspace ((unsigned char) *env
))
486 this_stride
= strtol (env
, &env
, 10);
489 while (isspace ((unsigned char) *env
))
493 if (this_negate
&& this_len
!= 1)
495 if (gomp_places_list
&& pass
== this_negate
)
499 if (!gomp_affinity_remove_cpu (p
, this_num
))
502 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
516 while (isspace ((unsigned char) *env
))
521 while (isspace ((unsigned char) *env
))
524 len
= strtoul (env
, &env
, 10);
525 if (errno
|| len
== 0 || len
>= 65536)
527 while (isspace ((unsigned char) *env
))
532 while (isspace ((unsigned char) *env
))
535 stride
= strtol (env
, &env
, 10);
538 while (isspace ((unsigned char) *env
))
542 if (*negatep
&& len
!= 1)
551 parse_places_var (const char *name
, bool ignore
)
553 char *env
= getenv (name
), *end
;
554 bool any_negate
= false;
556 unsigned long count
= 0;
560 while (isspace ((unsigned char) *env
))
565 if (strncasecmp (env
, "threads", 7) == 0)
570 else if (strncasecmp (env
, "cores", 5) == 0)
575 else if (strncasecmp (env
, "sockets", 7) == 0)
583 while (isspace ((unsigned char) *env
))
589 while (isspace ((unsigned char) *env
))
593 count
= strtoul (env
, &end
, 10);
597 while (isspace ((unsigned char) *env
))
602 while (isspace ((unsigned char) *env
))
611 return gomp_affinity_init_level (level
, count
, false);
621 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
644 gomp_places_list_len
= 0;
645 gomp_places_list
= gomp_affinity_alloc (count
, false);
646 if (gomp_places_list
== NULL
)
654 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
655 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
660 for (count
= 0; count
< gomp_places_list_len
; count
++)
661 if (gomp_affinity_same_place
662 (gomp_places_list
[count
],
663 gomp_places_list
[gomp_places_list_len
]))
665 if (count
== gomp_places_list_len
)
667 gomp_error ("Trying to remove a non-existing place from list "
671 p
= gomp_places_list
[count
];
672 memmove (&gomp_places_list
[count
],
673 &gomp_places_list
[count
+ 1],
674 (gomp_places_list_len
- count
- 1) * sizeof (void *));
675 --gomp_places_list_len
;
676 gomp_places_list
[gomp_places_list_len
] = p
;
679 ++gomp_places_list_len
;
682 for (count
= 0; count
< len
- 1; count
++)
683 if (!gomp_affinity_copy_place
684 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
685 gomp_places_list
[gomp_places_list_len
+ count
],
688 gomp_places_list_len
+= len
;
696 if (gomp_places_list_len
== 0)
698 gomp_error ("All places have been removed");
701 if (!gomp_affinity_finalize_place_list (false))
706 free (gomp_places_list
);
707 gomp_places_list
= NULL
;
708 gomp_places_list_len
= 0;
709 gomp_error ("Invalid value for environment variable %s", name
);
713 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
714 present and it was successfully parsed. */
717 parse_stacksize (const char *name
, unsigned long *pvalue
)
720 unsigned long value
, shift
= 10;
726 while (isspace ((unsigned char) *env
))
732 value
= strtoul (env
, &end
, 10);
736 while (isspace ((unsigned char) *end
))
740 switch (tolower ((unsigned char) *end
))
757 while (isspace ((unsigned char) *end
))
763 if (((value
<< shift
) >> shift
) != value
)
766 *pvalue
= value
<< shift
;
770 gomp_error ("Invalid value for environment variable %s", name
);
774 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
775 present and it was successfully parsed. */
778 parse_spincount (const char *name
, unsigned long long *pvalue
)
781 unsigned long long value
, mult
= 1;
787 while (isspace ((unsigned char) *env
))
792 if (strncasecmp (env
, "infinite", 8) == 0
793 || strncasecmp (env
, "infinity", 8) == 0)
801 value
= strtoull (env
, &end
, 10);
805 while (isspace ((unsigned char) *end
))
809 switch (tolower ((unsigned char) *end
))
815 mult
= 1000LL * 1000LL;
818 mult
= 1000LL * 1000LL * 1000LL;
821 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
828 while (isspace ((unsigned char) *end
))
834 if (value
> ~0ULL / mult
)
843 gomp_error ("Invalid value for environment variable %s", name
);
847 /* Parse a boolean value for environment variable NAME and store the
851 parse_boolean (const char *name
, bool *value
)
859 while (isspace ((unsigned char) *env
))
861 if (strncasecmp (env
, "true", 4) == 0)
866 else if (strncasecmp (env
, "false", 5) == 0)
873 while (isspace ((unsigned char) *env
))
876 gomp_error ("Invalid value for environment variable %s", name
);
879 /* Parse the OMP_WAIT_POLICY environment variable and store the
880 result in gomp_active_wait_policy. */
883 parse_wait_policy (void)
888 env
= getenv ("OMP_WAIT_POLICY");
892 while (isspace ((unsigned char) *env
))
894 if (strncasecmp (env
, "active", 6) == 0)
899 else if (strncasecmp (env
, "passive", 7) == 0)
906 while (isspace ((unsigned char) *env
))
910 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
914 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
915 present and it was successfully parsed. */
918 parse_affinity (bool ignore
)
920 char *env
, *end
, *start
;
922 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
923 size_t count
= 0, needed
;
925 env
= getenv ("GOMP_CPU_AFFINITY");
930 for (pass
= 0; pass
< 2; pass
++)
938 gomp_places_list_len
= 0;
939 gomp_places_list
= gomp_affinity_alloc (count
, true);
940 if (gomp_places_list
== NULL
)
945 while (isspace ((unsigned char) *env
))
949 cpu_beg
= strtoul (env
, &end
, 0);
950 if (errno
|| cpu_beg
>= 65536)
959 cpu_end
= strtoul (++env
, &end
, 0);
960 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
967 cpu_stride
= strtoul (++env
, &end
, 0);
968 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
975 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
982 void *p
= gomp_places_list
[gomp_places_list_len
];
983 gomp_affinity_init_place (p
);
984 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
985 ++gomp_places_list_len
;
986 cpu_beg
+= cpu_stride
;
990 while (isspace ((unsigned char) *env
))
995 else if (*env
== '\0')
1001 if (gomp_places_list_len
== 0)
1003 free (gomp_places_list
);
1004 gomp_places_list
= NULL
;
1010 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1016 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1019 bool display
= false;
1020 bool verbose
= false;
1023 env
= getenv ("OMP_DISPLAY_ENV");
1027 while (isspace ((unsigned char) *env
))
1029 if (strncasecmp (env
, "true", 4) == 0)
1034 else if (strncasecmp (env
, "false", 5) == 0)
1039 else if (strncasecmp (env
, "verbose", 7) == 0)
1047 while (isspace ((unsigned char) *env
))
1050 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1055 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1057 fputs (" _OPENMP = '201307'\n", stderr
);
1058 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1059 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1060 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1061 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1063 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1064 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1065 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1066 fputs ("'\n", stderr
);
1068 fprintf (stderr
, " OMP_SCHEDULE = '");
1069 switch (gomp_global_icv
.run_sched_var
)
1072 fputs ("RUNTIME", stderr
);
1075 fputs ("STATIC", stderr
);
1078 fputs ("DYNAMIC", stderr
);
1081 fputs ("GUIDED", stderr
);
1084 fputs ("AUTO", stderr
);
1087 fputs ("'\n", stderr
);
1089 fputs (" OMP_PROC_BIND = '", stderr
);
1090 switch (gomp_global_icv
.bind_var
)
1092 case omp_proc_bind_false
:
1093 fputs ("FALSE", stderr
);
1095 case omp_proc_bind_true
:
1096 fputs ("TRUE", stderr
);
1098 case omp_proc_bind_master
:
1099 fputs ("MASTER", stderr
);
1101 case omp_proc_bind_close
:
1102 fputs ("CLOSE", stderr
);
1104 case omp_proc_bind_spread
:
1105 fputs ("SPREAD", stderr
);
1108 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1109 switch (gomp_bind_var_list
[i
])
1111 case omp_proc_bind_master
:
1112 fputs (",MASTER", stderr
);
1114 case omp_proc_bind_close
:
1115 fputs (",CLOSE", stderr
);
1117 case omp_proc_bind_spread
:
1118 fputs (",SPREAD", stderr
);
1121 fputs ("'\n", stderr
);
1122 fputs (" OMP_PLACES = '", stderr
);
1123 for (i
= 0; i
< gomp_places_list_len
; i
++)
1125 fputs ("{", stderr
);
1126 gomp_affinity_print_place (gomp_places_list
[i
]);
1127 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1129 fputs ("'\n", stderr
);
1131 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1133 /* GOMP's default value is actually neither active nor passive. */
1134 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1135 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1136 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1137 gomp_global_icv
.thread_limit_var
);
1138 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1139 gomp_max_active_levels_var
);
1141 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1142 gomp_cancel_var
? "TRUE" : "FALSE");
1143 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1144 gomp_global_icv
.default_device_var
);
1148 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1149 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1150 #ifdef HAVE_INTTYPES_H
1151 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1152 (uint64_t) gomp_spin_count_var
);
1154 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1155 (unsigned long) gomp_spin_count_var
);
1159 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1163 static void __attribute__((constructor
))
1164 initialize_env (void)
1166 unsigned long thread_limit_var
, stacksize
;
1169 /* Do a compile time check that mkomp_h.pl did good job. */
1170 omp_check_defines ();
1173 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1174 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1175 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1176 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1177 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1179 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1181 gomp_global_icv
.thread_limit_var
1182 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1184 #ifndef HAVE_SYNC_BUILTINS
1185 gomp_mutex_init (&gomp_managed_threads_lock
);
1187 gomp_init_num_threads ();
1188 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1189 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1190 &gomp_global_icv
.nthreads_var
,
1191 &gomp_nthreads_var_list
,
1192 &gomp_nthreads_var_list_len
))
1193 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1194 bool ignore
= false;
1195 if (parse_bind_var ("OMP_PROC_BIND",
1196 &gomp_global_icv
.bind_var
,
1197 &gomp_bind_var_list
,
1198 &gomp_bind_var_list_len
)
1199 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1201 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1202 parsed if present in the environment. If OMP_PROC_BIND was set
1203 explictly to false, don't populate places list though. If places
1204 list was successfully set from OMP_PLACES, only parse but don't process
1205 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1206 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1207 was successfully parsed into a places list, otherwise to
1208 OMP_PROC_BIND=false. */
1209 if (parse_places_var ("OMP_PLACES", ignore
))
1211 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1212 gomp_global_icv
.bind_var
= true;
1215 if (parse_affinity (ignore
))
1217 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1218 gomp_global_icv
.bind_var
= true;
1221 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1222 gomp_init_affinity ();
1223 wait_policy
= parse_wait_policy ();
1224 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1226 /* Using a rough estimation of 100000 spins per msec,
1227 use 5 min blocking for OMP_WAIT_POLICY=active,
1228 3 msec blocking when OMP_WAIT_POLICY is not specificed
1229 and 0 when OMP_WAIT_POLICY=passive.
1230 Depending on the CPU speed, this can be e.g. 5 times longer
1231 or 5 times shorter. */
1232 if (wait_policy
> 0)
1233 gomp_spin_count_var
= 30000000000LL;
1234 else if (wait_policy
< 0)
1235 gomp_spin_count_var
= 300000LL;
1237 /* gomp_throttled_spin_count_var is used when there are more libgomp
1238 managed threads than available CPUs. Use very short spinning. */
1239 if (wait_policy
> 0)
1240 gomp_throttled_spin_count_var
= 1000LL;
1241 else if (wait_policy
< 0)
1242 gomp_throttled_spin_count_var
= 100LL;
1243 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1244 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1246 /* Not strictly environment related, but ordering constructors is tricky. */
1247 pthread_attr_init (&gomp_thread_attr
);
1248 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1250 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1251 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
))
1255 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1257 #ifdef PTHREAD_STACK_MIN
1260 if (stacksize
< PTHREAD_STACK_MIN
)
1261 gomp_error ("Stack size less than minimum of %luk",
1262 PTHREAD_STACK_MIN
/ 1024ul
1263 + (PTHREAD_STACK_MIN
% 1024 != 0));
1265 gomp_error ("Stack size larger than system limit");
1270 gomp_error ("Stack size change failed: %s", strerror (err
));
1273 handle_omp_display_env (stacksize
, wait_policy
);
1277 /* The public OpenMP API routines that access these variables. */
1280 omp_set_num_threads (int n
)
1282 struct gomp_task_icv
*icv
= gomp_icv (true);
1283 icv
->nthreads_var
= (n
> 0 ? n
: 1);
1287 omp_set_dynamic (int val
)
1289 struct gomp_task_icv
*icv
= gomp_icv (true);
1294 omp_get_dynamic (void)
1296 struct gomp_task_icv
*icv
= gomp_icv (false);
1297 return icv
->dyn_var
;
1301 omp_set_nested (int val
)
1303 struct gomp_task_icv
*icv
= gomp_icv (true);
1304 icv
->nest_var
= val
;
1308 omp_get_nested (void)
1310 struct gomp_task_icv
*icv
= gomp_icv (false);
1311 return icv
->nest_var
;
1315 omp_set_schedule (omp_sched_t kind
, int modifier
)
1317 struct gomp_task_icv
*icv
= gomp_icv (true);
1320 case omp_sched_static
:
1323 icv
->run_sched_modifier
= modifier
;
1325 case omp_sched_dynamic
:
1326 case omp_sched_guided
:
1329 icv
->run_sched_modifier
= modifier
;
1331 case omp_sched_auto
:
1336 icv
->run_sched_var
= kind
;
1340 omp_get_schedule (omp_sched_t
*kind
, int *modifier
)
1342 struct gomp_task_icv
*icv
= gomp_icv (false);
1343 *kind
= icv
->run_sched_var
;
1344 *modifier
= icv
->run_sched_modifier
;
1348 omp_get_max_threads (void)
1350 struct gomp_task_icv
*icv
= gomp_icv (false);
1351 return icv
->nthreads_var
;
1355 omp_get_thread_limit (void)
1357 struct gomp_task_icv
*icv
= gomp_icv (false);
1358 return icv
->thread_limit_var
> INT_MAX
? INT_MAX
: icv
->thread_limit_var
;
1362 omp_set_max_active_levels (int max_levels
)
1364 if (max_levels
>= 0)
1365 gomp_max_active_levels_var
= max_levels
;
1369 omp_get_max_active_levels (void)
1371 return gomp_max_active_levels_var
;
1375 omp_get_cancellation (void)
1377 return gomp_cancel_var
;
1381 omp_get_proc_bind (void)
1383 struct gomp_task_icv
*icv
= gomp_icv (false);
1384 return icv
->bind_var
;
1388 omp_set_default_device (int device_num
)
1390 struct gomp_task_icv
*icv
= gomp_icv (true);
1391 icv
->default_device_var
= device_num
>= 0 ? device_num
: 0;
1395 omp_get_default_device (void)
1397 struct gomp_task_icv
*icv
= gomp_icv (false);
1398 return icv
->default_device_var
;
1402 omp_get_num_devices (void)
1404 return gomp_get_num_devices ();
1408 omp_get_num_teams (void)
1410 /* Hardcoded to 1 on host, MIC, HSAIL? Maybe variable on PTX. */
1415 omp_get_team_num (void)
1417 /* Hardcoded to 0 on host, MIC, HSAIL? Maybe variable on PTX. */
1422 omp_is_initial_device (void)
1424 /* Hardcoded to 1 on host, should be 0 on MIC, HSAIL, PTX. */
1428 ialias (omp_set_dynamic
)
1429 ialias (omp_set_nested
)
1430 ialias (omp_set_num_threads
)
1431 ialias (omp_get_dynamic
)
1432 ialias (omp_get_nested
)
1433 ialias (omp_set_schedule
)
1434 ialias (omp_get_schedule
)
1435 ialias (omp_get_max_threads
)
1436 ialias (omp_get_thread_limit
)
1437 ialias (omp_set_max_active_levels
)
1438 ialias (omp_get_max_active_levels
)
1439 ialias (omp_get_cancellation
)
1440 ialias (omp_get_proc_bind
)
1441 ialias (omp_set_default_device
)
1442 ialias (omp_get_default_device
)
1443 ialias (omp_get_num_devices
)
1444 ialias (omp_get_num_teams
)
1445 ialias (omp_get_team_num
)
1446 ialias (omp_is_initial_device
)