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