1 /* Copyright (C) 2005-2014 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"
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
;
82 char* goacc_device_type
;
84 /* Parse the OMP_SCHEDULE environment variable. */
92 env
= getenv ("OMP_SCHEDULE");
96 while (isspace ((unsigned char) *env
))
98 if (strncasecmp (env
, "static", 6) == 0)
100 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
103 else if (strncasecmp (env
, "dynamic", 7) == 0)
105 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
108 else if (strncasecmp (env
, "guided", 6) == 0)
110 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
113 else if (strncasecmp (env
, "auto", 4) == 0)
115 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
121 while (isspace ((unsigned char) *env
))
125 gomp_global_icv
.run_sched_modifier
126 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
131 while (isspace ((unsigned char) *env
))
137 value
= strtoul (env
, &end
, 10);
141 while (isspace ((unsigned char) *end
))
146 if ((int)value
!= value
)
149 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
151 gomp_global_icv
.run_sched_modifier
= value
;
155 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
159 gomp_error ("Invalid value for chunk size in "
160 "environment variable OMP_SCHEDULE");
164 /* Parse an unsigned long environment variable. Return true if one was
165 present and it was successfully parsed. */
168 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
177 while (isspace ((unsigned char) *env
))
183 value
= strtoul (env
, &end
, 10);
184 if (errno
|| (long) value
<= 0 - allow_zero
)
187 while (isspace ((unsigned char) *end
))
196 gomp_error ("Invalid value for environment variable %s", name
);
200 /* Parse a positive int environment variable. Return true if one was
201 present and it was successfully parsed. */
204 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
207 if (!parse_unsigned_long (name
, &value
, allow_zero
))
211 gomp_error ("Invalid value for environment variable %s", name
);
214 *pvalue
= (int) value
;
218 /* Parse an unsigned long list environment variable. Return true if one was
219 present and it was successfully parsed. */
222 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
223 unsigned long **pvalues
,
224 unsigned long *pnvalues
)
227 unsigned long value
, *values
= NULL
;
233 while (isspace ((unsigned char) *env
))
239 value
= strtoul (env
, &end
, 10);
240 if (errno
|| (long) value
<= 0)
243 while (isspace ((unsigned char) *end
))
249 unsigned long nvalues
= 0, nalloced
= 0;
254 if (nvalues
== nalloced
)
257 nalloced
= nalloced
? nalloced
* 2 : 16;
258 n
= realloc (values
, nalloced
* sizeof (unsigned long));
262 gomp_error ("Out of memory while trying to parse"
263 " environment variable %s", name
);
268 values
[nvalues
++] = value
;
271 while (isspace ((unsigned char) *env
))
277 value
= strtoul (env
, &end
, 10);
278 if (errno
|| (long) value
<= 0)
281 values
[nvalues
++] = value
;
282 while (isspace ((unsigned char) *end
))
290 *p1stvalue
= values
[0];
303 gomp_error ("Invalid value for environment variable %s", name
);
307 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
308 enum values. Return true if one was present and it was successfully
312 parse_bind_var (const char *name
, char *p1stvalue
,
313 char **pvalues
, unsigned long *pnvalues
)
316 char value
= omp_proc_bind_false
, *values
= NULL
;
318 static struct proc_bind_kinds
322 omp_proc_bind_t kind
;
325 { "false", 5, omp_proc_bind_false
},
326 { "true", 4, omp_proc_bind_true
},
327 { "master", 6, omp_proc_bind_master
},
328 { "close", 5, omp_proc_bind_close
},
329 { "spread", 6, omp_proc_bind_spread
}
336 while (isspace ((unsigned char) *env
))
341 for (i
= 0; i
< 5; i
++)
342 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
344 value
= kinds
[i
].kind
;
351 while (isspace ((unsigned char) *env
))
357 unsigned long nvalues
= 0, nalloced
= 0;
359 if (value
== omp_proc_bind_false
360 || value
== omp_proc_bind_true
)
366 if (nvalues
== nalloced
)
369 nalloced
= nalloced
? nalloced
* 2 : 16;
370 n
= realloc (values
, nalloced
);
374 gomp_error ("Out of memory while trying to parse"
375 " environment variable %s", name
);
380 values
[nvalues
++] = value
;
383 while (isspace ((unsigned char) *env
))
388 for (i
= 2; i
< 5; i
++)
389 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
391 value
= kinds
[i
].kind
;
398 values
[nvalues
++] = value
;
399 while (isspace ((unsigned char) *env
))
407 *p1stvalue
= values
[0];
420 gomp_error ("Invalid value for environment variable %s", name
);
425 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
428 char *env
= *envp
, *start
;
429 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
430 unsigned long len
= 1;
433 bool any_negate
= false;
435 while (isspace ((unsigned char) *env
))
441 while (isspace ((unsigned char) *env
))
447 while (isspace ((unsigned char) *env
))
450 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
455 unsigned long this_num
, this_len
= 1;
456 long this_stride
= 1;
457 bool this_negate
= (*env
== '!');
460 if (gomp_places_list
)
463 while (isspace ((unsigned char) *env
))
468 this_num
= strtoul (env
, &env
, 10);
471 while (isspace ((unsigned char) *env
))
476 while (isspace ((unsigned char) *env
))
479 this_len
= strtoul (env
, &env
, 10);
480 if (errno
|| this_len
== 0)
482 while (isspace ((unsigned char) *env
))
487 while (isspace ((unsigned char) *env
))
490 this_stride
= strtol (env
, &env
, 10);
493 while (isspace ((unsigned char) *env
))
497 if (this_negate
&& this_len
!= 1)
499 if (gomp_places_list
&& pass
== this_negate
)
503 if (!gomp_affinity_remove_cpu (p
, this_num
))
506 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
520 while (isspace ((unsigned char) *env
))
525 while (isspace ((unsigned char) *env
))
528 len
= strtoul (env
, &env
, 10);
529 if (errno
|| len
== 0 || len
>= 65536)
531 while (isspace ((unsigned char) *env
))
536 while (isspace ((unsigned char) *env
))
539 stride
= strtol (env
, &env
, 10);
542 while (isspace ((unsigned char) *env
))
546 if (*negatep
&& len
!= 1)
555 parse_places_var (const char *name
, bool ignore
)
557 char *env
= getenv (name
), *end
;
558 bool any_negate
= false;
560 unsigned long count
= 0;
564 while (isspace ((unsigned char) *env
))
569 if (strncasecmp (env
, "threads", 7) == 0)
574 else if (strncasecmp (env
, "cores", 5) == 0)
579 else if (strncasecmp (env
, "sockets", 7) == 0)
587 while (isspace ((unsigned char) *env
))
593 while (isspace ((unsigned char) *env
))
597 count
= strtoul (env
, &end
, 10);
601 while (isspace ((unsigned char) *env
))
606 while (isspace ((unsigned char) *env
))
615 return gomp_affinity_init_level (level
, count
, false);
625 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
648 gomp_places_list_len
= 0;
649 gomp_places_list
= gomp_affinity_alloc (count
, false);
650 if (gomp_places_list
== NULL
)
658 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
659 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
664 for (count
= 0; count
< gomp_places_list_len
; count
++)
665 if (gomp_affinity_same_place
666 (gomp_places_list
[count
],
667 gomp_places_list
[gomp_places_list_len
]))
669 if (count
== gomp_places_list_len
)
671 gomp_error ("Trying to remove a non-existing place from list "
675 p
= gomp_places_list
[count
];
676 memmove (&gomp_places_list
[count
],
677 &gomp_places_list
[count
+ 1],
678 (gomp_places_list_len
- count
- 1) * sizeof (void *));
679 --gomp_places_list_len
;
680 gomp_places_list
[gomp_places_list_len
] = p
;
683 ++gomp_places_list_len
;
686 for (count
= 0; count
< len
- 1; count
++)
687 if (!gomp_affinity_copy_place
688 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
689 gomp_places_list
[gomp_places_list_len
+ count
],
692 gomp_places_list_len
+= len
;
700 if (gomp_places_list_len
== 0)
702 gomp_error ("All places have been removed");
705 if (!gomp_affinity_finalize_place_list (false))
710 free (gomp_places_list
);
711 gomp_places_list
= NULL
;
712 gomp_places_list_len
= 0;
713 gomp_error ("Invalid value for environment variable %s", name
);
717 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
718 present and it was successfully parsed. */
721 parse_stacksize (const char *name
, unsigned long *pvalue
)
724 unsigned long value
, shift
= 10;
730 while (isspace ((unsigned char) *env
))
736 value
= strtoul (env
, &end
, 10);
740 while (isspace ((unsigned char) *end
))
744 switch (tolower ((unsigned char) *end
))
761 while (isspace ((unsigned char) *end
))
767 if (((value
<< shift
) >> shift
) != value
)
770 *pvalue
= value
<< shift
;
774 gomp_error ("Invalid value for environment variable %s", name
);
778 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
779 present and it was successfully parsed. */
782 parse_spincount (const char *name
, unsigned long long *pvalue
)
785 unsigned long long value
, mult
= 1;
791 while (isspace ((unsigned char) *env
))
796 if (strncasecmp (env
, "infinite", 8) == 0
797 || strncasecmp (env
, "infinity", 8) == 0)
805 value
= strtoull (env
, &end
, 10);
809 while (isspace ((unsigned char) *end
))
813 switch (tolower ((unsigned char) *end
))
819 mult
= 1000LL * 1000LL;
822 mult
= 1000LL * 1000LL * 1000LL;
825 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
832 while (isspace ((unsigned char) *end
))
838 if (value
> ~0ULL / mult
)
847 gomp_error ("Invalid value for environment variable %s", name
);
851 /* Parse a boolean value for environment variable NAME and store the
855 parse_boolean (const char *name
, bool *value
)
863 while (isspace ((unsigned char) *env
))
865 if (strncasecmp (env
, "true", 4) == 0)
870 else if (strncasecmp (env
, "false", 5) == 0)
877 while (isspace ((unsigned char) *env
))
880 gomp_error ("Invalid value for environment variable %s", name
);
883 /* Parse the OMP_WAIT_POLICY environment variable and store the
884 result in gomp_active_wait_policy. */
887 parse_wait_policy (void)
892 env
= getenv ("OMP_WAIT_POLICY");
896 while (isspace ((unsigned char) *env
))
898 if (strncasecmp (env
, "active", 6) == 0)
903 else if (strncasecmp (env
, "passive", 7) == 0)
910 while (isspace ((unsigned char) *env
))
914 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
918 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
919 present and it was successfully parsed. */
922 parse_affinity (bool ignore
)
924 char *env
, *end
, *start
;
926 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
927 size_t count
= 0, needed
;
929 env
= getenv ("GOMP_CPU_AFFINITY");
934 for (pass
= 0; pass
< 2; pass
++)
942 gomp_places_list_len
= 0;
943 gomp_places_list
= gomp_affinity_alloc (count
, true);
944 if (gomp_places_list
== NULL
)
949 while (isspace ((unsigned char) *env
))
953 cpu_beg
= strtoul (env
, &end
, 0);
954 if (errno
|| cpu_beg
>= 65536)
963 cpu_end
= strtoul (++env
, &end
, 0);
964 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
971 cpu_stride
= strtoul (++env
, &end
, 0);
972 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
979 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
986 void *p
= gomp_places_list
[gomp_places_list_len
];
987 gomp_affinity_init_place (p
);
988 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
989 ++gomp_places_list_len
;
990 cpu_beg
+= cpu_stride
;
994 while (isspace ((unsigned char) *env
))
999 else if (*env
== '\0')
1005 if (gomp_places_list_len
== 0)
1007 free (gomp_places_list
);
1008 gomp_places_list
= NULL
;
1014 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1020 goacc_parse_device_num (void)
1022 const char *env
= getenv ("ACC_DEVICE_NUM");
1023 int default_num
= -1;
1025 if (env
&& *env
!= '\0')
1028 default_num
= strtol (env
, &end
, 0);
1030 if (*end
|| default_num
< 0)
1036 goacc_device_num
= default_num
;
1040 goacc_parse_device_type (void)
1042 const char *env
= getenv ("ACC_DEVICE_TYPE");
1044 if (env
&& *env
!= '\0')
1045 goacc_device_type
= strdup (env
);
1047 goacc_device_type
= NULL
;
1051 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1054 bool display
= false;
1055 bool verbose
= false;
1058 env
= getenv ("OMP_DISPLAY_ENV");
1062 while (isspace ((unsigned char) *env
))
1064 if (strncasecmp (env
, "true", 4) == 0)
1069 else if (strncasecmp (env
, "false", 5) == 0)
1074 else if (strncasecmp (env
, "verbose", 7) == 0)
1082 while (isspace ((unsigned char) *env
))
1085 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1090 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1092 fputs (" _OPENMP = '201307'\n", stderr
);
1093 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1094 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1095 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1096 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1098 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1099 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1100 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1101 fputs ("'\n", stderr
);
1103 fprintf (stderr
, " OMP_SCHEDULE = '");
1104 switch (gomp_global_icv
.run_sched_var
)
1107 fputs ("RUNTIME", stderr
);
1110 fputs ("STATIC", stderr
);
1113 fputs ("DYNAMIC", stderr
);
1116 fputs ("GUIDED", stderr
);
1119 fputs ("AUTO", stderr
);
1122 fputs ("'\n", stderr
);
1124 fputs (" OMP_PROC_BIND = '", stderr
);
1125 switch (gomp_global_icv
.bind_var
)
1127 case omp_proc_bind_false
:
1128 fputs ("FALSE", stderr
);
1130 case omp_proc_bind_true
:
1131 fputs ("TRUE", stderr
);
1133 case omp_proc_bind_master
:
1134 fputs ("MASTER", stderr
);
1136 case omp_proc_bind_close
:
1137 fputs ("CLOSE", stderr
);
1139 case omp_proc_bind_spread
:
1140 fputs ("SPREAD", stderr
);
1143 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1144 switch (gomp_bind_var_list
[i
])
1146 case omp_proc_bind_master
:
1147 fputs (",MASTER", stderr
);
1149 case omp_proc_bind_close
:
1150 fputs (",CLOSE", stderr
);
1152 case omp_proc_bind_spread
:
1153 fputs (",SPREAD", stderr
);
1156 fputs ("'\n", stderr
);
1157 fputs (" OMP_PLACES = '", stderr
);
1158 for (i
= 0; i
< gomp_places_list_len
; i
++)
1160 fputs ("{", stderr
);
1161 gomp_affinity_print_place (gomp_places_list
[i
]);
1162 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1164 fputs ("'\n", stderr
);
1166 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1168 /* GOMP's default value is actually neither active nor passive. */
1169 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1170 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1171 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1172 gomp_global_icv
.thread_limit_var
);
1173 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1174 gomp_max_active_levels_var
);
1176 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1177 gomp_cancel_var
? "TRUE" : "FALSE");
1178 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1179 gomp_global_icv
.default_device_var
);
1183 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1184 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1185 #ifdef HAVE_INTTYPES_H
1186 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1187 (uint64_t) gomp_spin_count_var
);
1189 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1190 (unsigned long) gomp_spin_count_var
);
1194 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1198 static void __attribute__((constructor
))
1199 initialize_env (void)
1201 unsigned long thread_limit_var
, stacksize
;
1204 /* Do a compile time check that mkomp_h.pl did good job. */
1205 omp_check_defines ();
1208 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1209 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1210 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1211 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1212 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1214 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1216 gomp_global_icv
.thread_limit_var
1217 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1219 parse_int ("GCC_ACC_NOTIFY", &gomp_global_icv
.acc_notify_var
, true);
1220 #ifndef HAVE_SYNC_BUILTINS
1221 gomp_mutex_init (&gomp_managed_threads_lock
);
1223 gomp_init_num_threads ();
1224 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1225 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1226 &gomp_global_icv
.nthreads_var
,
1227 &gomp_nthreads_var_list
,
1228 &gomp_nthreads_var_list_len
))
1229 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1230 bool ignore
= false;
1231 if (parse_bind_var ("OMP_PROC_BIND",
1232 &gomp_global_icv
.bind_var
,
1233 &gomp_bind_var_list
,
1234 &gomp_bind_var_list_len
)
1235 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1237 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1238 parsed if present in the environment. If OMP_PROC_BIND was set
1239 explictly to false, don't populate places list though. If places
1240 list was successfully set from OMP_PLACES, only parse but don't process
1241 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1242 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1243 was successfully parsed into a places list, otherwise to
1244 OMP_PROC_BIND=false. */
1245 if (parse_places_var ("OMP_PLACES", ignore
))
1247 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1248 gomp_global_icv
.bind_var
= true;
1251 if (parse_affinity (ignore
))
1253 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1254 gomp_global_icv
.bind_var
= true;
1257 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1258 gomp_init_affinity ();
1259 wait_policy
= parse_wait_policy ();
1260 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1262 /* Using a rough estimation of 100000 spins per msec,
1263 use 5 min blocking for OMP_WAIT_POLICY=active,
1264 3 msec blocking when OMP_WAIT_POLICY is not specificed
1265 and 0 when OMP_WAIT_POLICY=passive.
1266 Depending on the CPU speed, this can be e.g. 5 times longer
1267 or 5 times shorter. */
1268 if (wait_policy
> 0)
1269 gomp_spin_count_var
= 30000000000LL;
1270 else if (wait_policy
< 0)
1271 gomp_spin_count_var
= 300000LL;
1273 /* gomp_throttled_spin_count_var is used when there are more libgomp
1274 managed threads than available CPUs. Use very short spinning. */
1275 if (wait_policy
> 0)
1276 gomp_throttled_spin_count_var
= 1000LL;
1277 else if (wait_policy
< 0)
1278 gomp_throttled_spin_count_var
= 100LL;
1279 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1280 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1282 /* Not strictly environment related, but ordering constructors is tricky. */
1283 pthread_attr_init (&gomp_thread_attr
);
1284 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1286 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1287 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
))
1291 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1293 #ifdef PTHREAD_STACK_MIN
1296 if (stacksize
< PTHREAD_STACK_MIN
)
1297 gomp_error ("Stack size less than minimum of %luk",
1298 PTHREAD_STACK_MIN
/ 1024ul
1299 + (PTHREAD_STACK_MIN
% 1024 != 0));
1301 gomp_error ("Stack size larger than system limit");
1306 gomp_error ("Stack size change failed: %s", strerror (err
));
1309 handle_omp_display_env (stacksize
, wait_policy
);
1311 /* Look for OpenACC-specific environment variables. */
1312 goacc_parse_device_num ();
1313 goacc_parse_device_type ();
1315 /* Initialize OpenACC-specific internal state. */
1316 ACC_runtime_initialize ();
1320 /* The public OpenMP API routines that access these variables. */
1323 omp_set_num_threads (int n
)
1325 struct gomp_task_icv
*icv
= gomp_icv (true);
1326 icv
->nthreads_var
= (n
> 0 ? n
: 1);
1330 omp_set_dynamic (int val
)
1332 struct gomp_task_icv
*icv
= gomp_icv (true);
1337 omp_get_dynamic (void)
1339 struct gomp_task_icv
*icv
= gomp_icv (false);
1340 return icv
->dyn_var
;
1344 omp_set_nested (int val
)
1346 struct gomp_task_icv
*icv
= gomp_icv (true);
1347 icv
->nest_var
= val
;
1351 omp_get_nested (void)
1353 struct gomp_task_icv
*icv
= gomp_icv (false);
1354 return icv
->nest_var
;
1358 omp_set_schedule (omp_sched_t kind
, int modifier
)
1360 struct gomp_task_icv
*icv
= gomp_icv (true);
1363 case omp_sched_static
:
1366 icv
->run_sched_modifier
= modifier
;
1368 case omp_sched_dynamic
:
1369 case omp_sched_guided
:
1372 icv
->run_sched_modifier
= modifier
;
1374 case omp_sched_auto
:
1379 icv
->run_sched_var
= kind
;
1383 omp_get_schedule (omp_sched_t
*kind
, int *modifier
)
1385 struct gomp_task_icv
*icv
= gomp_icv (false);
1386 *kind
= icv
->run_sched_var
;
1387 *modifier
= icv
->run_sched_modifier
;
1391 omp_get_max_threads (void)
1393 struct gomp_task_icv
*icv
= gomp_icv (false);
1394 return icv
->nthreads_var
;
1398 omp_get_thread_limit (void)
1400 struct gomp_task_icv
*icv
= gomp_icv (false);
1401 return icv
->thread_limit_var
> INT_MAX
? INT_MAX
: icv
->thread_limit_var
;
1405 omp_set_max_active_levels (int max_levels
)
1407 if (max_levels
>= 0)
1408 gomp_max_active_levels_var
= max_levels
;
1412 omp_get_max_active_levels (void)
1414 return gomp_max_active_levels_var
;
1418 omp_get_cancellation (void)
1420 return gomp_cancel_var
;
1424 omp_get_proc_bind (void)
1426 struct gomp_task_icv
*icv
= gomp_icv (false);
1427 return icv
->bind_var
;
1431 omp_set_default_device (int device_num
)
1433 struct gomp_task_icv
*icv
= gomp_icv (true);
1434 icv
->default_device_var
= device_num
>= 0 ? device_num
: 0;
1438 omp_get_default_device (void)
1440 struct gomp_task_icv
*icv
= gomp_icv (false);
1441 return icv
->default_device_var
;
1445 omp_get_num_devices (void)
1447 return gomp_get_num_devices ();
1451 omp_get_num_teams (void)
1453 /* Hardcoded to 1 on host, MIC, HSAIL? Maybe variable on PTX. */
1458 omp_get_team_num (void)
1460 /* Hardcoded to 0 on host, MIC, HSAIL? Maybe variable on PTX. */
1465 omp_is_initial_device (void)
1467 /* Hardcoded to 1 on host, should be 0 on MIC, HSAIL, PTX. */
1471 ialias (omp_set_dynamic
)
1472 ialias (omp_set_nested
)
1473 ialias (omp_set_num_threads
)
1474 ialias (omp_get_dynamic
)
1475 ialias (omp_get_nested
)
1476 ialias (omp_set_schedule
)
1477 ialias (omp_get_schedule
)
1478 ialias (omp_get_max_threads
)
1479 ialias (omp_get_thread_limit
)
1480 ialias (omp_set_max_active_levels
)
1481 ialias (omp_get_max_active_levels
)
1482 ialias (omp_get_cancellation
)
1483 ialias (omp_get_proc_bind
)
1484 ialias (omp_set_default_device
)
1485 ialias (omp_get_default_device
)
1486 ialias (omp_get_num_devices
)
1487 ialias (omp_get_num_teams
)
1488 ialias (omp_get_team_num
)
1489 ialias (omp_is_initial_device
)