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