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