1 /* Copyright (C) 2005-2016 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"
32 #include "gomp-constants.h"
36 #ifdef HAVE_INTTYPES_H
37 # include <inttypes.h> /* For PRIu64. */
39 #ifdef STRING_WITH_STRINGS
46 # ifdef HAVE_STRINGS_H
55 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
58 struct gomp_task_icv gomp_global_icv
= {
60 .thread_limit_var
= UINT_MAX
,
61 .run_sched_var
= GFS_DYNAMIC
,
62 .run_sched_chunk_size
= 1,
63 .default_device_var
= 0,
66 .bind_var
= omp_proc_bind_false
,
70 unsigned long gomp_max_active_levels_var
= INT_MAX
;
71 bool gomp_cancel_var
= false;
72 int gomp_max_task_priority_var
= 0;
73 #ifndef HAVE_SYNC_BUILTINS
74 gomp_mutex_t gomp_managed_threads_lock
;
76 unsigned long gomp_available_cpus
= 1, gomp_managed_threads
= 1;
77 unsigned long long gomp_spin_count_var
, gomp_throttled_spin_count_var
;
78 unsigned long *gomp_nthreads_var_list
, gomp_nthreads_var_list_len
;
79 char *gomp_bind_var_list
;
80 unsigned long gomp_bind_var_list_len
;
81 void **gomp_places_list
;
82 unsigned long gomp_places_list_len
;
84 char *goacc_device_type
;
87 /* Parse the OMP_SCHEDULE environment variable. */
95 env
= getenv ("OMP_SCHEDULE");
99 while (isspace ((unsigned char) *env
))
101 if (strncasecmp (env
, "static", 6) == 0)
103 gomp_global_icv
.run_sched_var
= GFS_STATIC
;
106 else if (strncasecmp (env
, "dynamic", 7) == 0)
108 gomp_global_icv
.run_sched_var
= GFS_DYNAMIC
;
111 else if (strncasecmp (env
, "guided", 6) == 0)
113 gomp_global_icv
.run_sched_var
= GFS_GUIDED
;
116 else if (strncasecmp (env
, "auto", 4) == 0)
118 gomp_global_icv
.run_sched_var
= GFS_AUTO
;
124 while (isspace ((unsigned char) *env
))
128 gomp_global_icv
.run_sched_chunk_size
129 = gomp_global_icv
.run_sched_var
!= GFS_STATIC
;
134 while (isspace ((unsigned char) *env
))
140 value
= strtoul (env
, &end
, 10);
144 while (isspace ((unsigned char) *end
))
149 if ((int)value
!= value
)
152 if (value
== 0 && gomp_global_icv
.run_sched_var
!= GFS_STATIC
)
154 gomp_global_icv
.run_sched_chunk_size
= value
;
158 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
162 gomp_error ("Invalid value for chunk size in "
163 "environment variable OMP_SCHEDULE");
167 /* Parse an unsigned long environment variable. Return true if one was
168 present and it was successfully parsed. */
171 parse_unsigned_long (const char *name
, unsigned long *pvalue
, bool allow_zero
)
180 while (isspace ((unsigned char) *env
))
186 value
= strtoul (env
, &end
, 10);
187 if (errno
|| (long) value
<= 0 - allow_zero
)
190 while (isspace ((unsigned char) *end
))
199 gomp_error ("Invalid value for environment variable %s", name
);
203 /* Parse a positive int environment variable. Return true if one was
204 present and it was successfully parsed. */
207 parse_int (const char *name
, int *pvalue
, bool allow_zero
)
210 if (!parse_unsigned_long (name
, &value
, allow_zero
))
214 gomp_error ("Invalid value for environment variable %s", name
);
217 *pvalue
= (int) value
;
221 /* Parse an unsigned long list environment variable. Return true if one was
222 present and it was successfully parsed. */
225 parse_unsigned_long_list (const char *name
, unsigned long *p1stvalue
,
226 unsigned long **pvalues
,
227 unsigned long *pnvalues
)
230 unsigned long value
, *values
= NULL
;
236 while (isspace ((unsigned char) *env
))
242 value
= strtoul (env
, &end
, 10);
243 if (errno
|| (long) value
<= 0)
246 while (isspace ((unsigned char) *end
))
252 unsigned long nvalues
= 0, nalloced
= 0;
257 if (nvalues
== nalloced
)
260 nalloced
= nalloced
? nalloced
* 2 : 16;
261 n
= realloc (values
, nalloced
* sizeof (unsigned long));
265 gomp_error ("Out of memory while trying to parse"
266 " environment variable %s", name
);
271 values
[nvalues
++] = value
;
274 while (isspace ((unsigned char) *env
))
280 value
= strtoul (env
, &end
, 10);
281 if (errno
|| (long) value
<= 0)
284 values
[nvalues
++] = value
;
285 while (isspace ((unsigned char) *end
))
293 *p1stvalue
= values
[0];
306 gomp_error ("Invalid value for environment variable %s", name
);
310 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
311 enum values. Return true if one was present and it was successfully
315 parse_bind_var (const char *name
, char *p1stvalue
,
316 char **pvalues
, unsigned long *pnvalues
)
319 char value
= omp_proc_bind_false
, *values
= NULL
;
321 static struct proc_bind_kinds
325 omp_proc_bind_t kind
;
328 { "false", 5, omp_proc_bind_false
},
329 { "true", 4, omp_proc_bind_true
},
330 { "master", 6, omp_proc_bind_master
},
331 { "close", 5, omp_proc_bind_close
},
332 { "spread", 6, omp_proc_bind_spread
}
339 while (isspace ((unsigned char) *env
))
344 for (i
= 0; i
< 5; i
++)
345 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
347 value
= kinds
[i
].kind
;
354 while (isspace ((unsigned char) *env
))
360 unsigned long nvalues
= 0, nalloced
= 0;
362 if (value
== omp_proc_bind_false
363 || value
== omp_proc_bind_true
)
369 if (nvalues
== nalloced
)
372 nalloced
= nalloced
? nalloced
* 2 : 16;
373 n
= realloc (values
, nalloced
);
377 gomp_error ("Out of memory while trying to parse"
378 " environment variable %s", name
);
383 values
[nvalues
++] = value
;
386 while (isspace ((unsigned char) *env
))
391 for (i
= 2; i
< 5; i
++)
392 if (strncasecmp (env
, kinds
[i
].name
, kinds
[i
].len
) == 0)
394 value
= kinds
[i
].kind
;
401 values
[nvalues
++] = value
;
402 while (isspace ((unsigned char) *env
))
410 *p1stvalue
= values
[0];
423 gomp_error ("Invalid value for environment variable %s", name
);
428 parse_one_place (char **envp
, bool *negatep
, unsigned long *lenp
,
431 char *env
= *envp
, *start
;
432 void *p
= gomp_places_list
? gomp_places_list
[gomp_places_list_len
] : NULL
;
433 unsigned long len
= 1;
436 bool any_negate
= false;
438 while (isspace ((unsigned char) *env
))
444 while (isspace ((unsigned char) *env
))
450 while (isspace ((unsigned char) *env
))
453 for (pass
= 0; pass
< (any_negate
? 2 : 1); pass
++)
458 unsigned long this_num
, this_len
= 1;
459 long this_stride
= 1;
460 bool this_negate
= (*env
== '!');
463 if (gomp_places_list
)
466 while (isspace ((unsigned char) *env
))
471 this_num
= strtoul (env
, &env
, 10);
474 while (isspace ((unsigned char) *env
))
479 while (isspace ((unsigned char) *env
))
482 this_len
= strtoul (env
, &env
, 10);
483 if (errno
|| this_len
== 0)
485 while (isspace ((unsigned char) *env
))
490 while (isspace ((unsigned char) *env
))
493 this_stride
= strtol (env
, &env
, 10);
496 while (isspace ((unsigned char) *env
))
500 if (this_negate
&& this_len
!= 1)
502 if (gomp_places_list
&& pass
== this_negate
)
506 if (!gomp_affinity_remove_cpu (p
, this_num
))
509 else if (!gomp_affinity_add_cpus (p
, this_num
, this_len
,
523 while (isspace ((unsigned char) *env
))
528 while (isspace ((unsigned char) *env
))
531 len
= strtoul (env
, &env
, 10);
532 if (errno
|| len
== 0 || len
>= 65536)
534 while (isspace ((unsigned char) *env
))
539 while (isspace ((unsigned char) *env
))
542 stride
= strtol (env
, &env
, 10);
545 while (isspace ((unsigned char) *env
))
549 if (*negatep
&& len
!= 1)
558 parse_places_var (const char *name
, bool ignore
)
560 char *env
= getenv (name
), *end
;
561 bool any_negate
= false;
563 unsigned long count
= 0;
567 while (isspace ((unsigned char) *env
))
572 if (strncasecmp (env
, "threads", 7) == 0)
577 else if (strncasecmp (env
, "cores", 5) == 0)
582 else if (strncasecmp (env
, "sockets", 7) == 0)
590 while (isspace ((unsigned char) *env
))
596 while (isspace ((unsigned char) *env
))
600 count
= strtoul (env
, &end
, 10);
604 while (isspace ((unsigned char) *env
))
609 while (isspace ((unsigned char) *env
))
618 return gomp_affinity_init_level (level
, count
, false);
628 if (!parse_one_place (&end
, &negate
, &len
, &stride
))
651 gomp_places_list_len
= 0;
652 gomp_places_list
= gomp_affinity_alloc (count
, false);
653 if (gomp_places_list
== NULL
)
661 gomp_affinity_init_place (gomp_places_list
[gomp_places_list_len
]);
662 if (!parse_one_place (&env
, &negate
, &len
, &stride
))
667 for (count
= 0; count
< gomp_places_list_len
; count
++)
668 if (gomp_affinity_same_place
669 (gomp_places_list
[count
],
670 gomp_places_list
[gomp_places_list_len
]))
672 if (count
== gomp_places_list_len
)
674 gomp_error ("Trying to remove a non-existing place from list "
678 p
= gomp_places_list
[count
];
679 memmove (&gomp_places_list
[count
],
680 &gomp_places_list
[count
+ 1],
681 (gomp_places_list_len
- count
- 1) * sizeof (void *));
682 --gomp_places_list_len
;
683 gomp_places_list
[gomp_places_list_len
] = p
;
686 ++gomp_places_list_len
;
689 for (count
= 0; count
< len
- 1; count
++)
690 if (!gomp_affinity_copy_place
691 (gomp_places_list
[gomp_places_list_len
+ count
+ 1],
692 gomp_places_list
[gomp_places_list_len
+ count
],
695 gomp_places_list_len
+= len
;
703 if (gomp_places_list_len
== 0)
705 gomp_error ("All places have been removed");
708 if (!gomp_affinity_finalize_place_list (false))
713 free (gomp_places_list
);
714 gomp_places_list
= NULL
;
715 gomp_places_list_len
= 0;
716 gomp_error ("Invalid value for environment variable %s", name
);
720 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
721 present and it was successfully parsed. */
724 parse_stacksize (const char *name
, unsigned long *pvalue
)
727 unsigned long value
, shift
= 10;
733 while (isspace ((unsigned char) *env
))
739 value
= strtoul (env
, &end
, 10);
743 while (isspace ((unsigned char) *end
))
747 switch (tolower ((unsigned char) *end
))
764 while (isspace ((unsigned char) *end
))
770 if (((value
<< shift
) >> shift
) != value
)
773 *pvalue
= value
<< shift
;
777 gomp_error ("Invalid value for environment variable %s", name
);
781 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
782 present and it was successfully parsed. */
785 parse_spincount (const char *name
, unsigned long long *pvalue
)
788 unsigned long long value
, mult
= 1;
794 while (isspace ((unsigned char) *env
))
799 if (strncasecmp (env
, "infinite", 8) == 0
800 || strncasecmp (env
, "infinity", 8) == 0)
808 value
= strtoull (env
, &end
, 10);
812 while (isspace ((unsigned char) *end
))
816 switch (tolower ((unsigned char) *end
))
822 mult
= 1000LL * 1000LL;
825 mult
= 1000LL * 1000LL * 1000LL;
828 mult
= 1000LL * 1000LL * 1000LL * 1000LL;
835 while (isspace ((unsigned char) *end
))
841 if (value
> ~0ULL / mult
)
850 gomp_error ("Invalid value for environment variable %s", name
);
854 /* Parse a boolean value for environment variable NAME and store the
858 parse_boolean (const char *name
, bool *value
)
866 while (isspace ((unsigned char) *env
))
868 if (strncasecmp (env
, "true", 4) == 0)
873 else if (strncasecmp (env
, "false", 5) == 0)
880 while (isspace ((unsigned char) *env
))
883 gomp_error ("Invalid value for environment variable %s", name
);
886 /* Parse the OMP_WAIT_POLICY environment variable and store the
887 result in gomp_active_wait_policy. */
890 parse_wait_policy (void)
895 env
= getenv ("OMP_WAIT_POLICY");
899 while (isspace ((unsigned char) *env
))
901 if (strncasecmp (env
, "active", 6) == 0)
906 else if (strncasecmp (env
, "passive", 7) == 0)
913 while (isspace ((unsigned char) *env
))
917 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
921 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
922 present and it was successfully parsed. */
925 parse_affinity (bool ignore
)
927 char *env
, *end
, *start
;
929 unsigned long cpu_beg
, cpu_end
, cpu_stride
;
930 size_t count
= 0, needed
;
932 env
= getenv ("GOMP_CPU_AFFINITY");
937 for (pass
= 0; pass
< 2; pass
++)
945 gomp_places_list_len
= 0;
946 gomp_places_list
= gomp_affinity_alloc (count
, true);
947 if (gomp_places_list
== NULL
)
952 while (isspace ((unsigned char) *env
))
956 cpu_beg
= strtoul (env
, &end
, 0);
957 if (errno
|| cpu_beg
>= 65536)
966 cpu_end
= strtoul (++env
, &end
, 0);
967 if (errno
|| cpu_end
>= 65536 || cpu_end
< cpu_beg
)
974 cpu_stride
= strtoul (++env
, &end
, 0);
975 if (errno
|| cpu_stride
== 0 || cpu_stride
>= 65536)
982 needed
= (cpu_end
- cpu_beg
) / cpu_stride
+ 1;
989 void *p
= gomp_places_list
[gomp_places_list_len
];
990 gomp_affinity_init_place (p
);
991 if (gomp_affinity_add_cpus (p
, cpu_beg
, 1, 0, true))
992 ++gomp_places_list_len
;
993 cpu_beg
+= cpu_stride
;
997 while (isspace ((unsigned char) *env
))
1002 else if (*env
== '\0')
1008 if (gomp_places_list_len
== 0)
1010 free (gomp_places_list
);
1011 gomp_places_list
= NULL
;
1017 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
1022 parse_acc_device_type (void)
1024 const char *env
= getenv ("ACC_DEVICE_TYPE");
1026 if (env
&& *env
!= '\0')
1027 goacc_device_type
= strdup (env
);
1029 goacc_device_type
= NULL
;
1033 handle_omp_display_env (unsigned long stacksize
, int wait_policy
)
1036 bool display
= false;
1037 bool verbose
= false;
1040 env
= getenv ("OMP_DISPLAY_ENV");
1044 while (isspace ((unsigned char) *env
))
1046 if (strncasecmp (env
, "true", 4) == 0)
1051 else if (strncasecmp (env
, "false", 5) == 0)
1056 else if (strncasecmp (env
, "verbose", 7) == 0)
1064 while (isspace ((unsigned char) *env
))
1067 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1072 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr
);
1074 fputs (" _OPENMP = '201511'\n", stderr
);
1075 fprintf (stderr
, " OMP_DYNAMIC = '%s'\n",
1076 gomp_global_icv
.dyn_var
? "TRUE" : "FALSE");
1077 fprintf (stderr
, " OMP_NESTED = '%s'\n",
1078 gomp_global_icv
.nest_var
? "TRUE" : "FALSE");
1080 fprintf (stderr
, " OMP_NUM_THREADS = '%lu", gomp_global_icv
.nthreads_var
);
1081 for (i
= 1; i
< gomp_nthreads_var_list_len
; i
++)
1082 fprintf (stderr
, ",%lu", gomp_nthreads_var_list
[i
]);
1083 fputs ("'\n", stderr
);
1085 fprintf (stderr
, " OMP_SCHEDULE = '");
1086 switch (gomp_global_icv
.run_sched_var
)
1089 fputs ("RUNTIME", stderr
);
1092 fputs ("STATIC", stderr
);
1095 fputs ("DYNAMIC", stderr
);
1098 fputs ("GUIDED", stderr
);
1101 fputs ("AUTO", stderr
);
1104 fputs ("'\n", stderr
);
1106 fputs (" OMP_PROC_BIND = '", stderr
);
1107 switch (gomp_global_icv
.bind_var
)
1109 case omp_proc_bind_false
:
1110 fputs ("FALSE", stderr
);
1112 case omp_proc_bind_true
:
1113 fputs ("TRUE", stderr
);
1115 case omp_proc_bind_master
:
1116 fputs ("MASTER", stderr
);
1118 case omp_proc_bind_close
:
1119 fputs ("CLOSE", stderr
);
1121 case omp_proc_bind_spread
:
1122 fputs ("SPREAD", stderr
);
1125 for (i
= 1; i
< gomp_bind_var_list_len
; i
++)
1126 switch (gomp_bind_var_list
[i
])
1128 case omp_proc_bind_master
:
1129 fputs (",MASTER", stderr
);
1131 case omp_proc_bind_close
:
1132 fputs (",CLOSE", stderr
);
1134 case omp_proc_bind_spread
:
1135 fputs (",SPREAD", stderr
);
1138 fputs ("'\n", stderr
);
1139 fputs (" OMP_PLACES = '", stderr
);
1140 for (i
= 0; i
< gomp_places_list_len
; i
++)
1142 fputs ("{", stderr
);
1143 gomp_affinity_print_place (gomp_places_list
[i
]);
1144 fputs (i
+ 1 == gomp_places_list_len
? "}" : "},", stderr
);
1146 fputs ("'\n", stderr
);
1148 fprintf (stderr
, " OMP_STACKSIZE = '%lu'\n", stacksize
);
1150 /* GOMP's default value is actually neither active nor passive. */
1151 fprintf (stderr
, " OMP_WAIT_POLICY = '%s'\n",
1152 wait_policy
> 0 ? "ACTIVE" : "PASSIVE");
1153 fprintf (stderr
, " OMP_THREAD_LIMIT = '%u'\n",
1154 gomp_global_icv
.thread_limit_var
);
1155 fprintf (stderr
, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1156 gomp_max_active_levels_var
);
1158 fprintf (stderr
, " OMP_CANCELLATION = '%s'\n",
1159 gomp_cancel_var
? "TRUE" : "FALSE");
1160 fprintf (stderr
, " OMP_DEFAULT_DEVICE = '%d'\n",
1161 gomp_global_icv
.default_device_var
);
1162 fprintf (stderr
, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1163 gomp_max_task_priority_var
);
1167 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr
);
1168 fprintf (stderr
, " GOMP_STACKSIZE = '%lu'\n", stacksize
);
1169 #ifdef HAVE_INTTYPES_H
1170 fprintf (stderr
, " GOMP_SPINCOUNT = '%"PRIu64
"'\n",
1171 (uint64_t) gomp_spin_count_var
);
1173 fprintf (stderr
, " GOMP_SPINCOUNT = '%lu'\n",
1174 (unsigned long) gomp_spin_count_var
);
1178 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr
);
1182 static void __attribute__((constructor
))
1183 initialize_env (void)
1185 unsigned long thread_limit_var
, stacksize
;
1188 /* Do a compile time check that mkomp_h.pl did good job. */
1189 omp_check_defines ();
1192 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv
.dyn_var
);
1193 parse_boolean ("OMP_NESTED", &gomp_global_icv
.nest_var
);
1194 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var
);
1195 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv
.default_device_var
, true);
1196 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var
, true);
1197 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var
,
1199 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var
, false))
1201 gomp_global_icv
.thread_limit_var
1202 = thread_limit_var
> INT_MAX
? UINT_MAX
: thread_limit_var
;
1204 parse_int ("GOMP_DEBUG", &gomp_debug_var
, true);
1205 #ifndef HAVE_SYNC_BUILTINS
1206 gomp_mutex_init (&gomp_managed_threads_lock
);
1208 gomp_init_num_threads ();
1209 gomp_available_cpus
= gomp_global_icv
.nthreads_var
;
1210 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1211 &gomp_global_icv
.nthreads_var
,
1212 &gomp_nthreads_var_list
,
1213 &gomp_nthreads_var_list_len
))
1214 gomp_global_icv
.nthreads_var
= gomp_available_cpus
;
1215 bool ignore
= false;
1216 if (parse_bind_var ("OMP_PROC_BIND",
1217 &gomp_global_icv
.bind_var
,
1218 &gomp_bind_var_list
,
1219 &gomp_bind_var_list_len
)
1220 && gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1222 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1223 parsed if present in the environment. If OMP_PROC_BIND was set
1224 explictly to false, don't populate places list though. If places
1225 list was successfully set from OMP_PLACES, only parse but don't process
1226 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1227 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1228 was successfully parsed into a places list, otherwise to
1229 OMP_PROC_BIND=false. */
1230 if (parse_places_var ("OMP_PLACES", ignore
))
1232 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1233 gomp_global_icv
.bind_var
= true;
1236 if (parse_affinity (ignore
))
1238 if (gomp_global_icv
.bind_var
== omp_proc_bind_false
)
1239 gomp_global_icv
.bind_var
= true;
1242 if (gomp_global_icv
.bind_var
!= omp_proc_bind_false
)
1243 gomp_init_affinity ();
1244 wait_policy
= parse_wait_policy ();
1245 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var
))
1247 /* Using a rough estimation of 100000 spins per msec,
1248 use 5 min blocking for OMP_WAIT_POLICY=active,
1249 3 msec blocking when OMP_WAIT_POLICY is not specificed
1250 and 0 when OMP_WAIT_POLICY=passive.
1251 Depending on the CPU speed, this can be e.g. 5 times longer
1252 or 5 times shorter. */
1253 if (wait_policy
> 0)
1254 gomp_spin_count_var
= 30000000000LL;
1255 else if (wait_policy
< 0)
1256 gomp_spin_count_var
= 300000LL;
1258 /* gomp_throttled_spin_count_var is used when there are more libgomp
1259 managed threads than available CPUs. Use very short spinning. */
1260 if (wait_policy
> 0)
1261 gomp_throttled_spin_count_var
= 1000LL;
1262 else if (wait_policy
< 0)
1263 gomp_throttled_spin_count_var
= 100LL;
1264 if (gomp_throttled_spin_count_var
> gomp_spin_count_var
)
1265 gomp_throttled_spin_count_var
= gomp_spin_count_var
;
1267 /* Not strictly environment related, but ordering constructors is tricky. */
1268 pthread_attr_init (&gomp_thread_attr
);
1269 pthread_attr_setdetachstate (&gomp_thread_attr
, PTHREAD_CREATE_DETACHED
);
1271 if (parse_stacksize ("OMP_STACKSIZE", &stacksize
)
1272 || parse_stacksize ("GOMP_STACKSIZE", &stacksize
))
1276 err
= pthread_attr_setstacksize (&gomp_thread_attr
, stacksize
);
1278 #ifdef PTHREAD_STACK_MIN
1281 if (stacksize
< PTHREAD_STACK_MIN
)
1282 gomp_error ("Stack size less than minimum of %luk",
1283 PTHREAD_STACK_MIN
/ 1024ul
1284 + (PTHREAD_STACK_MIN
% 1024 != 0));
1286 gomp_error ("Stack size larger than system limit");
1291 gomp_error ("Stack size change failed: %s", strerror (err
));
1294 handle_omp_display_env (stacksize
, wait_policy
);
1298 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num
, true))
1299 goacc_device_num
= 0;
1301 parse_acc_device_type ();
1303 goacc_runtime_initialize ();
1307 /* The public OpenMP API routines that access these variables. */
1310 omp_set_num_threads (int n
)
1312 struct gomp_task_icv
*icv
= gomp_icv (true);
1313 icv
->nthreads_var
= (n
> 0 ? n
: 1);
1317 omp_set_dynamic (int val
)
1319 struct gomp_task_icv
*icv
= gomp_icv (true);
1324 omp_get_dynamic (void)
1326 struct gomp_task_icv
*icv
= gomp_icv (false);
1327 return icv
->dyn_var
;
1331 omp_set_nested (int val
)
1333 struct gomp_task_icv
*icv
= gomp_icv (true);
1334 icv
->nest_var
= val
;
1338 omp_get_nested (void)
1340 struct gomp_task_icv
*icv
= gomp_icv (false);
1341 return icv
->nest_var
;
1345 omp_set_schedule (omp_sched_t kind
, int chunk_size
)
1347 struct gomp_task_icv
*icv
= gomp_icv (true);
1350 case omp_sched_static
:
1353 icv
->run_sched_chunk_size
= chunk_size
;
1355 case omp_sched_dynamic
:
1356 case omp_sched_guided
:
1359 icv
->run_sched_chunk_size
= chunk_size
;
1361 case omp_sched_auto
:
1366 icv
->run_sched_var
= kind
;
1370 omp_get_schedule (omp_sched_t
*kind
, int *chunk_size
)
1372 struct gomp_task_icv
*icv
= gomp_icv (false);
1373 *kind
= icv
->run_sched_var
;
1374 *chunk_size
= icv
->run_sched_chunk_size
;
1378 omp_get_max_threads (void)
1380 struct gomp_task_icv
*icv
= gomp_icv (false);
1381 return icv
->nthreads_var
;
1385 omp_get_thread_limit (void)
1387 struct gomp_task_icv
*icv
= gomp_icv (false);
1388 return icv
->thread_limit_var
> INT_MAX
? INT_MAX
: icv
->thread_limit_var
;
1392 omp_set_max_active_levels (int max_levels
)
1394 if (max_levels
>= 0)
1395 gomp_max_active_levels_var
= max_levels
;
1399 omp_get_max_active_levels (void)
1401 return gomp_max_active_levels_var
;
1405 omp_get_cancellation (void)
1407 return gomp_cancel_var
;
1411 omp_get_max_task_priority (void)
1413 return gomp_max_task_priority_var
;
1417 omp_get_proc_bind (void)
1419 struct gomp_task_icv
*icv
= gomp_icv (false);
1420 return icv
->bind_var
;
1424 omp_set_default_device (int device_num
)
1426 struct gomp_task_icv
*icv
= gomp_icv (true);
1427 icv
->default_device_var
= device_num
>= 0 ? device_num
: 0;
1431 omp_get_default_device (void)
1433 struct gomp_task_icv
*icv
= gomp_icv (false);
1434 return icv
->default_device_var
;
1438 omp_get_num_devices (void)
1440 return gomp_get_num_devices ();
1444 omp_get_num_teams (void)
1446 /* Hardcoded to 1 on host, MIC, HSAIL? Maybe variable on PTX. */
1451 omp_get_team_num (void)
1453 /* Hardcoded to 0 on host, MIC, HSAIL? Maybe variable on PTX. */
1458 omp_is_initial_device (void)
1460 /* Hardcoded to 1 on host, should be 0 on MIC, HSAIL, PTX. */
1465 omp_get_initial_device (void)
1467 return GOMP_DEVICE_HOST_FALLBACK
;
1471 omp_get_num_places (void)
1473 return gomp_places_list_len
;
1477 omp_get_place_num (void)
1479 if (gomp_places_list
== NULL
)
1482 struct gomp_thread
*thr
= gomp_thread ();
1483 if (thr
->place
== 0)
1484 gomp_init_affinity ();
1486 return (int) thr
->place
- 1;
1490 omp_get_partition_num_places (void)
1492 if (gomp_places_list
== NULL
)
1495 struct gomp_thread
*thr
= gomp_thread ();
1496 if (thr
->place
== 0)
1497 gomp_init_affinity ();
1499 return thr
->ts
.place_partition_len
;
1503 omp_get_partition_place_nums (int *place_nums
)
1505 if (gomp_places_list
== NULL
)
1508 struct gomp_thread
*thr
= gomp_thread ();
1509 if (thr
->place
== 0)
1510 gomp_init_affinity ();
1513 for (i
= 0; i
< thr
->ts
.place_partition_len
; i
++)
1514 *place_nums
++ = thr
->ts
.place_partition_off
+ i
;
1517 ialias (omp_set_dynamic
)
1518 ialias (omp_set_nested
)
1519 ialias (omp_set_num_threads
)
1520 ialias (omp_get_dynamic
)
1521 ialias (omp_get_nested
)
1522 ialias (omp_set_schedule
)
1523 ialias (omp_get_schedule
)
1524 ialias (omp_get_max_threads
)
1525 ialias (omp_get_thread_limit
)
1526 ialias (omp_set_max_active_levels
)
1527 ialias (omp_get_max_active_levels
)
1528 ialias (omp_get_cancellation
)
1529 ialias (omp_get_proc_bind
)
1530 ialias (omp_set_default_device
)
1531 ialias (omp_get_default_device
)
1532 ialias (omp_get_num_devices
)
1533 ialias (omp_get_num_teams
)
1534 ialias (omp_get_team_num
)
1535 ialias (omp_is_initial_device
)
1536 ialias (omp_get_initial_device
)
1537 ialias (omp_get_max_task_priority
)
1538 ialias (omp_get_num_places
)
1539 ialias (omp_get_place_num
)
1540 ialias (omp_get_partition_num_places
)
1541 ialias (omp_get_partition_place_nums
)