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