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"
30 #include "libgomp_target.h"
35 #ifdef HAVE_INTTYPES_H
36 # include <inttypes.h> /* For PRIu64. */
38 #ifdef STRING_WITH_STRINGS
45 # ifdef HAVE_STRINGS_H
54 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
57 struct gomp_task_icv gomp_global_icv
= {
59 .thread_limit_var
= UINT_MAX
,
60 .run_sched_var
= GFS_DYNAMIC
,
61 .run_sched_modifier
= 1,
62 .default_device_var
= 0,
65 .bind_var
= omp_proc_bind_false
,
69 unsigned long gomp_max_active_levels_var
= INT_MAX
;
70 bool gomp_cancel_var
= false;
71 #ifndef HAVE_SYNC_BUILTINS
72 gomp_mutex_t gomp_managed_threads_lock
;
74 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
75 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
76 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
77 char *gomp_bind_var_list
;
78 unsigned long gomp_bind_var_list_len
;
79 void **gomp_places_list
;
80 unsigned long gomp_places_list_len
;
84 char* goacc_device_type
;
86 /* Parse the OMP_SCHEDULE environment variable. */
94 env
= getenv ("OMP_SCHEDULE");
98 while (isspace ((unsigned char) *env
))
100 if (strncasecmp (env
, "static", 6) == 0)
102 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
105 else if (strncasecmp (env
, "dynamic", 7) == 0)
107 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
110 else if (strncasecmp (env
, "guided", 6) == 0)
112 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
115 else if (strncasecmp (env
, "auto", 4) == 0)
117 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
123 while (isspace ((unsigned char) *env
))
127 gomp_global_icv
.run_sched_modifier
128 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
133 while (isspace ((unsigned char) *env
))
139 value
= strtoul (env
, &end
, 10);
143 while (isspace ((unsigned char) *end
))
148 if ((int)value
!= value
)
151 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
153 gomp_global_icv
.run_sched_modifier
= value
;
157 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
161 gomp_error ("Invalid value for chunk size in "
162 "environment variable OMP_SCHEDULE");
166 /* Parse an unsigned long environment variable. Return true if one was
167 present and it was successfully parsed. */
170 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
179 while (isspace ((unsigned char) *env
))
185 value
= strtoul (env
, &end
, 10);
186 if (errno
|| (long) value
<= 0 - allow_zero
)
189 while (isspace ((unsigned char) *end
))
198 gomp_error ("Invalid value for environment variable %s", name
);
202 /* Parse a positive int environment variable. Return true if one was
203 present and it was successfully parsed. */
206 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
209 if (!parse_unsigned_long (name
, &value
, allow_zero
))
213 gomp_error ("Invalid value for environment variable %s", name
);
216 *pvalue
= (int) value
;
220 /* Parse an unsigned long list environment variable. Return true if one was
221 present and it was successfully parsed. */
224 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
225 unsigned long **pvalues
,
226 unsigned long *pnvalues
)
229 unsigned long value
, *values
= NULL
;
235 while (isspace ((unsigned char) *env
))
241 value
= strtoul (env
, &end
, 10);
242 if (errno
|| (long) value
<= 0)
245 while (isspace ((unsigned char) *end
))
251 unsigned long nvalues
= 0, nalloced
= 0;
256 if (nvalues
== nalloced
)
259 nalloced
= nalloced
? nalloced
* 2 : 16;
260 n
= realloc (values
, nalloced
* sizeof (unsigned long));
264 gomp_error ("Out of memory while trying to parse"
265 " environment variable %s", name
);
270 values
[nvalues
++] = value
;
273 while (isspace ((unsigned char) *env
))
279 value
= strtoul (env
, &end
, 10);
280 if (errno
|| (long) value
<= 0)
283 values
[nvalues
++] = value
;
284 while (isspace ((unsigned char) *end
))
292 *p1stvalue
= values
[0];
305 gomp_error ("Invalid value for environment variable %s", name
);
309 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
310 enum values. Return true if one was present and it was successfully
314 parse_bind_var (const char *name
, char *p1stvalue
,
315 char **pvalues
, unsigned long *pnvalues
)
318 char value
= omp_proc_bind_false
, *values
= NULL
;
320 static struct proc_bind_kinds
324 omp_proc_bind_t kind
;
327 { "false", 5, omp_proc_bind_false
},
328 { "true", 4, omp_proc_bind_true
},
329 { "master", 6, omp_proc_bind_master
},
330 { "close", 5, omp_proc_bind_close
},
331 { "spread", 6, omp_proc_bind_spread
}
338 while (isspace ((unsigned char) *env
))
343 for (i
= 0; i
< 5; i
++)
344 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
346 value
= kinds
[i
].kind
;
353 while (isspace ((unsigned char) *env
))
359 unsigned long nvalues
= 0, nalloced
= 0;
361 if (value
== omp_proc_bind_false
362 || value
== omp_proc_bind_true
)
368 if (nvalues
== nalloced
)
371 nalloced
= nalloced
? nalloced
* 2 : 16;
372 n
= realloc (values
, nalloced
);
376 gomp_error ("Out of memory while trying to parse"
377 " environment variable %s", name
);
382 values
[nvalues
++] = value
;
385 while (isspace ((unsigned char) *env
))
390 for (i
= 2; i
< 5; i
++)
391 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
393 value
= kinds
[i
].kind
;
400 values
[nvalues
++] = value
;
401 while (isspace ((unsigned char) *env
))
409 *p1stvalue
= values
[0];
422 gomp_error ("Invalid value for environment variable %s", name
);
427 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
430 char *env
= *envp
, *start
;
431 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
432 unsigned long len
= 1;
435 bool any_negate
= false;
437 while (isspace ((unsigned char) *env
))
443 while (isspace ((unsigned char) *env
))
449 while (isspace ((unsigned char) *env
))
452 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
457 unsigned long this_num
, this_len
= 1;
458 long this_stride
= 1;
459 bool this_negate
= (*env
== '!');
462 if (gomp_places_list
)
465 while (isspace ((unsigned char) *env
))
470 this_num
= strtoul (env
, &env
, 10);
473 while (isspace ((unsigned char) *env
))
478 while (isspace ((unsigned char) *env
))
481 this_len
= strtoul (env
, &env
, 10);
482 if (errno
|| this_len
== 0)
484 while (isspace ((unsigned char) *env
))
489 while (isspace ((unsigned char) *env
))
492 this_stride
= strtol (env
, &env
, 10);
495 while (isspace ((unsigned char) *env
))
499 if (this_negate
&& this_len
!= 1)
501 if (gomp_places_list
&& pass
== this_negate
)
505 if (!gomp_affinity_remove_cpu (p
, this_num
))
508 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
522 while (isspace ((unsigned char) *env
))
527 while (isspace ((unsigned char) *env
))
530 len
= strtoul (env
, &env
, 10);
531 if (errno
|| len
== 0 || len
>= 65536)
533 while (isspace ((unsigned char) *env
))
538 while (isspace ((unsigned char) *env
))
541 stride
= strtol (env
, &env
, 10);
544 while (isspace ((unsigned char) *env
))
548 if (*negatep
&& len
!= 1)
557 parse_places_var (const char *name
, bool ignore
)
559 char *env
= getenv (name
), *end
;
560 bool any_negate
= false;
562 unsigned long count
= 0;
566 while (isspace ((unsigned char) *env
))
571 if (strncasecmp (env
, "threads", 7) == 0)
576 else if (strncasecmp (env
, "cores", 5) == 0)
581 else if (strncasecmp (env
, "sockets", 7) == 0)
589 while (isspace ((unsigned char) *env
))
595 while (isspace ((unsigned char) *env
))
599 count
= strtoul (env
, &end
, 10);
603 while (isspace ((unsigned char) *env
))
608 while (isspace ((unsigned char) *env
))
617 return gomp_affinity_init_level (level
, count
, false);
627 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
650 gomp_places_list_len
= 0;
651 gomp_places_list
= gomp_affinity_alloc (count
, false);
652 if (gomp_places_list
== NULL
)
660 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
661 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
666 for (count
= 0; count
< gomp_places_list_len
; count
++)
667 if (gomp_affinity_same_place
668 (gomp_places_list
[count
],
669 gomp_places_list
[gomp_places_list_len
]))
671 if (count
== gomp_places_list_len
)
673 gomp_error ("Trying to remove a non-existing place from list "
677 p
= gomp_places_list
[count
];
678 memmove (&gomp_places_list
[count
],
679 &gomp_places_list
[count
+ 1],
680 (gomp_places_list_len
- count
- 1) * sizeof (void *));
681 --gomp_places_list_len
;
682 gomp_places_list
[gomp_places_list_len
] = p
;
685 ++gomp_places_list_len
;
688 for (count
= 0; count
< len
- 1; count
++)
689 if (!gomp_affinity_copy_place
690 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
691 gomp_places_list
[gomp_places_list_len
+ count
],
694 gomp_places_list_len
+= len
;
702 if (gomp_places_list_len
== 0)
704 gomp_error ("All places have been removed");
707 if (!gomp_affinity_finalize_place_list (false))
712 free (gomp_places_list
);
713 gomp_places_list
= NULL
;
714 gomp_places_list_len
= 0;
715 gomp_error ("Invalid value for environment variable %s", name
);
719 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
720 present and it was successfully parsed. */
723 parse_stacksize (const char *name
, unsigned long *pvalue
)
726 unsigned long value
, shift
= 10;
732 while (isspace ((unsigned char) *env
))
738 value
= strtoul (env
, &end
, 10);
742 while (isspace ((unsigned char) *end
))
746 switch (tolower ((unsigned char) *end
))
763 while (isspace ((unsigned char) *end
))
769 if (((value
<< shift
) >> shift
) != value
)
772 *pvalue
= value
<< shift
;
776 gomp_error ("Invalid value for environment variable %s", name
);
780 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
781 present and it was successfully parsed. */
784 parse_spincount (const char *name
, unsigned long long *pvalue
)
787 unsigned long long value
, mult
= 1;
793 while (isspace ((unsigned char) *env
))
798 if (strncasecmp (env
, "infinite", 8) == 0
799 || strncasecmp (env
, "infinity", 8) == 0)
807 value
= strtoull (env
, &end
, 10);
811 while (isspace ((unsigned char) *end
))
815 switch (tolower ((unsigned char) *end
))
821 mult
= 1000LL * 1000LL;
824 mult
= 1000LL * 1000LL * 1000LL;
827 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
834 while (isspace ((unsigned char) *end
))
840 if (value
> ~0ULL / mult
)
849 gomp_error ("Invalid value for environment variable %s", name
);
853 /* Parse a boolean value for environment variable NAME and store the
857 parse_boolean (const char *name
, bool *value
)
865 while (isspace ((unsigned char) *env
))
867 if (strncasecmp (env
, "true", 4) == 0)
872 else if (strncasecmp (env
, "false", 5) == 0)
879 while (isspace ((unsigned char) *env
))
882 gomp_error ("Invalid value for environment variable %s", name
);
885 /* Parse the OMP_WAIT_POLICY environment variable and store the
886 result in gomp_active_wait_policy. */
889 parse_wait_policy (void)
894 env
= getenv ("OMP_WAIT_POLICY");
898 while (isspace ((unsigned char) *env
))
900 if (strncasecmp (env
, "active", 6) == 0)
905 else if (strncasecmp (env
, "passive", 7) == 0)
912 while (isspace ((unsigned char) *env
))
916 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
920 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
921 present and it was successfully parsed. */
924 parse_affinity (bool ignore
)
926 char *env
, *end
, *start
;
928 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
929 size_t count
= 0, needed
;
931 env
= getenv ("GOMP_CPU_AFFINITY");
936 for (pass
= 0; pass
< 2; pass
++)
944 gomp_places_list_len
= 0;
945 gomp_places_list
= gomp_affinity_alloc (count
, true);
946 if (gomp_places_list
== NULL
)
951 while (isspace ((unsigned char) *env
))
955 cpu_beg
= strtoul (env
, &end
, 0);
956 if (errno
|| cpu_beg
>= 65536)
965 cpu_end
= strtoul (++env
, &end
, 0);
966 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
973 cpu_stride
= strtoul (++env
, &end
, 0);
974 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
981 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
988 void *p
= gomp_places_list
[gomp_places_list_len
];
989 gomp_affinity_init_place (p
);
990 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
991 ++gomp_places_list_len
;
992 cpu_beg
+= cpu_stride
;
996 while (isspace ((unsigned char) *env
))
1001 else if (*env
== '\0')
1007 if (gomp_places_list_len
== 0)
1009 free (gomp_places_list
);
1010 gomp_places_list
= NULL
;
1016 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1021 goacc_parse_device_type (void)
1023 const char *env
= getenv ("ACC_DEVICE_TYPE");
1025 if (env
&& *env
!= '\0')
1026 goacc_device_type
= strdup (env
);
1028 goacc_device_type
= NULL
;
1032 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1035 bool display
= false;
1036 bool verbose
= false;
1039 env
= getenv ("OMP_DISPLAY_ENV");
1043 while (isspace ((unsigned char) *env
))
1045 if (strncasecmp (env
, "true", 4) == 0)
1050 else if (strncasecmp (env
, "false", 5) == 0)
1055 else if (strncasecmp (env
, "verbose", 7) == 0)
1063 while (isspace ((unsigned char) *env
))
1066 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1071 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1073 fputs (" _OPENMP = '201307'\n", stderr
);
1074 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1075 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1076 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1077 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1079 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1080 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1081 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1082 fputs ("'\n", stderr
);
1084 fprintf (stderr
, " OMP_SCHEDULE = '");
1085 switch (gomp_global_icv
.run_sched_var
)
1088 fputs ("RUNTIME", stderr
);
1091 fputs ("STATIC", stderr
);
1094 fputs ("DYNAMIC", stderr
);
1097 fputs ("GUIDED", stderr
);
1100 fputs ("AUTO", stderr
);
1103 fputs ("'\n", stderr
);
1105 fputs (" OMP_PROC_BIND = '", stderr
);
1106 switch (gomp_global_icv
.bind_var
)
1108 case omp_proc_bind_false
:
1109 fputs ("FALSE", stderr
);
1111 case omp_proc_bind_true
:
1112 fputs ("TRUE", stderr
);
1114 case omp_proc_bind_master
:
1115 fputs ("MASTER", stderr
);
1117 case omp_proc_bind_close
:
1118 fputs ("CLOSE", stderr
);
1120 case omp_proc_bind_spread
:
1121 fputs ("SPREAD", stderr
);
1124 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1125 switch (gomp_bind_var_list
[i
])
1127 case omp_proc_bind_master
:
1128 fputs (",MASTER", stderr
);
1130 case omp_proc_bind_close
:
1131 fputs (",CLOSE", stderr
);
1133 case omp_proc_bind_spread
:
1134 fputs (",SPREAD", stderr
);
1137 fputs ("'\n", stderr
);
1138 fputs (" OMP_PLACES = '", stderr
);
1139 for (i
= 0; i
< gomp_places_list_len
; i
++)
1141 fputs ("{", stderr
);
1142 gomp_affinity_print_place (gomp_places_list
[i
]);
1143 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1145 fputs ("'\n", stderr
);
1147 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1149 /* GOMP's default value is actually neither active nor passive. */
1150 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1151 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1152 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1153 gomp_global_icv
.thread_limit_var
);
1154 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1155 gomp_max_active_levels_var
);
1157 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1158 gomp_cancel_var
? "TRUE" : "FALSE");
1159 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1160 gomp_global_icv
.default_device_var
);
1164 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1165 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1166 #ifdef HAVE_INTTYPES_H
1167 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1168 (uint64_t) gomp_spin_count_var
);
1170 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1171 (unsigned long) gomp_spin_count_var
);
1175 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1179 static void __attribute__((constructor
))
1180 initialize_env (void)
1182 unsigned long thread_limit_var
, stacksize
;
1185 /* Do a compile time check that mkomp_h.pl did good job. */
1186 omp_check_defines ();
1189 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1190 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1191 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1192 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1193 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1195 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1197 gomp_global_icv
.thread_limit_var
1198 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1200 parse_int ("GCC_ACC_NOTIFY", &goacc_notify_var
, true);
1201 #ifndef HAVE_SYNC_BUILTINS
1202 gomp_mutex_init (&gomp_managed_threads_lock
);
1204 gomp_init_num_threads ();
1205 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1206 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1207 &gomp_global_icv
.nthreads_var
,
1208 &gomp_nthreads_var_list
,
1209 &gomp_nthreads_var_list_len
))
1210 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1211 bool ignore
= false;
1212 if (parse_bind_var ("OMP_PROC_BIND",
1213 &gomp_global_icv
.bind_var
,
1214 &gomp_bind_var_list
,
1215 &gomp_bind_var_list_len
)
1216 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1218 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1219 parsed if present in the environment. If OMP_PROC_BIND was set
1220 explictly to false, don't populate places list though. If places
1221 list was successfully set from OMP_PLACES, only parse but don't process
1222 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1223 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1224 was successfully parsed into a places list, otherwise to
1225 OMP_PROC_BIND=false. */
1226 if (parse_places_var ("OMP_PLACES", ignore
))
1228 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1229 gomp_global_icv
.bind_var
= true;
1232 if (parse_affinity (ignore
))
1234 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1235 gomp_global_icv
.bind_var
= true;
1238 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1239 gomp_init_affinity ();
1240 wait_policy
= parse_wait_policy ();
1241 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1243 /* Using a rough estimation of 100000 spins per msec,
1244 use 5 min blocking for OMP_WAIT_POLICY=active,
1245 3 msec blocking when OMP_WAIT_POLICY is not specificed
1246 and 0 when OMP_WAIT_POLICY=passive.
1247 Depending on the CPU speed, this can be e.g. 5 times longer
1248 or 5 times shorter. */
1249 if (wait_policy
> 0)
1250 gomp_spin_count_var
= 30000000000LL;
1251 else if (wait_policy
< 0)
1252 gomp_spin_count_var
= 300000LL;
1254 /* gomp_throttled_spin_count_var is used when there are more libgomp
1255 managed threads than available CPUs. Use very short spinning. */
1256 if (wait_policy
> 0)
1257 gomp_throttled_spin_count_var
= 1000LL;
1258 else if (wait_policy
< 0)
1259 gomp_throttled_spin_count_var
= 100LL;
1260 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1261 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1263 /* Not strictly environment related, but ordering constructors is tricky. */
1264 pthread_attr_init (&gomp_thread_attr
);
1265 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1267 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1268 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
))
1272 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1274 #ifdef PTHREAD_STACK_MIN
1277 if (stacksize
< PTHREAD_STACK_MIN
)
1278 gomp_error ("Stack size less than minimum of %luk",
1279 PTHREAD_STACK_MIN
/ 1024ul
1280 + (PTHREAD_STACK_MIN
% 1024 != 0));
1282 gomp_error ("Stack size larger than system limit");
1287 gomp_error ("Stack size change failed: %s", strerror (err
));
1290 handle_omp_display_env (stacksize
, wait_policy
);
1292 /* Look for OpenACC-specific environment variables. */
1293 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1294 goacc_device_num
= 0;
1296 goacc_parse_device_type ();
1298 /* Initialize OpenACC-specific internal state. */
1299 ACC_runtime_initialize ();
1303 /* The public OpenMP API routines that access these variables. */
1306 omp_set_num_threads (int n
)
1308 struct gomp_task_icv
*icv
= gomp_icv (true);
1309 icv
->nthreads_var
= (n
> 0 ? n
: 1);
1313 omp_set_dynamic (int val
)
1315 struct gomp_task_icv
*icv
= gomp_icv (true);
1320 omp_get_dynamic (void)
1322 struct gomp_task_icv
*icv
= gomp_icv (false);
1323 return icv
->dyn_var
;
1327 omp_set_nested (int val
)
1329 struct gomp_task_icv
*icv
= gomp_icv (true);
1330 icv
->nest_var
= val
;
1334 omp_get_nested (void)
1336 struct gomp_task_icv
*icv
= gomp_icv (false);
1337 return icv
->nest_var
;
1341 omp_set_schedule (omp_sched_t kind
, int modifier
)
1343 struct gomp_task_icv
*icv
= gomp_icv (true);
1346 case omp_sched_static
:
1349 icv
->run_sched_modifier
= modifier
;
1351 case omp_sched_dynamic
:
1352 case omp_sched_guided
:
1355 icv
->run_sched_modifier
= modifier
;
1357 case omp_sched_auto
:
1362 icv
->run_sched_var
= kind
;
1366 omp_get_schedule (omp_sched_t
*kind
, int *modifier
)
1368 struct gomp_task_icv
*icv
= gomp_icv (false);
1369 *kind
= icv
->run_sched_var
;
1370 *modifier
= icv
->run_sched_modifier
;
1374 omp_get_max_threads (void)
1376 struct gomp_task_icv
*icv
= gomp_icv (false);
1377 return icv
->nthreads_var
;
1381 omp_get_thread_limit (void)
1383 struct gomp_task_icv
*icv
= gomp_icv (false);
1384 return icv
->thread_limit_var
> INT_MAX
? INT_MAX
: icv
->thread_limit_var
;
1388 omp_set_max_active_levels (int max_levels
)
1390 if (max_levels
>= 0)
1391 gomp_max_active_levels_var
= max_levels
;
1395 omp_get_max_active_levels (void)
1397 return gomp_max_active_levels_var
;
1401 omp_get_cancellation (void)
1403 return gomp_cancel_var
;
1407 omp_get_proc_bind (void)
1409 struct gomp_task_icv
*icv
= gomp_icv (false);
1410 return icv
->bind_var
;
1414 omp_set_default_device (int device_num
)
1416 struct gomp_task_icv
*icv
= gomp_icv (true);
1417 icv
->default_device_var
= device_num
>= 0 ? device_num
: 0;
1421 omp_get_default_device (void)
1423 struct gomp_task_icv
*icv
= gomp_icv (false);
1424 return icv
->default_device_var
;
1428 omp_get_num_devices (void)
1430 return gomp_get_num_devices ();
1434 omp_get_num_teams (void)
1436 /* Hardcoded to 1 on host, MIC, HSAIL? Maybe variable on PTX. */
1441 omp_get_team_num (void)
1443 /* Hardcoded to 0 on host, MIC, HSAIL? Maybe variable on PTX. */
1448 omp_is_initial_device (void)
1450 /* Hardcoded to 1 on host, should be 0 on MIC, HSAIL, PTX. */
1454 ialias (omp_set_dynamic
)
1455 ialias (omp_set_nested
)
1456 ialias (omp_set_num_threads
)
1457 ialias (omp_get_dynamic
)
1458 ialias (omp_get_nested
)
1459 ialias (omp_set_schedule
)
1460 ialias (omp_get_schedule
)
1461 ialias (omp_get_max_threads
)
1462 ialias (omp_get_thread_limit
)
1463 ialias (omp_set_max_active_levels
)
1464 ialias (omp_get_max_active_levels
)
1465 ialias (omp_get_cancellation
)
1466 ialias (omp_get_proc_bind
)
1467 ialias (omp_set_default_device
)
1468 ialias (omp_get_default_device
)
1469 ialias (omp_get_num_devices
)
1470 ialias (omp_get_num_teams
)
1471 ialias (omp_get_team_num
)
1472 ialias (omp_is_initial_device
)