* config/spu/spu.md (floatunsdidf2): Remove unused local variable.
[official-gcc.git] / libgomp / env.c
blob7ba7663da9aeccde4a3f1fcb5f2b91988c5c143d
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
5 (libgomp).
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)
10 any later version.
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
15 more details.
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 arranges for OpenMP internal control variables to be initialized
27 from environment variables at startup. */
29 #include "libgomp.h"
30 #include "libgomp_f.h"
31 #include "oacc-int.h"
32 #include "gomp-constants.h"
33 #include <ctype.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #ifdef HAVE_INTTYPES_H
37 # include <inttypes.h> /* For PRIu64. */
38 #endif
39 #ifdef STRING_WITH_STRINGS
40 # include <string.h>
41 # include <strings.h>
42 #else
43 # ifdef HAVE_STRING_H
44 # include <string.h>
45 # else
46 # ifdef HAVE_STRINGS_H
47 # include <strings.h>
48 # endif
49 # endif
50 #endif
51 #include <limits.h>
52 #include <errno.h>
54 #ifndef HAVE_STRTOULL
55 # define strtoull(ptr, eptr, base) strtoul (ptr, eptr, base)
56 #endif
58 /* Parse the OMP_SCHEDULE environment variable. */
60 static void
61 parse_schedule (void)
63 char *env, *end;
64 unsigned long value;
66 env = getenv ("OMP_SCHEDULE");
67 if (env == NULL)
68 return;
70 while (isspace ((unsigned char) *env))
71 ++env;
72 if (strncasecmp (env, "static", 6) == 0)
74 gomp_global_icv.run_sched_var = GFS_STATIC;
75 env += 6;
77 else if (strncasecmp (env, "dynamic", 7) == 0)
79 gomp_global_icv.run_sched_var = GFS_DYNAMIC;
80 env += 7;
82 else if (strncasecmp (env, "guided", 6) == 0)
84 gomp_global_icv.run_sched_var = GFS_GUIDED;
85 env += 6;
87 else if (strncasecmp (env, "auto", 4) == 0)
89 gomp_global_icv.run_sched_var = GFS_AUTO;
90 env += 4;
92 else
93 goto unknown;
95 while (isspace ((unsigned char) *env))
96 ++env;
97 if (*env == '\0')
99 gomp_global_icv.run_sched_chunk_size
100 = gomp_global_icv.run_sched_var != GFS_STATIC;
101 return;
103 if (*env++ != ',')
104 goto unknown;
105 while (isspace ((unsigned char) *env))
106 ++env;
107 if (*env == '\0')
108 goto invalid;
110 errno = 0;
111 value = strtoul (env, &end, 10);
112 if (errno)
113 goto invalid;
115 while (isspace ((unsigned char) *end))
116 ++end;
117 if (*end != '\0')
118 goto invalid;
120 if ((int)value != value)
121 goto invalid;
123 if (value == 0 && gomp_global_icv.run_sched_var != GFS_STATIC)
124 value = 1;
125 gomp_global_icv.run_sched_chunk_size = value;
126 return;
128 unknown:
129 gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
130 return;
132 invalid:
133 gomp_error ("Invalid value for chunk size in "
134 "environment variable OMP_SCHEDULE");
135 return;
138 /* Parse an unsigned long environment variable. Return true if one was
139 present and it was successfully parsed. */
141 static bool
142 parse_unsigned_long (const char *name, unsigned long *pvalue, bool allow_zero)
144 char *env, *end;
145 unsigned long value;
147 env = getenv (name);
148 if (env == NULL)
149 return false;
151 while (isspace ((unsigned char) *env))
152 ++env;
153 if (*env == '\0')
154 goto invalid;
156 errno = 0;
157 value = strtoul (env, &end, 10);
158 if (errno || (long) value <= 0 - allow_zero)
159 goto invalid;
161 while (isspace ((unsigned char) *end))
162 ++end;
163 if (*end != '\0')
164 goto invalid;
166 *pvalue = value;
167 return true;
169 invalid:
170 gomp_error ("Invalid value for environment variable %s", name);
171 return false;
174 /* Parse a positive int environment variable. Return true if one was
175 present and it was successfully parsed. */
177 static bool
178 parse_int (const char *name, int *pvalue, bool allow_zero)
180 unsigned long value;
181 if (!parse_unsigned_long (name, &value, allow_zero))
182 return false;
183 if (value > INT_MAX)
185 gomp_error ("Invalid value for environment variable %s", name);
186 return false;
188 *pvalue = (int) value;
189 return true;
192 /* Parse an unsigned long list environment variable. Return true if one was
193 present and it was successfully parsed. */
195 static bool
196 parse_unsigned_long_list (const char *name, unsigned long *p1stvalue,
197 unsigned long **pvalues,
198 unsigned long *pnvalues)
200 char *env, *end;
201 unsigned long value, *values = NULL;
203 env = getenv (name);
204 if (env == NULL)
205 return false;
207 while (isspace ((unsigned char) *env))
208 ++env;
209 if (*env == '\0')
210 goto invalid;
212 errno = 0;
213 value = strtoul (env, &end, 10);
214 if (errno || (long) value <= 0)
215 goto invalid;
217 while (isspace ((unsigned char) *end))
218 ++end;
219 if (*end != '\0')
221 if (*end == ',')
223 unsigned long nvalues = 0, nalloced = 0;
227 env = end + 1;
228 if (nvalues == nalloced)
230 unsigned long *n;
231 nalloced = nalloced ? nalloced * 2 : 16;
232 n = realloc (values, nalloced * sizeof (unsigned long));
233 if (n == NULL)
235 free (values);
236 gomp_error ("Out of memory while trying to parse"
237 " environment variable %s", name);
238 return false;
240 values = n;
241 if (nvalues == 0)
242 values[nvalues++] = value;
245 while (isspace ((unsigned char) *env))
246 ++env;
247 if (*env == '\0')
248 goto invalid;
250 errno = 0;
251 value = strtoul (env, &end, 10);
252 if (errno || (long) value <= 0)
253 goto invalid;
255 values[nvalues++] = value;
256 while (isspace ((unsigned char) *end))
257 ++end;
258 if (*end == '\0')
259 break;
260 if (*end != ',')
261 goto invalid;
263 while (1);
264 *p1stvalue = values[0];
265 *pvalues = values;
266 *pnvalues = nvalues;
267 return true;
269 goto invalid;
272 *p1stvalue = value;
273 return true;
275 invalid:
276 free (values);
277 gomp_error ("Invalid value for environment variable %s", name);
278 return false;
281 /* Parse environment variable set to a boolean or list of omp_proc_bind_t
282 enum values. Return true if one was present and it was successfully
283 parsed. */
285 static bool
286 parse_bind_var (const char *name, char *p1stvalue,
287 char **pvalues, unsigned long *pnvalues)
289 char *env;
290 char value = omp_proc_bind_false, *values = NULL;
291 int i;
292 static struct proc_bind_kinds
294 const char name[7];
295 const char len;
296 omp_proc_bind_t kind;
297 } kinds[] =
299 { "false", 5, omp_proc_bind_false },
300 { "true", 4, omp_proc_bind_true },
301 { "master", 6, omp_proc_bind_master },
302 { "close", 5, omp_proc_bind_close },
303 { "spread", 6, omp_proc_bind_spread }
306 env = getenv (name);
307 if (env == NULL)
308 return false;
310 while (isspace ((unsigned char) *env))
311 ++env;
312 if (*env == '\0')
313 goto invalid;
315 for (i = 0; i < 5; i++)
316 if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
318 value = kinds[i].kind;
319 env += kinds[i].len;
320 break;
322 if (i == 5)
323 goto invalid;
325 while (isspace ((unsigned char) *env))
326 ++env;
327 if (*env != '\0')
329 if (*env == ',')
331 unsigned long nvalues = 0, nalloced = 0;
333 if (value == omp_proc_bind_false
334 || value == omp_proc_bind_true)
335 goto invalid;
339 env++;
340 if (nvalues == nalloced)
342 char *n;
343 nalloced = nalloced ? nalloced * 2 : 16;
344 n = realloc (values, nalloced);
345 if (n == NULL)
347 free (values);
348 gomp_error ("Out of memory while trying to parse"
349 " environment variable %s", name);
350 return false;
352 values = n;
353 if (nvalues == 0)
354 values[nvalues++] = value;
357 while (isspace ((unsigned char) *env))
358 ++env;
359 if (*env == '\0')
360 goto invalid;
362 for (i = 2; i < 5; i++)
363 if (strncasecmp (env, kinds[i].name, kinds[i].len) == 0)
365 value = kinds[i].kind;
366 env += kinds[i].len;
367 break;
369 if (i == 5)
370 goto invalid;
372 values[nvalues++] = value;
373 while (isspace ((unsigned char) *env))
374 ++env;
375 if (*env == '\0')
376 break;
377 if (*env != ',')
378 goto invalid;
380 while (1);
381 *p1stvalue = values[0];
382 *pvalues = values;
383 *pnvalues = nvalues;
384 return true;
386 goto invalid;
389 *p1stvalue = value;
390 return true;
392 invalid:
393 free (values);
394 gomp_error ("Invalid value for environment variable %s", name);
395 return false;
398 static bool
399 parse_one_place (char **envp, bool *negatep, unsigned long *lenp,
400 long *stridep)
402 char *env = *envp, *start;
403 void *p = gomp_places_list ? gomp_places_list[gomp_places_list_len] : NULL;
404 unsigned long len = 1;
405 long stride = 1;
406 int pass;
407 bool any_negate = false;
408 *negatep = false;
409 while (isspace ((unsigned char) *env))
410 ++env;
411 if (*env == '!')
413 *negatep = true;
414 ++env;
415 while (isspace ((unsigned char) *env))
416 ++env;
418 if (*env != '{')
419 return false;
420 ++env;
421 while (isspace ((unsigned char) *env))
422 ++env;
423 start = env;
424 for (pass = 0; pass < (any_negate ? 2 : 1); pass++)
426 env = start;
429 unsigned long this_num, this_len = 1;
430 long this_stride = 1;
431 bool this_negate = (*env == '!');
432 if (this_negate)
434 if (gomp_places_list)
435 any_negate = true;
436 ++env;
437 while (isspace ((unsigned char) *env))
438 ++env;
441 errno = 0;
442 this_num = strtoul (env, &env, 10);
443 if (errno)
444 return false;
445 while (isspace ((unsigned char) *env))
446 ++env;
447 if (*env == ':')
449 ++env;
450 while (isspace ((unsigned char) *env))
451 ++env;
452 errno = 0;
453 this_len = strtoul (env, &env, 10);
454 if (errno || this_len == 0)
455 return false;
456 while (isspace ((unsigned char) *env))
457 ++env;
458 if (*env == ':')
460 ++env;
461 while (isspace ((unsigned char) *env))
462 ++env;
463 errno = 0;
464 this_stride = strtol (env, &env, 10);
465 if (errno)
466 return false;
467 while (isspace ((unsigned char) *env))
468 ++env;
471 if (this_negate && this_len != 1)
472 return false;
473 if (gomp_places_list && pass == this_negate)
475 if (this_negate)
477 if (!gomp_affinity_remove_cpu (p, this_num))
478 return false;
480 else if (!gomp_affinity_add_cpus (p, this_num, this_len,
481 this_stride, false))
482 return false;
484 if (*env == '}')
485 break;
486 if (*env != ',')
487 return false;
488 ++env;
490 while (1);
493 ++env;
494 while (isspace ((unsigned char) *env))
495 ++env;
496 if (*env == ':')
498 ++env;
499 while (isspace ((unsigned char) *env))
500 ++env;
501 errno = 0;
502 len = strtoul (env, &env, 10);
503 if (errno || len == 0 || len >= 65536)
504 return false;
505 while (isspace ((unsigned char) *env))
506 ++env;
507 if (*env == ':')
509 ++env;
510 while (isspace ((unsigned char) *env))
511 ++env;
512 errno = 0;
513 stride = strtol (env, &env, 10);
514 if (errno)
515 return false;
516 while (isspace ((unsigned char) *env))
517 ++env;
520 if (*negatep && len != 1)
521 return false;
522 *envp = env;
523 *lenp = len;
524 *stridep = stride;
525 return true;
528 static bool
529 parse_places_var (const char *name, bool ignore)
531 char *env = getenv (name), *end;
532 bool any_negate = false;
533 int level = 0;
534 unsigned long count = 0;
535 if (env == NULL)
536 return false;
538 while (isspace ((unsigned char) *env))
539 ++env;
540 if (*env == '\0')
541 goto invalid;
543 if (strncasecmp (env, "threads", 7) == 0)
545 env += 7;
546 level = 1;
548 else if (strncasecmp (env, "cores", 5) == 0)
550 env += 5;
551 level = 2;
553 else if (strncasecmp (env, "sockets", 7) == 0)
555 env += 7;
556 level = 3;
558 if (level)
560 count = ULONG_MAX;
561 while (isspace ((unsigned char) *env))
562 ++env;
563 if (*env != '\0')
565 if (*env++ != '(')
566 goto invalid;
567 while (isspace ((unsigned char) *env))
568 ++env;
570 errno = 0;
571 count = strtoul (env, &end, 10);
572 if (errno)
573 goto invalid;
574 env = end;
575 while (isspace ((unsigned char) *env))
576 ++env;
577 if (*env != ')')
578 goto invalid;
579 ++env;
580 while (isspace ((unsigned char) *env))
581 ++env;
582 if (*env != '\0')
583 goto invalid;
586 if (ignore)
587 return false;
589 return gomp_affinity_init_level (level, count, false);
592 count = 0;
593 end = env;
596 bool negate;
597 unsigned long len;
598 long stride;
599 if (!parse_one_place (&end, &negate, &len, &stride))
600 goto invalid;
601 if (negate)
603 if (!any_negate)
604 count++;
605 any_negate = true;
607 else
608 count += len;
609 if (count > 65536)
610 goto invalid;
611 if (*end == '\0')
612 break;
613 if (*end != ',')
614 goto invalid;
615 end++;
617 while (1);
619 if (ignore)
620 return false;
622 gomp_places_list_len = 0;
623 gomp_places_list = gomp_affinity_alloc (count, false);
624 if (gomp_places_list == NULL)
625 return false;
629 bool negate;
630 unsigned long len;
631 long stride;
632 gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
633 if (!parse_one_place (&env, &negate, &len, &stride))
634 goto invalid;
635 if (negate)
637 void *p;
638 for (count = 0; count < gomp_places_list_len; count++)
639 if (gomp_affinity_same_place
640 (gomp_places_list[count],
641 gomp_places_list[gomp_places_list_len]))
642 break;
643 if (count == gomp_places_list_len)
645 gomp_error ("Trying to remove a non-existing place from list "
646 "of places");
647 goto invalid;
649 p = gomp_places_list[count];
650 memmove (&gomp_places_list[count],
651 &gomp_places_list[count + 1],
652 (gomp_places_list_len - count - 1) * sizeof (void *));
653 --gomp_places_list_len;
654 gomp_places_list[gomp_places_list_len] = p;
656 else if (len == 1)
657 ++gomp_places_list_len;
658 else
660 for (count = 0; count < len - 1; count++)
661 if (!gomp_affinity_copy_place
662 (gomp_places_list[gomp_places_list_len + count + 1],
663 gomp_places_list[gomp_places_list_len + count],
664 stride))
665 goto invalid;
666 gomp_places_list_len += len;
668 if (*env == '\0')
669 break;
670 env++;
672 while (1);
674 if (gomp_places_list_len == 0)
676 gomp_error ("All places have been removed");
677 goto invalid;
679 if (!gomp_affinity_finalize_place_list (false))
680 goto invalid;
681 return true;
683 invalid:
684 free (gomp_places_list);
685 gomp_places_list = NULL;
686 gomp_places_list_len = 0;
687 gomp_error ("Invalid value for environment variable %s", name);
688 return false;
691 /* Parse the OMP_STACKSIZE environment varible. Return true if one was
692 present and it was successfully parsed. */
694 static bool
695 parse_stacksize (const char *name, unsigned long *pvalue)
697 char *env, *end;
698 unsigned long value, shift = 10;
700 env = getenv (name);
701 if (env == NULL)
702 return false;
704 while (isspace ((unsigned char) *env))
705 ++env;
706 if (*env == '\0')
707 goto invalid;
709 errno = 0;
710 value = strtoul (env, &end, 10);
711 if (errno)
712 goto invalid;
714 while (isspace ((unsigned char) *end))
715 ++end;
716 if (*end != '\0')
718 switch (tolower ((unsigned char) *end))
720 case 'b':
721 shift = 0;
722 break;
723 case 'k':
724 break;
725 case 'm':
726 shift = 20;
727 break;
728 case 'g':
729 shift = 30;
730 break;
731 default:
732 goto invalid;
734 ++end;
735 while (isspace ((unsigned char) *end))
736 ++end;
737 if (*end != '\0')
738 goto invalid;
741 if (((value << shift) >> shift) != value)
742 goto invalid;
744 *pvalue = value << shift;
745 return true;
747 invalid:
748 gomp_error ("Invalid value for environment variable %s", name);
749 return false;
752 /* Parse the GOMP_SPINCOUNT environment varible. Return true if one was
753 present and it was successfully parsed. */
755 static bool
756 parse_spincount (const char *name, unsigned long long *pvalue)
758 char *env, *end;
759 unsigned long long value, mult = 1;
761 env = getenv (name);
762 if (env == NULL)
763 return false;
765 while (isspace ((unsigned char) *env))
766 ++env;
767 if (*env == '\0')
768 goto invalid;
770 if (strncasecmp (env, "infinite", 8) == 0
771 || strncasecmp (env, "infinity", 8) == 0)
773 value = ~0ULL;
774 end = env + 8;
775 goto check_tail;
778 errno = 0;
779 value = strtoull (env, &end, 10);
780 if (errno)
781 goto invalid;
783 while (isspace ((unsigned char) *end))
784 ++end;
785 if (*end != '\0')
787 switch (tolower ((unsigned char) *end))
789 case 'k':
790 mult = 1000LL;
791 break;
792 case 'm':
793 mult = 1000LL * 1000LL;
794 break;
795 case 'g':
796 mult = 1000LL * 1000LL * 1000LL;
797 break;
798 case 't':
799 mult = 1000LL * 1000LL * 1000LL * 1000LL;
800 break;
801 default:
802 goto invalid;
804 ++end;
805 check_tail:
806 while (isspace ((unsigned char) *end))
807 ++end;
808 if (*end != '\0')
809 goto invalid;
812 if (value > ~0ULL / mult)
813 value = ~0ULL;
814 else
815 value *= mult;
817 *pvalue = value;
818 return true;
820 invalid:
821 gomp_error ("Invalid value for environment variable %s", name);
822 return false;
825 /* Parse a boolean value for environment variable NAME and store the
826 result in VALUE. */
828 static void
829 parse_boolean (const char *name, bool *value)
831 const char *env;
833 env = getenv (name);
834 if (env == NULL)
835 return;
837 while (isspace ((unsigned char) *env))
838 ++env;
839 if (strncasecmp (env, "true", 4) == 0)
841 *value = true;
842 env += 4;
844 else if (strncasecmp (env, "false", 5) == 0)
846 *value = false;
847 env += 5;
849 else
850 env = "X";
851 while (isspace ((unsigned char) *env))
852 ++env;
853 if (*env != '\0')
854 gomp_error ("Invalid value for environment variable %s", name);
857 /* Parse the OMP_WAIT_POLICY environment variable and store the
858 result in gomp_active_wait_policy. */
860 static int
861 parse_wait_policy (void)
863 const char *env;
864 int ret = -1;
866 env = getenv ("OMP_WAIT_POLICY");
867 if (env == NULL)
868 return -1;
870 while (isspace ((unsigned char) *env))
871 ++env;
872 if (strncasecmp (env, "active", 6) == 0)
874 ret = 1;
875 env += 6;
877 else if (strncasecmp (env, "passive", 7) == 0)
879 ret = 0;
880 env += 7;
882 else
883 env = "X";
884 while (isspace ((unsigned char) *env))
885 ++env;
886 if (*env == '\0')
887 return ret;
888 gomp_error ("Invalid value for environment variable OMP_WAIT_POLICY");
889 return -1;
892 /* Parse the GOMP_CPU_AFFINITY environment varible. Return true if one was
893 present and it was successfully parsed. */
895 static bool
896 parse_affinity (bool ignore)
898 char *env, *end, *start;
899 int pass;
900 unsigned long cpu_beg, cpu_end, cpu_stride;
901 size_t count = 0, needed;
903 env = getenv ("GOMP_CPU_AFFINITY");
904 if (env == NULL)
905 return false;
907 start = env;
908 for (pass = 0; pass < 2; pass++)
910 env = start;
911 if (pass == 1)
913 if (ignore)
914 return false;
916 gomp_places_list_len = 0;
917 gomp_places_list = gomp_affinity_alloc (count, true);
918 if (gomp_places_list == NULL)
919 return false;
923 while (isspace ((unsigned char) *env))
924 ++env;
926 errno = 0;
927 cpu_beg = strtoul (env, &end, 0);
928 if (errno || cpu_beg >= 65536)
929 goto invalid;
930 cpu_end = cpu_beg;
931 cpu_stride = 1;
933 env = end;
934 if (*env == '-')
936 errno = 0;
937 cpu_end = strtoul (++env, &end, 0);
938 if (errno || cpu_end >= 65536 || cpu_end < cpu_beg)
939 goto invalid;
941 env = end;
942 if (*env == ':')
944 errno = 0;
945 cpu_stride = strtoul (++env, &end, 0);
946 if (errno || cpu_stride == 0 || cpu_stride >= 65536)
947 goto invalid;
949 env = end;
953 needed = (cpu_end - cpu_beg) / cpu_stride + 1;
954 if (pass == 0)
955 count += needed;
956 else
958 while (needed--)
960 void *p = gomp_places_list[gomp_places_list_len];
961 gomp_affinity_init_place (p);
962 if (gomp_affinity_add_cpus (p, cpu_beg, 1, 0, true))
963 ++gomp_places_list_len;
964 cpu_beg += cpu_stride;
968 while (isspace ((unsigned char) *env))
969 ++env;
971 if (*env == ',')
972 env++;
973 else if (*env == '\0')
974 break;
976 while (1);
979 if (gomp_places_list_len == 0)
981 free (gomp_places_list);
982 gomp_places_list = NULL;
983 return false;
985 return true;
987 invalid:
988 gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
989 return false;
992 static void
993 parse_acc_device_type (void)
995 const char *env = getenv ("ACC_DEVICE_TYPE");
997 if (env && *env != '\0')
998 goacc_device_type = strdup (env);
999 else
1000 goacc_device_type = NULL;
1003 static void
1004 handle_omp_display_env (unsigned long stacksize, int wait_policy)
1006 const char *env;
1007 bool display = false;
1008 bool verbose = false;
1009 int i;
1011 env = getenv ("OMP_DISPLAY_ENV");
1012 if (env == NULL)
1013 return;
1015 while (isspace ((unsigned char) *env))
1016 ++env;
1017 if (strncasecmp (env, "true", 4) == 0)
1019 display = true;
1020 env += 4;
1022 else if (strncasecmp (env, "false", 5) == 0)
1024 display = false;
1025 env += 5;
1027 else if (strncasecmp (env, "verbose", 7) == 0)
1029 display = true;
1030 verbose = true;
1031 env += 7;
1033 else
1034 env = "X";
1035 while (isspace ((unsigned char) *env))
1036 ++env;
1037 if (*env != '\0')
1038 gomp_error ("Invalid value for environment variable OMP_DISPLAY_ENV");
1040 if (!display)
1041 return;
1043 fputs ("\nOPENMP DISPLAY ENVIRONMENT BEGIN\n", stderr);
1045 fputs (" _OPENMP = '201511'\n", stderr);
1046 fprintf (stderr, " OMP_DYNAMIC = '%s'\n",
1047 gomp_global_icv.dyn_var ? "TRUE" : "FALSE");
1048 fprintf (stderr, " OMP_NESTED = '%s'\n",
1049 gomp_global_icv.nest_var ? "TRUE" : "FALSE");
1051 fprintf (stderr, " OMP_NUM_THREADS = '%lu", gomp_global_icv.nthreads_var);
1052 for (i = 1; i < gomp_nthreads_var_list_len; i++)
1053 fprintf (stderr, ",%lu", gomp_nthreads_var_list[i]);
1054 fputs ("'\n", stderr);
1056 fprintf (stderr, " OMP_SCHEDULE = '");
1057 switch (gomp_global_icv.run_sched_var)
1059 case GFS_RUNTIME:
1060 fputs ("RUNTIME", stderr);
1061 break;
1062 case GFS_STATIC:
1063 fputs ("STATIC", stderr);
1064 break;
1065 case GFS_DYNAMIC:
1066 fputs ("DYNAMIC", stderr);
1067 break;
1068 case GFS_GUIDED:
1069 fputs ("GUIDED", stderr);
1070 break;
1071 case GFS_AUTO:
1072 fputs ("AUTO", stderr);
1073 break;
1075 fputs ("'\n", stderr);
1077 fputs (" OMP_PROC_BIND = '", stderr);
1078 switch (gomp_global_icv.bind_var)
1080 case omp_proc_bind_false:
1081 fputs ("FALSE", stderr);
1082 break;
1083 case omp_proc_bind_true:
1084 fputs ("TRUE", stderr);
1085 break;
1086 case omp_proc_bind_master:
1087 fputs ("MASTER", stderr);
1088 break;
1089 case omp_proc_bind_close:
1090 fputs ("CLOSE", stderr);
1091 break;
1092 case omp_proc_bind_spread:
1093 fputs ("SPREAD", stderr);
1094 break;
1096 for (i = 1; i < gomp_bind_var_list_len; i++)
1097 switch (gomp_bind_var_list[i])
1099 case omp_proc_bind_master:
1100 fputs (",MASTER", stderr);
1101 break;
1102 case omp_proc_bind_close:
1103 fputs (",CLOSE", stderr);
1104 break;
1105 case omp_proc_bind_spread:
1106 fputs (",SPREAD", stderr);
1107 break;
1109 fputs ("'\n", stderr);
1110 fputs (" OMP_PLACES = '", stderr);
1111 for (i = 0; i < gomp_places_list_len; i++)
1113 fputs ("{", stderr);
1114 gomp_affinity_print_place (gomp_places_list[i]);
1115 fputs (i + 1 == gomp_places_list_len ? "}" : "},", stderr);
1117 fputs ("'\n", stderr);
1119 fprintf (stderr, " OMP_STACKSIZE = '%lu'\n", stacksize);
1121 /* GOMP's default value is actually neither active nor passive. */
1122 fprintf (stderr, " OMP_WAIT_POLICY = '%s'\n",
1123 wait_policy > 0 ? "ACTIVE" : "PASSIVE");
1124 fprintf (stderr, " OMP_THREAD_LIMIT = '%u'\n",
1125 gomp_global_icv.thread_limit_var);
1126 fprintf (stderr, " OMP_MAX_ACTIVE_LEVELS = '%lu'\n",
1127 gomp_max_active_levels_var);
1129 fprintf (stderr, " OMP_CANCELLATION = '%s'\n",
1130 gomp_cancel_var ? "TRUE" : "FALSE");
1131 fprintf (stderr, " OMP_DEFAULT_DEVICE = '%d'\n",
1132 gomp_global_icv.default_device_var);
1133 fprintf (stderr, " OMP_MAX_TASK_PRIORITY = '%d'\n",
1134 gomp_max_task_priority_var);
1136 if (verbose)
1138 fputs (" GOMP_CPU_AFFINITY = ''\n", stderr);
1139 fprintf (stderr, " GOMP_STACKSIZE = '%lu'\n", stacksize);
1140 #ifdef HAVE_INTTYPES_H
1141 fprintf (stderr, " GOMP_SPINCOUNT = '%"PRIu64"'\n",
1142 (uint64_t) gomp_spin_count_var);
1143 #else
1144 fprintf (stderr, " GOMP_SPINCOUNT = '%lu'\n",
1145 (unsigned long) gomp_spin_count_var);
1146 #endif
1149 fputs ("OPENMP DISPLAY ENVIRONMENT END\n", stderr);
1153 static void __attribute__((constructor))
1154 initialize_env (void)
1156 unsigned long thread_limit_var, stacksize;
1157 int wait_policy;
1159 /* Do a compile time check that mkomp_h.pl did good job. */
1160 omp_check_defines ();
1162 parse_schedule ();
1163 parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var);
1164 parse_boolean ("OMP_NESTED", &gomp_global_icv.nest_var);
1165 parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
1166 parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
1167 parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
1168 parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var,
1169 true);
1170 if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false))
1172 gomp_global_icv.thread_limit_var
1173 = thread_limit_var > INT_MAX ? UINT_MAX : thread_limit_var;
1175 parse_int ("GOMP_DEBUG", &gomp_debug_var, true);
1176 #ifndef HAVE_SYNC_BUILTINS
1177 gomp_mutex_init (&gomp_managed_threads_lock);
1178 #endif
1179 gomp_init_num_threads ();
1180 gomp_available_cpus = gomp_global_icv.nthreads_var;
1181 if (!parse_unsigned_long_list ("OMP_NUM_THREADS",
1182 &gomp_global_icv.nthreads_var,
1183 &gomp_nthreads_var_list,
1184 &gomp_nthreads_var_list_len))
1185 gomp_global_icv.nthreads_var = gomp_available_cpus;
1186 bool ignore = false;
1187 if (parse_bind_var ("OMP_PROC_BIND",
1188 &gomp_global_icv.bind_var,
1189 &gomp_bind_var_list,
1190 &gomp_bind_var_list_len)
1191 && gomp_global_icv.bind_var == omp_proc_bind_false)
1192 ignore = true;
1193 /* Make sure OMP_PLACES and GOMP_CPU_AFFINITY env vars are always
1194 parsed if present in the environment. If OMP_PROC_BIND was set
1195 explictly to false, don't populate places list though. If places
1196 list was successfully set from OMP_PLACES, only parse but don't process
1197 GOMP_CPU_AFFINITY. If OMP_PROC_BIND was not set in the environment,
1198 default to OMP_PROC_BIND=true if OMP_PLACES or GOMP_CPU_AFFINITY
1199 was successfully parsed into a places list, otherwise to
1200 OMP_PROC_BIND=false. */
1201 if (parse_places_var ("OMP_PLACES", ignore))
1203 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1204 gomp_global_icv.bind_var = true;
1205 ignore = true;
1207 if (parse_affinity (ignore))
1209 if (gomp_global_icv.bind_var == omp_proc_bind_false)
1210 gomp_global_icv.bind_var = true;
1211 ignore = true;
1213 if (gomp_global_icv.bind_var != omp_proc_bind_false)
1214 gomp_init_affinity ();
1215 wait_policy = parse_wait_policy ();
1216 if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var))
1218 /* Using a rough estimation of 100000 spins per msec,
1219 use 5 min blocking for OMP_WAIT_POLICY=active,
1220 3 msec blocking when OMP_WAIT_POLICY is not specificed
1221 and 0 when OMP_WAIT_POLICY=passive.
1222 Depending on the CPU speed, this can be e.g. 5 times longer
1223 or 5 times shorter. */
1224 if (wait_policy > 0)
1225 gomp_spin_count_var = 30000000000LL;
1226 else if (wait_policy < 0)
1227 gomp_spin_count_var = 300000LL;
1229 /* gomp_throttled_spin_count_var is used when there are more libgomp
1230 managed threads than available CPUs. Use very short spinning. */
1231 if (wait_policy > 0)
1232 gomp_throttled_spin_count_var = 1000LL;
1233 else if (wait_policy < 0)
1234 gomp_throttled_spin_count_var = 100LL;
1235 if (gomp_throttled_spin_count_var > gomp_spin_count_var)
1236 gomp_throttled_spin_count_var = gomp_spin_count_var;
1238 /* Not strictly environment related, but ordering constructors is tricky. */
1239 pthread_attr_init (&gomp_thread_attr);
1240 pthread_attr_setdetachstate (&gomp_thread_attr, PTHREAD_CREATE_DETACHED);
1242 if (parse_stacksize ("OMP_STACKSIZE", &stacksize)
1243 || parse_stacksize ("GOMP_STACKSIZE", &stacksize))
1245 int err;
1247 err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);
1249 #ifdef PTHREAD_STACK_MIN
1250 if (err == EINVAL)
1252 if (stacksize < PTHREAD_STACK_MIN)
1253 gomp_error ("Stack size less than minimum of %luk",
1254 PTHREAD_STACK_MIN / 1024ul
1255 + (PTHREAD_STACK_MIN % 1024 != 0));
1256 else
1257 gomp_error ("Stack size larger than system limit");
1259 else
1260 #endif
1261 if (err != 0)
1262 gomp_error ("Stack size change failed: %s", strerror (err));
1265 handle_omp_display_env (stacksize, wait_policy);
1267 /* OpenACC. */
1269 if (!parse_int ("ACC_DEVICE_NUM", &goacc_device_num, true))
1270 goacc_device_num = 0;
1272 parse_acc_device_type ();
1274 goacc_runtime_initialize ();