]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/openmp/runtime/src/kmp_settings.cpp
Add LLVM openmp trunk r351319 (just before the release_80 branch point)
[FreeBSD/FreeBSD.git] / contrib / openmp / runtime / src / kmp_settings.cpp
1 /*
2  * kmp_settings.cpp -- Initialize environment variables
3  */
4
5 //===----------------------------------------------------------------------===//
6 //
7 //                     The LLVM Compiler Infrastructure
8 //
9 // This file is dual licensed under the MIT and the University of Illinois Open
10 // Source Licenses. See LICENSE.txt for details.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "kmp.h"
15 #include "kmp_affinity.h"
16 #include "kmp_atomic.h"
17 #if KMP_USE_HIER_SCHED
18 #include "kmp_dispatch_hier.h"
19 #endif
20 #include "kmp_environment.h"
21 #include "kmp_i18n.h"
22 #include "kmp_io.h"
23 #include "kmp_itt.h"
24 #include "kmp_lock.h"
25 #include "kmp_settings.h"
26 #include "kmp_str.h"
27 #include "kmp_wrapper_getpid.h"
28 #include <ctype.h> // toupper()
29
30 static int __kmp_env_toPrint(char const *name, int flag);
31
32 bool __kmp_env_format = 0; // 0 - old format; 1 - new format
33
34 // -----------------------------------------------------------------------------
35 // Helper string functions. Subject to move to kmp_str.
36
37 #ifdef USE_LOAD_BALANCE
38 static double __kmp_convert_to_double(char const *s) {
39   double result;
40
41   if (KMP_SSCANF(s, "%lf", &result) < 1) {
42     result = 0.0;
43   }
44
45   return result;
46 }
47 #endif
48
49 #ifdef KMP_DEBUG
50 static unsigned int __kmp_readstr_with_sentinel(char *dest, char const *src,
51                                                 size_t len, char sentinel) {
52   unsigned int i;
53   for (i = 0; i < len; i++) {
54     if ((*src == '\0') || (*src == sentinel)) {
55       break;
56     }
57     *(dest++) = *(src++);
58   }
59   *dest = '\0';
60   return i;
61 }
62 #endif
63
64 static int __kmp_match_with_sentinel(char const *a, char const *b, size_t len,
65                                      char sentinel) {
66   size_t l = 0;
67
68   if (a == NULL)
69     a = "";
70   if (b == NULL)
71     b = "";
72   while (*a && *b && *b != sentinel) {
73     char ca = *a, cb = *b;
74
75     if (ca >= 'a' && ca <= 'z')
76       ca -= 'a' - 'A';
77     if (cb >= 'a' && cb <= 'z')
78       cb -= 'a' - 'A';
79     if (ca != cb)
80       return FALSE;
81     ++l;
82     ++a;
83     ++b;
84   }
85   return l >= len;
86 }
87
88 // Expected usage:
89 //     token is the token to check for.
90 //     buf is the string being parsed.
91 //     *end returns the char after the end of the token.
92 //        it is not modified unless a match occurs.
93 //
94 // Example 1:
95 //
96 //     if (__kmp_match_str("token", buf, *end) {
97 //         <do something>
98 //         buf = end;
99 //     }
100 //
101 //  Example 2:
102 //
103 //     if (__kmp_match_str("token", buf, *end) {
104 //         char *save = **end;
105 //         **end = sentinel;
106 //         <use any of the __kmp*_with_sentinel() functions>
107 //         **end = save;
108 //         buf = end;
109 //     }
110
111 static int __kmp_match_str(char const *token, char const *buf,
112                            const char **end) {
113
114   KMP_ASSERT(token != NULL);
115   KMP_ASSERT(buf != NULL);
116   KMP_ASSERT(end != NULL);
117
118   while (*token && *buf) {
119     char ct = *token, cb = *buf;
120
121     if (ct >= 'a' && ct <= 'z')
122       ct -= 'a' - 'A';
123     if (cb >= 'a' && cb <= 'z')
124       cb -= 'a' - 'A';
125     if (ct != cb)
126       return FALSE;
127     ++token;
128     ++buf;
129   }
130   if (*token) {
131     return FALSE;
132   }
133   *end = buf;
134   return TRUE;
135 }
136
137 #if KMP_OS_DARWIN
138 static size_t __kmp_round4k(size_t size) {
139   size_t _4k = 4 * 1024;
140   if (size & (_4k - 1)) {
141     size &= ~(_4k - 1);
142     if (size <= KMP_SIZE_T_MAX - _4k) {
143       size += _4k; // Round up if there is no overflow.
144     }
145   }
146   return size;
147 } // __kmp_round4k
148 #endif
149
150 /* Here, multipliers are like __kmp_convert_to_seconds, but floating-point
151    values are allowed, and the return value is in milliseconds.  The default
152    multiplier is milliseconds.  Returns INT_MAX only if the value specified
153    matches "infinit*".  Returns -1 if specified string is invalid. */
154 int __kmp_convert_to_milliseconds(char const *data) {
155   int ret, nvalues, factor;
156   char mult, extra;
157   double value;
158
159   if (data == NULL)
160     return (-1);
161   if (__kmp_str_match("infinit", -1, data))
162     return (INT_MAX);
163   value = (double)0.0;
164   mult = '\0';
165   nvalues = KMP_SSCANF(data, "%lf%c%c", &value, &mult, &extra);
166   if (nvalues < 1)
167     return (-1);
168   if (nvalues == 1)
169     mult = '\0';
170   if (nvalues == 3)
171     return (-1);
172
173   if (value < 0)
174     return (-1);
175
176   switch (mult) {
177   case '\0':
178     /*  default is milliseconds  */
179     factor = 1;
180     break;
181   case 's':
182   case 'S':
183     factor = 1000;
184     break;
185   case 'm':
186   case 'M':
187     factor = 1000 * 60;
188     break;
189   case 'h':
190   case 'H':
191     factor = 1000 * 60 * 60;
192     break;
193   case 'd':
194   case 'D':
195     factor = 1000 * 24 * 60 * 60;
196     break;
197   default:
198     return (-1);
199   }
200
201   if (value >= ((INT_MAX - 1) / factor))
202     ret = INT_MAX - 1; /* Don't allow infinite value here */
203   else
204     ret = (int)(value * (double)factor); /* truncate to int  */
205
206   return ret;
207 }
208
209 static int __kmp_strcasecmp_with_sentinel(char const *a, char const *b,
210                                           char sentinel) {
211   if (a == NULL)
212     a = "";
213   if (b == NULL)
214     b = "";
215   while (*a && *b && *b != sentinel) {
216     char ca = *a, cb = *b;
217
218     if (ca >= 'a' && ca <= 'z')
219       ca -= 'a' - 'A';
220     if (cb >= 'a' && cb <= 'z')
221       cb -= 'a' - 'A';
222     if (ca != cb)
223       return (int)(unsigned char)*a - (int)(unsigned char)*b;
224     ++a;
225     ++b;
226   }
227   return *a
228              ? (*b && *b != sentinel)
229                    ? (int)(unsigned char)*a - (int)(unsigned char)*b
230                    : 1
231              : (*b && *b != sentinel) ? -1 : 0;
232 }
233
234 // =============================================================================
235 // Table structures and helper functions.
236
237 typedef struct __kmp_setting kmp_setting_t;
238 typedef struct __kmp_stg_ss_data kmp_stg_ss_data_t;
239 typedef struct __kmp_stg_wp_data kmp_stg_wp_data_t;
240 typedef struct __kmp_stg_fr_data kmp_stg_fr_data_t;
241
242 typedef void (*kmp_stg_parse_func_t)(char const *name, char const *value,
243                                      void *data);
244 typedef void (*kmp_stg_print_func_t)(kmp_str_buf_t *buffer, char const *name,
245                                      void *data);
246
247 struct __kmp_setting {
248   char const *name; // Name of setting (environment variable).
249   kmp_stg_parse_func_t parse; // Parser function.
250   kmp_stg_print_func_t print; // Print function.
251   void *data; // Data passed to parser and printer.
252   int set; // Variable set during this "session"
253   //     (__kmp_env_initialize() or kmp_set_defaults() call).
254   int defined; // Variable set in any "session".
255 }; // struct __kmp_setting
256
257 struct __kmp_stg_ss_data {
258   size_t factor; // Default factor: 1 for KMP_STACKSIZE, 1024 for others.
259   kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
260 }; // struct __kmp_stg_ss_data
261
262 struct __kmp_stg_wp_data {
263   int omp; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY.
264   kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
265 }; // struct __kmp_stg_wp_data
266
267 struct __kmp_stg_fr_data {
268   int force; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION.
269   kmp_setting_t **rivals; // Array of pointers to rivals (including itself).
270 }; // struct __kmp_stg_fr_data
271
272 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
273     char const *name, // Name of variable.
274     char const *value, // Value of the variable.
275     kmp_setting_t **rivals // List of rival settings (must include current one).
276     );
277
278 // -----------------------------------------------------------------------------
279 // Helper parse functions.
280
281 static void __kmp_stg_parse_bool(char const *name, char const *value,
282                                  int *out) {
283   if (__kmp_str_match_true(value)) {
284     *out = TRUE;
285   } else if (__kmp_str_match_false(value)) {
286     *out = FALSE;
287   } else {
288     __kmp_msg(kmp_ms_warning, KMP_MSG(BadBoolValue, name, value),
289               KMP_HNT(ValidBoolValues), __kmp_msg_null);
290   }
291 } // __kmp_stg_parse_bool
292
293 static void __kmp_stg_parse_size(char const *name, char const *value,
294                                  size_t size_min, size_t size_max,
295                                  int *is_specified, size_t *out,
296                                  size_t factor) {
297   char const *msg = NULL;
298 #if KMP_OS_DARWIN
299   size_min = __kmp_round4k(size_min);
300   size_max = __kmp_round4k(size_max);
301 #endif // KMP_OS_DARWIN
302   if (value) {
303     if (is_specified != NULL) {
304       *is_specified = 1;
305     }
306     __kmp_str_to_size(value, out, factor, &msg);
307     if (msg == NULL) {
308       if (*out > size_max) {
309         *out = size_max;
310         msg = KMP_I18N_STR(ValueTooLarge);
311       } else if (*out < size_min) {
312         *out = size_min;
313         msg = KMP_I18N_STR(ValueTooSmall);
314       } else {
315 #if KMP_OS_DARWIN
316         size_t round4k = __kmp_round4k(*out);
317         if (*out != round4k) {
318           *out = round4k;
319           msg = KMP_I18N_STR(NotMultiple4K);
320         }
321 #endif
322       }
323     } else {
324       // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to
325       // size_max silently.
326       if (*out < size_min) {
327         *out = size_max;
328       } else if (*out > size_max) {
329         *out = size_max;
330       }
331     }
332     if (msg != NULL) {
333       // Message is not empty. Print warning.
334       kmp_str_buf_t buf;
335       __kmp_str_buf_init(&buf);
336       __kmp_str_buf_print_size(&buf, *out);
337       KMP_WARNING(ParseSizeIntWarn, name, value, msg);
338       KMP_INFORM(Using_str_Value, name, buf.str);
339       __kmp_str_buf_free(&buf);
340     }
341   }
342 } // __kmp_stg_parse_size
343
344 static void __kmp_stg_parse_str(char const *name, char const *value,
345                                 char **out) {
346   __kmp_str_free(out);
347   *out = __kmp_str_format("%s", value);
348 } // __kmp_stg_parse_str
349
350 static void __kmp_stg_parse_int(
351     char const
352         *name, // I: Name of environment variable (used in warning messages).
353     char const *value, // I: Value of environment variable to parse.
354     int min, // I: Miminal allowed value.
355     int max, // I: Maximum allowed value.
356     int *out // O: Output (parsed) value.
357     ) {
358   char const *msg = NULL;
359   kmp_uint64 uint = *out;
360   __kmp_str_to_uint(value, &uint, &msg);
361   if (msg == NULL) {
362     if (uint < (unsigned int)min) {
363       msg = KMP_I18N_STR(ValueTooSmall);
364       uint = min;
365     } else if (uint > (unsigned int)max) {
366       msg = KMP_I18N_STR(ValueTooLarge);
367       uint = max;
368     }
369   } else {
370     // If overflow occurred msg contains error message and uint is very big. Cut
371     // tmp it to INT_MAX.
372     if (uint < (unsigned int)min) {
373       uint = min;
374     } else if (uint > (unsigned int)max) {
375       uint = max;
376     }
377   }
378   if (msg != NULL) {
379     // Message is not empty. Print warning.
380     kmp_str_buf_t buf;
381     KMP_WARNING(ParseSizeIntWarn, name, value, msg);
382     __kmp_str_buf_init(&buf);
383     __kmp_str_buf_print(&buf, "%" KMP_UINT64_SPEC "", uint);
384     KMP_INFORM(Using_uint64_Value, name, buf.str);
385     __kmp_str_buf_free(&buf);
386   }
387   *out = uint;
388 } // __kmp_stg_parse_int
389
390 #if KMP_DEBUG_ADAPTIVE_LOCKS
391 static void __kmp_stg_parse_file(char const *name, char const *value,
392                                  const char *suffix, char **out) {
393   char buffer[256];
394   char *t;
395   int hasSuffix;
396   __kmp_str_free(out);
397   t = (char *)strrchr(value, '.');
398   hasSuffix = t && __kmp_str_eqf(t, suffix);
399   t = __kmp_str_format("%s%s", value, hasSuffix ? "" : suffix);
400   __kmp_expand_file_name(buffer, sizeof(buffer), t);
401   __kmp_str_free(&t);
402   *out = __kmp_str_format("%s", buffer);
403 } // __kmp_stg_parse_file
404 #endif
405
406 #ifdef KMP_DEBUG
407 static char *par_range_to_print = NULL;
408
409 static void __kmp_stg_parse_par_range(char const *name, char const *value,
410                                       int *out_range, char *out_routine,
411                                       char *out_file, int *out_lb,
412                                       int *out_ub) {
413   size_t len = KMP_STRLEN(value) + 1;
414   par_range_to_print = (char *)KMP_INTERNAL_MALLOC(len + 1);
415   KMP_STRNCPY_S(par_range_to_print, len + 1, value, len + 1);
416   __kmp_par_range = +1;
417   __kmp_par_range_lb = 0;
418   __kmp_par_range_ub = INT_MAX;
419   for (;;) {
420     unsigned int len;
421     if (*value == '\0') {
422       break;
423     }
424     if (!__kmp_strcasecmp_with_sentinel("routine", value, '=')) {
425       value = strchr(value, '=') + 1;
426       len = __kmp_readstr_with_sentinel(out_routine, value,
427                                         KMP_PAR_RANGE_ROUTINE_LEN - 1, ',');
428       if (len == 0) {
429         goto par_range_error;
430       }
431       value = strchr(value, ',');
432       if (value != NULL) {
433         value++;
434       }
435       continue;
436     }
437     if (!__kmp_strcasecmp_with_sentinel("filename", value, '=')) {
438       value = strchr(value, '=') + 1;
439       len = __kmp_readstr_with_sentinel(out_file, value,
440                                         KMP_PAR_RANGE_FILENAME_LEN - 1, ',');
441       if (len == 0) {
442         goto par_range_error;
443       }
444       value = strchr(value, ',');
445       if (value != NULL) {
446         value++;
447       }
448       continue;
449     }
450     if ((!__kmp_strcasecmp_with_sentinel("range", value, '=')) ||
451         (!__kmp_strcasecmp_with_sentinel("incl_range", value, '='))) {
452       value = strchr(value, '=') + 1;
453       if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {
454         goto par_range_error;
455       }
456       *out_range = +1;
457       value = strchr(value, ',');
458       if (value != NULL) {
459         value++;
460       }
461       continue;
462     }
463     if (!__kmp_strcasecmp_with_sentinel("excl_range", value, '=')) {
464       value = strchr(value, '=') + 1;
465       if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {
466         goto par_range_error;
467       }
468       *out_range = -1;
469       value = strchr(value, ',');
470       if (value != NULL) {
471         value++;
472       }
473       continue;
474     }
475   par_range_error:
476     KMP_WARNING(ParRangeSyntax, name);
477     __kmp_par_range = 0;
478     break;
479   }
480 } // __kmp_stg_parse_par_range
481 #endif
482
483 int __kmp_initial_threads_capacity(int req_nproc) {
484   int nth = 32;
485
486   /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
487    * __kmp_max_nth) */
488   if (nth < (4 * req_nproc))
489     nth = (4 * req_nproc);
490   if (nth < (4 * __kmp_xproc))
491     nth = (4 * __kmp_xproc);
492
493   if (nth > __kmp_max_nth)
494     nth = __kmp_max_nth;
495
496   return nth;
497 }
498
499 int __kmp_default_tp_capacity(int req_nproc, int max_nth,
500                               int all_threads_specified) {
501   int nth = 128;
502
503   if (all_threads_specified)
504     return max_nth;
505   /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
506    * __kmp_max_nth ) */
507   if (nth < (4 * req_nproc))
508     nth = (4 * req_nproc);
509   if (nth < (4 * __kmp_xproc))
510     nth = (4 * __kmp_xproc);
511
512   if (nth > __kmp_max_nth)
513     nth = __kmp_max_nth;
514
515   return nth;
516 }
517
518 // -----------------------------------------------------------------------------
519 // Helper print functions.
520
521 static void __kmp_stg_print_bool(kmp_str_buf_t *buffer, char const *name,
522                                  int value) {
523   if (__kmp_env_format) {
524     KMP_STR_BUF_PRINT_BOOL;
525   } else {
526     __kmp_str_buf_print(buffer, "   %s=%s\n", name, value ? "true" : "false");
527   }
528 } // __kmp_stg_print_bool
529
530 static void __kmp_stg_print_int(kmp_str_buf_t *buffer, char const *name,
531                                 int value) {
532   if (__kmp_env_format) {
533     KMP_STR_BUF_PRINT_INT;
534   } else {
535     __kmp_str_buf_print(buffer, "   %s=%d\n", name, value);
536   }
537 } // __kmp_stg_print_int
538
539 #if USE_ITT_BUILD && USE_ITT_NOTIFY
540 static void __kmp_stg_print_uint64(kmp_str_buf_t *buffer, char const *name,
541                                    kmp_uint64 value) {
542   if (__kmp_env_format) {
543     KMP_STR_BUF_PRINT_UINT64;
544   } else {
545     __kmp_str_buf_print(buffer, "   %s=%" KMP_UINT64_SPEC "\n", name, value);
546   }
547 } // __kmp_stg_print_uint64
548 #endif
549
550 static void __kmp_stg_print_str(kmp_str_buf_t *buffer, char const *name,
551                                 char const *value) {
552   if (__kmp_env_format) {
553     KMP_STR_BUF_PRINT_STR;
554   } else {
555     __kmp_str_buf_print(buffer, "   %s=%s\n", name, value);
556   }
557 } // __kmp_stg_print_str
558
559 static void __kmp_stg_print_size(kmp_str_buf_t *buffer, char const *name,
560                                  size_t value) {
561   if (__kmp_env_format) {
562     KMP_STR_BUF_PRINT_NAME_EX(name);
563     __kmp_str_buf_print_size(buffer, value);
564     __kmp_str_buf_print(buffer, "'\n");
565   } else {
566     __kmp_str_buf_print(buffer, "   %s=", name);
567     __kmp_str_buf_print_size(buffer, value);
568     __kmp_str_buf_print(buffer, "\n");
569     return;
570   }
571 } // __kmp_stg_print_size
572
573 // =============================================================================
574 // Parse and print functions.
575
576 // -----------------------------------------------------------------------------
577 // KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS
578
579 static void __kmp_stg_parse_device_thread_limit(char const *name,
580                                                 char const *value, void *data) {
581   kmp_setting_t **rivals = (kmp_setting_t **)data;
582   int rc;
583   if (strcmp(name, "KMP_ALL_THREADS") == 0) {
584     KMP_INFORM(EnvVarDeprecated, name, "KMP_DEVICE_THREAD_LIMIT");
585   }
586   rc = __kmp_stg_check_rivals(name, value, rivals);
587   if (rc) {
588     return;
589   }
590   if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
591     __kmp_max_nth = __kmp_xproc;
592     __kmp_allThreadsSpecified = 1;
593   } else {
594     __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_max_nth);
595     __kmp_allThreadsSpecified = 0;
596   }
597   K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth));
598
599 } // __kmp_stg_parse_device_thread_limit
600
601 static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t *buffer,
602                                                 char const *name, void *data) {
603   __kmp_stg_print_int(buffer, name, __kmp_max_nth);
604 } // __kmp_stg_print_device_thread_limit
605
606 // -----------------------------------------------------------------------------
607 // OMP_THREAD_LIMIT
608 static void __kmp_stg_parse_thread_limit(char const *name, char const *value,
609                                          void *data) {
610   __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_cg_max_nth);
611   K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth));
612
613 } // __kmp_stg_parse_thread_limit
614
615 static void __kmp_stg_print_thread_limit(kmp_str_buf_t *buffer,
616                                          char const *name, void *data) {
617   __kmp_stg_print_int(buffer, name, __kmp_cg_max_nth);
618 } // __kmp_stg_print_thread_limit
619
620 // -----------------------------------------------------------------------------
621 // KMP_TEAMS_THREAD_LIMIT
622 static void __kmp_stg_parse_teams_thread_limit(char const *name,
623                                                char const *value, void *data) {
624   __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_teams_max_nth);
625 } // __kmp_stg_teams_thread_limit
626
627 static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t *buffer,
628                                                char const *name, void *data) {
629   __kmp_stg_print_int(buffer, name, __kmp_teams_max_nth);
630 } // __kmp_stg_print_teams_thread_limit
631
632 // -----------------------------------------------------------------------------
633 // KMP_BLOCKTIME
634
635 static void __kmp_stg_parse_blocktime(char const *name, char const *value,
636                                       void *data) {
637   __kmp_dflt_blocktime = __kmp_convert_to_milliseconds(value);
638   if (__kmp_dflt_blocktime < 0) {
639     __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME;
640     __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidValue, name, value),
641               __kmp_msg_null);
642     KMP_INFORM(Using_int_Value, name, __kmp_dflt_blocktime);
643     __kmp_env_blocktime = FALSE; // Revert to default as if var not set.
644   } else {
645     if (__kmp_dflt_blocktime < KMP_MIN_BLOCKTIME) {
646       __kmp_dflt_blocktime = KMP_MIN_BLOCKTIME;
647       __kmp_msg(kmp_ms_warning, KMP_MSG(SmallValue, name, value),
648                 __kmp_msg_null);
649       KMP_INFORM(MinValueUsing, name, __kmp_dflt_blocktime);
650     } else if (__kmp_dflt_blocktime > KMP_MAX_BLOCKTIME) {
651       __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;
652       __kmp_msg(kmp_ms_warning, KMP_MSG(LargeValue, name, value),
653                 __kmp_msg_null);
654       KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime);
655     }
656     __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified.
657   }
658 #if KMP_USE_MONITOR
659   // calculate number of monitor thread wakeup intervals corresponding to
660   // blocktime.
661   __kmp_monitor_wakeups =
662       KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);
663   __kmp_bt_intervals =
664       KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);
665 #endif
666   K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime));
667   if (__kmp_env_blocktime) {
668     K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime));
669   }
670 } // __kmp_stg_parse_blocktime
671
672 static void __kmp_stg_print_blocktime(kmp_str_buf_t *buffer, char const *name,
673                                       void *data) {
674   __kmp_stg_print_int(buffer, name, __kmp_dflt_blocktime);
675 } // __kmp_stg_print_blocktime
676
677 // -----------------------------------------------------------------------------
678 // KMP_DUPLICATE_LIB_OK
679
680 static void __kmp_stg_parse_duplicate_lib_ok(char const *name,
681                                              char const *value, void *data) {
682   /* actually this variable is not supported, put here for compatibility with
683      earlier builds and for static/dynamic combination */
684   __kmp_stg_parse_bool(name, value, &__kmp_duplicate_library_ok);
685 } // __kmp_stg_parse_duplicate_lib_ok
686
687 static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t *buffer,
688                                              char const *name, void *data) {
689   __kmp_stg_print_bool(buffer, name, __kmp_duplicate_library_ok);
690 } // __kmp_stg_print_duplicate_lib_ok
691
692 // -----------------------------------------------------------------------------
693 // KMP_INHERIT_FP_CONTROL
694
695 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
696
697 static void __kmp_stg_parse_inherit_fp_control(char const *name,
698                                                char const *value, void *data) {
699   __kmp_stg_parse_bool(name, value, &__kmp_inherit_fp_control);
700 } // __kmp_stg_parse_inherit_fp_control
701
702 static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t *buffer,
703                                                char const *name, void *data) {
704 #if KMP_DEBUG
705   __kmp_stg_print_bool(buffer, name, __kmp_inherit_fp_control);
706 #endif /* KMP_DEBUG */
707 } // __kmp_stg_print_inherit_fp_control
708
709 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
710
711 // Used for OMP_WAIT_POLICY
712 static char const *blocktime_str = NULL;
713
714 // -----------------------------------------------------------------------------
715 // KMP_LIBRARY, OMP_WAIT_POLICY
716
717 static void __kmp_stg_parse_wait_policy(char const *name, char const *value,
718                                         void *data) {
719
720   kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data;
721   int rc;
722
723   rc = __kmp_stg_check_rivals(name, value, wait->rivals);
724   if (rc) {
725     return;
726   }
727
728   if (wait->omp) {
729     if (__kmp_str_match("ACTIVE", 1, value)) {
730       __kmp_library = library_turnaround;
731       if (blocktime_str == NULL) {
732         // KMP_BLOCKTIME not specified, so set default to "infinite".
733         __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;
734       }
735     } else if (__kmp_str_match("PASSIVE", 1, value)) {
736       __kmp_library = library_throughput;
737       if (blocktime_str == NULL) {
738         // KMP_BLOCKTIME not specified, so set default to 0.
739         __kmp_dflt_blocktime = 0;
740       }
741     } else {
742       KMP_WARNING(StgInvalidValue, name, value);
743     }
744   } else {
745     if (__kmp_str_match("serial", 1, value)) { /* S */
746       __kmp_library = library_serial;
747     } else if (__kmp_str_match("throughput", 2, value)) { /* TH */
748       __kmp_library = library_throughput;
749     } else if (__kmp_str_match("turnaround", 2, value)) { /* TU */
750       __kmp_library = library_turnaround;
751     } else if (__kmp_str_match("dedicated", 1, value)) { /* D */
752       __kmp_library = library_turnaround;
753     } else if (__kmp_str_match("multiuser", 1, value)) { /* M */
754       __kmp_library = library_throughput;
755     } else {
756       KMP_WARNING(StgInvalidValue, name, value);
757     }
758   }
759   __kmp_aux_set_library(__kmp_library);
760
761 } // __kmp_stg_parse_wait_policy
762
763 static void __kmp_stg_print_wait_policy(kmp_str_buf_t *buffer, char const *name,
764                                         void *data) {
765
766   kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data;
767   char const *value = NULL;
768
769   if (wait->omp) {
770     switch (__kmp_library) {
771     case library_turnaround: {
772       value = "ACTIVE";
773     } break;
774     case library_throughput: {
775       value = "PASSIVE";
776     } break;
777     }
778   } else {
779     switch (__kmp_library) {
780     case library_serial: {
781       value = "serial";
782     } break;
783     case library_turnaround: {
784       value = "turnaround";
785     } break;
786     case library_throughput: {
787       value = "throughput";
788     } break;
789     }
790   }
791   if (value != NULL) {
792     __kmp_stg_print_str(buffer, name, value);
793   }
794
795 } // __kmp_stg_print_wait_policy
796
797 #if KMP_USE_MONITOR
798 // -----------------------------------------------------------------------------
799 // KMP_MONITOR_STACKSIZE
800
801 static void __kmp_stg_parse_monitor_stacksize(char const *name,
802                                               char const *value, void *data) {
803   __kmp_stg_parse_size(name, value, __kmp_sys_min_stksize, KMP_MAX_STKSIZE,
804                        NULL, &__kmp_monitor_stksize, 1);
805 } // __kmp_stg_parse_monitor_stacksize
806
807 static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t *buffer,
808                                               char const *name, void *data) {
809   if (__kmp_env_format) {
810     if (__kmp_monitor_stksize > 0)
811       KMP_STR_BUF_PRINT_NAME_EX(name);
812     else
813       KMP_STR_BUF_PRINT_NAME;
814   } else {
815     __kmp_str_buf_print(buffer, "   %s", name);
816   }
817   if (__kmp_monitor_stksize > 0) {
818     __kmp_str_buf_print_size(buffer, __kmp_monitor_stksize);
819   } else {
820     __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
821   }
822   if (__kmp_env_format && __kmp_monitor_stksize) {
823     __kmp_str_buf_print(buffer, "'\n");
824   }
825 } // __kmp_stg_print_monitor_stacksize
826 #endif // KMP_USE_MONITOR
827
828 // -----------------------------------------------------------------------------
829 // KMP_SETTINGS
830
831 static void __kmp_stg_parse_settings(char const *name, char const *value,
832                                      void *data) {
833   __kmp_stg_parse_bool(name, value, &__kmp_settings);
834 } // __kmp_stg_parse_settings
835
836 static void __kmp_stg_print_settings(kmp_str_buf_t *buffer, char const *name,
837                                      void *data) {
838   __kmp_stg_print_bool(buffer, name, __kmp_settings);
839 } // __kmp_stg_print_settings
840
841 // -----------------------------------------------------------------------------
842 // KMP_STACKPAD
843
844 static void __kmp_stg_parse_stackpad(char const *name, char const *value,
845                                      void *data) {
846   __kmp_stg_parse_int(name, // Env var name
847                       value, // Env var value
848                       KMP_MIN_STKPADDING, // Min value
849                       KMP_MAX_STKPADDING, // Max value
850                       &__kmp_stkpadding // Var to initialize
851                       );
852 } // __kmp_stg_parse_stackpad
853
854 static void __kmp_stg_print_stackpad(kmp_str_buf_t *buffer, char const *name,
855                                      void *data) {
856   __kmp_stg_print_int(buffer, name, __kmp_stkpadding);
857 } // __kmp_stg_print_stackpad
858
859 // -----------------------------------------------------------------------------
860 // KMP_STACKOFFSET
861
862 static void __kmp_stg_parse_stackoffset(char const *name, char const *value,
863                                         void *data) {
864   __kmp_stg_parse_size(name, // Env var name
865                        value, // Env var value
866                        KMP_MIN_STKOFFSET, // Min value
867                        KMP_MAX_STKOFFSET, // Max value
868                        NULL, //
869                        &__kmp_stkoffset, // Var to initialize
870                        1);
871 } // __kmp_stg_parse_stackoffset
872
873 static void __kmp_stg_print_stackoffset(kmp_str_buf_t *buffer, char const *name,
874                                         void *data) {
875   __kmp_stg_print_size(buffer, name, __kmp_stkoffset);
876 } // __kmp_stg_print_stackoffset
877
878 // -----------------------------------------------------------------------------
879 // KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE
880
881 static void __kmp_stg_parse_stacksize(char const *name, char const *value,
882                                       void *data) {
883
884   kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data;
885   int rc;
886
887   rc = __kmp_stg_check_rivals(name, value, stacksize->rivals);
888   if (rc) {
889     return;
890   }
891   __kmp_stg_parse_size(name, // Env var name
892                        value, // Env var value
893                        __kmp_sys_min_stksize, // Min value
894                        KMP_MAX_STKSIZE, // Max value
895                        &__kmp_env_stksize, //
896                        &__kmp_stksize, // Var to initialize
897                        stacksize->factor);
898
899 } // __kmp_stg_parse_stacksize
900
901 // This function is called for printing both KMP_STACKSIZE (factor is 1) and
902 // OMP_STACKSIZE (factor is 1024). Currently it is not possible to print
903 // OMP_STACKSIZE value in bytes. We can consider adding this possibility by a
904 // customer request in future.
905 static void __kmp_stg_print_stacksize(kmp_str_buf_t *buffer, char const *name,
906                                       void *data) {
907   kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data;
908   if (__kmp_env_format) {
909     KMP_STR_BUF_PRINT_NAME_EX(name);
910     __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024)
911                                          ? __kmp_stksize / stacksize->factor
912                                          : __kmp_stksize);
913     __kmp_str_buf_print(buffer, "'\n");
914   } else {
915     __kmp_str_buf_print(buffer, "   %s=", name);
916     __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024)
917                                          ? __kmp_stksize / stacksize->factor
918                                          : __kmp_stksize);
919     __kmp_str_buf_print(buffer, "\n");
920   }
921 } // __kmp_stg_print_stacksize
922
923 // -----------------------------------------------------------------------------
924 // KMP_VERSION
925
926 static void __kmp_stg_parse_version(char const *name, char const *value,
927                                     void *data) {
928   __kmp_stg_parse_bool(name, value, &__kmp_version);
929 } // __kmp_stg_parse_version
930
931 static void __kmp_stg_print_version(kmp_str_buf_t *buffer, char const *name,
932                                     void *data) {
933   __kmp_stg_print_bool(buffer, name, __kmp_version);
934 } // __kmp_stg_print_version
935
936 // -----------------------------------------------------------------------------
937 // KMP_WARNINGS
938
939 static void __kmp_stg_parse_warnings(char const *name, char const *value,
940                                      void *data) {
941   __kmp_stg_parse_bool(name, value, &__kmp_generate_warnings);
942   if (__kmp_generate_warnings != kmp_warnings_off) {
943     // AC: only 0/1 values documented, so reset to explicit to distinguish from
944     // default setting
945     __kmp_generate_warnings = kmp_warnings_explicit;
946   }
947 } // __kmp_stg_parse_warnings
948
949 static void __kmp_stg_print_warnings(kmp_str_buf_t *buffer, char const *name,
950                                      void *data) {
951   // AC: TODO: change to print_int? (needs documentation change)
952   __kmp_stg_print_bool(buffer, name, __kmp_generate_warnings);
953 } // __kmp_stg_print_warnings
954
955 // -----------------------------------------------------------------------------
956 // OMP_NESTED, OMP_NUM_THREADS
957
958 static void __kmp_stg_parse_nested(char const *name, char const *value,
959                                    void *data) {
960   __kmp_stg_parse_bool(name, value, &__kmp_dflt_nested);
961 } // __kmp_stg_parse_nested
962
963 static void __kmp_stg_print_nested(kmp_str_buf_t *buffer, char const *name,
964                                    void *data) {
965   __kmp_stg_print_bool(buffer, name, __kmp_dflt_nested);
966 } // __kmp_stg_print_nested
967
968 static void __kmp_parse_nested_num_threads(const char *var, const char *env,
969                                            kmp_nested_nthreads_t *nth_array) {
970   const char *next = env;
971   const char *scan = next;
972
973   int total = 0; // Count elements that were set. It'll be used as an array size
974   int prev_comma = FALSE; // For correct processing sequential commas
975
976   // Count the number of values in the env. var string
977   for (;;) {
978     SKIP_WS(next);
979
980     if (*next == '\0') {
981       break;
982     }
983     // Next character is not an integer or not a comma => end of list
984     if (((*next < '0') || (*next > '9')) && (*next != ',')) {
985       KMP_WARNING(NthSyntaxError, var, env);
986       return;
987     }
988     // The next character is ','
989     if (*next == ',') {
990       // ',' is the fisrt character
991       if (total == 0 || prev_comma) {
992         total++;
993       }
994       prev_comma = TRUE;
995       next++; // skip ','
996       SKIP_WS(next);
997     }
998     // Next character is a digit
999     if (*next >= '0' && *next <= '9') {
1000       prev_comma = FALSE;
1001       SKIP_DIGITS(next);
1002       total++;
1003       const char *tmp = next;
1004       SKIP_WS(tmp);
1005       if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
1006         KMP_WARNING(NthSpacesNotAllowed, var, env);
1007         return;
1008       }
1009     }
1010   }
1011   KMP_DEBUG_ASSERT(total > 0);
1012   if (total <= 0) {
1013     KMP_WARNING(NthSyntaxError, var, env);
1014     return;
1015   }
1016
1017   // Check if the nested nthreads array exists
1018   if (!nth_array->nth) {
1019     // Allocate an array of double size
1020     nth_array->nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total * 2);
1021     if (nth_array->nth == NULL) {
1022       KMP_FATAL(MemoryAllocFailed);
1023     }
1024     nth_array->size = total * 2;
1025   } else {
1026     if (nth_array->size < total) {
1027       // Increase the array size
1028       do {
1029         nth_array->size *= 2;
1030       } while (nth_array->size < total);
1031
1032       nth_array->nth = (int *)KMP_INTERNAL_REALLOC(
1033           nth_array->nth, sizeof(int) * nth_array->size);
1034       if (nth_array->nth == NULL) {
1035         KMP_FATAL(MemoryAllocFailed);
1036       }
1037     }
1038   }
1039   nth_array->used = total;
1040   int i = 0;
1041
1042   prev_comma = FALSE;
1043   total = 0;
1044   // Save values in the array
1045   for (;;) {
1046     SKIP_WS(scan);
1047     if (*scan == '\0') {
1048       break;
1049     }
1050     // The next character is ','
1051     if (*scan == ',') {
1052       // ',' in the beginning of the list
1053       if (total == 0) {
1054         // The value is supposed to be equal to __kmp_avail_proc but it is
1055         // unknown at the moment.
1056         // So let's put a placeholder (#threads = 0) to correct it later.
1057         nth_array->nth[i++] = 0;
1058         total++;
1059       } else if (prev_comma) {
1060         // Num threads is inherited from the previous level
1061         nth_array->nth[i] = nth_array->nth[i - 1];
1062         i++;
1063         total++;
1064       }
1065       prev_comma = TRUE;
1066       scan++; // skip ','
1067       SKIP_WS(scan);
1068     }
1069     // Next character is a digit
1070     if (*scan >= '0' && *scan <= '9') {
1071       int num;
1072       const char *buf = scan;
1073       char const *msg = NULL;
1074       prev_comma = FALSE;
1075       SKIP_DIGITS(scan);
1076       total++;
1077
1078       num = __kmp_str_to_int(buf, *scan);
1079       if (num < KMP_MIN_NTH) {
1080         msg = KMP_I18N_STR(ValueTooSmall);
1081         num = KMP_MIN_NTH;
1082       } else if (num > __kmp_sys_max_nth) {
1083         msg = KMP_I18N_STR(ValueTooLarge);
1084         num = __kmp_sys_max_nth;
1085       }
1086       if (msg != NULL) {
1087         // Message is not empty. Print warning.
1088         KMP_WARNING(ParseSizeIntWarn, var, env, msg);
1089         KMP_INFORM(Using_int_Value, var, num);
1090       }
1091       nth_array->nth[i++] = num;
1092     }
1093   }
1094 }
1095
1096 static void __kmp_stg_parse_num_threads(char const *name, char const *value,
1097                                         void *data) {
1098   // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers!
1099   if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
1100     // The array of 1 element
1101     __kmp_nested_nth.nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int));
1102     __kmp_nested_nth.size = __kmp_nested_nth.used = 1;
1103     __kmp_nested_nth.nth[0] = __kmp_dflt_team_nth = __kmp_dflt_team_nth_ub =
1104         __kmp_xproc;
1105   } else {
1106     __kmp_parse_nested_num_threads(name, value, &__kmp_nested_nth);
1107     if (__kmp_nested_nth.nth) {
1108       __kmp_dflt_team_nth = __kmp_nested_nth.nth[0];
1109       if (__kmp_dflt_team_nth_ub < __kmp_dflt_team_nth) {
1110         __kmp_dflt_team_nth_ub = __kmp_dflt_team_nth;
1111       }
1112     }
1113   }
1114   K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth));
1115 } // __kmp_stg_parse_num_threads
1116
1117 static void __kmp_stg_print_num_threads(kmp_str_buf_t *buffer, char const *name,
1118                                         void *data) {
1119   if (__kmp_env_format) {
1120     KMP_STR_BUF_PRINT_NAME;
1121   } else {
1122     __kmp_str_buf_print(buffer, "   %s", name);
1123   }
1124   if (__kmp_nested_nth.used) {
1125     kmp_str_buf_t buf;
1126     __kmp_str_buf_init(&buf);
1127     for (int i = 0; i < __kmp_nested_nth.used; i++) {
1128       __kmp_str_buf_print(&buf, "%d", __kmp_nested_nth.nth[i]);
1129       if (i < __kmp_nested_nth.used - 1) {
1130         __kmp_str_buf_print(&buf, ",");
1131       }
1132     }
1133     __kmp_str_buf_print(buffer, "='%s'\n", buf.str);
1134     __kmp_str_buf_free(&buf);
1135   } else {
1136     __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1137   }
1138 } // __kmp_stg_print_num_threads
1139
1140 // -----------------------------------------------------------------------------
1141 // OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS,
1142
1143 static void __kmp_stg_parse_tasking(char const *name, char const *value,
1144                                     void *data) {
1145   __kmp_stg_parse_int(name, value, 0, (int)tskm_max,
1146                       (int *)&__kmp_tasking_mode);
1147 } // __kmp_stg_parse_tasking
1148
1149 static void __kmp_stg_print_tasking(kmp_str_buf_t *buffer, char const *name,
1150                                     void *data) {
1151   __kmp_stg_print_int(buffer, name, __kmp_tasking_mode);
1152 } // __kmp_stg_print_tasking
1153
1154 static void __kmp_stg_parse_task_stealing(char const *name, char const *value,
1155                                           void *data) {
1156   __kmp_stg_parse_int(name, value, 0, 1,
1157                       (int *)&__kmp_task_stealing_constraint);
1158 } // __kmp_stg_parse_task_stealing
1159
1160 static void __kmp_stg_print_task_stealing(kmp_str_buf_t *buffer,
1161                                           char const *name, void *data) {
1162   __kmp_stg_print_int(buffer, name, __kmp_task_stealing_constraint);
1163 } // __kmp_stg_print_task_stealing
1164
1165 static void __kmp_stg_parse_max_active_levels(char const *name,
1166                                               char const *value, void *data) {
1167   __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,
1168                       &__kmp_dflt_max_active_levels);
1169 } // __kmp_stg_parse_max_active_levels
1170
1171 static void __kmp_stg_print_max_active_levels(kmp_str_buf_t *buffer,
1172                                               char const *name, void *data) {
1173   __kmp_stg_print_int(buffer, name, __kmp_dflt_max_active_levels);
1174 } // __kmp_stg_print_max_active_levels
1175
1176 #if OMP_40_ENABLED
1177 // -----------------------------------------------------------------------------
1178 // OpenMP 4.0: OMP_DEFAULT_DEVICE
1179 static void __kmp_stg_parse_default_device(char const *name, char const *value,
1180                                            void *data) {
1181   __kmp_stg_parse_int(name, value, 0, KMP_MAX_DEFAULT_DEVICE_LIMIT,
1182                       &__kmp_default_device);
1183 } // __kmp_stg_parse_default_device
1184
1185 static void __kmp_stg_print_default_device(kmp_str_buf_t *buffer,
1186                                            char const *name, void *data) {
1187   __kmp_stg_print_int(buffer, name, __kmp_default_device);
1188 } // __kmp_stg_print_default_device
1189 #endif
1190
1191 #if OMP_50_ENABLED
1192 // -----------------------------------------------------------------------------
1193 // OpenMP 5.0: OMP_TARGET_OFFLOAD
1194 static void __kmp_stg_parse_target_offload(char const *name, char const *value,
1195                                            void *data) {
1196   const char *next = value;
1197   const char *scan = next;
1198
1199   __kmp_target_offload = tgt_default;
1200   SKIP_WS(next);
1201   if (*next == '\0')
1202     return;
1203   scan = next;
1204   if (__kmp_match_str("MANDATORY", scan, &next)) {
1205     __kmp_target_offload = tgt_mandatory;
1206   } else if (__kmp_match_str("DISABLED", scan, &next)) {
1207     __kmp_target_offload = tgt_disabled;
1208   } else if (__kmp_match_str("DEFAULT", scan, &next)) {
1209     __kmp_target_offload = tgt_default;
1210   } else {
1211     KMP_WARNING(SyntaxErrorUsing, name, "DEFAULT");
1212   }
1213
1214 } // __kmp_stg_parse_target_offload
1215
1216 static void __kmp_stg_print_target_offload(kmp_str_buf_t *buffer,
1217                                            char const *name, void *data) {
1218   const char *value = NULL;
1219   if (__kmp_target_offload == tgt_default)
1220     value = "DEFAULT";
1221   else if (__kmp_target_offload == tgt_mandatory)
1222     value = "MANDATORY";
1223   else if (__kmp_target_offload == tgt_disabled)
1224     value = "DISABLED";
1225   if (value) {
1226     __kmp_str_buf_print(buffer, "   %s=%s\n", name, value);
1227   }
1228 } // __kmp_stg_print_target_offload
1229 #endif
1230
1231 #if OMP_45_ENABLED
1232 // -----------------------------------------------------------------------------
1233 // OpenMP 4.5: OMP_MAX_TASK_PRIORITY
1234 static void __kmp_stg_parse_max_task_priority(char const *name,
1235                                               char const *value, void *data) {
1236   __kmp_stg_parse_int(name, value, 0, KMP_MAX_TASK_PRIORITY_LIMIT,
1237                       &__kmp_max_task_priority);
1238 } // __kmp_stg_parse_max_task_priority
1239
1240 static void __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer,
1241                                               char const *name, void *data) {
1242   __kmp_stg_print_int(buffer, name, __kmp_max_task_priority);
1243 } // __kmp_stg_print_max_task_priority
1244
1245 // KMP_TASKLOOP_MIN_TASKS
1246 // taskloop threashold to switch from recursive to linear tasks creation
1247 static void __kmp_stg_parse_taskloop_min_tasks(char const *name,
1248                                                char const *value, void *data) {
1249   int tmp;
1250   __kmp_stg_parse_int(name, value, 0, INT_MAX, &tmp);
1251   __kmp_taskloop_min_tasks = tmp;
1252 } // __kmp_stg_parse_taskloop_min_tasks
1253
1254 static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t *buffer,
1255                                                char const *name, void *data) {
1256   __kmp_stg_print_int(buffer, name, __kmp_taskloop_min_tasks);
1257 } // __kmp_stg_print_taskloop_min_tasks
1258 #endif // OMP_45_ENABLED
1259
1260 // -----------------------------------------------------------------------------
1261 // KMP_DISP_NUM_BUFFERS
1262 static void __kmp_stg_parse_disp_buffers(char const *name, char const *value,
1263                                          void *data) {
1264   if (TCR_4(__kmp_init_serial)) {
1265     KMP_WARNING(EnvSerialWarn, name);
1266     return;
1267   } // read value before serial initialization only
1268   __kmp_stg_parse_int(name, value, 1, KMP_MAX_NTH, &__kmp_dispatch_num_buffers);
1269 } // __kmp_stg_parse_disp_buffers
1270
1271 static void __kmp_stg_print_disp_buffers(kmp_str_buf_t *buffer,
1272                                          char const *name, void *data) {
1273   __kmp_stg_print_int(buffer, name, __kmp_dispatch_num_buffers);
1274 } // __kmp_stg_print_disp_buffers
1275
1276 #if KMP_NESTED_HOT_TEAMS
1277 // -----------------------------------------------------------------------------
1278 // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE
1279
1280 static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value,
1281                                             void *data) {
1282   if (TCR_4(__kmp_init_parallel)) {
1283     KMP_WARNING(EnvParallelWarn, name);
1284     return;
1285   } // read value before first parallel only
1286   __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,
1287                       &__kmp_hot_teams_max_level);
1288 } // __kmp_stg_parse_hot_teams_level
1289
1290 static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t *buffer,
1291                                             char const *name, void *data) {
1292   __kmp_stg_print_int(buffer, name, __kmp_hot_teams_max_level);
1293 } // __kmp_stg_print_hot_teams_level
1294
1295 static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value,
1296                                            void *data) {
1297   if (TCR_4(__kmp_init_parallel)) {
1298     KMP_WARNING(EnvParallelWarn, name);
1299     return;
1300   } // read value before first parallel only
1301   __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,
1302                       &__kmp_hot_teams_mode);
1303 } // __kmp_stg_parse_hot_teams_mode
1304
1305 static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t *buffer,
1306                                            char const *name, void *data) {
1307   __kmp_stg_print_int(buffer, name, __kmp_hot_teams_mode);
1308 } // __kmp_stg_print_hot_teams_mode
1309
1310 #endif // KMP_NESTED_HOT_TEAMS
1311
1312 // -----------------------------------------------------------------------------
1313 // KMP_HANDLE_SIGNALS
1314
1315 #if KMP_HANDLE_SIGNALS
1316
1317 static void __kmp_stg_parse_handle_signals(char const *name, char const *value,
1318                                            void *data) {
1319   __kmp_stg_parse_bool(name, value, &__kmp_handle_signals);
1320 } // __kmp_stg_parse_handle_signals
1321
1322 static void __kmp_stg_print_handle_signals(kmp_str_buf_t *buffer,
1323                                            char const *name, void *data) {
1324   __kmp_stg_print_bool(buffer, name, __kmp_handle_signals);
1325 } // __kmp_stg_print_handle_signals
1326
1327 #endif // KMP_HANDLE_SIGNALS
1328
1329 // -----------------------------------------------------------------------------
1330 // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG
1331
1332 #ifdef KMP_DEBUG
1333
1334 #define KMP_STG_X_DEBUG(x)                                                     \
1335   static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \
1336                                           void *data) {                        \
1337     __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug);            \
1338   } /* __kmp_stg_parse_x_debug */                                              \
1339   static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer,               \
1340                                           char const *name, void *data) {      \
1341     __kmp_stg_print_int(buffer, name, kmp_##x##_debug);                        \
1342   } /* __kmp_stg_print_x_debug */
1343
1344 KMP_STG_X_DEBUG(a)
1345 KMP_STG_X_DEBUG(b)
1346 KMP_STG_X_DEBUG(c)
1347 KMP_STG_X_DEBUG(d)
1348 KMP_STG_X_DEBUG(e)
1349 KMP_STG_X_DEBUG(f)
1350
1351 #undef KMP_STG_X_DEBUG
1352
1353 static void __kmp_stg_parse_debug(char const *name, char const *value,
1354                                   void *data) {
1355   int debug = 0;
1356   __kmp_stg_parse_int(name, value, 0, INT_MAX, &debug);
1357   if (kmp_a_debug < debug) {
1358     kmp_a_debug = debug;
1359   }
1360   if (kmp_b_debug < debug) {
1361     kmp_b_debug = debug;
1362   }
1363   if (kmp_c_debug < debug) {
1364     kmp_c_debug = debug;
1365   }
1366   if (kmp_d_debug < debug) {
1367     kmp_d_debug = debug;
1368   }
1369   if (kmp_e_debug < debug) {
1370     kmp_e_debug = debug;
1371   }
1372   if (kmp_f_debug < debug) {
1373     kmp_f_debug = debug;
1374   }
1375 } // __kmp_stg_parse_debug
1376
1377 static void __kmp_stg_parse_debug_buf(char const *name, char const *value,
1378                                       void *data) {
1379   __kmp_stg_parse_bool(name, value, &__kmp_debug_buf);
1380   // !!! TODO: Move buffer initialization of of this file! It may works
1381   // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or
1382   // KMP_DEBUG_BUF_CHARS.
1383   if (__kmp_debug_buf) {
1384     int i;
1385     int elements = __kmp_debug_buf_lines * __kmp_debug_buf_chars;
1386
1387     /* allocate and initialize all entries in debug buffer to empty */
1388     __kmp_debug_buffer = (char *)__kmp_page_allocate(elements * sizeof(char));
1389     for (i = 0; i < elements; i += __kmp_debug_buf_chars)
1390       __kmp_debug_buffer[i] = '\0';
1391
1392     __kmp_debug_count = 0;
1393   }
1394   K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf));
1395 } // __kmp_stg_parse_debug_buf
1396
1397 static void __kmp_stg_print_debug_buf(kmp_str_buf_t *buffer, char const *name,
1398                                       void *data) {
1399   __kmp_stg_print_bool(buffer, name, __kmp_debug_buf);
1400 } // __kmp_stg_print_debug_buf
1401
1402 static void __kmp_stg_parse_debug_buf_atomic(char const *name,
1403                                              char const *value, void *data) {
1404   __kmp_stg_parse_bool(name, value, &__kmp_debug_buf_atomic);
1405 } // __kmp_stg_parse_debug_buf_atomic
1406
1407 static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t *buffer,
1408                                              char const *name, void *data) {
1409   __kmp_stg_print_bool(buffer, name, __kmp_debug_buf_atomic);
1410 } // __kmp_stg_print_debug_buf_atomic
1411
1412 static void __kmp_stg_parse_debug_buf_chars(char const *name, char const *value,
1413                                             void *data) {
1414   __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_CHARS_MIN, INT_MAX,
1415                       &__kmp_debug_buf_chars);
1416 } // __kmp_stg_debug_parse_buf_chars
1417
1418 static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t *buffer,
1419                                             char const *name, void *data) {
1420   __kmp_stg_print_int(buffer, name, __kmp_debug_buf_chars);
1421 } // __kmp_stg_print_debug_buf_chars
1422
1423 static void __kmp_stg_parse_debug_buf_lines(char const *name, char const *value,
1424                                             void *data) {
1425   __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_LINES_MIN, INT_MAX,
1426                       &__kmp_debug_buf_lines);
1427 } // __kmp_stg_parse_debug_buf_lines
1428
1429 static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t *buffer,
1430                                             char const *name, void *data) {
1431   __kmp_stg_print_int(buffer, name, __kmp_debug_buf_lines);
1432 } // __kmp_stg_print_debug_buf_lines
1433
1434 static void __kmp_stg_parse_diag(char const *name, char const *value,
1435                                  void *data) {
1436   __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_diag);
1437 } // __kmp_stg_parse_diag
1438
1439 static void __kmp_stg_print_diag(kmp_str_buf_t *buffer, char const *name,
1440                                  void *data) {
1441   __kmp_stg_print_int(buffer, name, kmp_diag);
1442 } // __kmp_stg_print_diag
1443
1444 #endif // KMP_DEBUG
1445
1446 // -----------------------------------------------------------------------------
1447 // KMP_ALIGN_ALLOC
1448
1449 static void __kmp_stg_parse_align_alloc(char const *name, char const *value,
1450                                         void *data) {
1451   __kmp_stg_parse_size(name, value, CACHE_LINE, INT_MAX, NULL,
1452                        &__kmp_align_alloc, 1);
1453 } // __kmp_stg_parse_align_alloc
1454
1455 static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name,
1456                                         void *data) {
1457   __kmp_stg_print_size(buffer, name, __kmp_align_alloc);
1458 } // __kmp_stg_print_align_alloc
1459
1460 // -----------------------------------------------------------------------------
1461 // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER
1462
1463 // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from
1464 // parse and print functions, pass required info through data argument.
1465
1466 static void __kmp_stg_parse_barrier_branch_bit(char const *name,
1467                                                char const *value, void *data) {
1468   const char *var;
1469
1470   /* ---------- Barrier branch bit control ------------ */
1471   for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1472     var = __kmp_barrier_branch_bit_env_name[i];
1473     if ((strcmp(var, name) == 0) && (value != 0)) {
1474       char *comma;
1475
1476       comma = CCAST(char *, strchr(value, ','));
1477       __kmp_barrier_gather_branch_bits[i] =
1478           (kmp_uint32)__kmp_str_to_int(value, ',');
1479       /* is there a specified release parameter? */
1480       if (comma == NULL) {
1481         __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;
1482       } else {
1483         __kmp_barrier_release_branch_bits[i] =
1484             (kmp_uint32)__kmp_str_to_int(comma + 1, 0);
1485
1486         if (__kmp_barrier_release_branch_bits[i] > KMP_MAX_BRANCH_BITS) {
1487           __kmp_msg(kmp_ms_warning,
1488                     KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
1489                     __kmp_msg_null);
1490           __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;
1491         }
1492       }
1493       if (__kmp_barrier_gather_branch_bits[i] > KMP_MAX_BRANCH_BITS) {
1494         KMP_WARNING(BarrGatherValueInvalid, name, value);
1495         KMP_INFORM(Using_uint_Value, name, __kmp_barrier_gather_bb_dflt);
1496         __kmp_barrier_gather_branch_bits[i] = __kmp_barrier_gather_bb_dflt;
1497       }
1498     }
1499     K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[i],
1500                __kmp_barrier_gather_branch_bits[i],
1501                __kmp_barrier_release_branch_bits[i]))
1502   }
1503 } // __kmp_stg_parse_barrier_branch_bit
1504
1505 static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t *buffer,
1506                                                char const *name, void *data) {
1507   const char *var;
1508   for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1509     var = __kmp_barrier_branch_bit_env_name[i];
1510     if (strcmp(var, name) == 0) {
1511       if (__kmp_env_format) {
1512         KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name[i]);
1513       } else {
1514         __kmp_str_buf_print(buffer, "   %s='",
1515                             __kmp_barrier_branch_bit_env_name[i]);
1516       }
1517       __kmp_str_buf_print(buffer, "%d,%d'\n",
1518                           __kmp_barrier_gather_branch_bits[i],
1519                           __kmp_barrier_release_branch_bits[i]);
1520     }
1521   }
1522 } // __kmp_stg_print_barrier_branch_bit
1523
1524 // ----------------------------------------------------------------------------
1525 // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN,
1526 // KMP_REDUCTION_BARRIER_PATTERN
1527
1528 // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and
1529 // print functions, pass required data to functions through data argument.
1530
1531 static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value,
1532                                             void *data) {
1533   const char *var;
1534   /* ---------- Barrier method control ------------ */
1535
1536   for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1537     var = __kmp_barrier_pattern_env_name[i];
1538
1539     if ((strcmp(var, name) == 0) && (value != 0)) {
1540       int j;
1541       char *comma = CCAST(char *, strchr(value, ','));
1542
1543       /* handle first parameter: gather pattern */
1544       for (j = bp_linear_bar; j < bp_last_bar; j++) {
1545         if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name[j], value, 1,
1546                                       ',')) {
1547           __kmp_barrier_gather_pattern[i] = (kmp_bar_pat_e)j;
1548           break;
1549         }
1550       }
1551       if (j == bp_last_bar) {
1552         KMP_WARNING(BarrGatherValueInvalid, name, value);
1553         KMP_INFORM(Using_str_Value, name,
1554                    __kmp_barrier_pattern_name[bp_linear_bar]);
1555       }
1556
1557       /* handle second parameter: release pattern */
1558       if (comma != NULL) {
1559         for (j = bp_linear_bar; j < bp_last_bar; j++) {
1560           if (__kmp_str_match(__kmp_barrier_pattern_name[j], 1, comma + 1)) {
1561             __kmp_barrier_release_pattern[i] = (kmp_bar_pat_e)j;
1562             break;
1563           }
1564         }
1565         if (j == bp_last_bar) {
1566           __kmp_msg(kmp_ms_warning,
1567                     KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
1568                     __kmp_msg_null);
1569           KMP_INFORM(Using_str_Value, name,
1570                      __kmp_barrier_pattern_name[bp_linear_bar]);
1571         }
1572       }
1573     }
1574   }
1575 } // __kmp_stg_parse_barrier_pattern
1576
1577 static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t *buffer,
1578                                             char const *name, void *data) {
1579   const char *var;
1580   for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1581     var = __kmp_barrier_pattern_env_name[i];
1582     if (strcmp(var, name) == 0) {
1583       int j = __kmp_barrier_gather_pattern[i];
1584       int k = __kmp_barrier_release_pattern[i];
1585       if (__kmp_env_format) {
1586         KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name[i]);
1587       } else {
1588         __kmp_str_buf_print(buffer, "   %s='",
1589                             __kmp_barrier_pattern_env_name[i]);
1590       }
1591       __kmp_str_buf_print(buffer, "%s,%s'\n", __kmp_barrier_pattern_name[j],
1592                           __kmp_barrier_pattern_name[k]);
1593     }
1594   }
1595 } // __kmp_stg_print_barrier_pattern
1596
1597 // -----------------------------------------------------------------------------
1598 // KMP_ABORT_DELAY
1599
1600 static void __kmp_stg_parse_abort_delay(char const *name, char const *value,
1601                                         void *data) {
1602   // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is
1603   // milliseconds.
1604   int delay = __kmp_abort_delay / 1000;
1605   __kmp_stg_parse_int(name, value, 0, INT_MAX / 1000, &delay);
1606   __kmp_abort_delay = delay * 1000;
1607 } // __kmp_stg_parse_abort_delay
1608
1609 static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name,
1610                                         void *data) {
1611   __kmp_stg_print_int(buffer, name, __kmp_abort_delay);
1612 } // __kmp_stg_print_abort_delay
1613
1614 // -----------------------------------------------------------------------------
1615 // KMP_CPUINFO_FILE
1616
1617 static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value,
1618                                          void *data) {
1619 #if KMP_AFFINITY_SUPPORTED
1620   __kmp_stg_parse_str(name, value, &__kmp_cpuinfo_file);
1621   K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file));
1622 #endif
1623 } //__kmp_stg_parse_cpuinfo_file
1624
1625 static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t *buffer,
1626                                          char const *name, void *data) {
1627 #if KMP_AFFINITY_SUPPORTED
1628   if (__kmp_env_format) {
1629     KMP_STR_BUF_PRINT_NAME;
1630   } else {
1631     __kmp_str_buf_print(buffer, "   %s", name);
1632   }
1633   if (__kmp_cpuinfo_file) {
1634     __kmp_str_buf_print(buffer, "='%s'\n", __kmp_cpuinfo_file);
1635   } else {
1636     __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1637   }
1638 #endif
1639 } //__kmp_stg_print_cpuinfo_file
1640
1641 // -----------------------------------------------------------------------------
1642 // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION
1643
1644 static void __kmp_stg_parse_force_reduction(char const *name, char const *value,
1645                                             void *data) {
1646   kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;
1647   int rc;
1648
1649   rc = __kmp_stg_check_rivals(name, value, reduction->rivals);
1650   if (rc) {
1651     return;
1652   }
1653   if (reduction->force) {
1654     if (value != 0) {
1655       if (__kmp_str_match("critical", 0, value))
1656         __kmp_force_reduction_method = critical_reduce_block;
1657       else if (__kmp_str_match("atomic", 0, value))
1658         __kmp_force_reduction_method = atomic_reduce_block;
1659       else if (__kmp_str_match("tree", 0, value))
1660         __kmp_force_reduction_method = tree_reduce_block;
1661       else {
1662         KMP_FATAL(UnknownForceReduction, name, value);
1663       }
1664     }
1665   } else {
1666     __kmp_stg_parse_bool(name, value, &__kmp_determ_red);
1667     if (__kmp_determ_red) {
1668       __kmp_force_reduction_method = tree_reduce_block;
1669     } else {
1670       __kmp_force_reduction_method = reduction_method_not_defined;
1671     }
1672   }
1673   K_DIAG(1, ("__kmp_force_reduction_method == %d\n",
1674              __kmp_force_reduction_method));
1675 } // __kmp_stg_parse_force_reduction
1676
1677 static void __kmp_stg_print_force_reduction(kmp_str_buf_t *buffer,
1678                                             char const *name, void *data) {
1679
1680   kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;
1681   if (reduction->force) {
1682     if (__kmp_force_reduction_method == critical_reduce_block) {
1683       __kmp_stg_print_str(buffer, name, "critical");
1684     } else if (__kmp_force_reduction_method == atomic_reduce_block) {
1685       __kmp_stg_print_str(buffer, name, "atomic");
1686     } else if (__kmp_force_reduction_method == tree_reduce_block) {
1687       __kmp_stg_print_str(buffer, name, "tree");
1688     } else {
1689       if (__kmp_env_format) {
1690         KMP_STR_BUF_PRINT_NAME;
1691       } else {
1692         __kmp_str_buf_print(buffer, "   %s", name);
1693       }
1694       __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1695     }
1696   } else {
1697     __kmp_stg_print_bool(buffer, name, __kmp_determ_red);
1698   }
1699
1700 } // __kmp_stg_print_force_reduction
1701
1702 // -----------------------------------------------------------------------------
1703 // KMP_STORAGE_MAP
1704
1705 static void __kmp_stg_parse_storage_map(char const *name, char const *value,
1706                                         void *data) {
1707   if (__kmp_str_match("verbose", 1, value)) {
1708     __kmp_storage_map = TRUE;
1709     __kmp_storage_map_verbose = TRUE;
1710     __kmp_storage_map_verbose_specified = TRUE;
1711
1712   } else {
1713     __kmp_storage_map_verbose = FALSE;
1714     __kmp_stg_parse_bool(name, value, &__kmp_storage_map); // !!!
1715   }
1716 } // __kmp_stg_parse_storage_map
1717
1718 static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name,
1719                                         void *data) {
1720   if (__kmp_storage_map_verbose || __kmp_storage_map_verbose_specified) {
1721     __kmp_stg_print_str(buffer, name, "verbose");
1722   } else {
1723     __kmp_stg_print_bool(buffer, name, __kmp_storage_map);
1724   }
1725 } // __kmp_stg_print_storage_map
1726
1727 // -----------------------------------------------------------------------------
1728 // KMP_ALL_THREADPRIVATE
1729
1730 static void __kmp_stg_parse_all_threadprivate(char const *name,
1731                                               char const *value, void *data) {
1732   __kmp_stg_parse_int(name, value,
1733                       __kmp_allThreadsSpecified ? __kmp_max_nth : 1,
1734                       __kmp_max_nth, &__kmp_tp_capacity);
1735 } // __kmp_stg_parse_all_threadprivate
1736
1737 static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t *buffer,
1738                                               char const *name, void *data) {
1739   __kmp_stg_print_int(buffer, name, __kmp_tp_capacity);
1740 }
1741
1742 // -----------------------------------------------------------------------------
1743 // KMP_FOREIGN_THREADS_THREADPRIVATE
1744
1745 static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name,
1746                                                           char const *value,
1747                                                           void *data) {
1748   __kmp_stg_parse_bool(name, value, &__kmp_foreign_tp);
1749 } // __kmp_stg_parse_foreign_threads_threadprivate
1750
1751 static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t *buffer,
1752                                                           char const *name,
1753                                                           void *data) {
1754   __kmp_stg_print_bool(buffer, name, __kmp_foreign_tp);
1755 } // __kmp_stg_print_foreign_threads_threadprivate
1756
1757 // -----------------------------------------------------------------------------
1758 // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD
1759
1760 #if KMP_AFFINITY_SUPPORTED
1761 // Parse the proc id list.  Return TRUE if successful, FALSE otherwise.
1762 static int __kmp_parse_affinity_proc_id_list(const char *var, const char *env,
1763                                              const char **nextEnv,
1764                                              char **proclist) {
1765   const char *scan = env;
1766   const char *next = scan;
1767   int empty = TRUE;
1768
1769   *proclist = NULL;
1770
1771   for (;;) {
1772     int start, end, stride;
1773
1774     SKIP_WS(scan);
1775     next = scan;
1776     if (*next == '\0') {
1777       break;
1778     }
1779
1780     if (*next == '{') {
1781       int num;
1782       next++; // skip '{'
1783       SKIP_WS(next);
1784       scan = next;
1785
1786       // Read the first integer in the set.
1787       if ((*next < '0') || (*next > '9')) {
1788         KMP_WARNING(AffSyntaxError, var);
1789         return FALSE;
1790       }
1791       SKIP_DIGITS(next);
1792       num = __kmp_str_to_int(scan, *next);
1793       KMP_ASSERT(num >= 0);
1794
1795       for (;;) {
1796         // Check for end of set.
1797         SKIP_WS(next);
1798         if (*next == '}') {
1799           next++; // skip '}'
1800           break;
1801         }
1802
1803         // Skip optional comma.
1804         if (*next == ',') {
1805           next++;
1806         }
1807         SKIP_WS(next);
1808
1809         // Read the next integer in the set.
1810         scan = next;
1811         if ((*next < '0') || (*next > '9')) {
1812           KMP_WARNING(AffSyntaxError, var);
1813           return FALSE;
1814         }
1815
1816         SKIP_DIGITS(next);
1817         num = __kmp_str_to_int(scan, *next);
1818         KMP_ASSERT(num >= 0);
1819       }
1820       empty = FALSE;
1821
1822       SKIP_WS(next);
1823       if (*next == ',') {
1824         next++;
1825       }
1826       scan = next;
1827       continue;
1828     }
1829
1830     // Next character is not an integer => end of list
1831     if ((*next < '0') || (*next > '9')) {
1832       if (empty) {
1833         KMP_WARNING(AffSyntaxError, var);
1834         return FALSE;
1835       }
1836       break;
1837     }
1838
1839     // Read the first integer.
1840     SKIP_DIGITS(next);
1841     start = __kmp_str_to_int(scan, *next);
1842     KMP_ASSERT(start >= 0);
1843     SKIP_WS(next);
1844
1845     // If this isn't a range, then go on.
1846     if (*next != '-') {
1847       empty = FALSE;
1848
1849       // Skip optional comma.
1850       if (*next == ',') {
1851         next++;
1852       }
1853       scan = next;
1854       continue;
1855     }
1856
1857     // This is a range.  Skip over the '-' and read in the 2nd int.
1858     next++; // skip '-'
1859     SKIP_WS(next);
1860     scan = next;
1861     if ((*next < '0') || (*next > '9')) {
1862       KMP_WARNING(AffSyntaxError, var);
1863       return FALSE;
1864     }
1865     SKIP_DIGITS(next);
1866     end = __kmp_str_to_int(scan, *next);
1867     KMP_ASSERT(end >= 0);
1868
1869     // Check for a stride parameter
1870     stride = 1;
1871     SKIP_WS(next);
1872     if (*next == ':') {
1873       // A stride is specified.  Skip over the ':" and read the 3rd int.
1874       int sign = +1;
1875       next++; // skip ':'
1876       SKIP_WS(next);
1877       scan = next;
1878       if (*next == '-') {
1879         sign = -1;
1880         next++;
1881         SKIP_WS(next);
1882         scan = next;
1883       }
1884       if ((*next < '0') || (*next > '9')) {
1885         KMP_WARNING(AffSyntaxError, var);
1886         return FALSE;
1887       }
1888       SKIP_DIGITS(next);
1889       stride = __kmp_str_to_int(scan, *next);
1890       KMP_ASSERT(stride >= 0);
1891       stride *= sign;
1892     }
1893
1894     // Do some range checks.
1895     if (stride == 0) {
1896       KMP_WARNING(AffZeroStride, var);
1897       return FALSE;
1898     }
1899     if (stride > 0) {
1900       if (start > end) {
1901         KMP_WARNING(AffStartGreaterEnd, var, start, end);
1902         return FALSE;
1903       }
1904     } else {
1905       if (start < end) {
1906         KMP_WARNING(AffStrideLessZero, var, start, end);
1907         return FALSE;
1908       }
1909     }
1910     if ((end - start) / stride > 65536) {
1911       KMP_WARNING(AffRangeTooBig, var, end, start, stride);
1912       return FALSE;
1913     }
1914
1915     empty = FALSE;
1916
1917     // Skip optional comma.
1918     SKIP_WS(next);
1919     if (*next == ',') {
1920       next++;
1921     }
1922     scan = next;
1923   }
1924
1925   *nextEnv = next;
1926
1927   {
1928     int len = next - env;
1929     char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
1930     KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
1931     retlist[len] = '\0';
1932     *proclist = retlist;
1933   }
1934   return TRUE;
1935 }
1936
1937 // If KMP_AFFINITY is specified without a type, then
1938 // __kmp_affinity_notype should point to its setting.
1939 static kmp_setting_t *__kmp_affinity_notype = NULL;
1940
1941 static void __kmp_parse_affinity_env(char const *name, char const *value,
1942                                      enum affinity_type *out_type,
1943                                      char **out_proclist, int *out_verbose,
1944                                      int *out_warn, int *out_respect,
1945                                      enum affinity_gran *out_gran,
1946                                      int *out_gran_levels, int *out_dups,
1947                                      int *out_compact, int *out_offset) {
1948   char *buffer = NULL; // Copy of env var value.
1949   char *buf = NULL; // Buffer for strtok_r() function.
1950   char *next = NULL; // end of token / start of next.
1951   const char *start; // start of current token (for err msgs)
1952   int count = 0; // Counter of parsed integer numbers.
1953   int number[2]; // Parsed numbers.
1954
1955   // Guards.
1956   int type = 0;
1957   int proclist = 0;
1958   int verbose = 0;
1959   int warnings = 0;
1960   int respect = 0;
1961   int gran = 0;
1962   int dups = 0;
1963
1964   KMP_ASSERT(value != NULL);
1965
1966   if (TCR_4(__kmp_init_middle)) {
1967     KMP_WARNING(EnvMiddleWarn, name);
1968     __kmp_env_toPrint(name, 0);
1969     return;
1970   }
1971   __kmp_env_toPrint(name, 1);
1972
1973   buffer =
1974       __kmp_str_format("%s", value); // Copy env var to keep original intact.
1975   buf = buffer;
1976   SKIP_WS(buf);
1977
1978 // Helper macros.
1979
1980 // If we see a parse error, emit a warning and scan to the next ",".
1981 //
1982 // FIXME - there's got to be a better way to print an error
1983 // message, hopefully without overwritting peices of buf.
1984 #define EMIT_WARN(skip, errlist)                                               \
1985   {                                                                            \
1986     char ch;                                                                   \
1987     if (skip) {                                                                \
1988       SKIP_TO(next, ',');                                                      \
1989     }                                                                          \
1990     ch = *next;                                                                \
1991     *next = '\0';                                                              \
1992     KMP_WARNING errlist;                                                       \
1993     *next = ch;                                                                \
1994     if (skip) {                                                                \
1995       if (ch == ',')                                                           \
1996         next++;                                                                \
1997     }                                                                          \
1998     buf = next;                                                                \
1999   }
2000
2001 #define _set_param(_guard, _var, _val)                                         \
2002   {                                                                            \
2003     if (_guard == 0) {                                                         \
2004       _var = _val;                                                             \
2005     } else {                                                                   \
2006       EMIT_WARN(FALSE, (AffParamDefined, name, start));                        \
2007     }                                                                          \
2008     ++_guard;                                                                  \
2009   }
2010
2011 #define set_type(val) _set_param(type, *out_type, val)
2012 #define set_verbose(val) _set_param(verbose, *out_verbose, val)
2013 #define set_warnings(val) _set_param(warnings, *out_warn, val)
2014 #define set_respect(val) _set_param(respect, *out_respect, val)
2015 #define set_dups(val) _set_param(dups, *out_dups, val)
2016 #define set_proclist(val) _set_param(proclist, *out_proclist, val)
2017
2018 #define set_gran(val, levels)                                                  \
2019   {                                                                            \
2020     if (gran == 0) {                                                           \
2021       *out_gran = val;                                                         \
2022       *out_gran_levels = levels;                                               \
2023     } else {                                                                   \
2024       EMIT_WARN(FALSE, (AffParamDefined, name, start));                        \
2025     }                                                                          \
2026     ++gran;                                                                    \
2027   }
2028
2029 #if OMP_40_ENABLED
2030   KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
2031                    (__kmp_nested_proc_bind.used > 0));
2032 #endif
2033
2034   while (*buf != '\0') {
2035     start = next = buf;
2036
2037     if (__kmp_match_str("none", buf, CCAST(const char **, &next))) {
2038       set_type(affinity_none);
2039 #if OMP_40_ENABLED
2040       __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
2041 #endif
2042       buf = next;
2043     } else if (__kmp_match_str("scatter", buf, CCAST(const char **, &next))) {
2044       set_type(affinity_scatter);
2045 #if OMP_40_ENABLED
2046       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2047 #endif
2048       buf = next;
2049     } else if (__kmp_match_str("compact", buf, CCAST(const char **, &next))) {
2050       set_type(affinity_compact);
2051 #if OMP_40_ENABLED
2052       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2053 #endif
2054       buf = next;
2055     } else if (__kmp_match_str("logical", buf, CCAST(const char **, &next))) {
2056       set_type(affinity_logical);
2057 #if OMP_40_ENABLED
2058       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2059 #endif
2060       buf = next;
2061     } else if (__kmp_match_str("physical", buf, CCAST(const char **, &next))) {
2062       set_type(affinity_physical);
2063 #if OMP_40_ENABLED
2064       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2065 #endif
2066       buf = next;
2067     } else if (__kmp_match_str("explicit", buf, CCAST(const char **, &next))) {
2068       set_type(affinity_explicit);
2069 #if OMP_40_ENABLED
2070       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2071 #endif
2072       buf = next;
2073     } else if (__kmp_match_str("balanced", buf, CCAST(const char **, &next))) {
2074       set_type(affinity_balanced);
2075 #if OMP_40_ENABLED
2076       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2077 #endif
2078       buf = next;
2079     } else if (__kmp_match_str("disabled", buf, CCAST(const char **, &next))) {
2080       set_type(affinity_disabled);
2081 #if OMP_40_ENABLED
2082       __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
2083 #endif
2084       buf = next;
2085     } else if (__kmp_match_str("verbose", buf, CCAST(const char **, &next))) {
2086       set_verbose(TRUE);
2087       buf = next;
2088     } else if (__kmp_match_str("noverbose", buf, CCAST(const char **, &next))) {
2089       set_verbose(FALSE);
2090       buf = next;
2091     } else if (__kmp_match_str("warnings", buf, CCAST(const char **, &next))) {
2092       set_warnings(TRUE);
2093       buf = next;
2094     } else if (__kmp_match_str("nowarnings", buf,
2095                                CCAST(const char **, &next))) {
2096       set_warnings(FALSE);
2097       buf = next;
2098     } else if (__kmp_match_str("respect", buf, CCAST(const char **, &next))) {
2099       set_respect(TRUE);
2100       buf = next;
2101     } else if (__kmp_match_str("norespect", buf, CCAST(const char **, &next))) {
2102       set_respect(FALSE);
2103       buf = next;
2104     } else if (__kmp_match_str("duplicates", buf,
2105                                CCAST(const char **, &next)) ||
2106                __kmp_match_str("dups", buf, CCAST(const char **, &next))) {
2107       set_dups(TRUE);
2108       buf = next;
2109     } else if (__kmp_match_str("noduplicates", buf,
2110                                CCAST(const char **, &next)) ||
2111                __kmp_match_str("nodups", buf, CCAST(const char **, &next))) {
2112       set_dups(FALSE);
2113       buf = next;
2114     } else if (__kmp_match_str("granularity", buf,
2115                                CCAST(const char **, &next)) ||
2116                __kmp_match_str("gran", buf, CCAST(const char **, &next))) {
2117       SKIP_WS(next);
2118       if (*next != '=') {
2119         EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2120         continue;
2121       }
2122       next++; // skip '='
2123       SKIP_WS(next);
2124
2125       buf = next;
2126       if (__kmp_match_str("fine", buf, CCAST(const char **, &next))) {
2127         set_gran(affinity_gran_fine, -1);
2128         buf = next;
2129       } else if (__kmp_match_str("thread", buf, CCAST(const char **, &next))) {
2130         set_gran(affinity_gran_thread, -1);
2131         buf = next;
2132       } else if (__kmp_match_str("core", buf, CCAST(const char **, &next))) {
2133         set_gran(affinity_gran_core, -1);
2134         buf = next;
2135 #if KMP_USE_HWLOC
2136       } else if (__kmp_match_str("tile", buf, CCAST(const char **, &next))) {
2137         set_gran(affinity_gran_tile, -1);
2138         buf = next;
2139 #endif
2140       } else if (__kmp_match_str("package", buf, CCAST(const char **, &next))) {
2141         set_gran(affinity_gran_package, -1);
2142         buf = next;
2143       } else if (__kmp_match_str("node", buf, CCAST(const char **, &next))) {
2144         set_gran(affinity_gran_node, -1);
2145         buf = next;
2146 #if KMP_GROUP_AFFINITY
2147       } else if (__kmp_match_str("group", buf, CCAST(const char **, &next))) {
2148         set_gran(affinity_gran_group, -1);
2149         buf = next;
2150 #endif /* KMP_GROUP AFFINITY */
2151       } else if ((*buf >= '0') && (*buf <= '9')) {
2152         int n;
2153         next = buf;
2154         SKIP_DIGITS(next);
2155         n = __kmp_str_to_int(buf, *next);
2156         KMP_ASSERT(n >= 0);
2157         buf = next;
2158         set_gran(affinity_gran_default, n);
2159       } else {
2160         EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2161         continue;
2162       }
2163     } else if (__kmp_match_str("proclist", buf, CCAST(const char **, &next))) {
2164       char *temp_proclist;
2165
2166       SKIP_WS(next);
2167       if (*next != '=') {
2168         EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2169         continue;
2170       }
2171       next++; // skip '='
2172       SKIP_WS(next);
2173       if (*next != '[') {
2174         EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2175         continue;
2176       }
2177       next++; // skip '['
2178       buf = next;
2179       if (!__kmp_parse_affinity_proc_id_list(
2180               name, buf, CCAST(const char **, &next), &temp_proclist)) {
2181         // warning already emitted.
2182         SKIP_TO(next, ']');
2183         if (*next == ']')
2184           next++;
2185         SKIP_TO(next, ',');
2186         if (*next == ',')
2187           next++;
2188         buf = next;
2189         continue;
2190       }
2191       if (*next != ']') {
2192         EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2193         continue;
2194       }
2195       next++; // skip ']'
2196       set_proclist(temp_proclist);
2197     } else if ((*buf >= '0') && (*buf <= '9')) {
2198       // Parse integer numbers -- permute and offset.
2199       int n;
2200       next = buf;
2201       SKIP_DIGITS(next);
2202       n = __kmp_str_to_int(buf, *next);
2203       KMP_ASSERT(n >= 0);
2204       buf = next;
2205       if (count < 2) {
2206         number[count] = n;
2207       } else {
2208         KMP_WARNING(AffManyParams, name, start);
2209       }
2210       ++count;
2211     } else {
2212       EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2213       continue;
2214     }
2215
2216     SKIP_WS(next);
2217     if (*next == ',') {
2218       next++;
2219       SKIP_WS(next);
2220     } else if (*next != '\0') {
2221       const char *temp = next;
2222       EMIT_WARN(TRUE, (ParseExtraCharsWarn, name, temp));
2223       continue;
2224     }
2225     buf = next;
2226   } // while
2227
2228 #undef EMIT_WARN
2229 #undef _set_param
2230 #undef set_type
2231 #undef set_verbose
2232 #undef set_warnings
2233 #undef set_respect
2234 #undef set_granularity
2235
2236   __kmp_str_free(&buffer);
2237
2238   if (proclist) {
2239     if (!type) {
2240       KMP_WARNING(AffProcListNoType, name);
2241       *out_type = affinity_explicit;
2242 #if OMP_40_ENABLED
2243       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2244 #endif
2245     } else if (*out_type != affinity_explicit) {
2246       KMP_WARNING(AffProcListNotExplicit, name);
2247       KMP_ASSERT(*out_proclist != NULL);
2248       KMP_INTERNAL_FREE(*out_proclist);
2249       *out_proclist = NULL;
2250     }
2251   }
2252   switch (*out_type) {
2253   case affinity_logical:
2254   case affinity_physical: {
2255     if (count > 0) {
2256       *out_offset = number[0];
2257     }
2258     if (count > 1) {
2259       KMP_WARNING(AffManyParamsForLogic, name, number[1]);
2260     }
2261   } break;
2262   case affinity_balanced: {
2263     if (count > 0) {
2264       *out_compact = number[0];
2265     }
2266     if (count > 1) {
2267       *out_offset = number[1];
2268     }
2269
2270     if (__kmp_affinity_gran == affinity_gran_default) {
2271 #if KMP_MIC_SUPPORTED
2272       if (__kmp_mic_type != non_mic) {
2273         if (__kmp_affinity_verbose || __kmp_affinity_warnings) {
2274           KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "fine");
2275         }
2276         __kmp_affinity_gran = affinity_gran_fine;
2277       } else
2278 #endif
2279       {
2280         if (__kmp_affinity_verbose || __kmp_affinity_warnings) {
2281           KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "core");
2282         }
2283         __kmp_affinity_gran = affinity_gran_core;
2284       }
2285     }
2286   } break;
2287   case affinity_scatter:
2288   case affinity_compact: {
2289     if (count > 0) {
2290       *out_compact = number[0];
2291     }
2292     if (count > 1) {
2293       *out_offset = number[1];
2294     }
2295   } break;
2296   case affinity_explicit: {
2297     if (*out_proclist == NULL) {
2298       KMP_WARNING(AffNoProcList, name);
2299       __kmp_affinity_type = affinity_none;
2300     }
2301     if (count > 0) {
2302       KMP_WARNING(AffNoParam, name, "explicit");
2303     }
2304   } break;
2305   case affinity_none: {
2306     if (count > 0) {
2307       KMP_WARNING(AffNoParam, name, "none");
2308     }
2309   } break;
2310   case affinity_disabled: {
2311     if (count > 0) {
2312       KMP_WARNING(AffNoParam, name, "disabled");
2313     }
2314   } break;
2315   case affinity_default: {
2316     if (count > 0) {
2317       KMP_WARNING(AffNoParam, name, "default");
2318     }
2319   } break;
2320   default: { KMP_ASSERT(0); }
2321   }
2322 } // __kmp_parse_affinity_env
2323
2324 static void __kmp_stg_parse_affinity(char const *name, char const *value,
2325                                      void *data) {
2326   kmp_setting_t **rivals = (kmp_setting_t **)data;
2327   int rc;
2328
2329   rc = __kmp_stg_check_rivals(name, value, rivals);
2330   if (rc) {
2331     return;
2332   }
2333
2334   __kmp_parse_affinity_env(name, value, &__kmp_affinity_type,
2335                            &__kmp_affinity_proclist, &__kmp_affinity_verbose,
2336                            &__kmp_affinity_warnings,
2337                            &__kmp_affinity_respect_mask, &__kmp_affinity_gran,
2338                            &__kmp_affinity_gran_levels, &__kmp_affinity_dups,
2339                            &__kmp_affinity_compact, &__kmp_affinity_offset);
2340
2341 } // __kmp_stg_parse_affinity
2342
2343 static void __kmp_stg_print_affinity(kmp_str_buf_t *buffer, char const *name,
2344                                      void *data) {
2345   if (__kmp_env_format) {
2346     KMP_STR_BUF_PRINT_NAME_EX(name);
2347   } else {
2348     __kmp_str_buf_print(buffer, "   %s='", name);
2349   }
2350   if (__kmp_affinity_verbose) {
2351     __kmp_str_buf_print(buffer, "%s,", "verbose");
2352   } else {
2353     __kmp_str_buf_print(buffer, "%s,", "noverbose");
2354   }
2355   if (__kmp_affinity_warnings) {
2356     __kmp_str_buf_print(buffer, "%s,", "warnings");
2357   } else {
2358     __kmp_str_buf_print(buffer, "%s,", "nowarnings");
2359   }
2360   if (KMP_AFFINITY_CAPABLE()) {
2361     if (__kmp_affinity_respect_mask) {
2362       __kmp_str_buf_print(buffer, "%s,", "respect");
2363     } else {
2364       __kmp_str_buf_print(buffer, "%s,", "norespect");
2365     }
2366     switch (__kmp_affinity_gran) {
2367     case affinity_gran_default:
2368       __kmp_str_buf_print(buffer, "%s", "granularity=default,");
2369       break;
2370     case affinity_gran_fine:
2371       __kmp_str_buf_print(buffer, "%s", "granularity=fine,");
2372       break;
2373     case affinity_gran_thread:
2374       __kmp_str_buf_print(buffer, "%s", "granularity=thread,");
2375       break;
2376     case affinity_gran_core:
2377       __kmp_str_buf_print(buffer, "%s", "granularity=core,");
2378       break;
2379     case affinity_gran_package:
2380       __kmp_str_buf_print(buffer, "%s", "granularity=package,");
2381       break;
2382     case affinity_gran_node:
2383       __kmp_str_buf_print(buffer, "%s", "granularity=node,");
2384       break;
2385 #if KMP_GROUP_AFFINITY
2386     case affinity_gran_group:
2387       __kmp_str_buf_print(buffer, "%s", "granularity=group,");
2388       break;
2389 #endif /* KMP_GROUP_AFFINITY */
2390     }
2391   }
2392   if (!KMP_AFFINITY_CAPABLE()) {
2393     __kmp_str_buf_print(buffer, "%s", "disabled");
2394   } else
2395     switch (__kmp_affinity_type) {
2396     case affinity_none:
2397       __kmp_str_buf_print(buffer, "%s", "none");
2398       break;
2399     case affinity_physical:
2400       __kmp_str_buf_print(buffer, "%s,%d", "physical", __kmp_affinity_offset);
2401       break;
2402     case affinity_logical:
2403       __kmp_str_buf_print(buffer, "%s,%d", "logical", __kmp_affinity_offset);
2404       break;
2405     case affinity_compact:
2406       __kmp_str_buf_print(buffer, "%s,%d,%d", "compact", __kmp_affinity_compact,
2407                           __kmp_affinity_offset);
2408       break;
2409     case affinity_scatter:
2410       __kmp_str_buf_print(buffer, "%s,%d,%d", "scatter", __kmp_affinity_compact,
2411                           __kmp_affinity_offset);
2412       break;
2413     case affinity_explicit:
2414       __kmp_str_buf_print(buffer, "%s=[%s],%s", "proclist",
2415                           __kmp_affinity_proclist, "explicit");
2416       break;
2417     case affinity_balanced:
2418       __kmp_str_buf_print(buffer, "%s,%d,%d", "balanced",
2419                           __kmp_affinity_compact, __kmp_affinity_offset);
2420       break;
2421     case affinity_disabled:
2422       __kmp_str_buf_print(buffer, "%s", "disabled");
2423       break;
2424     case affinity_default:
2425       __kmp_str_buf_print(buffer, "%s", "default");
2426       break;
2427     default:
2428       __kmp_str_buf_print(buffer, "%s", "<unknown>");
2429       break;
2430     }
2431   __kmp_str_buf_print(buffer, "'\n");
2432 } //__kmp_stg_print_affinity
2433
2434 #ifdef KMP_GOMP_COMPAT
2435
2436 static void __kmp_stg_parse_gomp_cpu_affinity(char const *name,
2437                                               char const *value, void *data) {
2438   const char *next = NULL;
2439   char *temp_proclist;
2440   kmp_setting_t **rivals = (kmp_setting_t **)data;
2441   int rc;
2442
2443   rc = __kmp_stg_check_rivals(name, value, rivals);
2444   if (rc) {
2445     return;
2446   }
2447
2448   if (TCR_4(__kmp_init_middle)) {
2449     KMP_WARNING(EnvMiddleWarn, name);
2450     __kmp_env_toPrint(name, 0);
2451     return;
2452   }
2453
2454   __kmp_env_toPrint(name, 1);
2455
2456   if (__kmp_parse_affinity_proc_id_list(name, value, &next, &temp_proclist)) {
2457     SKIP_WS(next);
2458     if (*next == '\0') {
2459       // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...
2460       __kmp_affinity_proclist = temp_proclist;
2461       __kmp_affinity_type = affinity_explicit;
2462       __kmp_affinity_gran = affinity_gran_fine;
2463 #if OMP_40_ENABLED
2464       __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2465 #endif
2466     } else {
2467       KMP_WARNING(AffSyntaxError, name);
2468       if (temp_proclist != NULL) {
2469         KMP_INTERNAL_FREE((void *)temp_proclist);
2470       }
2471     }
2472   } else {
2473     // Warning already emitted
2474     __kmp_affinity_type = affinity_none;
2475 #if OMP_40_ENABLED
2476     __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
2477 #endif
2478   }
2479 } // __kmp_stg_parse_gomp_cpu_affinity
2480
2481 #endif /* KMP_GOMP_COMPAT */
2482
2483 #if OMP_40_ENABLED
2484
2485 /*-----------------------------------------------------------------------------
2486 The OMP_PLACES proc id list parser. Here is the grammar:
2487
2488 place_list := place
2489 place_list := place , place_list
2490 place := num
2491 place := place : num
2492 place := place : num : signed
2493 place := { subplacelist }
2494 place := ! place                  // (lowest priority)
2495 subplace_list := subplace
2496 subplace_list := subplace , subplace_list
2497 subplace := num
2498 subplace := num : num
2499 subplace := num : num : signed
2500 signed := num
2501 signed := + signed
2502 signed := - signed
2503 -----------------------------------------------------------------------------*/
2504
2505 static int __kmp_parse_subplace_list(const char *var, const char **scan) {
2506   const char *next;
2507
2508   for (;;) {
2509     int start, count, stride;
2510
2511     //
2512     // Read in the starting proc id
2513     //
2514     SKIP_WS(*scan);
2515     if ((**scan < '0') || (**scan > '9')) {
2516       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2517       return FALSE;
2518     }
2519     next = *scan;
2520     SKIP_DIGITS(next);
2521     start = __kmp_str_to_int(*scan, *next);
2522     KMP_ASSERT(start >= 0);
2523     *scan = next;
2524
2525     // valid follow sets are ',' ':' and '}'
2526     SKIP_WS(*scan);
2527     if (**scan == '}') {
2528       break;
2529     }
2530     if (**scan == ',') {
2531       (*scan)++; // skip ','
2532       continue;
2533     }
2534     if (**scan != ':') {
2535       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2536       return FALSE;
2537     }
2538     (*scan)++; // skip ':'
2539
2540     // Read count parameter
2541     SKIP_WS(*scan);
2542     if ((**scan < '0') || (**scan > '9')) {
2543       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2544       return FALSE;
2545     }
2546     next = *scan;
2547     SKIP_DIGITS(next);
2548     count = __kmp_str_to_int(*scan, *next);
2549     KMP_ASSERT(count >= 0);
2550     *scan = next;
2551
2552     // valid follow sets are ',' ':' and '}'
2553     SKIP_WS(*scan);
2554     if (**scan == '}') {
2555       break;
2556     }
2557     if (**scan == ',') {
2558       (*scan)++; // skip ','
2559       continue;
2560     }
2561     if (**scan != ':') {
2562       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2563       return FALSE;
2564     }
2565     (*scan)++; // skip ':'
2566
2567     // Read stride parameter
2568     int sign = +1;
2569     for (;;) {
2570       SKIP_WS(*scan);
2571       if (**scan == '+') {
2572         (*scan)++; // skip '+'
2573         continue;
2574       }
2575       if (**scan == '-') {
2576         sign *= -1;
2577         (*scan)++; // skip '-'
2578         continue;
2579       }
2580       break;
2581     }
2582     SKIP_WS(*scan);
2583     if ((**scan < '0') || (**scan > '9')) {
2584       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2585       return FALSE;
2586     }
2587     next = *scan;
2588     SKIP_DIGITS(next);
2589     stride = __kmp_str_to_int(*scan, *next);
2590     KMP_ASSERT(stride >= 0);
2591     *scan = next;
2592     stride *= sign;
2593
2594     // valid follow sets are ',' and '}'
2595     SKIP_WS(*scan);
2596     if (**scan == '}') {
2597       break;
2598     }
2599     if (**scan == ',') {
2600       (*scan)++; // skip ','
2601       continue;
2602     }
2603
2604     KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2605     return FALSE;
2606   }
2607   return TRUE;
2608 }
2609
2610 static int __kmp_parse_place(const char *var, const char **scan) {
2611   const char *next;
2612
2613   // valid follow sets are '{' '!' and num
2614   SKIP_WS(*scan);
2615   if (**scan == '{') {
2616     (*scan)++; // skip '{'
2617     if (!__kmp_parse_subplace_list(var, scan)) {
2618       return FALSE;
2619     }
2620     if (**scan != '}') {
2621       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2622       return FALSE;
2623     }
2624     (*scan)++; // skip '}'
2625   } else if (**scan == '!') {
2626     (*scan)++; // skip '!'
2627     return __kmp_parse_place(var, scan); //'!' has lower precedence than ':'
2628   } else if ((**scan >= '0') && (**scan <= '9')) {
2629     next = *scan;
2630     SKIP_DIGITS(next);
2631     int proc = __kmp_str_to_int(*scan, *next);
2632     KMP_ASSERT(proc >= 0);
2633     *scan = next;
2634   } else {
2635     KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2636     return FALSE;
2637   }
2638   return TRUE;
2639 }
2640
2641 static int __kmp_parse_place_list(const char *var, const char *env,
2642                                   char **place_list) {
2643   const char *scan = env;
2644   const char *next = scan;
2645
2646   for (;;) {
2647     int count, stride;
2648
2649     if (!__kmp_parse_place(var, &scan)) {
2650       return FALSE;
2651     }
2652
2653     // valid follow sets are ',' ':' and EOL
2654     SKIP_WS(scan);
2655     if (*scan == '\0') {
2656       break;
2657     }
2658     if (*scan == ',') {
2659       scan++; // skip ','
2660       continue;
2661     }
2662     if (*scan != ':') {
2663       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2664       return FALSE;
2665     }
2666     scan++; // skip ':'
2667
2668     // Read count parameter
2669     SKIP_WS(scan);
2670     if ((*scan < '0') || (*scan > '9')) {
2671       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2672       return FALSE;
2673     }
2674     next = scan;
2675     SKIP_DIGITS(next);
2676     count = __kmp_str_to_int(scan, *next);
2677     KMP_ASSERT(count >= 0);
2678     scan = next;
2679
2680     // valid follow sets are ',' ':' and EOL
2681     SKIP_WS(scan);
2682     if (*scan == '\0') {
2683       break;
2684     }
2685     if (*scan == ',') {
2686       scan++; // skip ','
2687       continue;
2688     }
2689     if (*scan != ':') {
2690       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2691       return FALSE;
2692     }
2693     scan++; // skip ':'
2694
2695     // Read stride parameter
2696     int sign = +1;
2697     for (;;) {
2698       SKIP_WS(scan);
2699       if (*scan == '+') {
2700         scan++; // skip '+'
2701         continue;
2702       }
2703       if (*scan == '-') {
2704         sign *= -1;
2705         scan++; // skip '-'
2706         continue;
2707       }
2708       break;
2709     }
2710     SKIP_WS(scan);
2711     if ((*scan < '0') || (*scan > '9')) {
2712       KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2713       return FALSE;
2714     }
2715     next = scan;
2716     SKIP_DIGITS(next);
2717     stride = __kmp_str_to_int(scan, *next);
2718     KMP_ASSERT(stride >= 0);
2719     scan = next;
2720     stride *= sign;
2721
2722     // valid follow sets are ',' and EOL
2723     SKIP_WS(scan);
2724     if (*scan == '\0') {
2725       break;
2726     }
2727     if (*scan == ',') {
2728       scan++; // skip ','
2729       continue;
2730     }
2731
2732     KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2733     return FALSE;
2734   }
2735
2736   {
2737     int len = scan - env;
2738     char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
2739     KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
2740     retlist[len] = '\0';
2741     *place_list = retlist;
2742   }
2743   return TRUE;
2744 }
2745
2746 static void __kmp_stg_parse_places(char const *name, char const *value,
2747                                    void *data) {
2748   int count;
2749   const char *scan = value;
2750   const char *next = scan;
2751   const char *kind = "\"threads\"";
2752   kmp_setting_t **rivals = (kmp_setting_t **)data;
2753   int rc;
2754
2755   rc = __kmp_stg_check_rivals(name, value, rivals);
2756   if (rc) {
2757     return;
2758   }
2759
2760   // If OMP_PROC_BIND is not specified but OMP_PLACES is,
2761   // then let OMP_PROC_BIND default to true.
2762   if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
2763     __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
2764   }
2765
2766   //__kmp_affinity_num_places = 0;
2767
2768   if (__kmp_match_str("threads", scan, &next)) {
2769     scan = next;
2770     __kmp_affinity_type = affinity_compact;
2771     __kmp_affinity_gran = affinity_gran_thread;
2772     __kmp_affinity_dups = FALSE;
2773     kind = "\"threads\"";
2774   } else if (__kmp_match_str("cores", scan, &next)) {
2775     scan = next;
2776     __kmp_affinity_type = affinity_compact;
2777     __kmp_affinity_gran = affinity_gran_core;
2778     __kmp_affinity_dups = FALSE;
2779     kind = "\"cores\"";
2780 #if KMP_USE_HWLOC
2781   } else if (__kmp_match_str("tiles", scan, &next)) {
2782     scan = next;
2783     __kmp_affinity_type = affinity_compact;
2784     __kmp_affinity_gran = affinity_gran_tile;
2785     __kmp_affinity_dups = FALSE;
2786     kind = "\"tiles\"";
2787 #endif
2788   } else if (__kmp_match_str("sockets", scan, &next)) {
2789     scan = next;
2790     __kmp_affinity_type = affinity_compact;
2791     __kmp_affinity_gran = affinity_gran_package;
2792     __kmp_affinity_dups = FALSE;
2793     kind = "\"sockets\"";
2794   } else {
2795     if (__kmp_affinity_proclist != NULL) {
2796       KMP_INTERNAL_FREE((void *)__kmp_affinity_proclist);
2797       __kmp_affinity_proclist = NULL;
2798     }
2799     if (__kmp_parse_place_list(name, value, &__kmp_affinity_proclist)) {
2800       __kmp_affinity_type = affinity_explicit;
2801       __kmp_affinity_gran = affinity_gran_fine;
2802       __kmp_affinity_dups = FALSE;
2803       if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
2804         __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
2805       }
2806     }
2807     return;
2808   }
2809
2810   if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
2811     __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
2812   }
2813
2814   SKIP_WS(scan);
2815   if (*scan == '\0') {
2816     return;
2817   }
2818
2819   // Parse option count parameter in parentheses
2820   if (*scan != '(') {
2821     KMP_WARNING(SyntaxErrorUsing, name, kind);
2822     return;
2823   }
2824   scan++; // skip '('
2825
2826   SKIP_WS(scan);
2827   next = scan;
2828   SKIP_DIGITS(next);
2829   count = __kmp_str_to_int(scan, *next);
2830   KMP_ASSERT(count >= 0);
2831   scan = next;
2832
2833   SKIP_WS(scan);
2834   if (*scan != ')') {
2835     KMP_WARNING(SyntaxErrorUsing, name, kind);
2836     return;
2837   }
2838   scan++; // skip ')'
2839
2840   SKIP_WS(scan);
2841   if (*scan != '\0') {
2842     KMP_WARNING(ParseExtraCharsWarn, name, scan);
2843   }
2844   __kmp_affinity_num_places = count;
2845 }
2846
2847 static void __kmp_stg_print_places(kmp_str_buf_t *buffer, char const *name,
2848                                    void *data) {
2849   if (__kmp_env_format) {
2850     KMP_STR_BUF_PRINT_NAME;
2851   } else {
2852     __kmp_str_buf_print(buffer, "   %s", name);
2853   }
2854   if ((__kmp_nested_proc_bind.used == 0) ||
2855       (__kmp_nested_proc_bind.bind_types == NULL) ||
2856       (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)) {
2857     __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2858   } else if (__kmp_affinity_type == affinity_explicit) {
2859     if (__kmp_affinity_proclist != NULL) {
2860       __kmp_str_buf_print(buffer, "='%s'\n", __kmp_affinity_proclist);
2861     } else {
2862       __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2863     }
2864   } else if (__kmp_affinity_type == affinity_compact) {
2865     int num;
2866     if (__kmp_affinity_num_masks > 0) {
2867       num = __kmp_affinity_num_masks;
2868     } else if (__kmp_affinity_num_places > 0) {
2869       num = __kmp_affinity_num_places;
2870     } else {
2871       num = 0;
2872     }
2873     if (__kmp_affinity_gran == affinity_gran_thread) {
2874       if (num > 0) {
2875         __kmp_str_buf_print(buffer, "='threads(%d)'\n", num);
2876       } else {
2877         __kmp_str_buf_print(buffer, "='threads'\n");
2878       }
2879     } else if (__kmp_affinity_gran == affinity_gran_core) {
2880       if (num > 0) {
2881         __kmp_str_buf_print(buffer, "='cores(%d)' \n", num);
2882       } else {
2883         __kmp_str_buf_print(buffer, "='cores'\n");
2884       }
2885 #if KMP_USE_HWLOC
2886     } else if (__kmp_affinity_gran == affinity_gran_tile) {
2887       if (num > 0) {
2888         __kmp_str_buf_print(buffer, "='tiles(%d)' \n", num);
2889       } else {
2890         __kmp_str_buf_print(buffer, "='tiles'\n");
2891       }
2892 #endif
2893     } else if (__kmp_affinity_gran == affinity_gran_package) {
2894       if (num > 0) {
2895         __kmp_str_buf_print(buffer, "='sockets(%d)'\n", num);
2896       } else {
2897         __kmp_str_buf_print(buffer, "='sockets'\n");
2898       }
2899     } else {
2900       __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2901     }
2902   } else {
2903     __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2904   }
2905 }
2906
2907 #endif /* OMP_40_ENABLED */
2908
2909 #if (!OMP_40_ENABLED)
2910
2911 static void __kmp_stg_parse_proc_bind(char const *name, char const *value,
2912                                       void *data) {
2913   int enabled;
2914   kmp_setting_t **rivals = (kmp_setting_t **)data;
2915   int rc;
2916
2917   rc = __kmp_stg_check_rivals(name, value, rivals);
2918   if (rc) {
2919     return;
2920   }
2921
2922   // In OMP 3.1, OMP_PROC_BIND is strictly a boolean
2923   __kmp_stg_parse_bool(name, value, &enabled);
2924   if (enabled) {
2925     // OMP_PROC_BIND => granularity=fine,scatter on MIC
2926     // OMP_PROC_BIND => granularity=core,scatter elsewhere
2927     __kmp_affinity_type = affinity_scatter;
2928 #if KMP_MIC_SUPPORTED
2929     if (__kmp_mic_type != non_mic)
2930       __kmp_affinity_gran = affinity_gran_fine;
2931     else
2932 #endif
2933       __kmp_affinity_gran = affinity_gran_core;
2934   } else {
2935     __kmp_affinity_type = affinity_none;
2936   }
2937 } // __kmp_parse_proc_bind
2938
2939 #endif /* if (! OMP_40_ENABLED) */
2940
2941 static void __kmp_stg_parse_topology_method(char const *name, char const *value,
2942                                             void *data) {
2943   if (__kmp_str_match("all", 1, value)) {
2944     __kmp_affinity_top_method = affinity_top_method_all;
2945   }
2946 #if KMP_USE_HWLOC
2947   else if (__kmp_str_match("hwloc", 1, value)) {
2948     __kmp_affinity_top_method = affinity_top_method_hwloc;
2949   }
2950 #endif
2951 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
2952   else if (__kmp_str_match("x2apic id", 9, value) ||
2953            __kmp_str_match("x2apic_id", 9, value) ||
2954            __kmp_str_match("x2apic-id", 9, value) ||
2955            __kmp_str_match("x2apicid", 8, value) ||
2956            __kmp_str_match("cpuid leaf 11", 13, value) ||
2957            __kmp_str_match("cpuid_leaf_11", 13, value) ||
2958            __kmp_str_match("cpuid-leaf-11", 13, value) ||
2959            __kmp_str_match("cpuid leaf11", 12, value) ||
2960            __kmp_str_match("cpuid_leaf11", 12, value) ||
2961            __kmp_str_match("cpuid-leaf11", 12, value) ||
2962            __kmp_str_match("cpuidleaf 11", 12, value) ||
2963            __kmp_str_match("cpuidleaf_11", 12, value) ||
2964            __kmp_str_match("cpuidleaf-11", 12, value) ||
2965            __kmp_str_match("cpuidleaf11", 11, value) ||
2966            __kmp_str_match("cpuid 11", 8, value) ||
2967            __kmp_str_match("cpuid_11", 8, value) ||
2968            __kmp_str_match("cpuid-11", 8, value) ||
2969            __kmp_str_match("cpuid11", 7, value) ||
2970            __kmp_str_match("leaf 11", 7, value) ||
2971            __kmp_str_match("leaf_11", 7, value) ||
2972            __kmp_str_match("leaf-11", 7, value) ||
2973            __kmp_str_match("leaf11", 6, value)) {
2974     __kmp_affinity_top_method = affinity_top_method_x2apicid;
2975   } else if (__kmp_str_match("apic id", 7, value) ||
2976              __kmp_str_match("apic_id", 7, value) ||
2977              __kmp_str_match("apic-id", 7, value) ||
2978              __kmp_str_match("apicid", 6, value) ||
2979              __kmp_str_match("cpuid leaf 4", 12, value) ||
2980              __kmp_str_match("cpuid_leaf_4", 12, value) ||
2981              __kmp_str_match("cpuid-leaf-4", 12, value) ||
2982              __kmp_str_match("cpuid leaf4", 11, value) ||
2983              __kmp_str_match("cpuid_leaf4", 11, value) ||
2984              __kmp_str_match("cpuid-leaf4", 11, value) ||
2985              __kmp_str_match("cpuidleaf 4", 11, value) ||
2986              __kmp_str_match("cpuidleaf_4", 11, value) ||
2987              __kmp_str_match("cpuidleaf-4", 11, value) ||
2988              __kmp_str_match("cpuidleaf4", 10, value) ||
2989              __kmp_str_match("cpuid 4", 7, value) ||
2990              __kmp_str_match("cpuid_4", 7, value) ||
2991              __kmp_str_match("cpuid-4", 7, value) ||
2992              __kmp_str_match("cpuid4", 6, value) ||
2993              __kmp_str_match("leaf 4", 6, value) ||
2994              __kmp_str_match("leaf_4", 6, value) ||
2995              __kmp_str_match("leaf-4", 6, value) ||
2996              __kmp_str_match("leaf4", 5, value)) {
2997     __kmp_affinity_top_method = affinity_top_method_apicid;
2998   }
2999 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3000   else if (__kmp_str_match("/proc/cpuinfo", 2, value) ||
3001            __kmp_str_match("cpuinfo", 5, value)) {
3002     __kmp_affinity_top_method = affinity_top_method_cpuinfo;
3003   }
3004 #if KMP_GROUP_AFFINITY
3005   else if (__kmp_str_match("group", 1, value)) {
3006     __kmp_affinity_top_method = affinity_top_method_group;
3007   }
3008 #endif /* KMP_GROUP_AFFINITY */
3009   else if (__kmp_str_match("flat", 1, value)) {
3010     __kmp_affinity_top_method = affinity_top_method_flat;
3011   } else {
3012     KMP_WARNING(StgInvalidValue, name, value);
3013   }
3014 } // __kmp_stg_parse_topology_method
3015
3016 static void __kmp_stg_print_topology_method(kmp_str_buf_t *buffer,
3017                                             char const *name, void *data) {
3018   char const *value = NULL;
3019
3020   switch (__kmp_affinity_top_method) {
3021   case affinity_top_method_default:
3022     value = "default";
3023     break;
3024
3025   case affinity_top_method_all:
3026     value = "all";
3027     break;
3028
3029 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3030   case affinity_top_method_x2apicid:
3031     value = "x2APIC id";
3032     break;
3033
3034   case affinity_top_method_apicid:
3035     value = "APIC id";
3036     break;
3037 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3038
3039 #if KMP_USE_HWLOC
3040   case affinity_top_method_hwloc:
3041     value = "hwloc";
3042     break;
3043 #endif
3044
3045   case affinity_top_method_cpuinfo:
3046     value = "cpuinfo";
3047     break;
3048
3049 #if KMP_GROUP_AFFINITY
3050   case affinity_top_method_group:
3051     value = "group";
3052     break;
3053 #endif /* KMP_GROUP_AFFINITY */
3054
3055   case affinity_top_method_flat:
3056     value = "flat";
3057     break;
3058   }
3059
3060   if (value != NULL) {
3061     __kmp_stg_print_str(buffer, name, value);
3062   }
3063 } // __kmp_stg_print_topology_method
3064
3065 #endif /* KMP_AFFINITY_SUPPORTED */
3066
3067 #if OMP_40_ENABLED
3068
3069 // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
3070 // OMP_PLACES / place-partition-var is not.
3071 static void __kmp_stg_parse_proc_bind(char const *name, char const *value,
3072                                       void *data) {
3073   kmp_setting_t **rivals = (kmp_setting_t **)data;
3074   int rc;
3075
3076   rc = __kmp_stg_check_rivals(name, value, rivals);
3077   if (rc) {
3078     return;
3079   }
3080
3081   // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
3082   KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
3083                    (__kmp_nested_proc_bind.used > 0));
3084
3085   const char *buf = value;
3086   const char *next;
3087   int num;
3088   SKIP_WS(buf);
3089   if ((*buf >= '0') && (*buf <= '9')) {
3090     next = buf;
3091     SKIP_DIGITS(next);
3092     num = __kmp_str_to_int(buf, *next);
3093     KMP_ASSERT(num >= 0);
3094     buf = next;
3095     SKIP_WS(buf);
3096   } else {
3097     num = -1;
3098   }
3099
3100   next = buf;
3101   if (__kmp_match_str("disabled", buf, &next)) {
3102     buf = next;
3103     SKIP_WS(buf);
3104 #if KMP_AFFINITY_SUPPORTED
3105     __kmp_affinity_type = affinity_disabled;
3106 #endif /* KMP_AFFINITY_SUPPORTED */
3107     __kmp_nested_proc_bind.used = 1;
3108     __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3109   } else if ((num == (int)proc_bind_false) ||
3110              __kmp_match_str("false", buf, &next)) {
3111     buf = next;
3112     SKIP_WS(buf);
3113 #if KMP_AFFINITY_SUPPORTED
3114     __kmp_affinity_type = affinity_none;
3115 #endif /* KMP_AFFINITY_SUPPORTED */
3116     __kmp_nested_proc_bind.used = 1;
3117     __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3118   } else if ((num == (int)proc_bind_true) ||
3119              __kmp_match_str("true", buf, &next)) {
3120     buf = next;
3121     SKIP_WS(buf);
3122     __kmp_nested_proc_bind.used = 1;
3123     __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
3124   } else {
3125     // Count the number of values in the env var string
3126     const char *scan;
3127     int nelem = 1;
3128     for (scan = buf; *scan != '\0'; scan++) {
3129       if (*scan == ',') {
3130         nelem++;
3131       }
3132     }
3133
3134     // Create / expand the nested proc_bind array as needed
3135     if (__kmp_nested_proc_bind.size < nelem) {
3136       __kmp_nested_proc_bind.bind_types =
3137           (kmp_proc_bind_t *)KMP_INTERNAL_REALLOC(
3138               __kmp_nested_proc_bind.bind_types,
3139               sizeof(kmp_proc_bind_t) * nelem);
3140       if (__kmp_nested_proc_bind.bind_types == NULL) {
3141         KMP_FATAL(MemoryAllocFailed);
3142       }
3143       __kmp_nested_proc_bind.size = nelem;
3144     }
3145     __kmp_nested_proc_bind.used = nelem;
3146
3147     // Save values in the nested proc_bind array
3148     int i = 0;
3149     for (;;) {
3150       enum kmp_proc_bind_t bind;
3151
3152       if ((num == (int)proc_bind_master) ||
3153           __kmp_match_str("master", buf, &next)) {
3154         buf = next;
3155         SKIP_WS(buf);
3156         bind = proc_bind_master;
3157       } else if ((num == (int)proc_bind_close) ||
3158                  __kmp_match_str("close", buf, &next)) {
3159         buf = next;
3160         SKIP_WS(buf);
3161         bind = proc_bind_close;
3162       } else if ((num == (int)proc_bind_spread) ||
3163                  __kmp_match_str("spread", buf, &next)) {
3164         buf = next;
3165         SKIP_WS(buf);
3166         bind = proc_bind_spread;
3167       } else {
3168         KMP_WARNING(StgInvalidValue, name, value);
3169         __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3170         __kmp_nested_proc_bind.used = 1;
3171         return;
3172       }
3173
3174       __kmp_nested_proc_bind.bind_types[i++] = bind;
3175       if (i >= nelem) {
3176         break;
3177       }
3178       KMP_DEBUG_ASSERT(*buf == ',');
3179       buf++;
3180       SKIP_WS(buf);
3181
3182       // Read next value if it was specified as an integer
3183       if ((*buf >= '0') && (*buf <= '9')) {
3184         next = buf;
3185         SKIP_DIGITS(next);
3186         num = __kmp_str_to_int(buf, *next);
3187         KMP_ASSERT(num >= 0);
3188         buf = next;
3189         SKIP_WS(buf);
3190       } else {
3191         num = -1;
3192       }
3193     }
3194     SKIP_WS(buf);
3195   }
3196   if (*buf != '\0') {
3197     KMP_WARNING(ParseExtraCharsWarn, name, buf);
3198   }
3199 }
3200
3201 static void __kmp_stg_print_proc_bind(kmp_str_buf_t *buffer, char const *name,
3202                                       void *data) {
3203   int nelem = __kmp_nested_proc_bind.used;
3204   if (__kmp_env_format) {
3205     KMP_STR_BUF_PRINT_NAME;
3206   } else {
3207     __kmp_str_buf_print(buffer, "   %s", name);
3208   }
3209   if (nelem == 0) {
3210     __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
3211   } else {
3212     int i;
3213     __kmp_str_buf_print(buffer, "='", name);
3214     for (i = 0; i < nelem; i++) {
3215       switch (__kmp_nested_proc_bind.bind_types[i]) {
3216       case proc_bind_false:
3217         __kmp_str_buf_print(buffer, "false");
3218         break;
3219
3220       case proc_bind_true:
3221         __kmp_str_buf_print(buffer, "true");
3222         break;
3223
3224       case proc_bind_master:
3225         __kmp_str_buf_print(buffer, "master");
3226         break;
3227
3228       case proc_bind_close:
3229         __kmp_str_buf_print(buffer, "close");
3230         break;
3231
3232       case proc_bind_spread:
3233         __kmp_str_buf_print(buffer, "spread");
3234         break;
3235
3236       case proc_bind_intel:
3237         __kmp_str_buf_print(buffer, "intel");
3238         break;
3239
3240       case proc_bind_default:
3241         __kmp_str_buf_print(buffer, "default");
3242         break;
3243       }
3244       if (i < nelem - 1) {
3245         __kmp_str_buf_print(buffer, ",");
3246       }
3247     }
3248     __kmp_str_buf_print(buffer, "'\n");
3249   }
3250 }
3251
3252 #endif /* OMP_40_ENABLED */
3253
3254 #if OMP_50_ENABLED
3255 static void __kmp_stg_parse_display_affinity(char const *name,
3256                                              char const *value, void *data) {
3257   __kmp_stg_parse_bool(name, value, &__kmp_display_affinity);
3258 }
3259 static void __kmp_stg_print_display_affinity(kmp_str_buf_t *buffer,
3260                                              char const *name, void *data) {
3261   __kmp_stg_print_bool(buffer, name, __kmp_display_affinity);
3262 }
3263 static void __kmp_stg_parse_affinity_format(char const *name, char const *value,
3264                                             void *data) {
3265   size_t length = KMP_STRLEN(value);
3266   __kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, value,
3267                          length);
3268 }
3269 static void __kmp_stg_print_affinity_format(kmp_str_buf_t *buffer,
3270                                             char const *name, void *data) {
3271   if (__kmp_env_format) {
3272     KMP_STR_BUF_PRINT_NAME_EX(name);
3273   } else {
3274     __kmp_str_buf_print(buffer, "   %s='", name);
3275   }
3276   __kmp_str_buf_print(buffer, "%s'\n", __kmp_affinity_format);
3277 }
3278 // OMP_ALLOCATOR sets default allocator
3279 static void __kmp_stg_parse_allocator(char const *name, char const *value,
3280                                       void *data) {
3281   /*
3282     The value can be any predefined allocator:
3283     omp_default_mem_alloc = 1;
3284     omp_large_cap_mem_alloc = 2;
3285     omp_const_mem_alloc = 3;
3286     omp_high_bw_mem_alloc = 4;
3287     omp_low_lat_mem_alloc = 5;
3288     omp_cgroup_mem_alloc = 6;
3289     omp_pteam_mem_alloc = 7;
3290     omp_thread_mem_alloc = 8;
3291     Acceptable value is either a digit or a string.
3292   */
3293   const char *buf = value;
3294   const char *next;
3295   int num;
3296   SKIP_WS(buf);
3297   if ((*buf > '0') && (*buf < '9')) {
3298     next = buf;
3299     SKIP_DIGITS(next);
3300     num = __kmp_str_to_int(buf, *next);
3301     KMP_ASSERT(num > 0);
3302     switch (num) {
3303     case 4:
3304       if (__kmp_hbw_mem_available) {
3305         __kmp_def_allocator = omp_high_bw_mem_alloc;
3306       } else {
3307         __kmp_msg(kmp_ms_warning,
3308                   KMP_MSG(OmpNoAllocator, "omp_high_bw_mem_alloc"),
3309                   __kmp_msg_null);
3310         __kmp_def_allocator = omp_default_mem_alloc;
3311       }
3312       break;
3313     case 1:
3314       __kmp_def_allocator = omp_default_mem_alloc;
3315       break;
3316     case 2:
3317       __kmp_msg(kmp_ms_warning,
3318                 KMP_MSG(OmpNoAllocator, "omp_large_cap_mem_alloc"),
3319                 __kmp_msg_null);
3320       __kmp_def_allocator = omp_default_mem_alloc;
3321       break;
3322     case 3:
3323       __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_const_mem_alloc"),
3324                 __kmp_msg_null);
3325       __kmp_def_allocator = omp_default_mem_alloc;
3326       break;
3327     case 5:
3328       __kmp_msg(kmp_ms_warning,
3329                 KMP_MSG(OmpNoAllocator, "omp_low_lat_mem_alloc"),
3330                 __kmp_msg_null);
3331       __kmp_def_allocator = omp_default_mem_alloc;
3332       break;
3333     case 6:
3334       __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_cgroup_mem_alloc"),
3335                 __kmp_msg_null);
3336       __kmp_def_allocator = omp_default_mem_alloc;
3337       break;
3338     case 7:
3339       __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_pteam_mem_alloc"),
3340                 __kmp_msg_null);
3341       __kmp_def_allocator = omp_default_mem_alloc;
3342       break;
3343     case 8:
3344       __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_thread_mem_alloc"),
3345                 __kmp_msg_null);
3346       __kmp_def_allocator = omp_default_mem_alloc;
3347       break;
3348     }
3349     return;
3350   }
3351   next = buf;
3352   if (__kmp_match_str("omp_high_bw_mem_alloc", buf, &next)) {
3353     if (__kmp_hbw_mem_available) {
3354       __kmp_def_allocator = omp_high_bw_mem_alloc;
3355     } else {
3356       __kmp_msg(kmp_ms_warning,
3357                 KMP_MSG(OmpNoAllocator, "omp_high_bw_mem_alloc"),
3358                 __kmp_msg_null);
3359       __kmp_def_allocator = omp_default_mem_alloc;
3360     }
3361   } else if (__kmp_match_str("omp_default_mem_alloc", buf, &next)) {
3362     __kmp_def_allocator = omp_default_mem_alloc;
3363   } else if (__kmp_match_str("omp_large_cap_mem_alloc", buf, &next)) {
3364     __kmp_msg(kmp_ms_warning,
3365               KMP_MSG(OmpNoAllocator, "omp_large_cap_mem_alloc"),
3366               __kmp_msg_null);
3367     __kmp_def_allocator = omp_default_mem_alloc;
3368   } else if (__kmp_match_str("omp_const_mem_alloc", buf, &next)) {
3369     __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_const_mem_alloc"),
3370               __kmp_msg_null);
3371     __kmp_def_allocator = omp_default_mem_alloc;
3372   } else if (__kmp_match_str("omp_low_lat_mem_alloc", buf, &next)) {
3373     __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_low_lat_mem_alloc"),
3374               __kmp_msg_null);
3375     __kmp_def_allocator = omp_default_mem_alloc;
3376   } else if (__kmp_match_str("omp_cgroup_mem_alloc", buf, &next)) {
3377     __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_cgroup_mem_alloc"),
3378               __kmp_msg_null);
3379     __kmp_def_allocator = omp_default_mem_alloc;
3380   } else if (__kmp_match_str("omp_pteam_mem_alloc", buf, &next)) {
3381     __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_pteam_mem_alloc"),
3382               __kmp_msg_null);
3383     __kmp_def_allocator = omp_default_mem_alloc;
3384   } else if (__kmp_match_str("omp_thread_mem_alloc", buf, &next)) {
3385     __kmp_msg(kmp_ms_warning, KMP_MSG(OmpNoAllocator, "omp_thread_mem_alloc"),
3386               __kmp_msg_null);
3387     __kmp_def_allocator = omp_default_mem_alloc;
3388   }
3389   buf = next;
3390   SKIP_WS(buf);
3391   if (*buf != '\0') {
3392     KMP_WARNING(ParseExtraCharsWarn, name, buf);
3393   }
3394 }
3395
3396 static void __kmp_stg_print_allocator(kmp_str_buf_t *buffer, char const *name,
3397                                       void *data) {
3398   if (__kmp_def_allocator == omp_default_mem_alloc) {
3399     __kmp_stg_print_str(buffer, name, "omp_default_mem_alloc");
3400   } else if (__kmp_def_allocator == omp_high_bw_mem_alloc) {
3401     __kmp_stg_print_str(buffer, name, "omp_high_bw_mem_alloc");
3402   } else if (__kmp_def_allocator == omp_large_cap_mem_alloc) {
3403     __kmp_stg_print_str(buffer, name, "omp_large_cap_mem_alloc");
3404   } else if (__kmp_def_allocator == omp_const_mem_alloc) {
3405     __kmp_stg_print_str(buffer, name, "omp_const_mem_alloc");
3406   } else if (__kmp_def_allocator == omp_low_lat_mem_alloc) {
3407     __kmp_stg_print_str(buffer, name, "omp_low_lat_mem_alloc");
3408   } else if (__kmp_def_allocator == omp_cgroup_mem_alloc) {
3409     __kmp_stg_print_str(buffer, name, "omp_cgroup_mem_alloc");
3410   } else if (__kmp_def_allocator == omp_pteam_mem_alloc) {
3411     __kmp_stg_print_str(buffer, name, "omp_pteam_mem_alloc");
3412   } else if (__kmp_def_allocator == omp_thread_mem_alloc) {
3413     __kmp_stg_print_str(buffer, name, "omp_thread_mem_alloc");
3414   }
3415 }
3416
3417 #endif /* OMP_50_ENABLED */
3418
3419 // -----------------------------------------------------------------------------
3420 // OMP_DYNAMIC
3421
3422 static void __kmp_stg_parse_omp_dynamic(char const *name, char const *value,
3423                                         void *data) {
3424   __kmp_stg_parse_bool(name, value, &(__kmp_global.g.g_dynamic));
3425 } // __kmp_stg_parse_omp_dynamic
3426
3427 static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t *buffer, char const *name,
3428                                         void *data) {
3429   __kmp_stg_print_bool(buffer, name, __kmp_global.g.g_dynamic);
3430 } // __kmp_stg_print_omp_dynamic
3431
3432 static void __kmp_stg_parse_kmp_dynamic_mode(char const *name,
3433                                              char const *value, void *data) {
3434   if (TCR_4(__kmp_init_parallel)) {
3435     KMP_WARNING(EnvParallelWarn, name);
3436     __kmp_env_toPrint(name, 0);
3437     return;
3438   }
3439 #ifdef USE_LOAD_BALANCE
3440   else if (__kmp_str_match("load balance", 2, value) ||
3441            __kmp_str_match("load_balance", 2, value) ||
3442            __kmp_str_match("load-balance", 2, value) ||
3443            __kmp_str_match("loadbalance", 2, value) ||
3444            __kmp_str_match("balance", 1, value)) {
3445     __kmp_global.g.g_dynamic_mode = dynamic_load_balance;
3446   }
3447 #endif /* USE_LOAD_BALANCE */
3448   else if (__kmp_str_match("thread limit", 1, value) ||
3449            __kmp_str_match("thread_limit", 1, value) ||
3450            __kmp_str_match("thread-limit", 1, value) ||
3451            __kmp_str_match("threadlimit", 1, value) ||
3452            __kmp_str_match("limit", 2, value)) {
3453     __kmp_global.g.g_dynamic_mode = dynamic_thread_limit;
3454   } else if (__kmp_str_match("random", 1, value)) {
3455     __kmp_global.g.g_dynamic_mode = dynamic_random;
3456   } else {
3457     KMP_WARNING(StgInvalidValue, name, value);
3458   }
3459 } //__kmp_stg_parse_kmp_dynamic_mode
3460
3461 static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t *buffer,
3462                                              char const *name, void *data) {
3463 #if KMP_DEBUG
3464   if (__kmp_global.g.g_dynamic_mode == dynamic_default) {
3465     __kmp_str_buf_print(buffer, "   %s: %s \n", name, KMP_I18N_STR(NotDefined));
3466   }
3467 #ifdef USE_LOAD_BALANCE
3468   else if (__kmp_global.g.g_dynamic_mode == dynamic_load_balance) {
3469     __kmp_stg_print_str(buffer, name, "load balance");
3470   }
3471 #endif /* USE_LOAD_BALANCE */
3472   else if (__kmp_global.g.g_dynamic_mode == dynamic_thread_limit) {
3473     __kmp_stg_print_str(buffer, name, "thread limit");
3474   } else if (__kmp_global.g.g_dynamic_mode == dynamic_random) {
3475     __kmp_stg_print_str(buffer, name, "random");
3476   } else {
3477     KMP_ASSERT(0);
3478   }
3479 #endif /* KMP_DEBUG */
3480 } // __kmp_stg_print_kmp_dynamic_mode
3481
3482 #ifdef USE_LOAD_BALANCE
3483
3484 // -----------------------------------------------------------------------------
3485 // KMP_LOAD_BALANCE_INTERVAL
3486
3487 static void __kmp_stg_parse_ld_balance_interval(char const *name,
3488                                                 char const *value, void *data) {
3489   double interval = __kmp_convert_to_double(value);
3490   if (interval >= 0) {
3491     __kmp_load_balance_interval = interval;
3492   } else {
3493     KMP_WARNING(StgInvalidValue, name, value);
3494   }
3495 } // __kmp_stg_parse_load_balance_interval
3496
3497 static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t *buffer,
3498                                                 char const *name, void *data) {
3499 #if KMP_DEBUG
3500   __kmp_str_buf_print(buffer, "   %s=%8.6f\n", name,
3501                       __kmp_load_balance_interval);
3502 #endif /* KMP_DEBUG */
3503 } // __kmp_stg_print_load_balance_interval
3504
3505 #endif /* USE_LOAD_BALANCE */
3506
3507 // -----------------------------------------------------------------------------
3508 // KMP_INIT_AT_FORK
3509
3510 static void __kmp_stg_parse_init_at_fork(char const *name, char const *value,
3511                                          void *data) {
3512   __kmp_stg_parse_bool(name, value, &__kmp_need_register_atfork);
3513   if (__kmp_need_register_atfork) {
3514     __kmp_need_register_atfork_specified = TRUE;
3515   }
3516 } // __kmp_stg_parse_init_at_fork
3517
3518 static void __kmp_stg_print_init_at_fork(kmp_str_buf_t *buffer,
3519                                          char const *name, void *data) {
3520   __kmp_stg_print_bool(buffer, name, __kmp_need_register_atfork_specified);
3521 } // __kmp_stg_print_init_at_fork
3522
3523 // -----------------------------------------------------------------------------
3524 // KMP_SCHEDULE
3525
3526 static void __kmp_stg_parse_schedule(char const *name, char const *value,
3527                                      void *data) {
3528
3529   if (value != NULL) {
3530     size_t length = KMP_STRLEN(value);
3531     if (length > INT_MAX) {
3532       KMP_WARNING(LongValue, name);
3533     } else {
3534       const char *semicolon;
3535       if (value[length - 1] == '"' || value[length - 1] == '\'')
3536         KMP_WARNING(UnbalancedQuotes, name);
3537       do {
3538         char sentinel;
3539
3540         semicolon = strchr(value, ';');
3541         if (*value && semicolon != value) {
3542           const char *comma = strchr(value, ',');
3543
3544           if (comma) {
3545             ++comma;
3546             sentinel = ',';
3547           } else
3548             sentinel = ';';
3549           if (!__kmp_strcasecmp_with_sentinel("static", value, sentinel)) {
3550             if (!__kmp_strcasecmp_with_sentinel("greedy", comma, ';')) {
3551               __kmp_static = kmp_sch_static_greedy;
3552               continue;
3553             } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma,
3554                                                        ';')) {
3555               __kmp_static = kmp_sch_static_balanced;
3556               continue;
3557             }
3558           } else if (!__kmp_strcasecmp_with_sentinel("guided", value,
3559                                                      sentinel)) {
3560             if (!__kmp_strcasecmp_with_sentinel("iterative", comma, ';')) {
3561               __kmp_guided = kmp_sch_guided_iterative_chunked;
3562               continue;
3563             } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma,
3564                                                        ';')) {
3565               /* analytical not allowed for too many threads */
3566               __kmp_guided = kmp_sch_guided_analytical_chunked;
3567               continue;
3568             }
3569           }
3570           KMP_WARNING(InvalidClause, name, value);
3571         } else
3572           KMP_WARNING(EmptyClause, name);
3573       } while ((value = semicolon ? semicolon + 1 : NULL));
3574     }
3575   }
3576
3577 } // __kmp_stg_parse__schedule
3578
3579 static void __kmp_stg_print_schedule(kmp_str_buf_t *buffer, char const *name,
3580                                      void *data) {
3581   if (__kmp_env_format) {
3582     KMP_STR_BUF_PRINT_NAME_EX(name);
3583   } else {
3584     __kmp_str_buf_print(buffer, "   %s='", name);
3585   }
3586   if (__kmp_static == kmp_sch_static_greedy) {
3587     __kmp_str_buf_print(buffer, "%s", "static,greedy");
3588   } else if (__kmp_static == kmp_sch_static_balanced) {
3589     __kmp_str_buf_print(buffer, "%s", "static,balanced");
3590   }
3591   if (__kmp_guided == kmp_sch_guided_iterative_chunked) {
3592     __kmp_str_buf_print(buffer, ";%s'\n", "guided,iterative");
3593   } else if (__kmp_guided == kmp_sch_guided_analytical_chunked) {
3594     __kmp_str_buf_print(buffer, ";%s'\n", "guided,analytical");
3595   }
3596 } // __kmp_stg_print_schedule
3597
3598 // -----------------------------------------------------------------------------
3599 // OMP_SCHEDULE
3600
3601 static inline void __kmp_omp_schedule_restore() {
3602 #if KMP_USE_HIER_SCHED
3603   __kmp_hier_scheds.deallocate();
3604 #endif
3605   __kmp_chunk = 0;
3606   __kmp_sched = kmp_sch_default;
3607 }
3608
3609 static const char *__kmp_parse_single_omp_schedule(const char *name,
3610                                                    const char *value,
3611                                                    bool parse_hier = false) {
3612   /* get the specified scheduling style */
3613   const char *ptr = value;
3614   const char *comma = strchr(ptr, ',');
3615   const char *delim;
3616   int chunk = 0;
3617   enum sched_type sched = kmp_sch_default;
3618   if (*ptr == '\0')
3619     return NULL;
3620 #if KMP_USE_HIER_SCHED
3621   kmp_hier_layer_e layer = kmp_hier_layer_e::LAYER_THREAD;
3622   if (parse_hier) {
3623     if (!__kmp_strcasecmp_with_sentinel("L1", ptr, ',')) {
3624       layer = kmp_hier_layer_e::LAYER_L1;
3625     } else if (!__kmp_strcasecmp_with_sentinel("L2", ptr, ',')) {
3626       layer = kmp_hier_layer_e::LAYER_L2;
3627     } else if (!__kmp_strcasecmp_with_sentinel("L3", ptr, ',')) {
3628       layer = kmp_hier_layer_e::LAYER_L3;
3629     } else if (!__kmp_strcasecmp_with_sentinel("NUMA", ptr, ',')) {
3630       layer = kmp_hier_layer_e::LAYER_NUMA;
3631     }
3632     if (layer != kmp_hier_layer_e::LAYER_THREAD && !comma) {
3633       // If there is no comma after the layer, then this schedule is invalid
3634       KMP_WARNING(StgInvalidValue, name, value);
3635       __kmp_omp_schedule_restore();
3636       return NULL;
3637     } else if (layer != kmp_hier_layer_e::LAYER_THREAD) {
3638       ptr = ++comma;
3639       comma = strchr(ptr, ',');
3640     }
3641   }
3642   delim = ptr;
3643   while (*delim != ',' && *delim != ':' && *delim != '\0')
3644     delim++;
3645 #else // KMP_USE_HIER_SCHED
3646   delim = ptr;
3647   while (*delim != ',' && *delim != '\0')
3648     delim++;
3649 #endif // KMP_USE_HIER_SCHED
3650   if (!__kmp_strcasecmp_with_sentinel("dynamic", ptr, *delim)) /* DYNAMIC */
3651     sched = kmp_sch_dynamic_chunked;
3652   else if (!__kmp_strcasecmp_with_sentinel("guided", ptr, *delim)) /* GUIDED */
3653     sched = kmp_sch_guided_chunked;
3654   // AC: TODO: add AUTO schedule, and probably remove TRAPEZOIDAL (OMP 3.0 does
3655   // not allow it)
3656   else if (!__kmp_strcasecmp_with_sentinel("auto", ptr, *delim)) { /* AUTO */
3657     sched = kmp_sch_auto;
3658     if (comma) {
3659       __kmp_msg(kmp_ms_warning, KMP_MSG(IgnoreChunk, name, comma),
3660                 __kmp_msg_null);
3661       comma = NULL;
3662     }
3663   } else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", ptr,
3664                                              *delim)) /* TRAPEZOIDAL */
3665     sched = kmp_sch_trapezoidal;
3666   else if (!__kmp_strcasecmp_with_sentinel("static", ptr, *delim)) /* STATIC */
3667     sched = kmp_sch_static;
3668 #if KMP_STATIC_STEAL_ENABLED
3669   else if (!__kmp_strcasecmp_with_sentinel("static_steal", ptr, *delim))
3670     sched = kmp_sch_static_steal;
3671 #endif
3672   else {
3673     KMP_WARNING(StgInvalidValue, name, value);
3674     __kmp_omp_schedule_restore();
3675     return NULL;
3676   }
3677   if (ptr && comma && *comma == *delim) {
3678     ptr = comma + 1;
3679     SKIP_DIGITS(ptr);
3680
3681     if (sched == kmp_sch_static)
3682       sched = kmp_sch_static_chunked;
3683     ++comma;
3684     chunk = __kmp_str_to_int(comma, *ptr);
3685     if (chunk < 1) {
3686       chunk = KMP_DEFAULT_CHUNK;
3687       __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidChunk, name, comma),
3688                 __kmp_msg_null);
3689       KMP_INFORM(Using_int_Value, name, __kmp_chunk);
3690       // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK
3691       // (to improve code coverage :)
3692       //     The default chunk size is 1 according to standard, thus making
3693       //     KMP_MIN_CHUNK not 1 we would introduce mess:
3694       //     wrong chunk becomes 1, but it will be impossible to explicitely set
3695       //     1, because it becomes KMP_MIN_CHUNK...
3696       //                } else if ( chunk < KMP_MIN_CHUNK ) {
3697       //                    chunk = KMP_MIN_CHUNK;
3698     } else if (chunk > KMP_MAX_CHUNK) {
3699       chunk = KMP_MAX_CHUNK;
3700       __kmp_msg(kmp_ms_warning, KMP_MSG(LargeChunk, name, comma),
3701                 __kmp_msg_null);
3702       KMP_INFORM(Using_int_Value, name, chunk);
3703     }
3704   } else if (ptr) {
3705     SKIP_TOKEN(ptr);
3706   }
3707 #if KMP_USE_HIER_SCHED
3708   if (layer != kmp_hier_layer_e::LAYER_THREAD) {
3709     __kmp_hier_scheds.append(sched, chunk, layer);
3710   } else
3711 #endif
3712   {
3713     __kmp_chunk = chunk;
3714     __kmp_sched = sched;
3715   }
3716   return ptr;
3717 }
3718
3719 static void __kmp_stg_parse_omp_schedule(char const *name, char const *value,
3720                                          void *data) {
3721   size_t length;
3722   const char *ptr = value;
3723   SKIP_WS(ptr);
3724   if (value) {
3725     length = KMP_STRLEN(value);
3726     if (length) {
3727       if (value[length - 1] == '"' || value[length - 1] == '\'')
3728         KMP_WARNING(UnbalancedQuotes, name);
3729 /* get the specified scheduling style */
3730 #if KMP_USE_HIER_SCHED
3731       if (!__kmp_strcasecmp_with_sentinel("EXPERIMENTAL", ptr, ' ')) {
3732         SKIP_TOKEN(ptr);
3733         SKIP_WS(ptr);
3734         while ((ptr = __kmp_parse_single_omp_schedule(name, ptr, true))) {
3735           while (*ptr == ' ' || *ptr == '\t' || *ptr == ':')
3736             ptr++;
3737         }
3738       } else
3739 #endif
3740         __kmp_parse_single_omp_schedule(name, ptr);
3741     } else
3742       KMP_WARNING(EmptyString, name);
3743   }
3744 #if KMP_USE_HIER_SCHED
3745   __kmp_hier_scheds.sort();
3746 #endif
3747   K_DIAG(1, ("__kmp_static == %d\n", __kmp_static))
3748   K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided))
3749   K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched))
3750   K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk))
3751 } // __kmp_stg_parse_omp_schedule
3752
3753 static void __kmp_stg_print_omp_schedule(kmp_str_buf_t *buffer,
3754                                          char const *name, void *data) {
3755   if (__kmp_env_format) {
3756     KMP_STR_BUF_PRINT_NAME_EX(name);
3757   } else {
3758     __kmp_str_buf_print(buffer, "   %s='", name);
3759   }
3760   if (__kmp_chunk) {
3761     switch (__kmp_sched) {
3762     case kmp_sch_dynamic_chunked:
3763       __kmp_str_buf_print(buffer, "%s,%d'\n", "dynamic", __kmp_chunk);
3764       break;
3765     case kmp_sch_guided_iterative_chunked:
3766     case kmp_sch_guided_analytical_chunked:
3767       __kmp_str_buf_print(buffer, "%s,%d'\n", "guided", __kmp_chunk);
3768       break;
3769     case kmp_sch_trapezoidal:
3770       __kmp_str_buf_print(buffer, "%s,%d'\n", "trapezoidal", __kmp_chunk);
3771       break;
3772     case kmp_sch_static:
3773     case kmp_sch_static_chunked:
3774     case kmp_sch_static_balanced:
3775     case kmp_sch_static_greedy:
3776       __kmp_str_buf_print(buffer, "%s,%d'\n", "static", __kmp_chunk);
3777       break;
3778     case kmp_sch_static_steal:
3779       __kmp_str_buf_print(buffer, "%s,%d'\n", "static_steal", __kmp_chunk);
3780       break;
3781     case kmp_sch_auto:
3782       __kmp_str_buf_print(buffer, "%s,%d'\n", "auto", __kmp_chunk);
3783       break;
3784     }
3785   } else {
3786     switch (__kmp_sched) {
3787     case kmp_sch_dynamic_chunked:
3788       __kmp_str_buf_print(buffer, "%s'\n", "dynamic");
3789       break;
3790     case kmp_sch_guided_iterative_chunked:
3791     case kmp_sch_guided_analytical_chunked:
3792       __kmp_str_buf_print(buffer, "%s'\n", "guided");
3793       break;
3794     case kmp_sch_trapezoidal:
3795       __kmp_str_buf_print(buffer, "%s'\n", "trapezoidal");
3796       break;
3797     case kmp_sch_static:
3798     case kmp_sch_static_chunked:
3799     case kmp_sch_static_balanced:
3800     case kmp_sch_static_greedy:
3801       __kmp_str_buf_print(buffer, "%s'\n", "static");
3802       break;
3803     case kmp_sch_static_steal:
3804       __kmp_str_buf_print(buffer, "%s'\n", "static_steal");
3805       break;
3806     case kmp_sch_auto:
3807       __kmp_str_buf_print(buffer, "%s'\n", "auto");
3808       break;
3809     }
3810   }
3811 } // __kmp_stg_print_omp_schedule
3812
3813 #if KMP_USE_HIER_SCHED
3814 // -----------------------------------------------------------------------------
3815 // KMP_DISP_HAND_THREAD
3816 static void __kmp_stg_parse_kmp_hand_thread(char const *name, char const *value,
3817                                             void *data) {
3818   __kmp_stg_parse_bool(name, value, &(__kmp_dispatch_hand_threading));
3819 } // __kmp_stg_parse_kmp_hand_thread
3820
3821 static void __kmp_stg_print_kmp_hand_thread(kmp_str_buf_t *buffer,
3822                                             char const *name, void *data) {
3823   __kmp_stg_print_bool(buffer, name, __kmp_dispatch_hand_threading);
3824 } // __kmp_stg_print_kmp_hand_thread
3825 #endif
3826
3827 // -----------------------------------------------------------------------------
3828 // KMP_ATOMIC_MODE
3829
3830 static void __kmp_stg_parse_atomic_mode(char const *name, char const *value,
3831                                         void *data) {
3832   // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP
3833   // compatibility mode.
3834   int mode = 0;
3835   int max = 1;
3836 #ifdef KMP_GOMP_COMPAT
3837   max = 2;
3838 #endif /* KMP_GOMP_COMPAT */
3839   __kmp_stg_parse_int(name, value, 0, max, &mode);
3840   // TODO; parse_int is not very suitable for this case. In case of overflow it
3841   // is better to use
3842   // 0 rather that max value.
3843   if (mode > 0) {
3844     __kmp_atomic_mode = mode;
3845   }
3846 } // __kmp_stg_parse_atomic_mode
3847
3848 static void __kmp_stg_print_atomic_mode(kmp_str_buf_t *buffer, char const *name,
3849                                         void *data) {
3850   __kmp_stg_print_int(buffer, name, __kmp_atomic_mode);
3851 } // __kmp_stg_print_atomic_mode
3852
3853 // -----------------------------------------------------------------------------
3854 // KMP_CONSISTENCY_CHECK
3855
3856 static void __kmp_stg_parse_consistency_check(char const *name,
3857                                               char const *value, void *data) {
3858   if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
3859     // Note, this will not work from kmp_set_defaults because th_cons stack was
3860     // not allocated
3861     // for existed thread(s) thus the first __kmp_push_<construct> will break
3862     // with assertion.
3863     // TODO: allocate th_cons if called from kmp_set_defaults.
3864     __kmp_env_consistency_check = TRUE;
3865   } else if (!__kmp_strcasecmp_with_sentinel("none", value, 0)) {
3866     __kmp_env_consistency_check = FALSE;
3867   } else {
3868     KMP_WARNING(StgInvalidValue, name, value);
3869   }
3870 } // __kmp_stg_parse_consistency_check
3871
3872 static void __kmp_stg_print_consistency_check(kmp_str_buf_t *buffer,
3873                                               char const *name, void *data) {
3874 #if KMP_DEBUG
3875   const char *value = NULL;
3876
3877   if (__kmp_env_consistency_check) {
3878     value = "all";
3879   } else {
3880     value = "none";
3881   }
3882
3883   if (value != NULL) {
3884     __kmp_stg_print_str(buffer, name, value);
3885   }
3886 #endif /* KMP_DEBUG */
3887 } // __kmp_stg_print_consistency_check
3888
3889 #if USE_ITT_BUILD
3890 // -----------------------------------------------------------------------------
3891 // KMP_ITT_PREPARE_DELAY
3892
3893 #if USE_ITT_NOTIFY
3894
3895 static void __kmp_stg_parse_itt_prepare_delay(char const *name,
3896                                               char const *value, void *data) {
3897   // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop
3898   // iterations.
3899   int delay = 0;
3900   __kmp_stg_parse_int(name, value, 0, INT_MAX, &delay);
3901   __kmp_itt_prepare_delay = delay;
3902 } // __kmp_str_parse_itt_prepare_delay
3903
3904 static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t *buffer,
3905                                               char const *name, void *data) {
3906   __kmp_stg_print_uint64(buffer, name, __kmp_itt_prepare_delay);
3907
3908 } // __kmp_str_print_itt_prepare_delay
3909
3910 #endif // USE_ITT_NOTIFY
3911 #endif /* USE_ITT_BUILD */
3912
3913 // -----------------------------------------------------------------------------
3914 // KMP_MALLOC_POOL_INCR
3915
3916 static void __kmp_stg_parse_malloc_pool_incr(char const *name,
3917                                              char const *value, void *data) {
3918   __kmp_stg_parse_size(name, value, KMP_MIN_MALLOC_POOL_INCR,
3919                        KMP_MAX_MALLOC_POOL_INCR, NULL, &__kmp_malloc_pool_incr,
3920                        1);
3921 } // __kmp_stg_parse_malloc_pool_incr
3922
3923 static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t *buffer,
3924                                              char const *name, void *data) {
3925   __kmp_stg_print_size(buffer, name, __kmp_malloc_pool_incr);
3926
3927 } // _kmp_stg_print_malloc_pool_incr
3928
3929 #ifdef KMP_DEBUG
3930
3931 // -----------------------------------------------------------------------------
3932 // KMP_PAR_RANGE
3933
3934 static void __kmp_stg_parse_par_range_env(char const *name, char const *value,
3935                                           void *data) {
3936   __kmp_stg_parse_par_range(name, value, &__kmp_par_range,
3937                             __kmp_par_range_routine, __kmp_par_range_filename,
3938                             &__kmp_par_range_lb, &__kmp_par_range_ub);
3939 } // __kmp_stg_parse_par_range_env
3940
3941 static void __kmp_stg_print_par_range_env(kmp_str_buf_t *buffer,
3942                                           char const *name, void *data) {
3943   if (__kmp_par_range != 0) {
3944     __kmp_stg_print_str(buffer, name, par_range_to_print);
3945   }
3946 } // __kmp_stg_print_par_range_env
3947
3948 // -----------------------------------------------------------------------------
3949 // KMP_YIELD_CYCLE, KMP_YIELD_ON, KMP_YIELD_OFF
3950
3951 static void __kmp_stg_parse_yield_cycle(char const *name, char const *value,
3952                                         void *data) {
3953   int flag = __kmp_yield_cycle;
3954   __kmp_stg_parse_bool(name, value, &flag);
3955   __kmp_yield_cycle = flag;
3956 } // __kmp_stg_parse_yield_cycle
3957
3958 static void __kmp_stg_print_yield_cycle(kmp_str_buf_t *buffer, char const *name,
3959                                         void *data) {
3960   __kmp_stg_print_bool(buffer, name, __kmp_yield_cycle);
3961 } // __kmp_stg_print_yield_cycle
3962
3963 static void __kmp_stg_parse_yield_on(char const *name, char const *value,
3964                                      void *data) {
3965   __kmp_stg_parse_int(name, value, 2, INT_MAX, &__kmp_yield_on_count);
3966 } // __kmp_stg_parse_yield_on
3967
3968 static void __kmp_stg_print_yield_on(kmp_str_buf_t *buffer, char const *name,
3969                                      void *data) {
3970   __kmp_stg_print_int(buffer, name, __kmp_yield_on_count);
3971 } // __kmp_stg_print_yield_on
3972
3973 static void __kmp_stg_parse_yield_off(char const *name, char const *value,
3974                                       void *data) {
3975   __kmp_stg_parse_int(name, value, 2, INT_MAX, &__kmp_yield_off_count);
3976 } // __kmp_stg_parse_yield_off
3977
3978 static void __kmp_stg_print_yield_off(kmp_str_buf_t *buffer, char const *name,
3979                                       void *data) {
3980   __kmp_stg_print_int(buffer, name, __kmp_yield_off_count);
3981 } // __kmp_stg_print_yield_off
3982
3983 #endif
3984
3985 // -----------------------------------------------------------------------------
3986 // KMP_INIT_WAIT, KMP_NEXT_WAIT
3987
3988 static void __kmp_stg_parse_init_wait(char const *name, char const *value,
3989                                       void *data) {
3990   int wait;
3991   KMP_ASSERT((__kmp_init_wait & 1) == 0);
3992   wait = __kmp_init_wait / 2;
3993   __kmp_stg_parse_int(name, value, KMP_MIN_INIT_WAIT, KMP_MAX_INIT_WAIT, &wait);
3994   __kmp_init_wait = wait * 2;
3995   KMP_ASSERT((__kmp_init_wait & 1) == 0);
3996   __kmp_yield_init = __kmp_init_wait;
3997 } // __kmp_stg_parse_init_wait
3998
3999 static void __kmp_stg_print_init_wait(kmp_str_buf_t *buffer, char const *name,
4000                                       void *data) {
4001   __kmp_stg_print_int(buffer, name, __kmp_init_wait);
4002 } // __kmp_stg_print_init_wait
4003
4004 static void __kmp_stg_parse_next_wait(char const *name, char const *value,
4005                                       void *data) {
4006   int wait;
4007   KMP_ASSERT((__kmp_next_wait & 1) == 0);
4008   wait = __kmp_next_wait / 2;
4009   __kmp_stg_parse_int(name, value, KMP_MIN_NEXT_WAIT, KMP_MAX_NEXT_WAIT, &wait);
4010   __kmp_next_wait = wait * 2;
4011   KMP_ASSERT((__kmp_next_wait & 1) == 0);
4012   __kmp_yield_next = __kmp_next_wait;
4013 } // __kmp_stg_parse_next_wait
4014
4015 static void __kmp_stg_print_next_wait(kmp_str_buf_t *buffer, char const *name,
4016                                       void *data) {
4017   __kmp_stg_print_int(buffer, name, __kmp_next_wait);
4018 } //__kmp_stg_print_next_wait
4019
4020 // -----------------------------------------------------------------------------
4021 // KMP_GTID_MODE
4022
4023 static void __kmp_stg_parse_gtid_mode(char const *name, char const *value,
4024                                       void *data) {
4025   // Modes:
4026   //   0 -- do not change default
4027   //   1 -- sp search
4028   //   2 -- use "keyed" TLS var, i.e.
4029   //        pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
4030   //   3 -- __declspec(thread) TLS var in tdata section
4031   int mode = 0;
4032   int max = 2;
4033 #ifdef KMP_TDATA_GTID
4034   max = 3;
4035 #endif /* KMP_TDATA_GTID */
4036   __kmp_stg_parse_int(name, value, 0, max, &mode);
4037   // TODO; parse_int is not very suitable for this case. In case of overflow it
4038   // is better to use 0 rather that max value.
4039   if (mode == 0) {
4040     __kmp_adjust_gtid_mode = TRUE;
4041   } else {
4042     __kmp_gtid_mode = mode;
4043     __kmp_adjust_gtid_mode = FALSE;
4044   }
4045 } // __kmp_str_parse_gtid_mode
4046
4047 static void __kmp_stg_print_gtid_mode(kmp_str_buf_t *buffer, char const *name,
4048                                       void *data) {
4049   if (__kmp_adjust_gtid_mode) {
4050     __kmp_stg_print_int(buffer, name, 0);
4051   } else {
4052     __kmp_stg_print_int(buffer, name, __kmp_gtid_mode);
4053   }
4054 } // __kmp_stg_print_gtid_mode
4055
4056 // -----------------------------------------------------------------------------
4057 // KMP_NUM_LOCKS_IN_BLOCK
4058
4059 static void __kmp_stg_parse_lock_block(char const *name, char const *value,
4060                                        void *data) {
4061   __kmp_stg_parse_int(name, value, 0, KMP_INT_MAX, &__kmp_num_locks_in_block);
4062 } // __kmp_str_parse_lock_block
4063
4064 static void __kmp_stg_print_lock_block(kmp_str_buf_t *buffer, char const *name,
4065                                        void *data) {
4066   __kmp_stg_print_int(buffer, name, __kmp_num_locks_in_block);
4067 } // __kmp_stg_print_lock_block
4068
4069 // -----------------------------------------------------------------------------
4070 // KMP_LOCK_KIND
4071
4072 #if KMP_USE_DYNAMIC_LOCK
4073 #define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a)
4074 #else
4075 #define KMP_STORE_LOCK_SEQ(a)
4076 #endif
4077
4078 static void __kmp_stg_parse_lock_kind(char const *name, char const *value,
4079                                       void *data) {
4080   if (__kmp_init_user_locks) {
4081     KMP_WARNING(EnvLockWarn, name);
4082     return;
4083   }
4084
4085   if (__kmp_str_match("tas", 2, value) ||
4086       __kmp_str_match("test and set", 2, value) ||
4087       __kmp_str_match("test_and_set", 2, value) ||
4088       __kmp_str_match("test-and-set", 2, value) ||
4089       __kmp_str_match("test andset", 2, value) ||
4090       __kmp_str_match("test_andset", 2, value) ||
4091       __kmp_str_match("test-andset", 2, value) ||
4092       __kmp_str_match("testand set", 2, value) ||
4093       __kmp_str_match("testand_set", 2, value) ||
4094       __kmp_str_match("testand-set", 2, value) ||
4095       __kmp_str_match("testandset", 2, value)) {
4096     __kmp_user_lock_kind = lk_tas;
4097     KMP_STORE_LOCK_SEQ(tas);
4098   }
4099 #if KMP_USE_FUTEX
4100   else if (__kmp_str_match("futex", 1, value)) {
4101     if (__kmp_futex_determine_capable()) {
4102       __kmp_user_lock_kind = lk_futex;
4103       KMP_STORE_LOCK_SEQ(futex);
4104     } else {
4105       KMP_WARNING(FutexNotSupported, name, value);
4106     }
4107   }
4108 #endif
4109   else if (__kmp_str_match("ticket", 2, value)) {
4110     __kmp_user_lock_kind = lk_ticket;
4111     KMP_STORE_LOCK_SEQ(ticket);
4112   } else if (__kmp_str_match("queuing", 1, value) ||
4113              __kmp_str_match("queue", 1, value)) {
4114     __kmp_user_lock_kind = lk_queuing;
4115     KMP_STORE_LOCK_SEQ(queuing);
4116   } else if (__kmp_str_match("drdpa ticket", 1, value) ||
4117              __kmp_str_match("drdpa_ticket", 1, value) ||
4118              __kmp_str_match("drdpa-ticket", 1, value) ||
4119              __kmp_str_match("drdpaticket", 1, value) ||
4120              __kmp_str_match("drdpa", 1, value)) {
4121     __kmp_user_lock_kind = lk_drdpa;
4122     KMP_STORE_LOCK_SEQ(drdpa);
4123   }
4124 #if KMP_USE_ADAPTIVE_LOCKS
4125   else if (__kmp_str_match("adaptive", 1, value)) {
4126     if (__kmp_cpuinfo.rtm) { // ??? Is cpuinfo available here?
4127       __kmp_user_lock_kind = lk_adaptive;
4128       KMP_STORE_LOCK_SEQ(adaptive);
4129     } else {
4130       KMP_WARNING(AdaptiveNotSupported, name, value);
4131       __kmp_user_lock_kind = lk_queuing;
4132       KMP_STORE_LOCK_SEQ(queuing);
4133     }
4134   }
4135 #endif // KMP_USE_ADAPTIVE_LOCKS
4136 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4137   else if (__kmp_str_match("rtm", 1, value)) {
4138     if (__kmp_cpuinfo.rtm) {
4139       __kmp_user_lock_kind = lk_rtm;
4140       KMP_STORE_LOCK_SEQ(rtm);
4141     } else {
4142       KMP_WARNING(AdaptiveNotSupported, name, value);
4143       __kmp_user_lock_kind = lk_queuing;
4144       KMP_STORE_LOCK_SEQ(queuing);
4145     }
4146   } else if (__kmp_str_match("hle", 1, value)) {
4147     __kmp_user_lock_kind = lk_hle;
4148     KMP_STORE_LOCK_SEQ(hle);
4149   }
4150 #endif
4151   else {
4152     KMP_WARNING(StgInvalidValue, name, value);
4153   }
4154 }
4155
4156 static void __kmp_stg_print_lock_kind(kmp_str_buf_t *buffer, char const *name,
4157                                       void *data) {
4158   const char *value = NULL;
4159
4160   switch (__kmp_user_lock_kind) {
4161   case lk_default:
4162     value = "default";
4163     break;
4164
4165   case lk_tas:
4166     value = "tas";
4167     break;
4168
4169 #if KMP_USE_FUTEX
4170   case lk_futex:
4171     value = "futex";
4172     break;
4173 #endif
4174
4175 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4176   case lk_rtm:
4177     value = "rtm";
4178     break;
4179
4180   case lk_hle:
4181     value = "hle";
4182     break;
4183 #endif
4184
4185   case lk_ticket:
4186     value = "ticket";
4187     break;
4188
4189   case lk_queuing:
4190     value = "queuing";
4191     break;
4192
4193   case lk_drdpa:
4194     value = "drdpa";
4195     break;
4196 #if KMP_USE_ADAPTIVE_LOCKS
4197   case lk_adaptive:
4198     value = "adaptive";
4199     break;
4200 #endif
4201   }
4202
4203   if (value != NULL) {
4204     __kmp_stg_print_str(buffer, name, value);
4205   }
4206 }
4207
4208 // -----------------------------------------------------------------------------
4209 // KMP_SPIN_BACKOFF_PARAMS
4210
4211 // KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick
4212 // for machine pause)
4213 static void __kmp_stg_parse_spin_backoff_params(const char *name,
4214                                                 const char *value, void *data) {
4215   const char *next = value;
4216
4217   int total = 0; // Count elements that were set. It'll be used as an array size
4218   int prev_comma = FALSE; // For correct processing sequential commas
4219   int i;
4220
4221   kmp_uint32 max_backoff = __kmp_spin_backoff_params.max_backoff;
4222   kmp_uint32 min_tick = __kmp_spin_backoff_params.min_tick;
4223
4224   // Run only 3 iterations because it is enough to read two values or find a
4225   // syntax error
4226   for (i = 0; i < 3; i++) {
4227     SKIP_WS(next);
4228
4229     if (*next == '\0') {
4230       break;
4231     }
4232     // Next character is not an integer or not a comma OR number of values > 2
4233     // => end of list
4234     if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
4235       KMP_WARNING(EnvSyntaxError, name, value);
4236       return;
4237     }
4238     // The next character is ','
4239     if (*next == ',') {
4240       // ',' is the fisrt character
4241       if (total == 0 || prev_comma) {
4242         total++;
4243       }
4244       prev_comma = TRUE;
4245       next++; // skip ','
4246       SKIP_WS(next);
4247     }
4248     // Next character is a digit
4249     if (*next >= '0' && *next <= '9') {
4250       int num;
4251       const char *buf = next;
4252       char const *msg = NULL;
4253       prev_comma = FALSE;
4254       SKIP_DIGITS(next);
4255       total++;
4256
4257       const char *tmp = next;
4258       SKIP_WS(tmp);
4259       if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
4260         KMP_WARNING(EnvSpacesNotAllowed, name, value);
4261         return;
4262       }
4263
4264       num = __kmp_str_to_int(buf, *next);
4265       if (num <= 0) { // The number of retries should be > 0
4266         msg = KMP_I18N_STR(ValueTooSmall);
4267         num = 1;
4268       } else if (num > KMP_INT_MAX) {
4269         msg = KMP_I18N_STR(ValueTooLarge);
4270         num = KMP_INT_MAX;
4271       }
4272       if (msg != NULL) {
4273         // Message is not empty. Print warning.
4274         KMP_WARNING(ParseSizeIntWarn, name, value, msg);
4275         KMP_INFORM(Using_int_Value, name, num);
4276       }
4277       if (total == 1) {
4278         max_backoff = num;
4279       } else if (total == 2) {
4280         min_tick = num;
4281       }
4282     }
4283   }
4284   KMP_DEBUG_ASSERT(total > 0);
4285   if (total <= 0) {
4286     KMP_WARNING(EnvSyntaxError, name, value);
4287     return;
4288   }
4289   __kmp_spin_backoff_params.max_backoff = max_backoff;
4290   __kmp_spin_backoff_params.min_tick = min_tick;
4291 }
4292
4293 static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t *buffer,
4294                                                 char const *name, void *data) {
4295   if (__kmp_env_format) {
4296     KMP_STR_BUF_PRINT_NAME_EX(name);
4297   } else {
4298     __kmp_str_buf_print(buffer, "   %s='", name);
4299   }
4300   __kmp_str_buf_print(buffer, "%d,%d'\n", __kmp_spin_backoff_params.max_backoff,
4301                       __kmp_spin_backoff_params.min_tick);
4302 }
4303
4304 #if KMP_USE_ADAPTIVE_LOCKS
4305
4306 // -----------------------------------------------------------------------------
4307 // KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE
4308
4309 // Parse out values for the tunable parameters from a string of the form
4310 // KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]
4311 static void __kmp_stg_parse_adaptive_lock_props(const char *name,
4312                                                 const char *value, void *data) {
4313   int max_retries = 0;
4314   int max_badness = 0;
4315
4316   const char *next = value;
4317
4318   int total = 0; // Count elements that were set. It'll be used as an array size
4319   int prev_comma = FALSE; // For correct processing sequential commas
4320   int i;
4321
4322   // Save values in the structure __kmp_speculative_backoff_params
4323   // Run only 3 iterations because it is enough to read two values or find a
4324   // syntax error
4325   for (i = 0; i < 3; i++) {
4326     SKIP_WS(next);
4327
4328     if (*next == '\0') {
4329       break;
4330     }
4331     // Next character is not an integer or not a comma OR number of values > 2
4332     // => end of list
4333     if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
4334       KMP_WARNING(EnvSyntaxError, name, value);
4335       return;
4336     }
4337     // The next character is ','
4338     if (*next == ',') {
4339       // ',' is the fisrt character
4340       if (total == 0 || prev_comma) {
4341         total++;
4342       }
4343       prev_comma = TRUE;
4344       next++; // skip ','
4345       SKIP_WS(next);
4346     }
4347     // Next character is a digit
4348     if (*next >= '0' && *next <= '9') {
4349       int num;
4350       const char *buf = next;
4351       char const *msg = NULL;
4352       prev_comma = FALSE;
4353       SKIP_DIGITS(next);
4354       total++;
4355
4356       const char *tmp = next;
4357       SKIP_WS(tmp);
4358       if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
4359         KMP_WARNING(EnvSpacesNotAllowed, name, value);
4360         return;
4361       }
4362
4363       num = __kmp_str_to_int(buf, *next);
4364       if (num < 0) { // The number of retries should be >= 0
4365         msg = KMP_I18N_STR(ValueTooSmall);
4366         num = 1;
4367       } else if (num > KMP_INT_MAX) {
4368         msg = KMP_I18N_STR(ValueTooLarge);
4369         num = KMP_INT_MAX;
4370       }
4371       if (msg != NULL) {
4372         // Message is not empty. Print warning.
4373         KMP_WARNING(ParseSizeIntWarn, name, value, msg);
4374         KMP_INFORM(Using_int_Value, name, num);
4375       }
4376       if (total == 1) {
4377         max_retries = num;
4378       } else if (total == 2) {
4379         max_badness = num;
4380       }
4381     }
4382   }
4383   KMP_DEBUG_ASSERT(total > 0);
4384   if (total <= 0) {
4385     KMP_WARNING(EnvSyntaxError, name, value);
4386     return;
4387   }
4388   __kmp_adaptive_backoff_params.max_soft_retries = max_retries;
4389   __kmp_adaptive_backoff_params.max_badness = max_badness;
4390 }
4391
4392 static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t *buffer,
4393                                                 char const *name, void *data) {
4394   if (__kmp_env_format) {
4395     KMP_STR_BUF_PRINT_NAME_EX(name);
4396   } else {
4397     __kmp_str_buf_print(buffer, "   %s='", name);
4398   }
4399   __kmp_str_buf_print(buffer, "%d,%d'\n",
4400                       __kmp_adaptive_backoff_params.max_soft_retries,
4401                       __kmp_adaptive_backoff_params.max_badness);
4402 } // __kmp_stg_print_adaptive_lock_props
4403
4404 #if KMP_DEBUG_ADAPTIVE_LOCKS
4405
4406 static void __kmp_stg_parse_speculative_statsfile(char const *name,
4407                                                   char const *value,
4408                                                   void *data) {
4409   __kmp_stg_parse_file(name, value, "", CCAST(char**, &__kmp_speculative_statsfile));
4410 } // __kmp_stg_parse_speculative_statsfile
4411
4412 static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t *buffer,
4413                                                   char const *name,
4414                                                   void *data) {
4415   if (__kmp_str_match("-", 0, __kmp_speculative_statsfile)) {
4416     __kmp_stg_print_str(buffer, name, "stdout");
4417   } else {
4418     __kmp_stg_print_str(buffer, name, __kmp_speculative_statsfile);
4419   }
4420
4421 } // __kmp_stg_print_speculative_statsfile
4422
4423 #endif // KMP_DEBUG_ADAPTIVE_LOCKS
4424
4425 #endif // KMP_USE_ADAPTIVE_LOCKS
4426
4427 // -----------------------------------------------------------------------------
4428 // KMP_HW_SUBSET (was KMP_PLACE_THREADS)
4429
4430 // The longest observable sequense of items is
4431 // Socket-Node-Tile-Core-Thread
4432 // So, let's limit to 5 levels for now
4433 // The input string is usually short enough, let's use 512 limit for now
4434 #define MAX_T_LEVEL 5
4435 #define MAX_STR_LEN 512
4436 static void __kmp_stg_parse_hw_subset(char const *name, char const *value,
4437                                       void *data) {
4438   // Value example: 1s,5c@3,2T
4439   // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core"
4440   kmp_setting_t **rivals = (kmp_setting_t **)data;
4441   if (strcmp(name, "KMP_PLACE_THREADS") == 0) {
4442     KMP_INFORM(EnvVarDeprecated, name, "KMP_HW_SUBSET");
4443   }
4444   if (__kmp_stg_check_rivals(name, value, rivals)) {
4445     return;
4446   }
4447
4448   char *components[MAX_T_LEVEL];
4449   char const *digits = "0123456789";
4450   char input[MAX_STR_LEN];
4451   size_t len = 0, mlen = MAX_STR_LEN;
4452   int level = 0;
4453   // Canonize the string (remove spaces, unify delimiters, etc.)
4454   char *pos = CCAST(char *, value);
4455   while (*pos && mlen) {
4456     if (*pos != ' ') { // skip spaces
4457       if (len == 0 && *pos == ':') {
4458         __kmp_hws_abs_flag = 1; // if the first symbol is ":", skip it
4459       } else {
4460         input[len] = toupper(*pos);
4461         if (input[len] == 'X')
4462           input[len] = ','; // unify delimiters of levels
4463         if (input[len] == 'O' && strchr(digits, *(pos + 1)))
4464           input[len] = '@'; // unify delimiters of offset
4465         len++;
4466       }
4467     }
4468     mlen--;
4469     pos++;
4470   }
4471   if (len == 0 || mlen == 0)
4472     goto err; // contents is either empty or too long
4473   input[len] = '\0';
4474   __kmp_hws_requested = 1; // mark that subset requested
4475   // Split by delimiter
4476   pos = input;
4477   components[level++] = pos;
4478   while ((pos = strchr(pos, ','))) {
4479     *pos = '\0'; // modify input and avoid more copying
4480     components[level++] = ++pos; // expect something after ","
4481     if (level > MAX_T_LEVEL)
4482       goto err; // too many components provided
4483   }
4484   // Check each component
4485   for (int i = 0; i < level; ++i) {
4486     int offset = 0;
4487     int num = atoi(components[i]); // each component should start with a number
4488     if ((pos = strchr(components[i], '@'))) {
4489       offset = atoi(pos + 1); // save offset
4490       *pos = '\0'; // cut the offset from the component
4491     }
4492     pos = components[i] + strspn(components[i], digits);
4493     if (pos == components[i])
4494       goto err;
4495     // detect the component type
4496     switch (*pos) {
4497     case 'S': // Socket
4498       if (__kmp_hws_socket.num > 0)
4499         goto err; // duplicate is not allowed
4500       __kmp_hws_socket.num = num;
4501       __kmp_hws_socket.offset = offset;
4502       break;
4503     case 'N': // NUMA Node
4504       if (__kmp_hws_node.num > 0)
4505         goto err; // duplicate is not allowed
4506       __kmp_hws_node.num = num;
4507       __kmp_hws_node.offset = offset;
4508       break;
4509     case 'L': // Cache
4510       if (*(pos + 1) == '2') { // L2 - Tile
4511         if (__kmp_hws_tile.num > 0)
4512           goto err; // duplicate is not allowed
4513         __kmp_hws_tile.num = num;
4514         __kmp_hws_tile.offset = offset;
4515       } else if (*(pos + 1) == '3') { // L3 - Socket
4516         if (__kmp_hws_socket.num > 0)
4517           goto err; // duplicate is not allowed
4518         __kmp_hws_socket.num = num;
4519         __kmp_hws_socket.offset = offset;
4520       } else if (*(pos + 1) == '1') { // L1 - Core
4521         if (__kmp_hws_core.num > 0)
4522           goto err; // duplicate is not allowed
4523         __kmp_hws_core.num = num;
4524         __kmp_hws_core.offset = offset;
4525       }
4526       break;
4527     case 'C': // Core (or Cache?)
4528       if (*(pos + 1) != 'A') {
4529         if (__kmp_hws_core.num > 0)
4530           goto err; // duplicate is not allowed
4531         __kmp_hws_core.num = num;
4532         __kmp_hws_core.offset = offset;
4533       } else { // Cache
4534         char *d = pos + strcspn(pos, digits); // find digit
4535         if (*d == '2') { // L2 - Tile
4536           if (__kmp_hws_tile.num > 0)
4537             goto err; // duplicate is not allowed
4538           __kmp_hws_tile.num = num;
4539           __kmp_hws_tile.offset = offset;
4540         } else if (*d == '3') { // L3 - Socket
4541           if (__kmp_hws_socket.num > 0)
4542             goto err; // duplicate is not allowed
4543           __kmp_hws_socket.num = num;
4544           __kmp_hws_socket.offset = offset;
4545         } else if (*d == '1') { // L1 - Core
4546           if (__kmp_hws_core.num > 0)
4547             goto err; // duplicate is not allowed
4548           __kmp_hws_core.num = num;
4549           __kmp_hws_core.offset = offset;
4550         } else {
4551           goto err;
4552         }
4553       }
4554       break;
4555     case 'T': // Thread
4556       if (__kmp_hws_proc.num > 0)
4557         goto err; // duplicate is not allowed
4558       __kmp_hws_proc.num = num;
4559       __kmp_hws_proc.offset = offset;
4560       break;
4561     default:
4562       goto err;
4563     }
4564   }
4565   return;
4566 err:
4567   KMP_WARNING(AffHWSubsetInvalid, name, value);
4568   __kmp_hws_requested = 0; // mark that subset not requested
4569   return;
4570 }
4571
4572 static void __kmp_stg_print_hw_subset(kmp_str_buf_t *buffer, char const *name,
4573                                       void *data) {
4574   if (__kmp_hws_requested) {
4575     int comma = 0;
4576     kmp_str_buf_t buf;
4577     __kmp_str_buf_init(&buf);
4578     if (__kmp_env_format)
4579       KMP_STR_BUF_PRINT_NAME_EX(name);
4580     else
4581       __kmp_str_buf_print(buffer, "   %s='", name);
4582     if (__kmp_hws_socket.num) {
4583       __kmp_str_buf_print(&buf, "%ds", __kmp_hws_socket.num);
4584       if (__kmp_hws_socket.offset)
4585         __kmp_str_buf_print(&buf, "@%d", __kmp_hws_socket.offset);
4586       comma = 1;
4587     }
4588     if (__kmp_hws_node.num) {
4589       __kmp_str_buf_print(&buf, "%s%dn", comma ? "," : "", __kmp_hws_node.num);
4590       if (__kmp_hws_node.offset)
4591         __kmp_str_buf_print(&buf, "@%d", __kmp_hws_node.offset);
4592       comma = 1;
4593     }
4594     if (__kmp_hws_tile.num) {
4595       __kmp_str_buf_print(&buf, "%s%dL2", comma ? "," : "", __kmp_hws_tile.num);
4596       if (__kmp_hws_tile.offset)
4597         __kmp_str_buf_print(&buf, "@%d", __kmp_hws_tile.offset);
4598       comma = 1;
4599     }
4600     if (__kmp_hws_core.num) {
4601       __kmp_str_buf_print(&buf, "%s%dc", comma ? "," : "", __kmp_hws_core.num);
4602       if (__kmp_hws_core.offset)
4603         __kmp_str_buf_print(&buf, "@%d", __kmp_hws_core.offset);
4604       comma = 1;
4605     }
4606     if (__kmp_hws_proc.num)
4607       __kmp_str_buf_print(&buf, "%s%dt", comma ? "," : "", __kmp_hws_proc.num);
4608     __kmp_str_buf_print(buffer, "%s'\n", buf.str);
4609     __kmp_str_buf_free(&buf);
4610   }
4611 }
4612
4613 #if USE_ITT_BUILD
4614 // -----------------------------------------------------------------------------
4615 // KMP_FORKJOIN_FRAMES
4616
4617 static void __kmp_stg_parse_forkjoin_frames(char const *name, char const *value,
4618                                             void *data) {
4619   __kmp_stg_parse_bool(name, value, &__kmp_forkjoin_frames);
4620 } // __kmp_stg_parse_forkjoin_frames
4621
4622 static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t *buffer,
4623                                             char const *name, void *data) {
4624   __kmp_stg_print_bool(buffer, name, __kmp_forkjoin_frames);
4625 } // __kmp_stg_print_forkjoin_frames
4626
4627 // -----------------------------------------------------------------------------
4628 // KMP_FORKJOIN_FRAMES_MODE
4629
4630 static void __kmp_stg_parse_forkjoin_frames_mode(char const *name,
4631                                                  char const *value,
4632                                                  void *data) {
4633   __kmp_stg_parse_int(name, value, 0, 3, &__kmp_forkjoin_frames_mode);
4634 } // __kmp_stg_parse_forkjoin_frames
4635
4636 static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t *buffer,
4637                                                  char const *name, void *data) {
4638   __kmp_stg_print_int(buffer, name, __kmp_forkjoin_frames_mode);
4639 } // __kmp_stg_print_forkjoin_frames
4640 #endif /* USE_ITT_BUILD */
4641
4642 // -----------------------------------------------------------------------------
4643 // OMP_DISPLAY_ENV
4644
4645 #if OMP_40_ENABLED
4646
4647 static void __kmp_stg_parse_omp_display_env(char const *name, char const *value,
4648                                             void *data) {
4649   if (__kmp_str_match("VERBOSE", 1, value)) {
4650     __kmp_display_env_verbose = TRUE;
4651   } else {
4652     __kmp_stg_parse_bool(name, value, &__kmp_display_env);
4653   }
4654
4655 } // __kmp_stg_parse_omp_display_env
4656
4657 static void __kmp_stg_print_omp_display_env(kmp_str_buf_t *buffer,
4658                                             char const *name, void *data) {
4659   if (__kmp_display_env_verbose) {
4660     __kmp_stg_print_str(buffer, name, "VERBOSE");
4661   } else {
4662     __kmp_stg_print_bool(buffer, name, __kmp_display_env);
4663   }
4664 } // __kmp_stg_print_omp_display_env
4665
4666 static void __kmp_stg_parse_omp_cancellation(char const *name,
4667                                              char const *value, void *data) {
4668   if (TCR_4(__kmp_init_parallel)) {
4669     KMP_WARNING(EnvParallelWarn, name);
4670     return;
4671   } // read value before first parallel only
4672   __kmp_stg_parse_bool(name, value, &__kmp_omp_cancellation);
4673 } // __kmp_stg_parse_omp_cancellation
4674
4675 static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t *buffer,
4676                                              char const *name, void *data) {
4677   __kmp_stg_print_bool(buffer, name, __kmp_omp_cancellation);
4678 } // __kmp_stg_print_omp_cancellation
4679
4680 #endif
4681
4682 #if OMP_50_ENABLED && OMPT_SUPPORT
4683 static int __kmp_tool = 1;
4684
4685 static void __kmp_stg_parse_omp_tool(char const *name, char const *value,
4686                                      void *data) {
4687   __kmp_stg_parse_bool(name, value, &__kmp_tool);
4688 } // __kmp_stg_parse_omp_tool
4689
4690 static void __kmp_stg_print_omp_tool(kmp_str_buf_t *buffer, char const *name,
4691                                      void *data) {
4692   if (__kmp_env_format) {
4693     KMP_STR_BUF_PRINT_BOOL_EX(name, __kmp_tool, "enabled", "disabled");
4694   } else {
4695     __kmp_str_buf_print(buffer, "   %s=%s\n", name,
4696                         __kmp_tool ? "enabled" : "disabled");
4697   }
4698 } // __kmp_stg_print_omp_tool
4699
4700 static char *__kmp_tool_libraries = NULL;
4701
4702 static void __kmp_stg_parse_omp_tool_libraries(char const *name,
4703                                                char const *value, void *data) {
4704   __kmp_stg_parse_str(name, value, &__kmp_tool_libraries);
4705 } // __kmp_stg_parse_omp_tool_libraries
4706
4707 static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t *buffer,
4708                                                char const *name, void *data) {
4709   if (__kmp_tool_libraries)
4710     __kmp_stg_print_str(buffer, name, __kmp_tool_libraries);
4711   else {
4712     if (__kmp_env_format) {
4713       KMP_STR_BUF_PRINT_NAME;
4714     } else {
4715       __kmp_str_buf_print(buffer, "   %s", name);
4716     }
4717     __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
4718   }
4719 } // __kmp_stg_print_omp_tool_libraries
4720
4721 #endif
4722
4723 // Table.
4724
4725 static kmp_setting_t __kmp_stg_table[] = {
4726
4727     {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit, NULL, NULL, 0, 0},
4728     {"KMP_BLOCKTIME", __kmp_stg_parse_blocktime, __kmp_stg_print_blocktime,
4729      NULL, 0, 0},
4730     {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok,
4731      __kmp_stg_print_duplicate_lib_ok, NULL, 0, 0},
4732     {"KMP_LIBRARY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy,
4733      NULL, 0, 0},
4734     {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit,
4735      __kmp_stg_print_device_thread_limit, NULL, 0, 0},
4736 #if KMP_USE_MONITOR
4737     {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize,
4738      __kmp_stg_print_monitor_stacksize, NULL, 0, 0},
4739 #endif
4740     {"KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL,
4741      0, 0},
4742     {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset,
4743      __kmp_stg_print_stackoffset, NULL, 0, 0},
4744     {"KMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,
4745      NULL, 0, 0},
4746     {"KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL,
4747      0, 0},
4748     {"KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0,
4749      0},
4750     {"KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL,
4751      0, 0},
4752
4753     {"OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0},
4754     {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads,
4755      __kmp_stg_print_num_threads, NULL, 0, 0},
4756     {"OMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,
4757      NULL, 0, 0},
4758
4759     {"KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0,
4760      0},
4761     {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing,
4762      __kmp_stg_print_task_stealing, NULL, 0, 0},
4763     {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels,
4764      __kmp_stg_print_max_active_levels, NULL, 0, 0},
4765 #if OMP_40_ENABLED
4766     {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device,
4767      __kmp_stg_print_default_device, NULL, 0, 0},
4768 #endif
4769 #if OMP_50_ENABLED
4770     {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload,
4771      __kmp_stg_print_target_offload, NULL, 0, 0},
4772 #endif
4773 #if OMP_45_ENABLED
4774     {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority,
4775      __kmp_stg_print_max_task_priority, NULL, 0, 0},
4776     {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks,
4777      __kmp_stg_print_taskloop_min_tasks, NULL, 0, 0},
4778 #endif
4779     {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit,
4780      __kmp_stg_print_thread_limit, NULL, 0, 0},
4781     {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit,
4782      __kmp_stg_print_teams_thread_limit, NULL, 0, 0},
4783     {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy,
4784      __kmp_stg_print_wait_policy, NULL, 0, 0},
4785     {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers,
4786      __kmp_stg_print_disp_buffers, NULL, 0, 0},
4787 #if KMP_NESTED_HOT_TEAMS
4788     {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level,
4789      __kmp_stg_print_hot_teams_level, NULL, 0, 0},
4790     {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode,
4791      __kmp_stg_print_hot_teams_mode, NULL, 0, 0},
4792 #endif // KMP_NESTED_HOT_TEAMS
4793
4794 #if KMP_HANDLE_SIGNALS
4795     {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals,
4796      __kmp_stg_print_handle_signals, NULL, 0, 0},
4797 #endif
4798
4799 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
4800     {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control,
4801      __kmp_stg_print_inherit_fp_control, NULL, 0, 0},
4802 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
4803
4804 #ifdef KMP_GOMP_COMPAT
4805     {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0},
4806 #endif
4807
4808 #ifdef KMP_DEBUG
4809     {"KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0,
4810      0},
4811     {"KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0,
4812      0},
4813     {"KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0,
4814      0},
4815     {"KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0,
4816      0},
4817     {"KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0,
4818      0},
4819     {"KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0,
4820      0},
4821     {"KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0},
4822     {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf,
4823      NULL, 0, 0},
4824     {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic,
4825      __kmp_stg_print_debug_buf_atomic, NULL, 0, 0},
4826     {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars,
4827      __kmp_stg_print_debug_buf_chars, NULL, 0, 0},
4828     {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines,
4829      __kmp_stg_print_debug_buf_lines, NULL, 0, 0},
4830     {"KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0},
4831
4832     {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env,
4833      __kmp_stg_print_par_range_env, NULL, 0, 0},
4834     {"KMP_YIELD_CYCLE", __kmp_stg_parse_yield_cycle,
4835      __kmp_stg_print_yield_cycle, NULL, 0, 0},
4836     {"KMP_YIELD_ON", __kmp_stg_parse_yield_on, __kmp_stg_print_yield_on, NULL,
4837      0, 0},
4838     {"KMP_YIELD_OFF", __kmp_stg_parse_yield_off, __kmp_stg_print_yield_off,
4839      NULL, 0, 0},
4840 #endif // KMP_DEBUG
4841
4842     {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc,
4843      __kmp_stg_print_align_alloc, NULL, 0, 0},
4844
4845     {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
4846      __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
4847     {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
4848      __kmp_stg_print_barrier_pattern, NULL, 0, 0},
4849     {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
4850      __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
4851     {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
4852      __kmp_stg_print_barrier_pattern, NULL, 0, 0},
4853 #if KMP_FAST_REDUCTION_BARRIER
4854     {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit,
4855      __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
4856     {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
4857      __kmp_stg_print_barrier_pattern, NULL, 0, 0},
4858 #endif
4859
4860     {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay,
4861      __kmp_stg_print_abort_delay, NULL, 0, 0},
4862     {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file,
4863      __kmp_stg_print_cpuinfo_file, NULL, 0, 0},
4864     {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction,
4865      __kmp_stg_print_force_reduction, NULL, 0, 0},
4866     {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction,
4867      __kmp_stg_print_force_reduction, NULL, 0, 0},
4868     {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map,
4869      __kmp_stg_print_storage_map, NULL, 0, 0},
4870     {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate,
4871      __kmp_stg_print_all_threadprivate, NULL, 0, 0},
4872     {"KMP_FOREIGN_THREADS_THREADPRIVATE",
4873      __kmp_stg_parse_foreign_threads_threadprivate,
4874      __kmp_stg_print_foreign_threads_threadprivate, NULL, 0, 0},
4875
4876 #if KMP_AFFINITY_SUPPORTED
4877     {"KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL,
4878      0, 0},
4879 #ifdef KMP_GOMP_COMPAT
4880     {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL,
4881      /* no print */ NULL, 0, 0},
4882 #endif /* KMP_GOMP_COMPAT */
4883 #if OMP_40_ENABLED
4884     {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,
4885      NULL, 0, 0},
4886     {"OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0},
4887 #else
4888     {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, NULL, /* no print */ NULL, 0,
4889      0},
4890 #endif /* OMP_40_ENABLED */
4891     {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method,
4892      __kmp_stg_print_topology_method, NULL, 0, 0},
4893
4894 #else
4895
4896 // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
4897 // OMP_PROC_BIND and proc-bind-var are supported, however.
4898 #if OMP_40_ENABLED
4899     {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,
4900      NULL, 0, 0},
4901 #endif
4902
4903 #endif // KMP_AFFINITY_SUPPORTED
4904 #if OMP_50_ENABLED
4905     {"OMP_DISPLAY_AFFINITY", __kmp_stg_parse_display_affinity,
4906      __kmp_stg_print_display_affinity, NULL, 0, 0},
4907     {"OMP_AFFINITY_FORMAT", __kmp_stg_parse_affinity_format,
4908      __kmp_stg_print_affinity_format, NULL, 0, 0},
4909 #endif
4910     {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork,
4911      __kmp_stg_print_init_at_fork, NULL, 0, 0},
4912     {"KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL,
4913      0, 0},
4914     {"OMP_SCHEDULE", __kmp_stg_parse_omp_schedule, __kmp_stg_print_omp_schedule,
4915      NULL, 0, 0},
4916 #if KMP_USE_HIER_SCHED
4917     {"KMP_DISP_HAND_THREAD", __kmp_stg_parse_kmp_hand_thread,
4918      __kmp_stg_print_kmp_hand_thread, NULL, 0, 0},
4919 #endif
4920     {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode,
4921      __kmp_stg_print_atomic_mode, NULL, 0, 0},
4922     {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check,
4923      __kmp_stg_print_consistency_check, NULL, 0, 0},
4924
4925 #if USE_ITT_BUILD && USE_ITT_NOTIFY
4926     {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay,
4927      __kmp_stg_print_itt_prepare_delay, NULL, 0, 0},
4928 #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
4929     {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr,
4930      __kmp_stg_print_malloc_pool_incr, NULL, 0, 0},
4931     {"KMP_INIT_WAIT", __kmp_stg_parse_init_wait, __kmp_stg_print_init_wait,
4932      NULL, 0, 0},
4933     {"KMP_NEXT_WAIT", __kmp_stg_parse_next_wait, __kmp_stg_print_next_wait,
4934      NULL, 0, 0},
4935     {"KMP_GTID_MODE", __kmp_stg_parse_gtid_mode, __kmp_stg_print_gtid_mode,
4936      NULL, 0, 0},
4937     {"OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic, __kmp_stg_print_omp_dynamic,
4938      NULL, 0, 0},
4939     {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode,
4940      __kmp_stg_print_kmp_dynamic_mode, NULL, 0, 0},
4941
4942 #ifdef USE_LOAD_BALANCE
4943     {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval,
4944      __kmp_stg_print_ld_balance_interval, NULL, 0, 0},
4945 #endif
4946
4947     {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block,
4948      __kmp_stg_print_lock_block, NULL, 0, 0},
4949     {"KMP_LOCK_KIND", __kmp_stg_parse_lock_kind, __kmp_stg_print_lock_kind,
4950      NULL, 0, 0},
4951     {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params,
4952      __kmp_stg_print_spin_backoff_params, NULL, 0, 0},
4953 #if KMP_USE_ADAPTIVE_LOCKS
4954     {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props,
4955      __kmp_stg_print_adaptive_lock_props, NULL, 0, 0},
4956 #if KMP_DEBUG_ADAPTIVE_LOCKS
4957     {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile,
4958      __kmp_stg_print_speculative_statsfile, NULL, 0, 0},
4959 #endif
4960 #endif // KMP_USE_ADAPTIVE_LOCKS
4961     {"KMP_PLACE_THREADS", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,
4962      NULL, 0, 0},
4963     {"KMP_HW_SUBSET", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,
4964      NULL, 0, 0},
4965 #if USE_ITT_BUILD
4966     {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames,
4967      __kmp_stg_print_forkjoin_frames, NULL, 0, 0},
4968     {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode,
4969      __kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0},
4970 #endif
4971
4972 #if OMP_40_ENABLED
4973     {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env,
4974      __kmp_stg_print_omp_display_env, NULL, 0, 0},
4975     {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation,
4976      __kmp_stg_print_omp_cancellation, NULL, 0, 0},
4977 #endif
4978
4979 #if OMP_50_ENABLED
4980     {"OMP_ALLOCATOR", __kmp_stg_parse_allocator, __kmp_stg_print_allocator,
4981      NULL, 0, 0},
4982 #endif
4983
4984 #if OMP_50_ENABLED && OMPT_SUPPORT
4985     {"OMP_TOOL", __kmp_stg_parse_omp_tool, __kmp_stg_print_omp_tool, NULL, 0,
4986      0},
4987     {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries,
4988      __kmp_stg_print_omp_tool_libraries, NULL, 0, 0},
4989 #endif
4990
4991     {"", NULL, NULL, NULL, 0, 0}}; // settings
4992
4993 static int const __kmp_stg_count =
4994     sizeof(__kmp_stg_table) / sizeof(kmp_setting_t);
4995
4996 static inline kmp_setting_t *__kmp_stg_find(char const *name) {
4997
4998   int i;
4999   if (name != NULL) {
5000     for (i = 0; i < __kmp_stg_count; ++i) {
5001       if (strcmp(__kmp_stg_table[i].name, name) == 0) {
5002         return &__kmp_stg_table[i];
5003       }
5004     }
5005   }
5006   return NULL;
5007
5008 } // __kmp_stg_find
5009
5010 static int __kmp_stg_cmp(void const *_a, void const *_b) {
5011   const kmp_setting_t *a = RCAST(const kmp_setting_t *, _a);
5012   const kmp_setting_t *b = RCAST(const kmp_setting_t *, _b);
5013
5014   // Process KMP_AFFINITY last.
5015   // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
5016   if (strcmp(a->name, "KMP_AFFINITY") == 0) {
5017     if (strcmp(b->name, "KMP_AFFINITY") == 0) {
5018       return 0;
5019     }
5020     return 1;
5021   } else if (strcmp(b->name, "KMP_AFFINITY") == 0) {
5022     return -1;
5023   }
5024   return strcmp(a->name, b->name);
5025 } // __kmp_stg_cmp
5026
5027 static void __kmp_stg_init(void) {
5028
5029   static int initialized = 0;
5030
5031   if (!initialized) {
5032
5033     // Sort table.
5034     qsort(__kmp_stg_table, __kmp_stg_count - 1, sizeof(kmp_setting_t),
5035           __kmp_stg_cmp);
5036
5037     { // Initialize *_STACKSIZE data.
5038       kmp_setting_t *kmp_stacksize =
5039           __kmp_stg_find("KMP_STACKSIZE"); // 1st priority.
5040 #ifdef KMP_GOMP_COMPAT
5041       kmp_setting_t *gomp_stacksize =
5042           __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority.
5043 #endif
5044       kmp_setting_t *omp_stacksize =
5045           __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority.
5046
5047       // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5048       // !!! Compiler does not understand rivals is used and optimizes out
5049       // assignments
5050       // !!!     rivals[ i ++ ] = ...;
5051       static kmp_setting_t *volatile rivals[4];
5052       static kmp_stg_ss_data_t kmp_data = {1, CCAST(kmp_setting_t **, rivals)};
5053 #ifdef KMP_GOMP_COMPAT
5054       static kmp_stg_ss_data_t gomp_data = {1024,
5055                                             CCAST(kmp_setting_t **, rivals)};
5056 #endif
5057       static kmp_stg_ss_data_t omp_data = {1024,
5058                                            CCAST(kmp_setting_t **, rivals)};
5059       int i = 0;
5060
5061       rivals[i++] = kmp_stacksize;
5062 #ifdef KMP_GOMP_COMPAT
5063       if (gomp_stacksize != NULL) {
5064         rivals[i++] = gomp_stacksize;
5065       }
5066 #endif
5067       rivals[i++] = omp_stacksize;
5068       rivals[i++] = NULL;
5069
5070       kmp_stacksize->data = &kmp_data;
5071 #ifdef KMP_GOMP_COMPAT
5072       if (gomp_stacksize != NULL) {
5073         gomp_stacksize->data = &gomp_data;
5074       }
5075 #endif
5076       omp_stacksize->data = &omp_data;
5077     }
5078
5079     { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
5080       kmp_setting_t *kmp_library =
5081           __kmp_stg_find("KMP_LIBRARY"); // 1st priority.
5082       kmp_setting_t *omp_wait_policy =
5083           __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority.
5084
5085       // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5086       static kmp_setting_t *volatile rivals[3];
5087       static kmp_stg_wp_data_t kmp_data = {0, CCAST(kmp_setting_t **, rivals)};
5088       static kmp_stg_wp_data_t omp_data = {1, CCAST(kmp_setting_t **, rivals)};
5089       int i = 0;
5090
5091       rivals[i++] = kmp_library;
5092       if (omp_wait_policy != NULL) {
5093         rivals[i++] = omp_wait_policy;
5094       }
5095       rivals[i++] = NULL;
5096
5097       kmp_library->data = &kmp_data;
5098       if (omp_wait_policy != NULL) {
5099         omp_wait_policy->data = &omp_data;
5100       }
5101     }
5102
5103     { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS
5104       kmp_setting_t *kmp_device_thread_limit =
5105           __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority.
5106       kmp_setting_t *kmp_all_threads =
5107           __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority.
5108
5109       // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5110       static kmp_setting_t *volatile rivals[3];
5111       int i = 0;
5112
5113       rivals[i++] = kmp_device_thread_limit;
5114       rivals[i++] = kmp_all_threads;
5115       rivals[i++] = NULL;
5116
5117       kmp_device_thread_limit->data = CCAST(kmp_setting_t **, rivals);
5118       kmp_all_threads->data = CCAST(kmp_setting_t **, rivals);
5119     }
5120
5121     { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS
5122       // 1st priority
5123       kmp_setting_t *kmp_hw_subset = __kmp_stg_find("KMP_HW_SUBSET");
5124       // 2nd priority
5125       kmp_setting_t *kmp_place_threads = __kmp_stg_find("KMP_PLACE_THREADS");
5126
5127       // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5128       static kmp_setting_t *volatile rivals[3];
5129       int i = 0;
5130
5131       rivals[i++] = kmp_hw_subset;
5132       rivals[i++] = kmp_place_threads;
5133       rivals[i++] = NULL;
5134
5135       kmp_hw_subset->data = CCAST(kmp_setting_t **, rivals);
5136       kmp_place_threads->data = CCAST(kmp_setting_t **, rivals);
5137     }
5138
5139 #if KMP_AFFINITY_SUPPORTED
5140     { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
5141       kmp_setting_t *kmp_affinity =
5142           __kmp_stg_find("KMP_AFFINITY"); // 1st priority.
5143       KMP_DEBUG_ASSERT(kmp_affinity != NULL);
5144
5145 #ifdef KMP_GOMP_COMPAT
5146       kmp_setting_t *gomp_cpu_affinity =
5147           __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority.
5148       KMP_DEBUG_ASSERT(gomp_cpu_affinity != NULL);
5149 #endif
5150
5151       kmp_setting_t *omp_proc_bind =
5152           __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority.
5153       KMP_DEBUG_ASSERT(omp_proc_bind != NULL);
5154
5155       // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5156       static kmp_setting_t *volatile rivals[4];
5157       int i = 0;
5158
5159       rivals[i++] = kmp_affinity;
5160
5161 #ifdef KMP_GOMP_COMPAT
5162       rivals[i++] = gomp_cpu_affinity;
5163       gomp_cpu_affinity->data = CCAST(kmp_setting_t **, rivals);
5164 #endif
5165
5166       rivals[i++] = omp_proc_bind;
5167       omp_proc_bind->data = CCAST(kmp_setting_t **, rivals);
5168       rivals[i++] = NULL;
5169
5170 #if OMP_40_ENABLED
5171       static kmp_setting_t *volatile places_rivals[4];
5172       i = 0;
5173
5174       kmp_setting_t *omp_places = __kmp_stg_find("OMP_PLACES"); // 3rd priority.
5175       KMP_DEBUG_ASSERT(omp_places != NULL);
5176
5177       places_rivals[i++] = kmp_affinity;
5178 #ifdef KMP_GOMP_COMPAT
5179       places_rivals[i++] = gomp_cpu_affinity;
5180 #endif
5181       places_rivals[i++] = omp_places;
5182       omp_places->data = CCAST(kmp_setting_t **, places_rivals);
5183       places_rivals[i++] = NULL;
5184 #endif
5185     }
5186 #else
5187 // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
5188 // OMP_PLACES not supported yet.
5189 #endif // KMP_AFFINITY_SUPPORTED
5190
5191     { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
5192       kmp_setting_t *kmp_force_red =
5193           __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority.
5194       kmp_setting_t *kmp_determ_red =
5195           __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority.
5196
5197       // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5198       static kmp_setting_t *volatile rivals[3];
5199       static kmp_stg_fr_data_t force_data = {1,
5200                                              CCAST(kmp_setting_t **, rivals)};
5201       static kmp_stg_fr_data_t determ_data = {0,
5202                                               CCAST(kmp_setting_t **, rivals)};
5203       int i = 0;
5204
5205       rivals[i++] = kmp_force_red;
5206       if (kmp_determ_red != NULL) {
5207         rivals[i++] = kmp_determ_red;
5208       }
5209       rivals[i++] = NULL;
5210
5211       kmp_force_red->data = &force_data;
5212       if (kmp_determ_red != NULL) {
5213         kmp_determ_red->data = &determ_data;
5214       }
5215     }
5216
5217     initialized = 1;
5218   }
5219
5220   // Reset flags.
5221   int i;
5222   for (i = 0; i < __kmp_stg_count; ++i) {
5223     __kmp_stg_table[i].set = 0;
5224   }
5225
5226 } // __kmp_stg_init
5227
5228 static void __kmp_stg_parse(char const *name, char const *value) {
5229   // On Windows* OS there are some nameless variables like "C:=C:\" (yeah,
5230   // really nameless, they are presented in environment block as
5231   // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
5232   if (name[0] == 0) {
5233     return;
5234   }
5235
5236   if (value != NULL) {
5237     kmp_setting_t *setting = __kmp_stg_find(name);
5238     if (setting != NULL) {
5239       setting->parse(name, value, setting->data);
5240       setting->defined = 1;
5241     }
5242   }
5243
5244 } // __kmp_stg_parse
5245
5246 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
5247     char const *name, // Name of variable.
5248     char const *value, // Value of the variable.
5249     kmp_setting_t **rivals // List of rival settings (must include current one).
5250     ) {
5251
5252   if (rivals == NULL) {
5253     return 0;
5254   }
5255
5256   // Loop thru higher priority settings (listed before current).
5257   int i = 0;
5258   for (; strcmp(rivals[i]->name, name) != 0; i++) {
5259     KMP_DEBUG_ASSERT(rivals[i] != NULL);
5260
5261 #if KMP_AFFINITY_SUPPORTED
5262     if (rivals[i] == __kmp_affinity_notype) {
5263       // If KMP_AFFINITY is specified without a type name,
5264       // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
5265       continue;
5266     }
5267 #endif
5268
5269     if (rivals[i]->set) {
5270       KMP_WARNING(StgIgnored, name, rivals[i]->name);
5271       return 1;
5272     }
5273   }
5274
5275   ++i; // Skip current setting.
5276   return 0;
5277
5278 } // __kmp_stg_check_rivals
5279
5280 static int __kmp_env_toPrint(char const *name, int flag) {
5281   int rc = 0;
5282   kmp_setting_t *setting = __kmp_stg_find(name);
5283   if (setting != NULL) {
5284     rc = setting->defined;
5285     if (flag >= 0) {
5286       setting->defined = flag;
5287     }
5288   }
5289   return rc;
5290 }
5291
5292 static void __kmp_aux_env_initialize(kmp_env_blk_t *block) {
5293
5294   char const *value;
5295
5296   /* OMP_NUM_THREADS */
5297   value = __kmp_env_blk_var(block, "OMP_NUM_THREADS");
5298   if (value) {
5299     ompc_set_num_threads(__kmp_dflt_team_nth);
5300   }
5301
5302   /* KMP_BLOCKTIME */
5303   value = __kmp_env_blk_var(block, "KMP_BLOCKTIME");
5304   if (value) {
5305     kmpc_set_blocktime(__kmp_dflt_blocktime);
5306   }
5307
5308   /* OMP_NESTED */
5309   value = __kmp_env_blk_var(block, "OMP_NESTED");
5310   if (value) {
5311     ompc_set_nested(__kmp_dflt_nested);
5312   }
5313
5314   /* OMP_DYNAMIC */
5315   value = __kmp_env_blk_var(block, "OMP_DYNAMIC");
5316   if (value) {
5317     ompc_set_dynamic(__kmp_global.g.g_dynamic);
5318   }
5319 }
5320
5321 void __kmp_env_initialize(char const *string) {
5322
5323   kmp_env_blk_t block;
5324   int i;
5325
5326   __kmp_stg_init();
5327
5328   // Hack!!!
5329   if (string == NULL) {
5330     // __kmp_max_nth = __kmp_sys_max_nth;
5331     __kmp_threads_capacity =
5332         __kmp_initial_threads_capacity(__kmp_dflt_team_nth_ub);
5333   }
5334   __kmp_env_blk_init(&block, string);
5335
5336   // update the set flag on all entries that have an env var
5337   for (i = 0; i < block.count; ++i) {
5338     if ((block.vars[i].name == NULL) || (*block.vars[i].name == '\0')) {
5339       continue;
5340     }
5341     if (block.vars[i].value == NULL) {
5342       continue;
5343     }
5344     kmp_setting_t *setting = __kmp_stg_find(block.vars[i].name);
5345     if (setting != NULL) {
5346       setting->set = 1;
5347     }
5348   }
5349
5350   // We need to know if blocktime was set when processing OMP_WAIT_POLICY
5351   blocktime_str = __kmp_env_blk_var(&block, "KMP_BLOCKTIME");
5352
5353   // Special case. If we parse environment, not a string, process KMP_WARNINGS
5354   // first.
5355   if (string == NULL) {
5356     char const *name = "KMP_WARNINGS";
5357     char const *value = __kmp_env_blk_var(&block, name);
5358     __kmp_stg_parse(name, value);
5359   }
5360
5361 #if KMP_AFFINITY_SUPPORTED
5362   // Special case. KMP_AFFINITY is not a rival to other affinity env vars
5363   // if no affinity type is specified.  We want to allow
5364   // KMP_AFFINITY=[no],verbose/[no]warnings/etc.  to be enabled when
5365   // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
5366   // affinity mechanism.
5367   __kmp_affinity_notype = NULL;
5368   char const *aff_str = __kmp_env_blk_var(&block, "KMP_AFFINITY");
5369   if (aff_str != NULL) {
5370 // Check if the KMP_AFFINITY type is specified in the string.
5371 // We just search the string for "compact", "scatter", etc.
5372 // without really parsing the string.  The syntax of the
5373 // KMP_AFFINITY env var is such that none of the affinity
5374 // type names can appear anywhere other that the type
5375 // specifier, even as substrings.
5376 //
5377 // I can't find a case-insensitive version of strstr on Windows* OS.
5378 // Use the case-sensitive version for now.
5379
5380 #if KMP_OS_WINDOWS
5381 #define FIND strstr
5382 #else
5383 #define FIND strcasestr
5384 #endif
5385
5386     if ((FIND(aff_str, "none") == NULL) &&
5387         (FIND(aff_str, "physical") == NULL) &&
5388         (FIND(aff_str, "logical") == NULL) &&
5389         (FIND(aff_str, "compact") == NULL) &&
5390         (FIND(aff_str, "scatter") == NULL) &&
5391         (FIND(aff_str, "explicit") == NULL) &&
5392         (FIND(aff_str, "balanced") == NULL) &&
5393         (FIND(aff_str, "disabled") == NULL)) {
5394       __kmp_affinity_notype = __kmp_stg_find("KMP_AFFINITY");
5395     } else {
5396       // A new affinity type is specified.
5397       // Reset the affinity flags to their default values,
5398       // in case this is called from kmp_set_defaults().
5399       __kmp_affinity_type = affinity_default;
5400       __kmp_affinity_gran = affinity_gran_default;
5401       __kmp_affinity_top_method = affinity_top_method_default;
5402       __kmp_affinity_respect_mask = affinity_respect_mask_default;
5403     }
5404 #undef FIND
5405
5406 #if OMP_40_ENABLED
5407     // Also reset the affinity flags if OMP_PROC_BIND is specified.
5408     aff_str = __kmp_env_blk_var(&block, "OMP_PROC_BIND");
5409     if (aff_str != NULL) {
5410       __kmp_affinity_type = affinity_default;
5411       __kmp_affinity_gran = affinity_gran_default;
5412       __kmp_affinity_top_method = affinity_top_method_default;
5413       __kmp_affinity_respect_mask = affinity_respect_mask_default;
5414     }
5415 #endif /* OMP_40_ENABLED */
5416   }
5417
5418 #endif /* KMP_AFFINITY_SUPPORTED */
5419
5420 #if OMP_40_ENABLED
5421   // Set up the nested proc bind type vector.
5422   if (__kmp_nested_proc_bind.bind_types == NULL) {
5423     __kmp_nested_proc_bind.bind_types =
5424         (kmp_proc_bind_t *)KMP_INTERNAL_MALLOC(sizeof(kmp_proc_bind_t));
5425     if (__kmp_nested_proc_bind.bind_types == NULL) {
5426       KMP_FATAL(MemoryAllocFailed);
5427     }
5428     __kmp_nested_proc_bind.size = 1;
5429     __kmp_nested_proc_bind.used = 1;
5430 #if KMP_AFFINITY_SUPPORTED
5431     __kmp_nested_proc_bind.bind_types[0] = proc_bind_default;
5432 #else
5433     // default proc bind is false if affinity not supported
5434     __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5435 #endif
5436   }
5437 #endif /* OMP_40_ENABLED */
5438
5439 #if OMP_50_ENABLED
5440   // Set up the affinity format ICV
5441   // Grab the default affinity format string from the message catalog
5442   kmp_msg_t m =
5443       __kmp_msg_format(kmp_i18n_msg_AffFormatDefault, "%P", "%i", "%n", "%A");
5444   KMP_DEBUG_ASSERT(KMP_STRLEN(m.str) < KMP_AFFINITY_FORMAT_SIZE);
5445
5446   if (__kmp_affinity_format == NULL) {
5447     __kmp_affinity_format =
5448         (char *)KMP_INTERNAL_MALLOC(sizeof(char) * KMP_AFFINITY_FORMAT_SIZE);
5449   }
5450   KMP_STRCPY_S(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, m.str);
5451   __kmp_str_free(&m.str);
5452 #endif
5453
5454   // Now process all of the settings.
5455   for (i = 0; i < block.count; ++i) {
5456     __kmp_stg_parse(block.vars[i].name, block.vars[i].value);
5457   }
5458
5459   // If user locks have been allocated yet, don't reset the lock vptr table.
5460   if (!__kmp_init_user_locks) {
5461     if (__kmp_user_lock_kind == lk_default) {
5462       __kmp_user_lock_kind = lk_queuing;
5463     }
5464 #if KMP_USE_DYNAMIC_LOCK
5465     __kmp_init_dynamic_user_locks();
5466 #else
5467     __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);
5468 #endif
5469   } else {
5470     KMP_DEBUG_ASSERT(string != NULL); // kmp_set_defaults() was called
5471     KMP_DEBUG_ASSERT(__kmp_user_lock_kind != lk_default);
5472 // Binds lock functions again to follow the transition between different
5473 // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
5474 // as we do not allow lock kind changes after making a call to any
5475 // user lock functions (true).
5476 #if KMP_USE_DYNAMIC_LOCK
5477     __kmp_init_dynamic_user_locks();
5478 #else
5479     __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);
5480 #endif
5481   }
5482
5483 #if KMP_AFFINITY_SUPPORTED
5484
5485   if (!TCR_4(__kmp_init_middle)) {
5486 #if KMP_USE_HWLOC
5487     // Force using hwloc when either tiles or numa nodes requested within
5488     // KMP_HW_SUBSET and no other topology method is requested
5489     if ((__kmp_hws_node.num > 0 || __kmp_hws_tile.num > 0 ||
5490          __kmp_affinity_gran == affinity_gran_tile) &&
5491         (__kmp_affinity_top_method == affinity_top_method_default)) {
5492       __kmp_affinity_top_method = affinity_top_method_hwloc;
5493     }
5494 #endif
5495     // Determine if the machine/OS is actually capable of supporting
5496     // affinity.
5497     const char *var = "KMP_AFFINITY";
5498     KMPAffinity::pick_api();
5499 #if KMP_USE_HWLOC
5500     // If Hwloc topology discovery was requested but affinity was also disabled,
5501     // then tell user that Hwloc request is being ignored and use default
5502     // topology discovery method.
5503     if (__kmp_affinity_top_method == affinity_top_method_hwloc &&
5504         __kmp_affinity_dispatch->get_api_type() != KMPAffinity::HWLOC) {
5505       KMP_WARNING(AffIgnoringHwloc, var);
5506       __kmp_affinity_top_method = affinity_top_method_all;
5507     }
5508 #endif
5509     if (__kmp_affinity_type == affinity_disabled) {
5510       KMP_AFFINITY_DISABLE();
5511     } else if (!KMP_AFFINITY_CAPABLE()) {
5512       __kmp_affinity_dispatch->determine_capable(var);
5513       if (!KMP_AFFINITY_CAPABLE()) {
5514         if (__kmp_affinity_verbose ||
5515             (__kmp_affinity_warnings &&
5516              (__kmp_affinity_type != affinity_default) &&
5517              (__kmp_affinity_type != affinity_none) &&
5518              (__kmp_affinity_type != affinity_disabled))) {
5519           KMP_WARNING(AffNotSupported, var);
5520         }
5521         __kmp_affinity_type = affinity_disabled;
5522         __kmp_affinity_respect_mask = 0;
5523         __kmp_affinity_gran = affinity_gran_fine;
5524       }
5525     }
5526
5527 #if OMP_40_ENABLED
5528     if (__kmp_affinity_type == affinity_disabled) {
5529       __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5530     } else if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_true) {
5531       // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
5532       __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread;
5533     }
5534 #endif /* OMP_40_ENABLED */
5535
5536     if (KMP_AFFINITY_CAPABLE()) {
5537
5538 #if KMP_GROUP_AFFINITY
5539       // This checks to see if the initial affinity mask is equal
5540       // to a single windows processor group.  If it is, then we do
5541       // not respect the initial affinity mask and instead, use the
5542       // entire machine.
5543       bool exactly_one_group = false;
5544       if (__kmp_num_proc_groups > 1) {
5545         int group;
5546         bool within_one_group;
5547         // Get the initial affinity mask and determine if it is
5548         // contained within a single group.
5549         kmp_affin_mask_t *init_mask;
5550         KMP_CPU_ALLOC(init_mask);
5551         __kmp_get_system_affinity(init_mask, TRUE);
5552         group = __kmp_get_proc_group(init_mask);
5553         within_one_group = (group >= 0);
5554         // If the initial affinity is within a single group,
5555         // then determine if it is equal to that single group.
5556         if (within_one_group) {
5557           DWORD num_bits_in_group = __kmp_GetActiveProcessorCount(group);
5558           DWORD num_bits_in_mask = 0;
5559           for (int bit = init_mask->begin(); bit != init_mask->end();
5560                bit = init_mask->next(bit))
5561             num_bits_in_mask++;
5562           exactly_one_group = (num_bits_in_group == num_bits_in_mask);
5563         }
5564         KMP_CPU_FREE(init_mask);
5565       }
5566
5567       // Handle the Win 64 group affinity stuff if there are multiple
5568       // processor groups, or if the user requested it, and OMP 4.0
5569       // affinity is not in effect.
5570       if (((__kmp_num_proc_groups > 1) &&
5571            (__kmp_affinity_type == affinity_default)
5572 #if OMP_40_ENABLED
5573            && (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default))
5574 #endif
5575           || (__kmp_affinity_top_method == affinity_top_method_group)) {
5576         if (__kmp_affinity_respect_mask == affinity_respect_mask_default &&
5577             exactly_one_group) {
5578           __kmp_affinity_respect_mask = FALSE;
5579         }
5580         if (__kmp_affinity_type == affinity_default) {
5581           __kmp_affinity_type = affinity_compact;
5582 #if OMP_40_ENABLED
5583           __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5584 #endif
5585         }
5586         if (__kmp_affinity_top_method == affinity_top_method_default) {
5587           if (__kmp_affinity_gran == affinity_gran_default) {
5588             __kmp_affinity_top_method = affinity_top_method_group;
5589             __kmp_affinity_gran = affinity_gran_group;
5590           } else if (__kmp_affinity_gran == affinity_gran_group) {
5591             __kmp_affinity_top_method = affinity_top_method_group;
5592           } else {
5593             __kmp_affinity_top_method = affinity_top_method_all;
5594           }
5595         } else if (__kmp_affinity_top_method == affinity_top_method_group) {
5596           if (__kmp_affinity_gran == affinity_gran_default) {
5597             __kmp_affinity_gran = affinity_gran_group;
5598           } else if ((__kmp_affinity_gran != affinity_gran_group) &&
5599                      (__kmp_affinity_gran != affinity_gran_fine) &&
5600                      (__kmp_affinity_gran != affinity_gran_thread)) {
5601             const char *str = NULL;
5602             switch (__kmp_affinity_gran) {
5603             case affinity_gran_core:
5604               str = "core";
5605               break;
5606             case affinity_gran_package:
5607               str = "package";
5608               break;
5609             case affinity_gran_node:
5610               str = "node";
5611               break;
5612             case affinity_gran_tile:
5613               str = "tile";
5614               break;
5615             default:
5616               KMP_DEBUG_ASSERT(0);
5617             }
5618             KMP_WARNING(AffGranTopGroup, var, str);
5619             __kmp_affinity_gran = affinity_gran_fine;
5620           }
5621         } else {
5622           if (__kmp_affinity_gran == affinity_gran_default) {
5623             __kmp_affinity_gran = affinity_gran_core;
5624           } else if (__kmp_affinity_gran == affinity_gran_group) {
5625             const char *str = NULL;
5626             switch (__kmp_affinity_type) {
5627             case affinity_physical:
5628               str = "physical";
5629               break;
5630             case affinity_logical:
5631               str = "logical";
5632               break;
5633             case affinity_compact:
5634               str = "compact";
5635               break;
5636             case affinity_scatter:
5637               str = "scatter";
5638               break;
5639             case affinity_explicit:
5640               str = "explicit";
5641               break;
5642             // No MIC on windows, so no affinity_balanced case
5643             default:
5644               KMP_DEBUG_ASSERT(0);
5645             }
5646             KMP_WARNING(AffGranGroupType, var, str);
5647             __kmp_affinity_gran = affinity_gran_core;
5648           }
5649         }
5650       } else
5651
5652 #endif /* KMP_GROUP_AFFINITY */
5653
5654       {
5655         if (__kmp_affinity_respect_mask == affinity_respect_mask_default) {
5656 #if KMP_GROUP_AFFINITY
5657           if (__kmp_num_proc_groups > 1 && exactly_one_group) {
5658             __kmp_affinity_respect_mask = FALSE;
5659           } else
5660 #endif /* KMP_GROUP_AFFINITY */
5661           {
5662             __kmp_affinity_respect_mask = TRUE;
5663           }
5664         }
5665 #if OMP_40_ENABLED
5666         if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) &&
5667             (__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) {
5668           if (__kmp_affinity_type == affinity_default) {
5669             __kmp_affinity_type = affinity_compact;
5670             __kmp_affinity_dups = FALSE;
5671           }
5672         } else
5673 #endif /* OMP_40_ENABLED */
5674             if (__kmp_affinity_type == affinity_default) {
5675 #if OMP_40_ENABLED
5676 #if KMP_MIC_SUPPORTED
5677           if (__kmp_mic_type != non_mic) {
5678             __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5679           } else
5680 #endif
5681           {
5682             __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5683           }
5684 #endif /* OMP_40_ENABLED */
5685 #if KMP_MIC_SUPPORTED
5686           if (__kmp_mic_type != non_mic) {
5687             __kmp_affinity_type = affinity_scatter;
5688           } else
5689 #endif
5690           {
5691             __kmp_affinity_type = affinity_none;
5692           }
5693         }
5694         if ((__kmp_affinity_gran == affinity_gran_default) &&
5695             (__kmp_affinity_gran_levels < 0)) {
5696 #if KMP_MIC_SUPPORTED
5697           if (__kmp_mic_type != non_mic) {
5698             __kmp_affinity_gran = affinity_gran_fine;
5699           } else
5700 #endif
5701           {
5702             __kmp_affinity_gran = affinity_gran_core;
5703           }
5704         }
5705         if (__kmp_affinity_top_method == affinity_top_method_default) {
5706           __kmp_affinity_top_method = affinity_top_method_all;
5707         }
5708       }
5709     }
5710
5711     K_DIAG(1, ("__kmp_affinity_type         == %d\n", __kmp_affinity_type));
5712     K_DIAG(1, ("__kmp_affinity_compact      == %d\n", __kmp_affinity_compact));
5713     K_DIAG(1, ("__kmp_affinity_offset       == %d\n", __kmp_affinity_offset));
5714     K_DIAG(1, ("__kmp_affinity_verbose      == %d\n", __kmp_affinity_verbose));
5715     K_DIAG(1, ("__kmp_affinity_warnings     == %d\n", __kmp_affinity_warnings));
5716     K_DIAG(1, ("__kmp_affinity_respect_mask == %d\n",
5717                __kmp_affinity_respect_mask));
5718     K_DIAG(1, ("__kmp_affinity_gran         == %d\n", __kmp_affinity_gran));
5719
5720     KMP_DEBUG_ASSERT(__kmp_affinity_type != affinity_default);
5721 #if OMP_40_ENABLED
5722     KMP_DEBUG_ASSERT(__kmp_nested_proc_bind.bind_types[0] != proc_bind_default);
5723     K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n",
5724                __kmp_nested_proc_bind.bind_types[0]));
5725 #endif
5726   }
5727
5728 #endif /* KMP_AFFINITY_SUPPORTED */
5729
5730   if (__kmp_version) {
5731     __kmp_print_version_1();
5732   }
5733
5734   // Post-initialization step: some env. vars need their value's further
5735   // processing
5736   if (string != NULL) { // kmp_set_defaults() was called
5737     __kmp_aux_env_initialize(&block);
5738   }
5739
5740   __kmp_env_blk_free(&block);
5741
5742   KMP_MB();
5743
5744 } // __kmp_env_initialize
5745
5746 void __kmp_env_print() {
5747
5748   kmp_env_blk_t block;
5749   int i;
5750   kmp_str_buf_t buffer;
5751
5752   __kmp_stg_init();
5753   __kmp_str_buf_init(&buffer);
5754
5755   __kmp_env_blk_init(&block, NULL);
5756   __kmp_env_blk_sort(&block);
5757
5758   // Print real environment values.
5759   __kmp_str_buf_print(&buffer, "\n%s\n\n", KMP_I18N_STR(UserSettings));
5760   for (i = 0; i < block.count; ++i) {
5761     char const *name = block.vars[i].name;
5762     char const *value = block.vars[i].value;
5763     if ((KMP_STRLEN(name) > 4 && strncmp(name, "KMP_", 4) == 0) ||
5764         strncmp(name, "OMP_", 4) == 0
5765 #ifdef KMP_GOMP_COMPAT
5766         || strncmp(name, "GOMP_", 5) == 0
5767 #endif // KMP_GOMP_COMPAT
5768         ) {
5769       __kmp_str_buf_print(&buffer, "   %s=%s\n", name, value);
5770     }
5771   }
5772   __kmp_str_buf_print(&buffer, "\n");
5773
5774   // Print internal (effective) settings.
5775   __kmp_str_buf_print(&buffer, "%s\n\n", KMP_I18N_STR(EffectiveSettings));
5776   for (int i = 0; i < __kmp_stg_count; ++i) {
5777     if (__kmp_stg_table[i].print != NULL) {
5778       __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
5779                                __kmp_stg_table[i].data);
5780     }
5781   }
5782
5783   __kmp_printf("%s", buffer.str);
5784
5785   __kmp_env_blk_free(&block);
5786   __kmp_str_buf_free(&buffer);
5787
5788   __kmp_printf("\n");
5789
5790 } // __kmp_env_print
5791
5792 #if OMP_40_ENABLED
5793 void __kmp_env_print_2() {
5794
5795   kmp_env_blk_t block;
5796   kmp_str_buf_t buffer;
5797
5798   __kmp_env_format = 1;
5799
5800   __kmp_stg_init();
5801   __kmp_str_buf_init(&buffer);
5802
5803   __kmp_env_blk_init(&block, NULL);
5804   __kmp_env_blk_sort(&block);
5805
5806   __kmp_str_buf_print(&buffer, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin));
5807   __kmp_str_buf_print(&buffer, "   _OPENMP='%d'\n", __kmp_openmp_version);
5808
5809   for (int i = 0; i < __kmp_stg_count; ++i) {
5810     if (__kmp_stg_table[i].print != NULL &&
5811         ((__kmp_display_env &&
5812           strncmp(__kmp_stg_table[i].name, "OMP_", 4) == 0) ||
5813          __kmp_display_env_verbose)) {
5814       __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
5815                                __kmp_stg_table[i].data);
5816     }
5817   }
5818
5819   __kmp_str_buf_print(&buffer, "%s\n", KMP_I18N_STR(DisplayEnvEnd));
5820   __kmp_str_buf_print(&buffer, "\n");
5821
5822   __kmp_printf("%s", buffer.str);
5823
5824   __kmp_env_blk_free(&block);
5825   __kmp_str_buf_free(&buffer);
5826
5827   __kmp_printf("\n");
5828
5829 } // __kmp_env_print_2
5830 #endif // OMP_40_ENABLED
5831
5832 // end of file