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"
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
;
82 char *goacc_device_type
;
85 /* Parse the OMP_SCHEDULE environment variable. */
93 env
= getenv ("OMP_SCHEDULE");
97 while (isspace ((unsigned char) *env
))
99 if (strncasecmp (env
, "static", 6) == 0)
101 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
104 else if (strncasecmp (env
, "dynamic", 7) == 0)
106 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
109 else if (strncasecmp (env
, "guided", 6) == 0)
111 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
114 else if (strncasecmp (env
, "auto", 4) == 0)
116 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
122 while (isspace ((unsigned char) *env
))
126 gomp_global_icv
.run_sched_modifier
127 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
132 while (isspace ((unsigned char) *env
))
138 value
= strtoul (env
, &end
, 10);
142 while (isspace ((unsigned char) *end
))
147 if ((int)value
!= value
)
150 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
152 gomp_global_icv
.run_sched_modifier
= value
;
156 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
160 gomp_error ("Invalid value for chunk size in "
161 "environment variable OMP_SCHEDULE");
165 /* Parse an unsigned long environment variable. Return true if one was
166 present and it was successfully parsed. */
169 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
178 while (isspace ((unsigned char) *env
))
184 value
= strtoul (env
, &end
, 10);
185 if (errno
|| (long) value
<= 0 - allow_zero
)
188 while (isspace ((unsigned char) *end
))
197 gomp_error ("Invalid value for environment variable %s", name
);
201 /* Parse a positive int environment variable. Return true if one was
202 present and it was successfully parsed. */
205 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
208 if (!parse_unsigned_long (name
, &value
, allow_zero
))
212 gomp_error ("Invalid value for environment variable %s", name
);
215 *pvalue
= (int) value
;
219 /* Parse an unsigned long list environment variable. Return true if one was
220 present and it was successfully parsed. */
223 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
224 unsigned long **pvalues
,
225 unsigned long *pnvalues
)
228 unsigned long value
, *values
= NULL
;
234 while (isspace ((unsigned char) *env
))
240 value
= strtoul (env
, &end
, 10);
241 if (errno
|| (long) value
<= 0)
244 while (isspace ((unsigned char) *end
))
250 unsigned long nvalues
= 0, nalloced
= 0;
255 if (nvalues
== nalloced
)
258 nalloced
= nalloced
? nalloced
* 2 : 16;
259 n
= realloc (values
, nalloced
* sizeof (unsigned long));
263 gomp_error ("Out of memory while trying to parse"
264 " environment variable %s", name
);
269 values
[nvalues
++] = value
;
272 while (isspace ((unsigned char) *env
))
278 value
= strtoul (env
, &end
, 10);
279 if (errno
|| (long) value
<= 0)
282 values
[nvalues
++] = value
;
283 while (isspace ((unsigned char) *end
))
291 *p1stvalue
= values
[0];
304 gomp_error ("Invalid value for environment variable %s", name
);
308 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
309 enum values. Return true if one was present and it was successfully
313 parse_bind_var (const char *name
, char *p1stvalue
,
314 char **pvalues
, unsigned long *pnvalues
)
317 char value
= omp_proc_bind_false
, *values
= NULL
;
319 static struct proc_bind_kinds
323 omp_proc_bind_t kind
;
326 { "false", 5, omp_proc_bind_false
},
327 { "true", 4, omp_proc_bind_true
},
328 { "master", 6, omp_proc_bind_master
},
329 { "close", 5, omp_proc_bind_close
},
330 { "spread", 6, omp_proc_bind_spread
}
337 while (isspace ((unsigned char) *env
))
342 for (i
= 0; i
< 5; i
++)
343 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
345 value
= kinds
[i
].kind
;
352 while (isspace ((unsigned char) *env
))
358 unsigned long nvalues
= 0, nalloced
= 0;
360 if (value
== omp_proc_bind_false
361 || value
== omp_proc_bind_true
)
367 if (nvalues
== nalloced
)
370 nalloced
= nalloced
? nalloced
* 2 : 16;
371 n
= realloc (values
, nalloced
);
375 gomp_error ("Out of memory while trying to parse"
376 " environment variable %s", name
);
381 values
[nvalues
++] = value
;
384 while (isspace ((unsigned char) *env
))
389 for (i
= 2; i
< 5; i
++)
390 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
392 value
= kinds
[i
].kind
;
399 values
[nvalues
++] = value
;
400 while (isspace ((unsigned char) *env
))
408 *p1stvalue
= values
[0];
421 gomp_error ("Invalid value for environment variable %s", name
);
426 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
429 char *env
= *envp
, *start
;
430 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
431 unsigned long len
= 1;
434 bool any_negate
= false;
436 while (isspace ((unsigned char) *env
))
442 while (isspace ((unsigned char) *env
))
448 while (isspace ((unsigned char) *env
))
451 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
456 unsigned long this_num
, this_len
= 1;
457 long this_stride
= 1;
458 bool this_negate
= (*env
== '!');
461 if (gomp_places_list
)
464 while (isspace ((unsigned char) *env
))
469 this_num
= strtoul (env
, &env
, 10);
472 while (isspace ((unsigned char) *env
))
477 while (isspace ((unsigned char) *env
))
480 this_len
= strtoul (env
, &env
, 10);
481 if (errno
|| this_len
== 0)
483 while (isspace ((unsigned char) *env
))
488 while (isspace ((unsigned char) *env
))
491 this_stride
= strtol (env
, &env
, 10);
494 while (isspace ((unsigned char) *env
))
498 if (this_negate
&& this_len
!= 1)
500 if (gomp_places_list
&& pass
== this_negate
)
504 if (!gomp_affinity_remove_cpu (p
, this_num
))
507 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
521 while (isspace ((unsigned char) *env
))
526 while (isspace ((unsigned char) *env
))
529 len
= strtoul (env
, &env
, 10);
530 if (errno
|| len
== 0 || len
>= 65536)
532 while (isspace ((unsigned char) *env
))
537 while (isspace ((unsigned char) *env
))
540 stride
= strtol (env
, &env
, 10);
543 while (isspace ((unsigned char) *env
))
547 if (*negatep
&& len
!= 1)
556 parse_places_var (const char *name
, bool ignore
)
558 char *env
= getenv (name
), *end
;
559 bool any_negate
= false;
561 unsigned long count
= 0;
565 while (isspace ((unsigned char) *env
))
570 if (strncasecmp (env
, "threads", 7) == 0)
575 else if (strncasecmp (env
, "cores", 5) == 0)
580 else if (strncasecmp (env
, "sockets", 7) == 0)
588 while (isspace ((unsigned char) *env
))
594 while (isspace ((unsigned char) *env
))
598 count
= strtoul (env
, &end
, 10);
602 while (isspace ((unsigned char) *env
))
607 while (isspace ((unsigned char) *env
))
616 return gomp_affinity_init_level (level
, count
, false);
626 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
649 gomp_places_list_len
= 0;
650 gomp_places_list
= gomp_affinity_alloc (count
, false);
651 if (gomp_places_list
== NULL
)
659 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
660 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
665 for (count
= 0; count
< gomp_places_list_len
; count
++)
666 if (gomp_affinity_same_place
667 (gomp_places_list
[count
],
668 gomp_places_list
[gomp_places_list_len
]))
670 if (count
== gomp_places_list_len
)
672 gomp_error ("Trying to remove a non-existing place from list "
676 p
= gomp_places_list
[count
];
677 memmove (&gomp_places_list
[count
],
678 &gomp_places_list
[count
+ 1],
679 (gomp_places_list_len
- count
- 1) * sizeof (void *));
680 --gomp_places_list_len
;
681 gomp_places_list
[gomp_places_list_len
] = p
;
684 ++gomp_places_list_len
;
687 for (count
= 0; count
< len
- 1; count
++)
688 if (!gomp_affinity_copy_place
689 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
690 gomp_places_list
[gomp_places_list_len
+ count
],
693 gomp_places_list_len
+= len
;
701 if (gomp_places_list_len
== 0)
703 gomp_error ("All places have been removed");
706 if (!gomp_affinity_finalize_place_list (false))
711 free (gomp_places_list
);
712 gomp_places_list
= NULL
;
713 gomp_places_list_len
= 0;
714 gomp_error ("Invalid value for environment variable %s", name
);
718 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
719 present and it was successfully parsed. */
722 parse_stacksize (const char *name
, unsigned long *pvalue
)
725 unsigned long value
, shift
= 10;
731 while (isspace ((unsigned char) *env
))
737 value
= strtoul (env
, &end
, 10);
741 while (isspace ((unsigned char) *end
))
745 switch (tolower ((unsigned char) *end
))
762 while (isspace ((unsigned char) *end
))
768 if (((value
<< shift
) >> shift
) != value
)
771 *pvalue
= value
<< shift
;
775 gomp_error ("Invalid value for environment variable %s", name
);
779 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
780 present and it was successfully parsed. */
783 parse_spincount (const char *name
, unsigned long long *pvalue
)
786 unsigned long long value
, mult
= 1;
792 while (isspace ((unsigned char) *env
))
797 if (strncasecmp (env
, "infinite", 8) == 0
798 || strncasecmp (env
, "infinity", 8) == 0)
806 value
= strtoull (env
, &end
, 10);
810 while (isspace ((unsigned char) *end
))
814 switch (tolower ((unsigned char) *end
))
820 mult
= 1000LL * 1000LL;
823 mult
= 1000LL * 1000LL * 1000LL;
826 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
833 while (isspace ((unsigned char) *end
))
839 if (value
> ~0ULL / mult
)
848 gomp_error ("Invalid value for environment variable %s", name
);
852 /* Parse a boolean value for environment variable NAME and store the
856 parse_boolean (const char *name
, bool *value
)
864 while (isspace ((unsigned char) *env
))
866 if (strncasecmp (env
, "true", 4) == 0)
871 else if (strncasecmp (env
, "false", 5) == 0)
878 while (isspace ((unsigned char) *env
))
881 gomp_error ("Invalid value for environment variable %s", name
);
884 /* Parse the OMP_WAIT_POLICY environment variable and store the
885 result in gomp_active_wait_policy. */
888 parse_wait_policy (void)
893 env
= getenv ("OMP_WAIT_POLICY");
897 while (isspace ((unsigned char) *env
))
899 if (strncasecmp (env
, "active", 6) == 0)
904 else if (strncasecmp (env
, "passive", 7) == 0)
911 while (isspace ((unsigned char) *env
))
915 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
919 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
920 present and it was successfully parsed. */
923 parse_affinity (bool ignore
)
925 char *env
, *end
, *start
;
927 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
928 size_t count
= 0, needed
;
930 env
= getenv ("GOMP_CPU_AFFINITY");
935 for (pass
= 0; pass
< 2; pass
++)
943 gomp_places_list_len
= 0;
944 gomp_places_list
= gomp_affinity_alloc (count
, true);
945 if (gomp_places_list
== NULL
)
950 while (isspace ((unsigned char) *env
))
954 cpu_beg
= strtoul (env
, &end
, 0);
955 if (errno
|| cpu_beg
>= 65536)
964 cpu_end
= strtoul (++env
, &end
, 0);
965 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
972 cpu_stride
= strtoul (++env
, &end
, 0);
973 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
980 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
987 void *p
= gomp_places_list
[gomp_places_list_len
];
988 gomp_affinity_init_place (p
);
989 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
990 ++gomp_places_list_len
;
991 cpu_beg
+= cpu_stride
;
995 while (isspace ((unsigned char) *env
))
1000 else if (*env
== '\0')
1006 if (gomp_places_list_len
== 0)
1008 free (gomp_places_list
);
1009 gomp_places_list
= NULL
;
1015 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1020 parse_acc_device_type (void)
1022 const char *env
= getenv ("ACC_DEVICE_TYPE");
1024 if (env
&& *env
!= '\0')
1025 goacc_device_type
= strdup (env
);
1027 goacc_device_type
= NULL
;
1031 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1034 bool display
= false;
1035 bool verbose
= false;
1038 env
= getenv ("OMP_DISPLAY_ENV");
1042 while (isspace ((unsigned char) *env
))
1044 if (strncasecmp (env
, "true", 4) == 0)
1049 else if (strncasecmp (env
, "false", 5) == 0)
1054 else if (strncasecmp (env
, "verbose", 7) == 0)
1062 while (isspace ((unsigned char) *env
))
1065 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1070 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1072 fputs (" _OPENMP = '201307'\n", stderr
);
1073 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1074 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1075 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1076 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1078 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1079 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1080 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1081 fputs ("'\n", stderr
);
1083 fprintf (stderr
, " OMP_SCHEDULE = '");
1084 switch (gomp_global_icv
.run_sched_var
)
1087 fputs ("RUNTIME", stderr
);
1090 fputs ("STATIC", stderr
);
1093 fputs ("DYNAMIC", stderr
);
1096 fputs ("GUIDED", stderr
);
1099 fputs ("AUTO", stderr
);
1102 fputs ("'\n", stderr
);
1104 fputs (" OMP_PROC_BIND = '", stderr
);
1105 switch (gomp_global_icv
.bind_var
)
1107 case omp_proc_bind_false
:
1108 fputs ("FALSE", stderr
);
1110 case omp_proc_bind_true
:
1111 fputs ("TRUE", stderr
);
1113 case omp_proc_bind_master
:
1114 fputs ("MASTER", stderr
);
1116 case omp_proc_bind_close
:
1117 fputs ("CLOSE", stderr
);
1119 case omp_proc_bind_spread
:
1120 fputs ("SPREAD", stderr
);
1123 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1124 switch (gomp_bind_var_list
[i
])
1126 case omp_proc_bind_master
:
1127 fputs (",MASTER", stderr
);
1129 case omp_proc_bind_close
:
1130 fputs (",CLOSE", stderr
);
1132 case omp_proc_bind_spread
:
1133 fputs (",SPREAD", stderr
);
1136 fputs ("'\n", stderr
);
1137 fputs (" OMP_PLACES = '", stderr
);
1138 for (i
= 0; i
< gomp_places_list_len
; i
++)
1140 fputs ("{", stderr
);
1141 gomp_affinity_print_place (gomp_places_list
[i
]);
1142 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1144 fputs ("'\n", stderr
);
1146 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1148 /* GOMP's default value is actually neither active nor passive. */
1149 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1150 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1151 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1152 gomp_global_icv
.thread_limit_var
);
1153 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1154 gomp_max_active_levels_var
);
1156 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1157 gomp_cancel_var
? "TRUE" : "FALSE");
1158 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1159 gomp_global_icv
.default_device_var
);
1163 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1164 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1165 #ifdef HAVE_INTTYPES_H
1166 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1167 (uint64_t) gomp_spin_count_var
);
1169 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1170 (unsigned long) gomp_spin_count_var
);
1174 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1178 static void __attribute__((constructor
))
1179 initialize_env (void)
1181 unsigned long thread_limit_var
, stacksize
;
1184 /* Do a compile time check that mkomp_h.pl did good job. */
1185 omp_check_defines ();
1188 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1189 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1190 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1191 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1192 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1194 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1196 gomp_global_icv
.thread_limit_var
1197 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1199 parse_int ("GOMP_DEBUG", &gomp_debug_var
, true);
1200 #ifndef HAVE_SYNC_BUILTINS
1201 gomp_mutex_init (&gomp_managed_threads_lock
);
1203 gomp_init_num_threads ();
1204 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1205 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1206 &gomp_global_icv
.nthreads_var
,
1207 &gomp_nthreads_var_list
,
1208 &gomp_nthreads_var_list_len
))
1209 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1210 bool ignore
= false;
1211 if (parse_bind_var ("OMP_PROC_BIND",
1212 &gomp_global_icv
.bind_var
,
1213 &gomp_bind_var_list
,
1214 &gomp_bind_var_list_len
)
1215 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1217 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1218 parsed if present in the environment. If OMP_PROC_BIND was set
1219 explictly to false, don't populate places list though. If places
1220 list was successfully set from OMP_PLACES, only parse but don't process
1221 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1222 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1223 was successfully parsed into a places list, otherwise to
1224 OMP_PROC_BIND=false. */
1225 if (parse_places_var ("OMP_PLACES", ignore
))
1227 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1228 gomp_global_icv
.bind_var
= true;
1231 if (parse_affinity (ignore
))
1233 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1234 gomp_global_icv
.bind_var
= true;
1237 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1238 gomp_init_affinity ();
1239 wait_policy
= parse_wait_policy ();
1240 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1242 /* Using a rough estimation of 100000 spins per msec,
1243 use 5 min blocking for OMP_WAIT_POLICY=active,
1244 3 msec blocking when OMP_WAIT_POLICY is not specificed
1245 and 0 when OMP_WAIT_POLICY=passive.
1246 Depending on the CPU speed, this can be e.g. 5 times longer
1247 or 5 times shorter. */
1248 if (wait_policy
> 0)
1249 gomp_spin_count_var
= 30000000000LL;
1250 else if (wait_policy
< 0)
1251 gomp_spin_count_var
= 300000LL;
1253 /* gomp_throttled_spin_count_var is used when there are more libgomp
1254 managed threads than available CPUs. Use very short spinning. */
1255 if (wait_policy
> 0)
1256 gomp_throttled_spin_count_var
= 1000LL;
1257 else if (wait_policy
< 0)
1258 gomp_throttled_spin_count_var
= 100LL;
1259 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1260 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1262 /* Not strictly environment related, but ordering constructors is tricky. */
1263 pthread_attr_init (&gomp_thread_attr
);
1264 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1266 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1267 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
))
1271 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1273 #ifdef PTHREAD_STACK_MIN
1276 if (stacksize
< PTHREAD_STACK_MIN
)
1277 gomp_error ("Stack size less than minimum of %luk",
1278 PTHREAD_STACK_MIN
/ 1024ul
1279 + (PTHREAD_STACK_MIN
% 1024 != 0));
1281 gomp_error ("Stack size larger than system limit");
1286 gomp_error ("Stack size change failed: %s", strerror (err
));
1289 handle_omp_display_env (stacksize
, wait_policy
);
1293 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1294 goacc_device_num
= 0;
1296 parse_acc_device_type ();
1298 goacc_runtime_initialize ();
1302 /* The public OpenMP API routines that access these variables. */
1305 omp_set_num_threads (int n
)
1307 struct gomp_task_icv
*icv
= gomp_icv (true);
1308 icv
->nthreads_var
= (n
> 0 ? n
: 1);
1312 omp_set_dynamic (int val
)
1314 struct gomp_task_icv
*icv
= gomp_icv (true);
1319 omp_get_dynamic (void)
1321 struct gomp_task_icv
*icv
= gomp_icv (false);
1322 return icv
->dyn_var
;
1326 omp_set_nested (int val
)
1328 struct gomp_task_icv
*icv
= gomp_icv (true);
1329 icv
->nest_var
= val
;
1333 omp_get_nested (void)
1335 struct gomp_task_icv
*icv
= gomp_icv (false);
1336 return icv
->nest_var
;
1340 omp_set_schedule (omp_sched_t kind
, int modifier
)
1342 struct gomp_task_icv
*icv
= gomp_icv (true);
1345 case omp_sched_static
:
1348 icv
->run_sched_modifier
= modifier
;
1350 case omp_sched_dynamic
:
1351 case omp_sched_guided
:
1354 icv
->run_sched_modifier
= modifier
;
1356 case omp_sched_auto
:
1361 icv
->run_sched_var
= kind
;
1365 omp_get_schedule (omp_sched_t
*kind
, int *modifier
)
1367 struct gomp_task_icv
*icv
= gomp_icv (false);
1368 *kind
= icv
->run_sched_var
;
1369 *modifier
= icv
->run_sched_modifier
;
1373 omp_get_max_threads (void)
1375 struct gomp_task_icv
*icv
= gomp_icv (false);
1376 return icv
->nthreads_var
;
1380 omp_get_thread_limit (void)
1382 struct gomp_task_icv
*icv
= gomp_icv (false);
1383 return icv
->thread_limit_var
> INT_MAX
? INT_MAX
: icv
->thread_limit_var
;
1387 omp_set_max_active_levels (int max_levels
)
1389 if (max_levels
>= 0)
1390 gomp_max_active_levels_var
= max_levels
;
1394 omp_get_max_active_levels (void)
1396 return gomp_max_active_levels_var
;
1400 omp_get_cancellation (void)
1402 return gomp_cancel_var
;
1406 omp_get_proc_bind (void)
1408 struct gomp_task_icv
*icv
= gomp_icv (false);
1409 return icv
->bind_var
;
1413 omp_set_default_device (int device_num
)
1415 struct gomp_task_icv
*icv
= gomp_icv (true);
1416 icv
->default_device_var
= device_num
>= 0 ? device_num
: 0;
1420 omp_get_default_device (void)
1422 struct gomp_task_icv
*icv
= gomp_icv (false);
1423 return icv
->default_device_var
;
1427 omp_get_num_devices (void)
1429 return gomp_get_num_devices ();
1433 omp_get_num_teams (void)
1435 /* Hardcoded to 1 on host, MIC, HSAIL? Maybe variable on PTX. */
1440 omp_get_team_num (void)
1442 /* Hardcoded to 0 on host, MIC, HSAIL? Maybe variable on PTX. */
1447 omp_is_initial_device (void)
1449 /* Hardcoded to 1 on host, should be 0 on MIC, HSAIL, PTX. */
1453 ialias (omp_set_dynamic
)
1454 ialias (omp_set_nested
)
1455 ialias (omp_set_num_threads
)
1456 ialias (omp_get_dynamic
)
1457 ialias (omp_get_nested
)
1458 ialias (omp_set_schedule
)
1459 ialias (omp_get_schedule
)
1460 ialias (omp_get_max_threads
)
1461 ialias (omp_get_thread_limit
)
1462 ialias (omp_set_max_active_levels
)
1463 ialias (omp_get_max_active_levels
)
1464 ialias (omp_get_cancellation
)
1465 ialias (omp_get_proc_bind
)
1466 ialias (omp_set_default_device
)
1467 ialias (omp_get_default_device
)
1468 ialias (omp_get_num_devices
)
1469 ialias (omp_get_num_teams
)
1470 ialias (omp_get_team_num
)
1471 ialias (omp_is_initial_device
)