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 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. */
30 #include "libgomp_f.h"
34 #ifdef HAVE_INTTYPES_H
35 # include <inttypes.h> /* For PRIu64. */
37 #ifdef STRING_WITH_STRINGS
44 # ifdef HAVE_STRINGS_H
53 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
56 struct gomp_task_icv gomp_global_icv
= {
58 .thread_limit_var
= UINT_MAX
,
59 .run_sched_var
= GFS_DYNAMIC
,
60 .run_sched_modifier
= 1,
61 .default_device_var
= 0,
64 .bind_var
= omp_proc_bind_false
,
68 unsigned long gomp_max_active_levels_var
= INT_MAX
;
69 bool gomp_cancel_var
= false;
70 #ifndef HAVE_SYNC_BUILTINS
71 gomp_mutex_t gomp_managed_threads_lock
;
73 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
74 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
75 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
76 char *gomp_bind_var_list
;
77 unsigned long gomp_bind_var_list_len
;
78 void **gomp_places_list
;
79 unsigned long gomp_places_list_len
;
81 /* Parse the OMP_SCHEDULE environment variable. */
89 env
= getenv ("OMP_SCHEDULE");
93 while (isspace ((unsigned char) *env
))
95 if (strncasecmp (env
, "static", 6) == 0)
97 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
100 else if (strncasecmp (env
, "dynamic", 7) == 0)
102 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
105 else if (strncasecmp (env
, "guided", 6) == 0)
107 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
110 else if (strncasecmp (env
, "auto", 4) == 0)
112 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
118 while (isspace ((unsigned char) *env
))
122 gomp_global_icv
.run_sched_modifier
123 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
128 while (isspace ((unsigned char) *env
))
134 value
= strtoul (env
, &end
, 10);
138 while (isspace ((unsigned char) *end
))
143 if ((int)value
!= value
)
146 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
148 gomp_global_icv
.run_sched_modifier
= value
;
152 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
156 gomp_error ("Invalid value for chunk size in "
157 "environment variable OMP_SCHEDULE");
161 /* Parse an unsigned long environment variable. Return true if one was
162 present and it was successfully parsed. */
165 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
174 while (isspace ((unsigned char) *env
))
180 value
= strtoul (env
, &end
, 10);
181 if (errno
|| (long) value
<= 0 - allow_zero
)
184 while (isspace ((unsigned char) *end
))
193 gomp_error ("Invalid value for environment variable %s", name
);
197 /* Parse a positive int environment variable. Return true if one was
198 present and it was successfully parsed. */
201 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
204 if (!parse_unsigned_long (name
, &value
, allow_zero
))
208 gomp_error ("Invalid value for environment variable %s", name
);
211 *pvalue
= (int) value
;
215 /* Parse an unsigned long list environment variable. Return true if one was
216 present and it was successfully parsed. */
219 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
220 unsigned long **pvalues
,
221 unsigned long *pnvalues
)
224 unsigned long value
, *values
= NULL
;
230 while (isspace ((unsigned char) *env
))
236 value
= strtoul (env
, &end
, 10);
237 if (errno
|| (long) value
<= 0)
240 while (isspace ((unsigned char) *end
))
246 unsigned long nvalues
= 0, nalloced
= 0;
251 if (nvalues
== nalloced
)
254 nalloced
= nalloced
? nalloced
* 2 : 16;
255 n
= realloc (values
, nalloced
* sizeof (unsigned long));
259 gomp_error ("Out of memory while trying to parse"
260 " environment variable %s", name
);
265 values
[nvalues
++] = value
;
268 while (isspace ((unsigned char) *env
))
274 value
= strtoul (env
, &end
, 10);
275 if (errno
|| (long) value
<= 0)
278 values
[nvalues
++] = value
;
279 while (isspace ((unsigned char) *end
))
287 *p1stvalue
= values
[0];
300 gomp_error ("Invalid value for environment variable %s", name
);
304 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
305 enum values. Return true if one was present and it was successfully
309 parse_bind_var (const char *name
, char *p1stvalue
,
310 char **pvalues
, unsigned long *pnvalues
)
313 char value
= omp_proc_bind_false
, *values
= NULL
;
315 static struct proc_bind_kinds
319 omp_proc_bind_t kind
;
322 { "false", 5, omp_proc_bind_false
},
323 { "true", 4, omp_proc_bind_true
},
324 { "master", 6, omp_proc_bind_master
},
325 { "close", 5, omp_proc_bind_close
},
326 { "spread", 6, omp_proc_bind_spread
}
333 while (isspace ((unsigned char) *env
))
338 for (i
= 0; i
< 5; i
++)
339 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
341 value
= kinds
[i
].kind
;
348 while (isspace ((unsigned char) *env
))
354 unsigned long nvalues
= 0, nalloced
= 0;
356 if (value
== omp_proc_bind_false
357 || value
== omp_proc_bind_true
)
363 if (nvalues
== nalloced
)
366 nalloced
= nalloced
? nalloced
* 2 : 16;
367 n
= realloc (values
, nalloced
);
371 gomp_error ("Out of memory while trying to parse"
372 " environment variable %s", name
);
377 values
[nvalues
++] = value
;
380 while (isspace ((unsigned char) *env
))
385 for (i
= 2; i
< 5; i
++)
386 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
388 value
= kinds
[i
].kind
;
395 values
[nvalues
++] = value
;
396 while (isspace ((unsigned char) *env
))
404 *p1stvalue
= values
[0];
417 gomp_error ("Invalid value for environment variable %s", name
);
422 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
425 char *env
= *envp
, *start
;
426 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
427 unsigned long len
= 1;
430 bool any_negate
= false;
432 while (isspace ((unsigned char) *env
))
438 while (isspace ((unsigned char) *env
))
444 while (isspace ((unsigned char) *env
))
447 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
452 unsigned long this_num
, this_len
= 1;
453 long this_stride
= 1;
454 bool this_negate
= (*env
== '!');
457 if (gomp_places_list
)
460 while (isspace ((unsigned char) *env
))
465 this_num
= strtoul (env
, &env
, 10);
468 while (isspace ((unsigned char) *env
))
473 while (isspace ((unsigned char) *env
))
476 this_len
= strtoul (env
, &env
, 10);
477 if (errno
|| this_len
== 0)
479 while (isspace ((unsigned char) *env
))
484 while (isspace ((unsigned char) *env
))
487 this_stride
= strtol (env
, &env
, 10);
490 while (isspace ((unsigned char) *env
))
494 if (this_negate
&& this_len
!= 1)
496 if (gomp_places_list
&& pass
== this_negate
)
500 if (!gomp_affinity_remove_cpu (p
, this_num
))
503 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
517 while (isspace ((unsigned char) *env
))
522 while (isspace ((unsigned char) *env
))
525 len
= strtoul (env
, &env
, 10);
526 if (errno
|| len
== 0 || len
>= 65536)
528 while (isspace ((unsigned char) *env
))
533 while (isspace ((unsigned char) *env
))
536 stride
= strtol (env
, &env
, 10);
539 while (isspace ((unsigned char) *env
))
543 if (*negatep
&& len
!= 1)
552 parse_places_var (const char *name
, bool ignore
)
554 char *env
= getenv (name
), *end
;
555 bool any_negate
= false;
557 unsigned long count
= 0;
561 while (isspace ((unsigned char) *env
))
566 if (strncasecmp (env
, "threads", 7) == 0)
571 else if (strncasecmp (env
, "cores", 5) == 0)
576 else if (strncasecmp (env
, "sockets", 7) == 0)
584 while (isspace ((unsigned char) *env
))
590 while (isspace ((unsigned char) *env
))
594 count
= strtoul (env
, &end
, 10);
598 while (isspace ((unsigned char) *env
))
603 while (isspace ((unsigned char) *env
))
612 return gomp_affinity_init_level (level
, count
, false);
622 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
645 gomp_places_list_len
= 0;
646 gomp_places_list
= gomp_affinity_alloc (count
, false);
647 if (gomp_places_list
== NULL
)
655 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
656 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
661 for (count
= 0; count
< gomp_places_list_len
; count
++)
662 if (gomp_affinity_same_place
663 (gomp_places_list
[count
],
664 gomp_places_list
[gomp_places_list_len
]))
666 if (count
== gomp_places_list_len
)
668 gomp_error ("Trying to remove a non-existing place from list "
672 p
= gomp_places_list
[count
];
673 memmove (&gomp_places_list
[count
],
674 &gomp_places_list
[count
+ 1],
675 (gomp_places_list_len
- count
- 1) * sizeof (void *));
676 --gomp_places_list_len
;
677 gomp_places_list
[gomp_places_list_len
] = p
;
680 ++gomp_places_list_len
;
683 for (count
= 0; count
< len
- 1; count
++)
684 if (!gomp_affinity_copy_place
685 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
686 gomp_places_list
[gomp_places_list_len
+ count
],
689 gomp_places_list_len
+= len
;
697 if (gomp_places_list_len
== 0)
699 gomp_error ("All places have been removed");
702 if (!gomp_affinity_finalize_place_list (false))
707 free (gomp_places_list
);
708 gomp_places_list
= NULL
;
709 gomp_places_list_len
= 0;
710 gomp_error ("Invalid value for environment variable %s", name
);
714 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
715 present and it was successfully parsed. */
718 parse_stacksize (const char *name
, unsigned long *pvalue
)
721 unsigned long value
, shift
= 10;
727 while (isspace ((unsigned char) *env
))
733 value
= strtoul (env
, &end
, 10);
737 while (isspace ((unsigned char) *end
))
741 switch (tolower ((unsigned char) *end
))
758 while (isspace ((unsigned char) *end
))
764 if (((value
<< shift
) >> shift
) != value
)
767 *pvalue
= value
<< shift
;
771 gomp_error ("Invalid value for environment variable %s", name
);
775 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
776 present and it was successfully parsed. */
779 parse_spincount (const char *name
, unsigned long long *pvalue
)
782 unsigned long long value
, mult
= 1;
788 while (isspace ((unsigned char) *env
))
793 if (strncasecmp (env
, "infinite", 8) == 0
794 || strncasecmp (env
, "infinity", 8) == 0)
802 value
= strtoull (env
, &end
, 10);
806 while (isspace ((unsigned char) *end
))
810 switch (tolower ((unsigned char) *end
))
816 mult
= 1000LL * 1000LL;
819 mult
= 1000LL * 1000LL * 1000LL;
822 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
829 while (isspace ((unsigned char) *end
))
835 if (value
> ~0ULL / mult
)
844 gomp_error ("Invalid value for environment variable %s", name
);
848 /* Parse a boolean value for environment variable NAME and store the
852 parse_boolean (const char *name
, bool *value
)
860 while (isspace ((unsigned char) *env
))
862 if (strncasecmp (env
, "true", 4) == 0)
867 else if (strncasecmp (env
, "false", 5) == 0)
874 while (isspace ((unsigned char) *env
))
877 gomp_error ("Invalid value for environment variable %s", name
);
880 /* Parse the OMP_WAIT_POLICY environment variable and store the
881 result in gomp_active_wait_policy. */
884 parse_wait_policy (void)
889 env
= getenv ("OMP_WAIT_POLICY");
893 while (isspace ((unsigned char) *env
))
895 if (strncasecmp (env
, "active", 6) == 0)
900 else if (strncasecmp (env
, "passive", 7) == 0)
907 while (isspace ((unsigned char) *env
))
911 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
915 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
916 present and it was successfully parsed. */
919 parse_affinity (bool ignore
)
921 char *env
, *end
, *start
;
923 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
924 size_t count
= 0, needed
;
926 env
= getenv ("GOMP_CPU_AFFINITY");
931 for (pass
= 0; pass
< 2; pass
++)
939 gomp_places_list_len
= 0;
940 gomp_places_list
= gomp_affinity_alloc (count
, true);
941 if (gomp_places_list
== NULL
)
946 while (isspace ((unsigned char) *env
))
950 cpu_beg
= strtoul (env
, &end
, 0);
951 if (errno
|| cpu_beg
>= 65536)
960 cpu_end
= strtoul (++env
, &end
, 0);
961 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
968 cpu_stride
= strtoul (++env
, &end
, 0);
969 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
976 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
983 void *p
= gomp_places_list
[gomp_places_list_len
];
984 gomp_affinity_init_place (p
);
985 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
986 ++gomp_places_list_len
;
987 cpu_beg
+= cpu_stride
;
991 while (isspace ((unsigned char) *env
))
996 else if (*env
== '\0')
1002 if (gomp_places_list_len
== 0)
1004 free (gomp_places_list
);
1005 gomp_places_list
= NULL
;
1011 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1017 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1020 bool display
= false;
1021 bool verbose
= false;
1024 env
= getenv ("OMP_DISPLAY_ENV");
1028 while (isspace ((unsigned char) *env
))
1030 if (strncasecmp (env
, "true", 4) == 0)
1035 else if (strncasecmp (env
, "false", 5) == 0)
1040 else if (strncasecmp (env
, "verbose", 7) == 0)
1048 while (isspace ((unsigned char) *env
))
1051 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1056 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1058 fputs (" _OPENMP = '201307'\n", stderr
);
1059 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1060 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1061 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1062 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1064 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1065 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1066 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1067 fputs ("'\n", stderr
);
1069 fprintf (stderr
, " OMP_SCHEDULE = '");
1070 switch (gomp_global_icv
.run_sched_var
)
1073 fputs ("RUNTIME", stderr
);
1076 fputs ("STATIC", stderr
);
1079 fputs ("DYNAMIC", stderr
);
1082 fputs ("GUIDED", stderr
);
1085 fputs ("AUTO", stderr
);
1088 fputs ("'\n", stderr
);
1090 fputs (" OMP_PROC_BIND = '", stderr
);
1091 switch (gomp_global_icv
.bind_var
)
1093 case omp_proc_bind_false
:
1094 fputs ("FALSE", stderr
);
1096 case omp_proc_bind_true
:
1097 fputs ("TRUE", stderr
);
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 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1110 switch (gomp_bind_var_list
[i
])
1112 case omp_proc_bind_master
:
1113 fputs (",MASTER", stderr
);
1115 case omp_proc_bind_close
:
1116 fputs (",CLOSE", stderr
);
1118 case omp_proc_bind_spread
:
1119 fputs (",SPREAD", stderr
);
1122 fputs ("'\n", stderr
);
1123 fputs (" OMP_PLACES = '", stderr
);
1124 for (i
= 0; i
< gomp_places_list_len
; i
++)
1126 fputs ("{", stderr
);
1127 gomp_affinity_print_place (gomp_places_list
[i
]);
1128 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1130 fputs ("'\n", stderr
);
1132 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1134 /* GOMP's default value is actually neither active nor passive. */
1135 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1136 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1137 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1138 gomp_global_icv
.thread_limit_var
);
1139 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1140 gomp_max_active_levels_var
);
1142 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1143 gomp_cancel_var
? "TRUE" : "FALSE");
1144 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1145 gomp_global_icv
.default_device_var
);
1149 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1150 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1151 #ifdef HAVE_INTTYPES_H
1152 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1153 (uint64_t) gomp_spin_count_var
);
1155 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1156 (unsigned long) gomp_spin_count_var
);
1160 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1164 static void __attribute__((constructor
))
1165 initialize_env (void)
1167 unsigned long thread_limit_var
, stacksize
;
1170 /* Do a compile time check that mkomp_h.pl did good job. */
1171 omp_check_defines ();
1174 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1175 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1176 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1177 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1178 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1180 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1182 gomp_global_icv
.thread_limit_var
1183 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1185 #ifndef HAVE_SYNC_BUILTINS
1186 gomp_mutex_init (&gomp_managed_threads_lock
);
1188 gomp_init_num_threads ();
1189 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1190 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1191 &gomp_global_icv
.nthreads_var
,
1192 &gomp_nthreads_var_list
,
1193 &gomp_nthreads_var_list_len
))
1194 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1195 bool ignore
= false;
1196 if (parse_bind_var ("OMP_PROC_BIND",
1197 &gomp_global_icv
.bind_var
,
1198 &gomp_bind_var_list
,
1199 &gomp_bind_var_list_len
)
1200 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1202 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1203 parsed if present in the environment. If OMP_PROC_BIND was set
1204 explictly to false, don't populate places list though. If places
1205 list was successfully set from OMP_PLACES, only parse but don't process
1206 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1207 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1208 was successfully parsed into a places list, otherwise to
1209 OMP_PROC_BIND=false. */
1210 if (parse_places_var ("OMP_PLACES", ignore
))
1212 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1213 gomp_global_icv
.bind_var
= true;
1216 if (parse_affinity (ignore
))
1218 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1219 gomp_global_icv
.bind_var
= true;
1222 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1223 gomp_init_affinity ();
1224 wait_policy
= parse_wait_policy ();
1225 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1227 /* Using a rough estimation of 100000 spins per msec,
1228 use 5 min blocking for OMP_WAIT_POLICY=active,
1229 3 msec blocking when OMP_WAIT_POLICY is not specificed
1230 and 0 when OMP_WAIT_POLICY=passive.
1231 Depending on the CPU speed, this can be e.g. 5 times longer
1232 or 5 times shorter. */
1233 if (wait_policy
> 0)
1234 gomp_spin_count_var
= 30000000000LL;
1235 else if (wait_policy
< 0)
1236 gomp_spin_count_var
= 300000LL;
1238 /* gomp_throttled_spin_count_var is used when there are more libgomp
1239 managed threads than available CPUs. Use very short spinning. */
1240 if (wait_policy
> 0)
1241 gomp_throttled_spin_count_var
= 1000LL;
1242 else if (wait_policy
< 0)
1243 gomp_throttled_spin_count_var
= 100LL;
1244 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1245 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1247 /* Not strictly environment related, but ordering constructors is tricky. */
1248 pthread_attr_init (&gomp_thread_attr
);
1249 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1251 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1252 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
))
1256 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1258 #ifdef PTHREAD_STACK_MIN
1261 if (stacksize
< PTHREAD_STACK_MIN
)
1262 gomp_error ("Stack size less than minimum of %luk",
1263 PTHREAD_STACK_MIN
/ 1024ul
1264 + (PTHREAD_STACK_MIN
% 1024 != 0));
1266 gomp_error ("Stack size larger than system limit");
1271 gomp_error ("Stack size change failed: %s", strerror (err
));
1274 handle_omp_display_env (stacksize
, wait_policy
);
1278 /* The public OpenMP API routines that access these variables. */
1281 omp_set_num_threads (int n
)
1283 struct gomp_task_icv
*icv
= gomp_icv (true);
1284 icv
->nthreads_var
= (n
> 0 ? n
: 1);
1288 omp_set_dynamic (int val
)
1290 struct gomp_task_icv
*icv
= gomp_icv (true);
1295 omp_get_dynamic (void)
1297 struct gomp_task_icv
*icv
= gomp_icv (false);
1298 return icv
->dyn_var
;
1302 omp_set_nested (int val
)
1304 struct gomp_task_icv
*icv
= gomp_icv (true);
1305 icv
->nest_var
= val
;
1309 omp_get_nested (void)
1311 struct gomp_task_icv
*icv
= gomp_icv (false);
1312 return icv
->nest_var
;
1316 omp_set_schedule (omp_sched_t kind
, int modifier
)
1318 struct gomp_task_icv
*icv
= gomp_icv (true);
1321 case omp_sched_static
:
1324 icv
->run_sched_modifier
= modifier
;
1326 case omp_sched_dynamic
:
1327 case omp_sched_guided
:
1330 icv
->run_sched_modifier
= modifier
;
1332 case omp_sched_auto
:
1337 icv
->run_sched_var
= kind
;
1341 omp_get_schedule (omp_sched_t
*kind
, int *modifier
)
1343 struct gomp_task_icv
*icv
= gomp_icv (false);
1344 *kind
= icv
->run_sched_var
;
1345 *modifier
= icv
->run_sched_modifier
;
1349 omp_get_max_threads (void)
1351 struct gomp_task_icv
*icv
= gomp_icv (false);
1352 return icv
->nthreads_var
;
1356 omp_get_thread_limit (void)
1358 struct gomp_task_icv
*icv
= gomp_icv (false);
1359 return icv
->thread_limit_var
> INT_MAX
? INT_MAX
: icv
->thread_limit_var
;
1363 omp_set_max_active_levels (int max_levels
)
1365 if (max_levels
>= 0)
1366 gomp_max_active_levels_var
= max_levels
;
1370 omp_get_max_active_levels (void)
1372 return gomp_max_active_levels_var
;
1376 omp_get_cancellation (void)
1378 return gomp_cancel_var
;
1382 omp_get_proc_bind (void)
1384 struct gomp_task_icv
*icv
= gomp_icv (false);
1385 return icv
->bind_var
;
1389 omp_set_default_device (int device_num
)
1391 struct gomp_task_icv
*icv
= gomp_icv (true);
1392 icv
->default_device_var
= device_num
>= 0 ? device_num
: 0;
1396 omp_get_default_device (void)
1398 struct gomp_task_icv
*icv
= gomp_icv (false);
1399 return icv
->default_device_var
;
1403 omp_get_num_devices (void)
1405 return gomp_get_num_devices ();
1409 omp_get_num_teams (void)
1411 /* Hardcoded to 1 on host, MIC, HSAIL? Maybe variable on PTX. */
1416 omp_get_team_num (void)
1418 /* Hardcoded to 0 on host, MIC, HSAIL? Maybe variable on PTX. */
1423 omp_is_initial_device (void)
1425 /* Hardcoded to 1 on host, should be 0 on MIC, HSAIL, PTX. */
1429 ialias (omp_set_dynamic
)
1430 ialias (omp_set_nested
)
1431 ialias (omp_set_num_threads
)
1432 ialias (omp_get_dynamic
)
1433 ialias (omp_get_nested
)
1434 ialias (omp_set_schedule
)
1435 ialias (omp_get_schedule
)
1436 ialias (omp_get_max_threads
)
1437 ialias (omp_get_thread_limit
)
1438 ialias (omp_set_max_active_levels
)
1439 ialias (omp_get_max_active_levels
)
1440 ialias (omp_get_cancellation
)
1441 ialias (omp_get_proc_bind
)
1442 ialias (omp_set_default_device
)
1443 ialias (omp_get_default_device
)
1444 ialias (omp_get_num_devices
)
1445 ialias (omp_get_num_teams
)
1446 ialias (omp_get_team_num
)
1447 ialias (omp_is_initial_device
)