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 // -----------------------------------------------------------------------------
669 // KMP_DUPLICATE_LIB_OK
670 
671 static void __kmp_stg_parse_duplicate_lib_ok(char const *name,
672  char const *value, void *data) {
673  /* actually this variable is not supported, put here for compatibility with
674  earlier builds and for static/dynamic combination */
675  __kmp_stg_parse_bool(name, value, &__kmp_duplicate_library_ok);
676 } // __kmp_stg_parse_duplicate_lib_ok
677 
678 static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t *buffer,
679  char const *name, void *data) {
680  __kmp_stg_print_bool(buffer, name, __kmp_duplicate_library_ok);
681 } // __kmp_stg_print_duplicate_lib_ok
682 
683 // -----------------------------------------------------------------------------
684 // KMP_INHERIT_FP_CONTROL
685 
686 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
687 
688 static void __kmp_stg_parse_inherit_fp_control(char const *name,
689  char const *value, void *data) {
690  __kmp_stg_parse_bool(name, value, &__kmp_inherit_fp_control);
691 } // __kmp_stg_parse_inherit_fp_control
692 
693 static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t *buffer,
694  char const *name, void *data) {
695 #if KMP_DEBUG
696  __kmp_stg_print_bool(buffer, name, __kmp_inherit_fp_control);
697 #endif /* KMP_DEBUG */
698 } // __kmp_stg_print_inherit_fp_control
699 
700 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
701 
702 // Used for OMP_WAIT_POLICY
703 static char const *blocktime_str = NULL;
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_50_ENABLED
1183 // -----------------------------------------------------------------------------
1184 // OpenMP 5.0: OMP_TARGET_OFFLOAD
1185 static void __kmp_stg_parse_target_offload(char const *name, char const *value,
1186  void *data) {
1187  const char *next = value;
1188  const char *scan = next;
1189 
1190  __kmp_target_offload = tgt_default;
1191  SKIP_WS(next);
1192  if (*next == '\0')
1193  return;
1194  scan = next;
1195  if (__kmp_match_str("MANDATORY", scan, &next)) {
1196  __kmp_target_offload = tgt_mandatory;
1197  } else if (__kmp_match_str("DISABLED", scan, &next)) {
1198  __kmp_target_offload = tgt_disabled;
1199  } else if (__kmp_match_str("DEFAULT", scan, &next)) {
1200  __kmp_target_offload = tgt_default;
1201  } else {
1202  KMP_WARNING(SyntaxErrorUsing, name, "DEFAULT");
1203  }
1204 
1205 } // __kmp_stg_parse_target_offload
1206 
1207 static void __kmp_stg_print_target_offload(kmp_str_buf_t *buffer,
1208  char const *name, void *data) {
1209  const char *value = NULL;
1210  if (__kmp_target_offload == tgt_default)
1211  value = "DEFAULT";
1212  else if (__kmp_target_offload == tgt_mandatory)
1213  value = "MANDATORY";
1214  else if (__kmp_target_offload == tgt_disabled)
1215  value = "DISABLED";
1216  if (value) {
1217  __kmp_str_buf_print(buffer, " %s=%s\n", name, value);
1218  }
1219 } // __kmp_stg_print_target_offload
1220 #endif
1221 
1222 #if OMP_45_ENABLED
1223 // -----------------------------------------------------------------------------
1224 // OpenMP 4.5: OMP_MAX_TASK_PRIORITY
1225 static void __kmp_stg_parse_max_task_priority(char const *name,
1226  char const *value, void *data) {
1227  __kmp_stg_parse_int(name, value, 0, KMP_MAX_TASK_PRIORITY_LIMIT,
1228  &__kmp_max_task_priority);
1229 } // __kmp_stg_parse_max_task_priority
1230 
1231 static void __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer,
1232  char const *name, void *data) {
1233  __kmp_stg_print_int(buffer, name, __kmp_max_task_priority);
1234 } // __kmp_stg_print_max_task_priority
1235 
1236 // KMP_TASKLOOP_MIN_TASKS
1237 // taskloop threashold to switch from recursive to linear tasks creation
1238 static void __kmp_stg_parse_taskloop_min_tasks(char const *name,
1239  char const *value, void *data) {
1240  int tmp;
1241  __kmp_stg_parse_int(name, value, 0, INT_MAX, &tmp);
1242  __kmp_taskloop_min_tasks = tmp;
1243 } // __kmp_stg_parse_taskloop_min_tasks
1244 
1245 static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t *buffer,
1246  char const *name, void *data) {
1247  __kmp_stg_print_int(buffer, name, __kmp_taskloop_min_tasks);
1248 } // __kmp_stg_print_taskloop_min_tasks
1249 #endif // OMP_45_ENABLED
1250 
1251 // -----------------------------------------------------------------------------
1252 // KMP_DISP_NUM_BUFFERS
1253 static void __kmp_stg_parse_disp_buffers(char const *name, char const *value,
1254  void *data) {
1255  if (TCR_4(__kmp_init_serial)) {
1256  KMP_WARNING(EnvSerialWarn, name);
1257  return;
1258  } // read value before serial initialization only
1259  __kmp_stg_parse_int(name, value, 1, KMP_MAX_NTH, &__kmp_dispatch_num_buffers);
1260 } // __kmp_stg_parse_disp_buffers
1261 
1262 static void __kmp_stg_print_disp_buffers(kmp_str_buf_t *buffer,
1263  char const *name, void *data) {
1264  __kmp_stg_print_int(buffer, name, __kmp_dispatch_num_buffers);
1265 } // __kmp_stg_print_disp_buffers
1266 
1267 #if KMP_NESTED_HOT_TEAMS
1268 // -----------------------------------------------------------------------------
1269 // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE
1270 
1271 static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value,
1272  void *data) {
1273  if (TCR_4(__kmp_init_parallel)) {
1274  KMP_WARNING(EnvParallelWarn, name);
1275  return;
1276  } // read value before first parallel only
1277  __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,
1278  &__kmp_hot_teams_max_level);
1279 } // __kmp_stg_parse_hot_teams_level
1280 
1281 static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t *buffer,
1282  char const *name, void *data) {
1283  __kmp_stg_print_int(buffer, name, __kmp_hot_teams_max_level);
1284 } // __kmp_stg_print_hot_teams_level
1285 
1286 static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value,
1287  void *data) {
1288  if (TCR_4(__kmp_init_parallel)) {
1289  KMP_WARNING(EnvParallelWarn, name);
1290  return;
1291  } // read value before first parallel only
1292  __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,
1293  &__kmp_hot_teams_mode);
1294 } // __kmp_stg_parse_hot_teams_mode
1295 
1296 static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t *buffer,
1297  char const *name, void *data) {
1298  __kmp_stg_print_int(buffer, name, __kmp_hot_teams_mode);
1299 } // __kmp_stg_print_hot_teams_mode
1300 
1301 #endif // KMP_NESTED_HOT_TEAMS
1302 
1303 // -----------------------------------------------------------------------------
1304 // KMP_HANDLE_SIGNALS
1305 
1306 #if KMP_HANDLE_SIGNALS
1307 
1308 static void __kmp_stg_parse_handle_signals(char const *name, char const *value,
1309  void *data) {
1310  __kmp_stg_parse_bool(name, value, &__kmp_handle_signals);
1311 } // __kmp_stg_parse_handle_signals
1312 
1313 static void __kmp_stg_print_handle_signals(kmp_str_buf_t *buffer,
1314  char const *name, void *data) {
1315  __kmp_stg_print_bool(buffer, name, __kmp_handle_signals);
1316 } // __kmp_stg_print_handle_signals
1317 
1318 #endif // KMP_HANDLE_SIGNALS
1319 
1320 // -----------------------------------------------------------------------------
1321 // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG
1322 
1323 #ifdef KMP_DEBUG
1324 
1325 #define KMP_STG_X_DEBUG(x) \
1326  static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \
1327  void *data) { \
1328  __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug); \
1329  } /* __kmp_stg_parse_x_debug */ \
1330  static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer, \
1331  char const *name, void *data) { \
1332  __kmp_stg_print_int(buffer, name, kmp_##x##_debug); \
1333  } /* __kmp_stg_print_x_debug */
1334 
1335 KMP_STG_X_DEBUG(a)
1336 KMP_STG_X_DEBUG(b)
1337 KMP_STG_X_DEBUG(c)
1338 KMP_STG_X_DEBUG(d)
1339 KMP_STG_X_DEBUG(e)
1340 KMP_STG_X_DEBUG(f)
1341 
1342 #undef KMP_STG_X_DEBUG
1343 
1344 static void __kmp_stg_parse_debug(char const *name, char const *value,
1345  void *data) {
1346  int debug = 0;
1347  __kmp_stg_parse_int(name, value, 0, INT_MAX, &debug);
1348  if (kmp_a_debug < debug) {
1349  kmp_a_debug = debug;
1350  }
1351  if (kmp_b_debug < debug) {
1352  kmp_b_debug = debug;
1353  }
1354  if (kmp_c_debug < debug) {
1355  kmp_c_debug = debug;
1356  }
1357  if (kmp_d_debug < debug) {
1358  kmp_d_debug = debug;
1359  }
1360  if (kmp_e_debug < debug) {
1361  kmp_e_debug = debug;
1362  }
1363  if (kmp_f_debug < debug) {
1364  kmp_f_debug = debug;
1365  }
1366 } // __kmp_stg_parse_debug
1367 
1368 static void __kmp_stg_parse_debug_buf(char const *name, char const *value,
1369  void *data) {
1370  __kmp_stg_parse_bool(name, value, &__kmp_debug_buf);
1371  // !!! TODO: Move buffer initialization of of this file! It may works
1372  // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or
1373  // KMP_DEBUG_BUF_CHARS.
1374  if (__kmp_debug_buf) {
1375  int i;
1376  int elements = __kmp_debug_buf_lines * __kmp_debug_buf_chars;
1377 
1378  /* allocate and initialize all entries in debug buffer to empty */
1379  __kmp_debug_buffer = (char *)__kmp_page_allocate(elements * sizeof(char));
1380  for (i = 0; i < elements; i += __kmp_debug_buf_chars)
1381  __kmp_debug_buffer[i] = '\0';
1382 
1383  __kmp_debug_count = 0;
1384  }
1385  K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf));
1386 } // __kmp_stg_parse_debug_buf
1387 
1388 static void __kmp_stg_print_debug_buf(kmp_str_buf_t *buffer, char const *name,
1389  void *data) {
1390  __kmp_stg_print_bool(buffer, name, __kmp_debug_buf);
1391 } // __kmp_stg_print_debug_buf
1392 
1393 static void __kmp_stg_parse_debug_buf_atomic(char const *name,
1394  char const *value, void *data) {
1395  __kmp_stg_parse_bool(name, value, &__kmp_debug_buf_atomic);
1396 } // __kmp_stg_parse_debug_buf_atomic
1397 
1398 static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t *buffer,
1399  char const *name, void *data) {
1400  __kmp_stg_print_bool(buffer, name, __kmp_debug_buf_atomic);
1401 } // __kmp_stg_print_debug_buf_atomic
1402 
1403 static void __kmp_stg_parse_debug_buf_chars(char const *name, char const *value,
1404  void *data) {
1405  __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_CHARS_MIN, INT_MAX,
1406  &__kmp_debug_buf_chars);
1407 } // __kmp_stg_debug_parse_buf_chars
1408 
1409 static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t *buffer,
1410  char const *name, void *data) {
1411  __kmp_stg_print_int(buffer, name, __kmp_debug_buf_chars);
1412 } // __kmp_stg_print_debug_buf_chars
1413 
1414 static void __kmp_stg_parse_debug_buf_lines(char const *name, char const *value,
1415  void *data) {
1416  __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_LINES_MIN, INT_MAX,
1417  &__kmp_debug_buf_lines);
1418 } // __kmp_stg_parse_debug_buf_lines
1419 
1420 static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t *buffer,
1421  char const *name, void *data) {
1422  __kmp_stg_print_int(buffer, name, __kmp_debug_buf_lines);
1423 } // __kmp_stg_print_debug_buf_lines
1424 
1425 static void __kmp_stg_parse_diag(char const *name, char const *value,
1426  void *data) {
1427  __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_diag);
1428 } // __kmp_stg_parse_diag
1429 
1430 static void __kmp_stg_print_diag(kmp_str_buf_t *buffer, char const *name,
1431  void *data) {
1432  __kmp_stg_print_int(buffer, name, kmp_diag);
1433 } // __kmp_stg_print_diag
1434 
1435 #endif // KMP_DEBUG
1436 
1437 // -----------------------------------------------------------------------------
1438 // KMP_ALIGN_ALLOC
1439 
1440 static void __kmp_stg_parse_align_alloc(char const *name, char const *value,
1441  void *data) {
1442  __kmp_stg_parse_size(name, value, CACHE_LINE, INT_MAX, NULL,
1443  &__kmp_align_alloc, 1);
1444 } // __kmp_stg_parse_align_alloc
1445 
1446 static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name,
1447  void *data) {
1448  __kmp_stg_print_size(buffer, name, __kmp_align_alloc);
1449 } // __kmp_stg_print_align_alloc
1450 
1451 // -----------------------------------------------------------------------------
1452 // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER
1453 
1454 // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from
1455 // parse and print functions, pass required info through data argument.
1456 
1457 static void __kmp_stg_parse_barrier_branch_bit(char const *name,
1458  char const *value, void *data) {
1459  const char *var;
1460 
1461  /* ---------- Barrier branch bit control ------------ */
1462  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1463  var = __kmp_barrier_branch_bit_env_name[i];
1464  if ((strcmp(var, name) == 0) && (value != 0)) {
1465  char *comma;
1466 
1467  comma = CCAST(char *, strchr(value, ','));
1468  __kmp_barrier_gather_branch_bits[i] =
1469  (kmp_uint32)__kmp_str_to_int(value, ',');
1470  /* is there a specified release parameter? */
1471  if (comma == NULL) {
1472  __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;
1473  } else {
1474  __kmp_barrier_release_branch_bits[i] =
1475  (kmp_uint32)__kmp_str_to_int(comma + 1, 0);
1476 
1477  if (__kmp_barrier_release_branch_bits[i] > KMP_MAX_BRANCH_BITS) {
1478  __kmp_msg(kmp_ms_warning,
1479  KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
1480  __kmp_msg_null);
1481  __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;
1482  }
1483  }
1484  if (__kmp_barrier_gather_branch_bits[i] > KMP_MAX_BRANCH_BITS) {
1485  KMP_WARNING(BarrGatherValueInvalid, name, value);
1486  KMP_INFORM(Using_uint_Value, name, __kmp_barrier_gather_bb_dflt);
1487  __kmp_barrier_gather_branch_bits[i] = __kmp_barrier_gather_bb_dflt;
1488  }
1489  }
1490  K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[i],
1491  __kmp_barrier_gather_branch_bits[i],
1492  __kmp_barrier_release_branch_bits[i]))
1493  }
1494 } // __kmp_stg_parse_barrier_branch_bit
1495 
1496 static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t *buffer,
1497  char const *name, void *data) {
1498  const char *var;
1499  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1500  var = __kmp_barrier_branch_bit_env_name[i];
1501  if (strcmp(var, name) == 0) {
1502  if (__kmp_env_format) {
1503  KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name[i]);
1504  } else {
1505  __kmp_str_buf_print(buffer, " %s='",
1506  __kmp_barrier_branch_bit_env_name[i]);
1507  }
1508  __kmp_str_buf_print(buffer, "%d,%d'\n",
1509  __kmp_barrier_gather_branch_bits[i],
1510  __kmp_barrier_release_branch_bits[i]);
1511  }
1512  }
1513 } // __kmp_stg_print_barrier_branch_bit
1514 
1515 // ----------------------------------------------------------------------------
1516 // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN,
1517 // KMP_REDUCTION_BARRIER_PATTERN
1518 
1519 // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and
1520 // print functions, pass required data to functions through data argument.
1521 
1522 static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value,
1523  void *data) {
1524  const char *var;
1525  /* ---------- Barrier method control ------------ */
1526 
1527  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1528  var = __kmp_barrier_pattern_env_name[i];
1529 
1530  if ((strcmp(var, name) == 0) && (value != 0)) {
1531  int j;
1532  char *comma = CCAST(char *, strchr(value, ','));
1533 
1534  /* handle first parameter: gather pattern */
1535  for (j = bp_linear_bar; j < bp_last_bar; j++) {
1536  if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name[j], value, 1,
1537  ',')) {
1538  __kmp_barrier_gather_pattern[i] = (kmp_bar_pat_e)j;
1539  break;
1540  }
1541  }
1542  if (j == bp_last_bar) {
1543  KMP_WARNING(BarrGatherValueInvalid, name, value);
1544  KMP_INFORM(Using_str_Value, name,
1545  __kmp_barrier_pattern_name[bp_linear_bar]);
1546  }
1547 
1548  /* handle second parameter: release pattern */
1549  if (comma != NULL) {
1550  for (j = bp_linear_bar; j < bp_last_bar; j++) {
1551  if (__kmp_str_match(__kmp_barrier_pattern_name[j], 1, comma + 1)) {
1552  __kmp_barrier_release_pattern[i] = (kmp_bar_pat_e)j;
1553  break;
1554  }
1555  }
1556  if (j == bp_last_bar) {
1557  __kmp_msg(kmp_ms_warning,
1558  KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),
1559  __kmp_msg_null);
1560  KMP_INFORM(Using_str_Value, name,
1561  __kmp_barrier_pattern_name[bp_linear_bar]);
1562  }
1563  }
1564  }
1565  }
1566 } // __kmp_stg_parse_barrier_pattern
1567 
1568 static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t *buffer,
1569  char const *name, void *data) {
1570  const char *var;
1571  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {
1572  var = __kmp_barrier_pattern_env_name[i];
1573  if (strcmp(var, name) == 0) {
1574  int j = __kmp_barrier_gather_pattern[i];
1575  int k = __kmp_barrier_release_pattern[i];
1576  if (__kmp_env_format) {
1577  KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name[i]);
1578  } else {
1579  __kmp_str_buf_print(buffer, " %s='",
1580  __kmp_barrier_pattern_env_name[i]);
1581  }
1582  __kmp_str_buf_print(buffer, "%s,%s'\n", __kmp_barrier_pattern_name[j],
1583  __kmp_barrier_pattern_name[k]);
1584  }
1585  }
1586 } // __kmp_stg_print_barrier_pattern
1587 
1588 // -----------------------------------------------------------------------------
1589 // KMP_ABORT_DELAY
1590 
1591 static void __kmp_stg_parse_abort_delay(char const *name, char const *value,
1592  void *data) {
1593  // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is
1594  // milliseconds.
1595  int delay = __kmp_abort_delay / 1000;
1596  __kmp_stg_parse_int(name, value, 0, INT_MAX / 1000, &delay);
1597  __kmp_abort_delay = delay * 1000;
1598 } // __kmp_stg_parse_abort_delay
1599 
1600 static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name,
1601  void *data) {
1602  __kmp_stg_print_int(buffer, name, __kmp_abort_delay);
1603 } // __kmp_stg_print_abort_delay
1604 
1605 // -----------------------------------------------------------------------------
1606 // KMP_CPUINFO_FILE
1607 
1608 static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value,
1609  void *data) {
1610 #if KMP_AFFINITY_SUPPORTED
1611  __kmp_stg_parse_str(name, value, &__kmp_cpuinfo_file);
1612  K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file));
1613 #endif
1614 } //__kmp_stg_parse_cpuinfo_file
1615 
1616 static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t *buffer,
1617  char const *name, void *data) {
1618 #if KMP_AFFINITY_SUPPORTED
1619  if (__kmp_env_format) {
1620  KMP_STR_BUF_PRINT_NAME;
1621  } else {
1622  __kmp_str_buf_print(buffer, " %s", name);
1623  }
1624  if (__kmp_cpuinfo_file) {
1625  __kmp_str_buf_print(buffer, "='%s'\n", __kmp_cpuinfo_file);
1626  } else {
1627  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1628  }
1629 #endif
1630 } //__kmp_stg_print_cpuinfo_file
1631 
1632 // -----------------------------------------------------------------------------
1633 // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION
1634 
1635 static void __kmp_stg_parse_force_reduction(char const *name, char const *value,
1636  void *data) {
1637  kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;
1638  int rc;
1639 
1640  rc = __kmp_stg_check_rivals(name, value, reduction->rivals);
1641  if (rc) {
1642  return;
1643  }
1644  if (reduction->force) {
1645  if (value != 0) {
1646  if (__kmp_str_match("critical", 0, value))
1647  __kmp_force_reduction_method = critical_reduce_block;
1648  else if (__kmp_str_match("atomic", 0, value))
1649  __kmp_force_reduction_method = atomic_reduce_block;
1650  else if (__kmp_str_match("tree", 0, value))
1651  __kmp_force_reduction_method = tree_reduce_block;
1652  else {
1653  KMP_FATAL(UnknownForceReduction, name, value);
1654  }
1655  }
1656  } else {
1657  __kmp_stg_parse_bool(name, value, &__kmp_determ_red);
1658  if (__kmp_determ_red) {
1659  __kmp_force_reduction_method = tree_reduce_block;
1660  } else {
1661  __kmp_force_reduction_method = reduction_method_not_defined;
1662  }
1663  }
1664  K_DIAG(1, ("__kmp_force_reduction_method == %d\n",
1665  __kmp_force_reduction_method));
1666 } // __kmp_stg_parse_force_reduction
1667 
1668 static void __kmp_stg_print_force_reduction(kmp_str_buf_t *buffer,
1669  char const *name, void *data) {
1670 
1671  kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;
1672  if (reduction->force) {
1673  if (__kmp_force_reduction_method == critical_reduce_block) {
1674  __kmp_stg_print_str(buffer, name, "critical");
1675  } else if (__kmp_force_reduction_method == atomic_reduce_block) {
1676  __kmp_stg_print_str(buffer, name, "atomic");
1677  } else if (__kmp_force_reduction_method == tree_reduce_block) {
1678  __kmp_stg_print_str(buffer, name, "tree");
1679  } else {
1680  if (__kmp_env_format) {
1681  KMP_STR_BUF_PRINT_NAME;
1682  } else {
1683  __kmp_str_buf_print(buffer, " %s", name);
1684  }
1685  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
1686  }
1687  } else {
1688  __kmp_stg_print_bool(buffer, name, __kmp_determ_red);
1689  }
1690 
1691 } // __kmp_stg_print_force_reduction
1692 
1693 // -----------------------------------------------------------------------------
1694 // KMP_STORAGE_MAP
1695 
1696 static void __kmp_stg_parse_storage_map(char const *name, char const *value,
1697  void *data) {
1698  if (__kmp_str_match("verbose", 1, value)) {
1699  __kmp_storage_map = TRUE;
1700  __kmp_storage_map_verbose = TRUE;
1701  __kmp_storage_map_verbose_specified = TRUE;
1702 
1703  } else {
1704  __kmp_storage_map_verbose = FALSE;
1705  __kmp_stg_parse_bool(name, value, &__kmp_storage_map); // !!!
1706  }
1707 } // __kmp_stg_parse_storage_map
1708 
1709 static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name,
1710  void *data) {
1711  if (__kmp_storage_map_verbose || __kmp_storage_map_verbose_specified) {
1712  __kmp_stg_print_str(buffer, name, "verbose");
1713  } else {
1714  __kmp_stg_print_bool(buffer, name, __kmp_storage_map);
1715  }
1716 } // __kmp_stg_print_storage_map
1717 
1718 // -----------------------------------------------------------------------------
1719 // KMP_ALL_THREADPRIVATE
1720 
1721 static void __kmp_stg_parse_all_threadprivate(char const *name,
1722  char const *value, void *data) {
1723  __kmp_stg_parse_int(name, value,
1724  __kmp_allThreadsSpecified ? __kmp_max_nth : 1,
1725  __kmp_max_nth, &__kmp_tp_capacity);
1726 } // __kmp_stg_parse_all_threadprivate
1727 
1728 static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t *buffer,
1729  char const *name, void *data) {
1730  __kmp_stg_print_int(buffer, name, __kmp_tp_capacity);
1731 }
1732 
1733 // -----------------------------------------------------------------------------
1734 // KMP_FOREIGN_THREADS_THREADPRIVATE
1735 
1736 static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name,
1737  char const *value,
1738  void *data) {
1739  __kmp_stg_parse_bool(name, value, &__kmp_foreign_tp);
1740 } // __kmp_stg_parse_foreign_threads_threadprivate
1741 
1742 static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t *buffer,
1743  char const *name,
1744  void *data) {
1745  __kmp_stg_print_bool(buffer, name, __kmp_foreign_tp);
1746 } // __kmp_stg_print_foreign_threads_threadprivate
1747 
1748 // -----------------------------------------------------------------------------
1749 // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD
1750 
1751 #if KMP_AFFINITY_SUPPORTED
1752 // Parse the proc id list. Return TRUE if successful, FALSE otherwise.
1753 static int __kmp_parse_affinity_proc_id_list(const char *var, const char *env,
1754  const char **nextEnv,
1755  char **proclist) {
1756  const char *scan = env;
1757  const char *next = scan;
1758  int empty = TRUE;
1759 
1760  *proclist = NULL;
1761 
1762  for (;;) {
1763  int start, end, stride;
1764 
1765  SKIP_WS(scan);
1766  next = scan;
1767  if (*next == '\0') {
1768  break;
1769  }
1770 
1771  if (*next == '{') {
1772  int num;
1773  next++; // skip '{'
1774  SKIP_WS(next);
1775  scan = next;
1776 
1777  // Read the first integer in the set.
1778  if ((*next < '0') || (*next > '9')) {
1779  KMP_WARNING(AffSyntaxError, var);
1780  return FALSE;
1781  }
1782  SKIP_DIGITS(next);
1783  num = __kmp_str_to_int(scan, *next);
1784  KMP_ASSERT(num >= 0);
1785 
1786  for (;;) {
1787  // Check for end of set.
1788  SKIP_WS(next);
1789  if (*next == '}') {
1790  next++; // skip '}'
1791  break;
1792  }
1793 
1794  // Skip optional comma.
1795  if (*next == ',') {
1796  next++;
1797  }
1798  SKIP_WS(next);
1799 
1800  // Read the next integer in the set.
1801  scan = next;
1802  if ((*next < '0') || (*next > '9')) {
1803  KMP_WARNING(AffSyntaxError, var);
1804  return FALSE;
1805  }
1806 
1807  SKIP_DIGITS(next);
1808  num = __kmp_str_to_int(scan, *next);
1809  KMP_ASSERT(num >= 0);
1810  }
1811  empty = FALSE;
1812 
1813  SKIP_WS(next);
1814  if (*next == ',') {
1815  next++;
1816  }
1817  scan = next;
1818  continue;
1819  }
1820 
1821  // Next character is not an integer => end of list
1822  if ((*next < '0') || (*next > '9')) {
1823  if (empty) {
1824  KMP_WARNING(AffSyntaxError, var);
1825  return FALSE;
1826  }
1827  break;
1828  }
1829 
1830  // Read the first integer.
1831  SKIP_DIGITS(next);
1832  start = __kmp_str_to_int(scan, *next);
1833  KMP_ASSERT(start >= 0);
1834  SKIP_WS(next);
1835 
1836  // If this isn't a range, then go on.
1837  if (*next != '-') {
1838  empty = FALSE;
1839 
1840  // Skip optional comma.
1841  if (*next == ',') {
1842  next++;
1843  }
1844  scan = next;
1845  continue;
1846  }
1847 
1848  // This is a range. Skip over the '-' and read in the 2nd int.
1849  next++; // skip '-'
1850  SKIP_WS(next);
1851  scan = next;
1852  if ((*next < '0') || (*next > '9')) {
1853  KMP_WARNING(AffSyntaxError, var);
1854  return FALSE;
1855  }
1856  SKIP_DIGITS(next);
1857  end = __kmp_str_to_int(scan, *next);
1858  KMP_ASSERT(end >= 0);
1859 
1860  // Check for a stride parameter
1861  stride = 1;
1862  SKIP_WS(next);
1863  if (*next == ':') {
1864  // A stride is specified. Skip over the ':" and read the 3rd int.
1865  int sign = +1;
1866  next++; // skip ':'
1867  SKIP_WS(next);
1868  scan = next;
1869  if (*next == '-') {
1870  sign = -1;
1871  next++;
1872  SKIP_WS(next);
1873  scan = next;
1874  }
1875  if ((*next < '0') || (*next > '9')) {
1876  KMP_WARNING(AffSyntaxError, var);
1877  return FALSE;
1878  }
1879  SKIP_DIGITS(next);
1880  stride = __kmp_str_to_int(scan, *next);
1881  KMP_ASSERT(stride >= 0);
1882  stride *= sign;
1883  }
1884 
1885  // Do some range checks.
1886  if (stride == 0) {
1887  KMP_WARNING(AffZeroStride, var);
1888  return FALSE;
1889  }
1890  if (stride > 0) {
1891  if (start > end) {
1892  KMP_WARNING(AffStartGreaterEnd, var, start, end);
1893  return FALSE;
1894  }
1895  } else {
1896  if (start < end) {
1897  KMP_WARNING(AffStrideLessZero, var, start, end);
1898  return FALSE;
1899  }
1900  }
1901  if ((end - start) / stride > 65536) {
1902  KMP_WARNING(AffRangeTooBig, var, end, start, stride);
1903  return FALSE;
1904  }
1905 
1906  empty = FALSE;
1907 
1908  // Skip optional comma.
1909  SKIP_WS(next);
1910  if (*next == ',') {
1911  next++;
1912  }
1913  scan = next;
1914  }
1915 
1916  *nextEnv = next;
1917 
1918  {
1919  int len = next - env;
1920  char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
1921  KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
1922  retlist[len] = '\0';
1923  *proclist = retlist;
1924  }
1925  return TRUE;
1926 }
1927 
1928 // If KMP_AFFINITY is specified without a type, then
1929 // __kmp_affinity_notype should point to its setting.
1930 static kmp_setting_t *__kmp_affinity_notype = NULL;
1931 
1932 static void __kmp_parse_affinity_env(char const *name, char const *value,
1933  enum affinity_type *out_type,
1934  char **out_proclist, int *out_verbose,
1935  int *out_warn, int *out_respect,
1936  enum affinity_gran *out_gran,
1937  int *out_gran_levels, int *out_dups,
1938  int *out_compact, int *out_offset) {
1939  char *buffer = NULL; // Copy of env var value.
1940  char *buf = NULL; // Buffer for strtok_r() function.
1941  char *next = NULL; // end of token / start of next.
1942  const char *start; // start of current token (for err msgs)
1943  int count = 0; // Counter of parsed integer numbers.
1944  int number[2]; // Parsed numbers.
1945 
1946  // Guards.
1947  int type = 0;
1948  int proclist = 0;
1949  int max_proclist = 0;
1950  int verbose = 0;
1951  int warnings = 0;
1952  int respect = 0;
1953  int gran = 0;
1954  int dups = 0;
1955 
1956  KMP_ASSERT(value != NULL);
1957 
1958  if (TCR_4(__kmp_init_middle)) {
1959  KMP_WARNING(EnvMiddleWarn, name);
1960  __kmp_env_toPrint(name, 0);
1961  return;
1962  }
1963  __kmp_env_toPrint(name, 1);
1964 
1965  buffer =
1966  __kmp_str_format("%s", value); // Copy env var to keep original intact.
1967  buf = buffer;
1968  SKIP_WS(buf);
1969 
1970 // Helper macros.
1971 
1972 // If we see a parse error, emit a warning and scan to the next ",".
1973 //
1974 // FIXME - there's got to be a better way to print an error
1975 // message, hopefully without overwritting peices of buf.
1976 #define EMIT_WARN(skip, errlist) \
1977  { \
1978  char ch; \
1979  if (skip) { \
1980  SKIP_TO(next, ','); \
1981  } \
1982  ch = *next; \
1983  *next = '\0'; \
1984  KMP_WARNING errlist; \
1985  *next = ch; \
1986  if (skip) { \
1987  if (ch == ',') \
1988  next++; \
1989  } \
1990  buf = next; \
1991  }
1992 
1993 #define _set_param(_guard, _var, _val) \
1994  { \
1995  if (_guard == 0) { \
1996  _var = _val; \
1997  } else { \
1998  EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
1999  } \
2000  ++_guard; \
2001  }
2002 
2003 #define set_type(val) _set_param(type, *out_type, val)
2004 #define set_verbose(val) _set_param(verbose, *out_verbose, val)
2005 #define set_warnings(val) _set_param(warnings, *out_warn, val)
2006 #define set_respect(val) _set_param(respect, *out_respect, val)
2007 #define set_dups(val) _set_param(dups, *out_dups, val)
2008 #define set_proclist(val) _set_param(proclist, *out_proclist, val)
2009 
2010 #define set_gran(val, levels) \
2011  { \
2012  if (gran == 0) { \
2013  *out_gran = val; \
2014  *out_gran_levels = levels; \
2015  } else { \
2016  EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
2017  } \
2018  ++gran; \
2019  }
2020 
2021 #if OMP_40_ENABLED
2022  KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
2023  (__kmp_nested_proc_bind.used > 0));
2024 #endif
2025 
2026  while (*buf != '\0') {
2027  start = next = buf;
2028 
2029  if (__kmp_match_str("none", buf, CCAST(const char **, &next))) {
2030  set_type(affinity_none);
2031 #if OMP_40_ENABLED
2032  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
2033 #endif
2034  buf = next;
2035  } else if (__kmp_match_str("scatter", buf, CCAST(const char **, &next))) {
2036  set_type(affinity_scatter);
2037 #if OMP_40_ENABLED
2038  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2039 #endif
2040  buf = next;
2041  } else if (__kmp_match_str("compact", buf, CCAST(const char **, &next))) {
2042  set_type(affinity_compact);
2043 #if OMP_40_ENABLED
2044  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2045 #endif
2046  buf = next;
2047  } else if (__kmp_match_str("logical", buf, CCAST(const char **, &next))) {
2048  set_type(affinity_logical);
2049 #if OMP_40_ENABLED
2050  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2051 #endif
2052  buf = next;
2053  } else if (__kmp_match_str("physical", buf, CCAST(const char **, &next))) {
2054  set_type(affinity_physical);
2055 #if OMP_40_ENABLED
2056  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2057 #endif
2058  buf = next;
2059  } else if (__kmp_match_str("explicit", buf, CCAST(const char **, &next))) {
2060  set_type(affinity_explicit);
2061 #if OMP_40_ENABLED
2062  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2063 #endif
2064  buf = next;
2065  } else if (__kmp_match_str("balanced", buf, CCAST(const char **, &next))) {
2066  set_type(affinity_balanced);
2067 #if OMP_40_ENABLED
2068  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2069 #endif
2070  buf = next;
2071  } else if (__kmp_match_str("disabled", buf, CCAST(const char **, &next))) {
2072  set_type(affinity_disabled);
2073 #if OMP_40_ENABLED
2074  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
2075 #endif
2076  buf = next;
2077  } else if (__kmp_match_str("verbose", buf, CCAST(const char **, &next))) {
2078  set_verbose(TRUE);
2079  buf = next;
2080  } else if (__kmp_match_str("noverbose", buf, CCAST(const char **, &next))) {
2081  set_verbose(FALSE);
2082  buf = next;
2083  } else if (__kmp_match_str("warnings", buf, CCAST(const char **, &next))) {
2084  set_warnings(TRUE);
2085  buf = next;
2086  } else if (__kmp_match_str("nowarnings", buf,
2087  CCAST(const char **, &next))) {
2088  set_warnings(FALSE);
2089  buf = next;
2090  } else if (__kmp_match_str("respect", buf, CCAST(const char **, &next))) {
2091  set_respect(TRUE);
2092  buf = next;
2093  } else if (__kmp_match_str("norespect", buf, CCAST(const char **, &next))) {
2094  set_respect(FALSE);
2095  buf = next;
2096  } else if (__kmp_match_str("duplicates", buf,
2097  CCAST(const char **, &next)) ||
2098  __kmp_match_str("dups", buf, CCAST(const char **, &next))) {
2099  set_dups(TRUE);
2100  buf = next;
2101  } else if (__kmp_match_str("noduplicates", buf,
2102  CCAST(const char **, &next)) ||
2103  __kmp_match_str("nodups", buf, CCAST(const char **, &next))) {
2104  set_dups(FALSE);
2105  buf = next;
2106  } else if (__kmp_match_str("granularity", buf,
2107  CCAST(const char **, &next)) ||
2108  __kmp_match_str("gran", buf, CCAST(const char **, &next))) {
2109  SKIP_WS(next);
2110  if (*next != '=') {
2111  EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2112  continue;
2113  }
2114  next++; // skip '='
2115  SKIP_WS(next);
2116 
2117  buf = next;
2118  if (__kmp_match_str("fine", buf, CCAST(const char **, &next))) {
2119  set_gran(affinity_gran_fine, -1);
2120  buf = next;
2121  } else if (__kmp_match_str("thread", buf, CCAST(const char **, &next))) {
2122  set_gran(affinity_gran_thread, -1);
2123  buf = next;
2124  } else if (__kmp_match_str("core", buf, CCAST(const char **, &next))) {
2125  set_gran(affinity_gran_core, -1);
2126  buf = next;
2127 #if KMP_USE_HWLOC
2128  } else if (__kmp_match_str("tile", buf, CCAST(const char **, &next))) {
2129  set_gran(affinity_gran_tile, -1);
2130  buf = next;
2131 #endif
2132  } else if (__kmp_match_str("package", buf, CCAST(const char **, &next))) {
2133  set_gran(affinity_gran_package, -1);
2134  buf = next;
2135  } else if (__kmp_match_str("node", buf, CCAST(const char **, &next))) {
2136  set_gran(affinity_gran_node, -1);
2137  buf = next;
2138 #if KMP_GROUP_AFFINITY
2139  } else if (__kmp_match_str("group", buf, CCAST(const char **, &next))) {
2140  set_gran(affinity_gran_group, -1);
2141  buf = next;
2142 #endif /* KMP_GROUP AFFINITY */
2143  } else if ((*buf >= '0') && (*buf <= '9')) {
2144  int n;
2145  next = buf;
2146  SKIP_DIGITS(next);
2147  n = __kmp_str_to_int(buf, *next);
2148  KMP_ASSERT(n >= 0);
2149  buf = next;
2150  set_gran(affinity_gran_default, n);
2151  } else {
2152  EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2153  continue;
2154  }
2155  } else if (__kmp_match_str("proclist", buf, CCAST(const char **, &next))) {
2156  char *temp_proclist;
2157 
2158  SKIP_WS(next);
2159  if (*next != '=') {
2160  EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2161  continue;
2162  }
2163  next++; // skip '='
2164  SKIP_WS(next);
2165  if (*next != '[') {
2166  EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2167  continue;
2168  }
2169  next++; // skip '['
2170  buf = next;
2171  if (!__kmp_parse_affinity_proc_id_list(
2172  name, buf, CCAST(const char **, &next), &temp_proclist)) {
2173  // warning already emitted.
2174  SKIP_TO(next, ']');
2175  if (*next == ']')
2176  next++;
2177  SKIP_TO(next, ',');
2178  if (*next == ',')
2179  next++;
2180  buf = next;
2181  continue;
2182  }
2183  if (*next != ']') {
2184  EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2185  continue;
2186  }
2187  next++; // skip ']'
2188  set_proclist(temp_proclist);
2189  } else if ((*buf >= '0') && (*buf <= '9')) {
2190  // Parse integer numbers -- permute and offset.
2191  int n;
2192  next = buf;
2193  SKIP_DIGITS(next);
2194  n = __kmp_str_to_int(buf, *next);
2195  KMP_ASSERT(n >= 0);
2196  buf = next;
2197  if (count < 2) {
2198  number[count] = n;
2199  } else {
2200  KMP_WARNING(AffManyParams, name, start);
2201  }
2202  ++count;
2203  } else {
2204  EMIT_WARN(TRUE, (AffInvalidParam, name, start));
2205  continue;
2206  }
2207 
2208  SKIP_WS(next);
2209  if (*next == ',') {
2210  next++;
2211  SKIP_WS(next);
2212  } else if (*next != '\0') {
2213  const char *temp = next;
2214  EMIT_WARN(TRUE, (ParseExtraCharsWarn, name, temp));
2215  continue;
2216  }
2217  buf = next;
2218  } // while
2219 
2220 #undef EMIT_WARN
2221 #undef _set_param
2222 #undef set_type
2223 #undef set_verbose
2224 #undef set_warnings
2225 #undef set_respect
2226 #undef set_granularity
2227 
2228  __kmp_str_free(&buffer);
2229 
2230  if (proclist) {
2231  if (!type) {
2232  KMP_WARNING(AffProcListNoType, name);
2233  *out_type = affinity_explicit;
2234 #if OMP_40_ENABLED
2235  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2236 #endif
2237  } else if (*out_type != affinity_explicit) {
2238  KMP_WARNING(AffProcListNotExplicit, name);
2239  KMP_ASSERT(*out_proclist != NULL);
2240  KMP_INTERNAL_FREE(*out_proclist);
2241  *out_proclist = NULL;
2242  }
2243  }
2244  switch (*out_type) {
2245  case affinity_logical:
2246  case affinity_physical: {
2247  if (count > 0) {
2248  *out_offset = number[0];
2249  }
2250  if (count > 1) {
2251  KMP_WARNING(AffManyParamsForLogic, name, number[1]);
2252  }
2253  } break;
2254  case affinity_balanced: {
2255  if (count > 0) {
2256  *out_compact = number[0];
2257  }
2258  if (count > 1) {
2259  *out_offset = number[1];
2260  }
2261 
2262  if (__kmp_affinity_gran == affinity_gran_default) {
2263 #if KMP_MIC_SUPPORTED
2264  if (__kmp_mic_type != non_mic) {
2265  if (__kmp_affinity_verbose || __kmp_affinity_warnings) {
2266  KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "fine");
2267  }
2268  __kmp_affinity_gran = affinity_gran_fine;
2269  } else
2270 #endif
2271  {
2272  if (__kmp_affinity_verbose || __kmp_affinity_warnings) {
2273  KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "core");
2274  }
2275  __kmp_affinity_gran = affinity_gran_core;
2276  }
2277  }
2278  } break;
2279  case affinity_scatter:
2280  case affinity_compact: {
2281  if (count > 0) {
2282  *out_compact = number[0];
2283  }
2284  if (count > 1) {
2285  *out_offset = number[1];
2286  }
2287  } break;
2288  case affinity_explicit: {
2289  if (*out_proclist == NULL) {
2290  KMP_WARNING(AffNoProcList, name);
2291  __kmp_affinity_type = affinity_none;
2292  }
2293  if (count > 0) {
2294  KMP_WARNING(AffNoParam, name, "explicit");
2295  }
2296  } break;
2297  case affinity_none: {
2298  if (count > 0) {
2299  KMP_WARNING(AffNoParam, name, "none");
2300  }
2301  } break;
2302  case affinity_disabled: {
2303  if (count > 0) {
2304  KMP_WARNING(AffNoParam, name, "disabled");
2305  }
2306  } break;
2307  case affinity_default: {
2308  if (count > 0) {
2309  KMP_WARNING(AffNoParam, name, "default");
2310  }
2311  } break;
2312  default: { KMP_ASSERT(0); }
2313  }
2314 } // __kmp_parse_affinity_env
2315 
2316 static void __kmp_stg_parse_affinity(char const *name, char const *value,
2317  void *data) {
2318  kmp_setting_t **rivals = (kmp_setting_t **)data;
2319  int rc;
2320 
2321  rc = __kmp_stg_check_rivals(name, value, rivals);
2322  if (rc) {
2323  return;
2324  }
2325 
2326  __kmp_parse_affinity_env(name, value, &__kmp_affinity_type,
2327  &__kmp_affinity_proclist, &__kmp_affinity_verbose,
2328  &__kmp_affinity_warnings,
2329  &__kmp_affinity_respect_mask, &__kmp_affinity_gran,
2330  &__kmp_affinity_gran_levels, &__kmp_affinity_dups,
2331  &__kmp_affinity_compact, &__kmp_affinity_offset);
2332 
2333 } // __kmp_stg_parse_affinity
2334 
2335 static void __kmp_stg_print_affinity(kmp_str_buf_t *buffer, char const *name,
2336  void *data) {
2337  if (__kmp_env_format) {
2338  KMP_STR_BUF_PRINT_NAME_EX(name);
2339  } else {
2340  __kmp_str_buf_print(buffer, " %s='", name);
2341  }
2342  if (__kmp_affinity_verbose) {
2343  __kmp_str_buf_print(buffer, "%s,", "verbose");
2344  } else {
2345  __kmp_str_buf_print(buffer, "%s,", "noverbose");
2346  }
2347  if (__kmp_affinity_warnings) {
2348  __kmp_str_buf_print(buffer, "%s,", "warnings");
2349  } else {
2350  __kmp_str_buf_print(buffer, "%s,", "nowarnings");
2351  }
2352  if (KMP_AFFINITY_CAPABLE()) {
2353  if (__kmp_affinity_respect_mask) {
2354  __kmp_str_buf_print(buffer, "%s,", "respect");
2355  } else {
2356  __kmp_str_buf_print(buffer, "%s,", "norespect");
2357  }
2358  switch (__kmp_affinity_gran) {
2359  case affinity_gran_default:
2360  __kmp_str_buf_print(buffer, "%s", "granularity=default,");
2361  break;
2362  case affinity_gran_fine:
2363  __kmp_str_buf_print(buffer, "%s", "granularity=fine,");
2364  break;
2365  case affinity_gran_thread:
2366  __kmp_str_buf_print(buffer, "%s", "granularity=thread,");
2367  break;
2368  case affinity_gran_core:
2369  __kmp_str_buf_print(buffer, "%s", "granularity=core,");
2370  break;
2371  case affinity_gran_package:
2372  __kmp_str_buf_print(buffer, "%s", "granularity=package,");
2373  break;
2374  case affinity_gran_node:
2375  __kmp_str_buf_print(buffer, "%s", "granularity=node,");
2376  break;
2377 #if KMP_GROUP_AFFINITY
2378  case affinity_gran_group:
2379  __kmp_str_buf_print(buffer, "%s", "granularity=group,");
2380  break;
2381 #endif /* KMP_GROUP_AFFINITY */
2382  }
2383  }
2384  if (!KMP_AFFINITY_CAPABLE()) {
2385  __kmp_str_buf_print(buffer, "%s", "disabled");
2386  } else
2387  switch (__kmp_affinity_type) {
2388  case affinity_none:
2389  __kmp_str_buf_print(buffer, "%s", "none");
2390  break;
2391  case affinity_physical:
2392  __kmp_str_buf_print(buffer, "%s,%d", "physical", __kmp_affinity_offset);
2393  break;
2394  case affinity_logical:
2395  __kmp_str_buf_print(buffer, "%s,%d", "logical", __kmp_affinity_offset);
2396  break;
2397  case affinity_compact:
2398  __kmp_str_buf_print(buffer, "%s,%d,%d", "compact", __kmp_affinity_compact,
2399  __kmp_affinity_offset);
2400  break;
2401  case affinity_scatter:
2402  __kmp_str_buf_print(buffer, "%s,%d,%d", "scatter", __kmp_affinity_compact,
2403  __kmp_affinity_offset);
2404  break;
2405  case affinity_explicit:
2406  __kmp_str_buf_print(buffer, "%s=[%s],%s", "proclist",
2407  __kmp_affinity_proclist, "explicit");
2408  break;
2409  case affinity_balanced:
2410  __kmp_str_buf_print(buffer, "%s,%d,%d", "balanced",
2411  __kmp_affinity_compact, __kmp_affinity_offset);
2412  break;
2413  case affinity_disabled:
2414  __kmp_str_buf_print(buffer, "%s", "disabled");
2415  break;
2416  case affinity_default:
2417  __kmp_str_buf_print(buffer, "%s", "default");
2418  break;
2419  default:
2420  __kmp_str_buf_print(buffer, "%s", "<unknown>");
2421  break;
2422  }
2423  __kmp_str_buf_print(buffer, "'\n");
2424 } //__kmp_stg_print_affinity
2425 
2426 #ifdef KMP_GOMP_COMPAT
2427 
2428 static void __kmp_stg_parse_gomp_cpu_affinity(char const *name,
2429  char const *value, void *data) {
2430  const char *next = NULL;
2431  char *temp_proclist;
2432  kmp_setting_t **rivals = (kmp_setting_t **)data;
2433  int rc;
2434 
2435  rc = __kmp_stg_check_rivals(name, value, rivals);
2436  if (rc) {
2437  return;
2438  }
2439 
2440  if (TCR_4(__kmp_init_middle)) {
2441  KMP_WARNING(EnvMiddleWarn, name);
2442  __kmp_env_toPrint(name, 0);
2443  return;
2444  }
2445 
2446  __kmp_env_toPrint(name, 1);
2447 
2448  if (__kmp_parse_affinity_proc_id_list(name, value, &next, &temp_proclist)) {
2449  SKIP_WS(next);
2450  if (*next == '\0') {
2451  // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...
2452  __kmp_affinity_proclist = temp_proclist;
2453  __kmp_affinity_type = affinity_explicit;
2454  __kmp_affinity_gran = affinity_gran_fine;
2455 #if OMP_40_ENABLED
2456  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
2457 #endif
2458  } else {
2459  KMP_WARNING(AffSyntaxError, name);
2460  if (temp_proclist != NULL) {
2461  KMP_INTERNAL_FREE((void *)temp_proclist);
2462  }
2463  }
2464  } else {
2465  // Warning already emitted
2466  __kmp_affinity_type = affinity_none;
2467 #if OMP_40_ENABLED
2468  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
2469 #endif
2470  }
2471 } // __kmp_stg_parse_gomp_cpu_affinity
2472 
2473 #endif /* KMP_GOMP_COMPAT */
2474 
2475 #if OMP_40_ENABLED
2476 
2477 /*-----------------------------------------------------------------------------
2478 The OMP_PLACES proc id list parser. Here is the grammar:
2479 
2480 place_list := place
2481 place_list := place , place_list
2482 place := num
2483 place := place : num
2484 place := place : num : signed
2485 place := { subplacelist }
2486 place := ! place // (lowest priority)
2487 subplace_list := subplace
2488 subplace_list := subplace , subplace_list
2489 subplace := num
2490 subplace := num : num
2491 subplace := num : num : signed
2492 signed := num
2493 signed := + signed
2494 signed := - signed
2495 -----------------------------------------------------------------------------*/
2496 
2497 static int __kmp_parse_subplace_list(const char *var, const char **scan) {
2498  const char *next;
2499 
2500  for (;;) {
2501  int start, count, stride;
2502 
2503  //
2504  // Read in the starting proc id
2505  //
2506  SKIP_WS(*scan);
2507  if ((**scan < '0') || (**scan > '9')) {
2508  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2509  return FALSE;
2510  }
2511  next = *scan;
2512  SKIP_DIGITS(next);
2513  start = __kmp_str_to_int(*scan, *next);
2514  KMP_ASSERT(start >= 0);
2515  *scan = next;
2516 
2517  // valid follow sets are ',' ':' and '}'
2518  SKIP_WS(*scan);
2519  if (**scan == '}') {
2520  break;
2521  }
2522  if (**scan == ',') {
2523  (*scan)++; // skip ','
2524  continue;
2525  }
2526  if (**scan != ':') {
2527  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2528  return FALSE;
2529  }
2530  (*scan)++; // skip ':'
2531 
2532  // Read count parameter
2533  SKIP_WS(*scan);
2534  if ((**scan < '0') || (**scan > '9')) {
2535  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2536  return FALSE;
2537  }
2538  next = *scan;
2539  SKIP_DIGITS(next);
2540  count = __kmp_str_to_int(*scan, *next);
2541  KMP_ASSERT(count >= 0);
2542  *scan = next;
2543 
2544  // valid follow sets are ',' ':' and '}'
2545  SKIP_WS(*scan);
2546  if (**scan == '}') {
2547  break;
2548  }
2549  if (**scan == ',') {
2550  (*scan)++; // skip ','
2551  continue;
2552  }
2553  if (**scan != ':') {
2554  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2555  return FALSE;
2556  }
2557  (*scan)++; // skip ':'
2558 
2559  // Read stride parameter
2560  int sign = +1;
2561  for (;;) {
2562  SKIP_WS(*scan);
2563  if (**scan == '+') {
2564  (*scan)++; // skip '+'
2565  continue;
2566  }
2567  if (**scan == '-') {
2568  sign *= -1;
2569  (*scan)++; // skip '-'
2570  continue;
2571  }
2572  break;
2573  }
2574  SKIP_WS(*scan);
2575  if ((**scan < '0') || (**scan > '9')) {
2576  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2577  return FALSE;
2578  }
2579  next = *scan;
2580  SKIP_DIGITS(next);
2581  stride = __kmp_str_to_int(*scan, *next);
2582  KMP_ASSERT(stride >= 0);
2583  *scan = next;
2584  stride *= sign;
2585 
2586  // valid follow sets are ',' and '}'
2587  SKIP_WS(*scan);
2588  if (**scan == '}') {
2589  break;
2590  }
2591  if (**scan == ',') {
2592  (*scan)++; // skip ','
2593  continue;
2594  }
2595 
2596  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2597  return FALSE;
2598  }
2599  return TRUE;
2600 }
2601 
2602 static int __kmp_parse_place(const char *var, const char **scan) {
2603  const char *next;
2604 
2605  // valid follow sets are '{' '!' and num
2606  SKIP_WS(*scan);
2607  if (**scan == '{') {
2608  (*scan)++; // skip '{'
2609  if (!__kmp_parse_subplace_list(var, scan)) {
2610  return FALSE;
2611  }
2612  if (**scan != '}') {
2613  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2614  return FALSE;
2615  }
2616  (*scan)++; // skip '}'
2617  } else if (**scan == '!') {
2618  (*scan)++; // skip '!'
2619  return __kmp_parse_place(var, scan); //'!' has lower precedence than ':'
2620  } else if ((**scan >= '0') && (**scan <= '9')) {
2621  next = *scan;
2622  SKIP_DIGITS(next);
2623  int proc = __kmp_str_to_int(*scan, *next);
2624  KMP_ASSERT(proc >= 0);
2625  *scan = next;
2626  } else {
2627  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2628  return FALSE;
2629  }
2630  return TRUE;
2631 }
2632 
2633 static int __kmp_parse_place_list(const char *var, const char *env,
2634  char **place_list) {
2635  const char *scan = env;
2636  const char *next = scan;
2637 
2638  for (;;) {
2639  int start, count, stride;
2640 
2641  if (!__kmp_parse_place(var, &scan)) {
2642  return FALSE;
2643  }
2644 
2645  // valid follow sets are ',' ':' and EOL
2646  SKIP_WS(scan);
2647  if (*scan == '\0') {
2648  break;
2649  }
2650  if (*scan == ',') {
2651  scan++; // skip ','
2652  continue;
2653  }
2654  if (*scan != ':') {
2655  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2656  return FALSE;
2657  }
2658  scan++; // skip ':'
2659 
2660  // Read count parameter
2661  SKIP_WS(scan);
2662  if ((*scan < '0') || (*scan > '9')) {
2663  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2664  return FALSE;
2665  }
2666  next = scan;
2667  SKIP_DIGITS(next);
2668  count = __kmp_str_to_int(scan, *next);
2669  KMP_ASSERT(count >= 0);
2670  scan = next;
2671 
2672  // valid follow sets are ',' ':' and EOL
2673  SKIP_WS(scan);
2674  if (*scan == '\0') {
2675  break;
2676  }
2677  if (*scan == ',') {
2678  scan++; // skip ','
2679  continue;
2680  }
2681  if (*scan != ':') {
2682  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2683  return FALSE;
2684  }
2685  scan++; // skip ':'
2686 
2687  // Read stride parameter
2688  int sign = +1;
2689  for (;;) {
2690  SKIP_WS(scan);
2691  if (*scan == '+') {
2692  scan++; // skip '+'
2693  continue;
2694  }
2695  if (*scan == '-') {
2696  sign *= -1;
2697  scan++; // skip '-'
2698  continue;
2699  }
2700  break;
2701  }
2702  SKIP_WS(scan);
2703  if ((*scan < '0') || (*scan > '9')) {
2704  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2705  return FALSE;
2706  }
2707  next = scan;
2708  SKIP_DIGITS(next);
2709  stride = __kmp_str_to_int(scan, *next);
2710  KMP_ASSERT(stride >= 0);
2711  scan = next;
2712  stride *= sign;
2713 
2714  // valid follow sets are ',' and EOL
2715  SKIP_WS(scan);
2716  if (*scan == '\0') {
2717  break;
2718  }
2719  if (*scan == ',') {
2720  scan++; // skip ','
2721  continue;
2722  }
2723 
2724  KMP_WARNING(SyntaxErrorUsing, var, "\"threads\"");
2725  return FALSE;
2726  }
2727 
2728  {
2729  int len = scan - env;
2730  char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
2731  KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));
2732  retlist[len] = '\0';
2733  *place_list = retlist;
2734  }
2735  return TRUE;
2736 }
2737 
2738 static void __kmp_stg_parse_places(char const *name, char const *value,
2739  void *data) {
2740  int count;
2741  const char *scan = value;
2742  const char *next = scan;
2743  const char *kind = "\"threads\"";
2744  kmp_setting_t **rivals = (kmp_setting_t **)data;
2745  int rc;
2746 
2747  rc = __kmp_stg_check_rivals(name, value, rivals);
2748  if (rc) {
2749  return;
2750  }
2751 
2752  // If OMP_PROC_BIND is not specified but OMP_PLACES is,
2753  // then let OMP_PROC_BIND default to true.
2754  if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
2755  __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
2756  }
2757 
2758  //__kmp_affinity_num_places = 0;
2759 
2760  if (__kmp_match_str("threads", scan, &next)) {
2761  scan = next;
2762  __kmp_affinity_type = affinity_compact;
2763  __kmp_affinity_gran = affinity_gran_thread;
2764  __kmp_affinity_dups = FALSE;
2765  kind = "\"threads\"";
2766  } else if (__kmp_match_str("cores", scan, &next)) {
2767  scan = next;
2768  __kmp_affinity_type = affinity_compact;
2769  __kmp_affinity_gran = affinity_gran_core;
2770  __kmp_affinity_dups = FALSE;
2771  kind = "\"cores\"";
2772 #if KMP_USE_HWLOC
2773  } else if (__kmp_match_str("tiles", scan, &next)) {
2774  scan = next;
2775  __kmp_affinity_type = affinity_compact;
2776  __kmp_affinity_gran = affinity_gran_tile;
2777  __kmp_affinity_dups = FALSE;
2778  kind = "\"tiles\"";
2779 #endif
2780  } else if (__kmp_match_str("sockets", scan, &next)) {
2781  scan = next;
2782  __kmp_affinity_type = affinity_compact;
2783  __kmp_affinity_gran = affinity_gran_package;
2784  __kmp_affinity_dups = FALSE;
2785  kind = "\"sockets\"";
2786  } else {
2787  if (__kmp_affinity_proclist != NULL) {
2788  KMP_INTERNAL_FREE((void *)__kmp_affinity_proclist);
2789  __kmp_affinity_proclist = NULL;
2790  }
2791  if (__kmp_parse_place_list(name, value, &__kmp_affinity_proclist)) {
2792  __kmp_affinity_type = affinity_explicit;
2793  __kmp_affinity_gran = affinity_gran_fine;
2794  __kmp_affinity_dups = FALSE;
2795  if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
2796  __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
2797  }
2798  }
2799  return;
2800  }
2801 
2802  if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {
2803  __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
2804  }
2805 
2806  SKIP_WS(scan);
2807  if (*scan == '\0') {
2808  return;
2809  }
2810 
2811  // Parse option count parameter in parentheses
2812  if (*scan != '(') {
2813  KMP_WARNING(SyntaxErrorUsing, name, kind);
2814  return;
2815  }
2816  scan++; // skip '('
2817 
2818  SKIP_WS(scan);
2819  next = scan;
2820  SKIP_DIGITS(next);
2821  count = __kmp_str_to_int(scan, *next);
2822  KMP_ASSERT(count >= 0);
2823  scan = next;
2824 
2825  SKIP_WS(scan);
2826  if (*scan != ')') {
2827  KMP_WARNING(SyntaxErrorUsing, name, kind);
2828  return;
2829  }
2830  scan++; // skip ')'
2831 
2832  SKIP_WS(scan);
2833  if (*scan != '\0') {
2834  KMP_WARNING(ParseExtraCharsWarn, name, scan);
2835  }
2836  __kmp_affinity_num_places = count;
2837 }
2838 
2839 static void __kmp_stg_print_places(kmp_str_buf_t *buffer, char const *name,
2840  void *data) {
2841  if (__kmp_env_format) {
2842  KMP_STR_BUF_PRINT_NAME;
2843  } else {
2844  __kmp_str_buf_print(buffer, " %s", name);
2845  }
2846  if ((__kmp_nested_proc_bind.used == 0) ||
2847  (__kmp_nested_proc_bind.bind_types == NULL) ||
2848  (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)) {
2849  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2850  } else if (__kmp_affinity_type == affinity_explicit) {
2851  if (__kmp_affinity_proclist != NULL) {
2852  __kmp_str_buf_print(buffer, "='%s'\n", __kmp_affinity_proclist);
2853  } else {
2854  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2855  }
2856  } else if (__kmp_affinity_type == affinity_compact) {
2857  int num;
2858  if (__kmp_affinity_num_masks > 0) {
2859  num = __kmp_affinity_num_masks;
2860  } else if (__kmp_affinity_num_places > 0) {
2861  num = __kmp_affinity_num_places;
2862  } else {
2863  num = 0;
2864  }
2865  if (__kmp_affinity_gran == affinity_gran_thread) {
2866  if (num > 0) {
2867  __kmp_str_buf_print(buffer, "='threads(%d)'\n", num);
2868  } else {
2869  __kmp_str_buf_print(buffer, "='threads'\n");
2870  }
2871  } else if (__kmp_affinity_gran == affinity_gran_core) {
2872  if (num > 0) {
2873  __kmp_str_buf_print(buffer, "='cores(%d)' \n", num);
2874  } else {
2875  __kmp_str_buf_print(buffer, "='cores'\n");
2876  }
2877 #if KMP_USE_HWLOC
2878  } else if (__kmp_affinity_gran == affinity_gran_tile) {
2879  if (num > 0) {
2880  __kmp_str_buf_print(buffer, "='tiles(%d)' \n", num);
2881  } else {
2882  __kmp_str_buf_print(buffer, "='tiles'\n");
2883  }
2884 #endif
2885  } else if (__kmp_affinity_gran == affinity_gran_package) {
2886  if (num > 0) {
2887  __kmp_str_buf_print(buffer, "='sockets(%d)'\n", num);
2888  } else {
2889  __kmp_str_buf_print(buffer, "='sockets'\n");
2890  }
2891  } else {
2892  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2893  }
2894  } else {
2895  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
2896  }
2897 }
2898 
2899 #endif /* OMP_40_ENABLED */
2900 
2901 #if (!OMP_40_ENABLED)
2902 
2903 static void __kmp_stg_parse_proc_bind(char const *name, char const *value,
2904  void *data) {
2905  int enabled;
2906  kmp_setting_t **rivals = (kmp_setting_t **)data;
2907  int rc;
2908 
2909  rc = __kmp_stg_check_rivals(name, value, rivals);
2910  if (rc) {
2911  return;
2912  }
2913 
2914  // In OMP 3.1, OMP_PROC_BIND is strictly a boolean
2915  __kmp_stg_parse_bool(name, value, &enabled);
2916  if (enabled) {
2917  // OMP_PROC_BIND => granularity=fine,scatter on MIC
2918  // OMP_PROC_BIND => granularity=core,scatter elsewhere
2919  __kmp_affinity_type = affinity_scatter;
2920 #if KMP_MIC_SUPPORTED
2921  if (__kmp_mic_type != non_mic)
2922  __kmp_affinity_gran = affinity_gran_fine;
2923  else
2924 #endif
2925  __kmp_affinity_gran = affinity_gran_core;
2926  } else {
2927  __kmp_affinity_type = affinity_none;
2928  }
2929 } // __kmp_parse_proc_bind
2930 
2931 #endif /* if (! OMP_40_ENABLED) */
2932 
2933 static void __kmp_stg_parse_topology_method(char const *name, char const *value,
2934  void *data) {
2935  if (__kmp_str_match("all", 1, value)) {
2936  __kmp_affinity_top_method = affinity_top_method_all;
2937  }
2938 #if KMP_USE_HWLOC
2939  else if (__kmp_str_match("hwloc", 1, value)) {
2940  __kmp_affinity_top_method = affinity_top_method_hwloc;
2941  }
2942 #endif
2943 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
2944  else if (__kmp_str_match("x2apic id", 9, value) ||
2945  __kmp_str_match("x2apic_id", 9, value) ||
2946  __kmp_str_match("x2apic-id", 9, value) ||
2947  __kmp_str_match("x2apicid", 8, value) ||
2948  __kmp_str_match("cpuid leaf 11", 13, value) ||
2949  __kmp_str_match("cpuid_leaf_11", 13, value) ||
2950  __kmp_str_match("cpuid-leaf-11", 13, value) ||
2951  __kmp_str_match("cpuid leaf11", 12, value) ||
2952  __kmp_str_match("cpuid_leaf11", 12, value) ||
2953  __kmp_str_match("cpuid-leaf11", 12, value) ||
2954  __kmp_str_match("cpuidleaf 11", 12, value) ||
2955  __kmp_str_match("cpuidleaf_11", 12, value) ||
2956  __kmp_str_match("cpuidleaf-11", 12, value) ||
2957  __kmp_str_match("cpuidleaf11", 11, value) ||
2958  __kmp_str_match("cpuid 11", 8, value) ||
2959  __kmp_str_match("cpuid_11", 8, value) ||
2960  __kmp_str_match("cpuid-11", 8, value) ||
2961  __kmp_str_match("cpuid11", 7, value) ||
2962  __kmp_str_match("leaf 11", 7, value) ||
2963  __kmp_str_match("leaf_11", 7, value) ||
2964  __kmp_str_match("leaf-11", 7, value) ||
2965  __kmp_str_match("leaf11", 6, value)) {
2966  __kmp_affinity_top_method = affinity_top_method_x2apicid;
2967  } else if (__kmp_str_match("apic id", 7, value) ||
2968  __kmp_str_match("apic_id", 7, value) ||
2969  __kmp_str_match("apic-id", 7, value) ||
2970  __kmp_str_match("apicid", 6, value) ||
2971  __kmp_str_match("cpuid leaf 4", 12, value) ||
2972  __kmp_str_match("cpuid_leaf_4", 12, value) ||
2973  __kmp_str_match("cpuid-leaf-4", 12, value) ||
2974  __kmp_str_match("cpuid leaf4", 11, value) ||
2975  __kmp_str_match("cpuid_leaf4", 11, value) ||
2976  __kmp_str_match("cpuid-leaf4", 11, value) ||
2977  __kmp_str_match("cpuidleaf 4", 11, value) ||
2978  __kmp_str_match("cpuidleaf_4", 11, value) ||
2979  __kmp_str_match("cpuidleaf-4", 11, value) ||
2980  __kmp_str_match("cpuidleaf4", 10, value) ||
2981  __kmp_str_match("cpuid 4", 7, value) ||
2982  __kmp_str_match("cpuid_4", 7, value) ||
2983  __kmp_str_match("cpuid-4", 7, value) ||
2984  __kmp_str_match("cpuid4", 6, value) ||
2985  __kmp_str_match("leaf 4", 6, value) ||
2986  __kmp_str_match("leaf_4", 6, value) ||
2987  __kmp_str_match("leaf-4", 6, value) ||
2988  __kmp_str_match("leaf4", 5, value)) {
2989  __kmp_affinity_top_method = affinity_top_method_apicid;
2990  }
2991 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
2992  else if (__kmp_str_match("/proc/cpuinfo", 2, value) ||
2993  __kmp_str_match("cpuinfo", 5, value)) {
2994  __kmp_affinity_top_method = affinity_top_method_cpuinfo;
2995  }
2996 #if KMP_GROUP_AFFINITY
2997  else if (__kmp_str_match("group", 1, value)) {
2998  __kmp_affinity_top_method = affinity_top_method_group;
2999  }
3000 #endif /* KMP_GROUP_AFFINITY */
3001  else if (__kmp_str_match("flat", 1, value)) {
3002  __kmp_affinity_top_method = affinity_top_method_flat;
3003  } else {
3004  KMP_WARNING(StgInvalidValue, name, value);
3005  }
3006 } // __kmp_stg_parse_topology_method
3007 
3008 static void __kmp_stg_print_topology_method(kmp_str_buf_t *buffer,
3009  char const *name, void *data) {
3010  char const *value = NULL;
3011 
3012  switch (__kmp_affinity_top_method) {
3013  case affinity_top_method_default:
3014  value = "default";
3015  break;
3016 
3017  case affinity_top_method_all:
3018  value = "all";
3019  break;
3020 
3021 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3022  case affinity_top_method_x2apicid:
3023  value = "x2APIC id";
3024  break;
3025 
3026  case affinity_top_method_apicid:
3027  value = "APIC id";
3028  break;
3029 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3030 
3031 #if KMP_USE_HWLOC
3032  case affinity_top_method_hwloc:
3033  value = "hwloc";
3034  break;
3035 #endif
3036 
3037  case affinity_top_method_cpuinfo:
3038  value = "cpuinfo";
3039  break;
3040 
3041 #if KMP_GROUP_AFFINITY
3042  case affinity_top_method_group:
3043  value = "group";
3044  break;
3045 #endif /* KMP_GROUP_AFFINITY */
3046 
3047  case affinity_top_method_flat:
3048  value = "flat";
3049  break;
3050  }
3051 
3052  if (value != NULL) {
3053  __kmp_stg_print_str(buffer, name, value);
3054  }
3055 } // __kmp_stg_print_topology_method
3056 
3057 #endif /* KMP_AFFINITY_SUPPORTED */
3058 
3059 #if OMP_40_ENABLED
3060 
3061 // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
3062 // OMP_PLACES / place-partition-var is not.
3063 static void __kmp_stg_parse_proc_bind(char const *name, char const *value,
3064  void *data) {
3065  kmp_setting_t **rivals = (kmp_setting_t **)data;
3066  int rc;
3067 
3068  rc = __kmp_stg_check_rivals(name, value, rivals);
3069  if (rc) {
3070  return;
3071  }
3072 
3073  // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
3074  KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&
3075  (__kmp_nested_proc_bind.used > 0));
3076 
3077  const char *buf = value;
3078  const char *next;
3079  int num;
3080  SKIP_WS(buf);
3081  if ((*buf >= '0') && (*buf <= '9')) {
3082  next = buf;
3083  SKIP_DIGITS(next);
3084  num = __kmp_str_to_int(buf, *next);
3085  KMP_ASSERT(num >= 0);
3086  buf = next;
3087  SKIP_WS(buf);
3088  } else {
3089  num = -1;
3090  }
3091 
3092  next = buf;
3093  if (__kmp_match_str("disabled", buf, &next)) {
3094  buf = next;
3095  SKIP_WS(buf);
3096 #if KMP_AFFINITY_SUPPORTED
3097  __kmp_affinity_type = affinity_disabled;
3098 #endif /* KMP_AFFINITY_SUPPORTED */
3099  __kmp_nested_proc_bind.used = 1;
3100  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3101  } else if ((num == (int)proc_bind_false) ||
3102  __kmp_match_str("false", buf, &next)) {
3103  buf = next;
3104  SKIP_WS(buf);
3105 #if KMP_AFFINITY_SUPPORTED
3106  __kmp_affinity_type = affinity_none;
3107 #endif /* KMP_AFFINITY_SUPPORTED */
3108  __kmp_nested_proc_bind.used = 1;
3109  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3110  } else if ((num == (int)proc_bind_true) ||
3111  __kmp_match_str("true", buf, &next)) {
3112  buf = next;
3113  SKIP_WS(buf);
3114  __kmp_nested_proc_bind.used = 1;
3115  __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
3116  } else {
3117  // Count the number of values in the env var string
3118  const char *scan;
3119  int nelem = 1;
3120  for (scan = buf; *scan != '\0'; scan++) {
3121  if (*scan == ',') {
3122  nelem++;
3123  }
3124  }
3125 
3126  // Create / expand the nested proc_bind array as needed
3127  if (__kmp_nested_proc_bind.size < nelem) {
3128  __kmp_nested_proc_bind.bind_types =
3129  (kmp_proc_bind_t *)KMP_INTERNAL_REALLOC(
3130  __kmp_nested_proc_bind.bind_types,
3131  sizeof(kmp_proc_bind_t) * nelem);
3132  if (__kmp_nested_proc_bind.bind_types == NULL) {
3133  KMP_FATAL(MemoryAllocFailed);
3134  }
3135  __kmp_nested_proc_bind.size = nelem;
3136  }
3137  __kmp_nested_proc_bind.used = nelem;
3138 
3139  // Save values in the nested proc_bind array
3140  int i = 0;
3141  for (;;) {
3142  enum kmp_proc_bind_t bind;
3143 
3144  if ((num == (int)proc_bind_master) ||
3145  __kmp_match_str("master", buf, &next)) {
3146  buf = next;
3147  SKIP_WS(buf);
3148  bind = proc_bind_master;
3149  } else if ((num == (int)proc_bind_close) ||
3150  __kmp_match_str("close", buf, &next)) {
3151  buf = next;
3152  SKIP_WS(buf);
3153  bind = proc_bind_close;
3154  } else if ((num == (int)proc_bind_spread) ||
3155  __kmp_match_str("spread", buf, &next)) {
3156  buf = next;
3157  SKIP_WS(buf);
3158  bind = proc_bind_spread;
3159  } else {
3160  KMP_WARNING(StgInvalidValue, name, value);
3161  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3162  __kmp_nested_proc_bind.used = 1;
3163  return;
3164  }
3165 
3166  __kmp_nested_proc_bind.bind_types[i++] = bind;
3167  if (i >= nelem) {
3168  break;
3169  }
3170  KMP_DEBUG_ASSERT(*buf == ',');
3171  buf++;
3172  SKIP_WS(buf);
3173 
3174  // Read next value if it was specified as an integer
3175  if ((*buf >= '0') && (*buf <= '9')) {
3176  next = buf;
3177  SKIP_DIGITS(next);
3178  num = __kmp_str_to_int(buf, *next);
3179  KMP_ASSERT(num >= 0);
3180  buf = next;
3181  SKIP_WS(buf);
3182  } else {
3183  num = -1;
3184  }
3185  }
3186  SKIP_WS(buf);
3187  }
3188  if (*buf != '\0') {
3189  KMP_WARNING(ParseExtraCharsWarn, name, buf);
3190  }
3191 }
3192 
3193 static void __kmp_stg_print_proc_bind(kmp_str_buf_t *buffer, char const *name,
3194  void *data) {
3195  int nelem = __kmp_nested_proc_bind.used;
3196  if (__kmp_env_format) {
3197  KMP_STR_BUF_PRINT_NAME;
3198  } else {
3199  __kmp_str_buf_print(buffer, " %s", name);
3200  }
3201  if (nelem == 0) {
3202  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
3203  } else {
3204  int i;
3205  __kmp_str_buf_print(buffer, "='", name);
3206  for (i = 0; i < nelem; i++) {
3207  switch (__kmp_nested_proc_bind.bind_types[i]) {
3208  case proc_bind_false:
3209  __kmp_str_buf_print(buffer, "false");
3210  break;
3211 
3212  case proc_bind_true:
3213  __kmp_str_buf_print(buffer, "true");
3214  break;
3215 
3216  case proc_bind_master:
3217  __kmp_str_buf_print(buffer, "master");
3218  break;
3219 
3220  case proc_bind_close:
3221  __kmp_str_buf_print(buffer, "close");
3222  break;
3223 
3224  case proc_bind_spread:
3225  __kmp_str_buf_print(buffer, "spread");
3226  break;
3227 
3228  case proc_bind_intel:
3229  __kmp_str_buf_print(buffer, "intel");
3230  break;
3231 
3232  case proc_bind_default:
3233  __kmp_str_buf_print(buffer, "default");
3234  break;
3235  }
3236  if (i < nelem - 1) {
3237  __kmp_str_buf_print(buffer, ",");
3238  }
3239  }
3240  __kmp_str_buf_print(buffer, "'\n");
3241  }
3242 }
3243 
3244 #endif /* OMP_40_ENABLED */
3245 
3246 // -----------------------------------------------------------------------------
3247 // OMP_DYNAMIC
3248 
3249 static void __kmp_stg_parse_omp_dynamic(char const *name, char const *value,
3250  void *data) {
3251  __kmp_stg_parse_bool(name, value, &(__kmp_global.g.g_dynamic));
3252 } // __kmp_stg_parse_omp_dynamic
3253 
3254 static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t *buffer, char const *name,
3255  void *data) {
3256  __kmp_stg_print_bool(buffer, name, __kmp_global.g.g_dynamic);
3257 } // __kmp_stg_print_omp_dynamic
3258 
3259 static void __kmp_stg_parse_kmp_dynamic_mode(char const *name,
3260  char const *value, void *data) {
3261  if (TCR_4(__kmp_init_parallel)) {
3262  KMP_WARNING(EnvParallelWarn, name);
3263  __kmp_env_toPrint(name, 0);
3264  return;
3265  }
3266 #ifdef USE_LOAD_BALANCE
3267  else if (__kmp_str_match("load balance", 2, value) ||
3268  __kmp_str_match("load_balance", 2, value) ||
3269  __kmp_str_match("load-balance", 2, value) ||
3270  __kmp_str_match("loadbalance", 2, value) ||
3271  __kmp_str_match("balance", 1, value)) {
3272  __kmp_global.g.g_dynamic_mode = dynamic_load_balance;
3273  }
3274 #endif /* USE_LOAD_BALANCE */
3275  else if (__kmp_str_match("thread limit", 1, value) ||
3276  __kmp_str_match("thread_limit", 1, value) ||
3277  __kmp_str_match("thread-limit", 1, value) ||
3278  __kmp_str_match("threadlimit", 1, value) ||
3279  __kmp_str_match("limit", 2, value)) {
3280  __kmp_global.g.g_dynamic_mode = dynamic_thread_limit;
3281  } else if (__kmp_str_match("random", 1, value)) {
3282  __kmp_global.g.g_dynamic_mode = dynamic_random;
3283  } else {
3284  KMP_WARNING(StgInvalidValue, name, value);
3285  }
3286 } //__kmp_stg_parse_kmp_dynamic_mode
3287 
3288 static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t *buffer,
3289  char const *name, void *data) {
3290 #if KMP_DEBUG
3291  if (__kmp_global.g.g_dynamic_mode == dynamic_default) {
3292  __kmp_str_buf_print(buffer, " %s: %s \n", name, KMP_I18N_STR(NotDefined));
3293  }
3294 #ifdef USE_LOAD_BALANCE
3295  else if (__kmp_global.g.g_dynamic_mode == dynamic_load_balance) {
3296  __kmp_stg_print_str(buffer, name, "load balance");
3297  }
3298 #endif /* USE_LOAD_BALANCE */
3299  else if (__kmp_global.g.g_dynamic_mode == dynamic_thread_limit) {
3300  __kmp_stg_print_str(buffer, name, "thread limit");
3301  } else if (__kmp_global.g.g_dynamic_mode == dynamic_random) {
3302  __kmp_stg_print_str(buffer, name, "random");
3303  } else {
3304  KMP_ASSERT(0);
3305  }
3306 #endif /* KMP_DEBUG */
3307 } // __kmp_stg_print_kmp_dynamic_mode
3308 
3309 #ifdef USE_LOAD_BALANCE
3310 
3311 // -----------------------------------------------------------------------------
3312 // KMP_LOAD_BALANCE_INTERVAL
3313 
3314 static void __kmp_stg_parse_ld_balance_interval(char const *name,
3315  char const *value, void *data) {
3316  double interval = __kmp_convert_to_double(value);
3317  if (interval >= 0) {
3318  __kmp_load_balance_interval = interval;
3319  } else {
3320  KMP_WARNING(StgInvalidValue, name, value);
3321  }
3322 } // __kmp_stg_parse_load_balance_interval
3323 
3324 static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t *buffer,
3325  char const *name, void *data) {
3326 #if KMP_DEBUG
3327  __kmp_str_buf_print(buffer, " %s=%8.6f\n", name,
3328  __kmp_load_balance_interval);
3329 #endif /* KMP_DEBUG */
3330 } // __kmp_stg_print_load_balance_interval
3331 
3332 #endif /* USE_LOAD_BALANCE */
3333 
3334 // -----------------------------------------------------------------------------
3335 // KMP_INIT_AT_FORK
3336 
3337 static void __kmp_stg_parse_init_at_fork(char const *name, char const *value,
3338  void *data) {
3339  __kmp_stg_parse_bool(name, value, &__kmp_need_register_atfork);
3340  if (__kmp_need_register_atfork) {
3341  __kmp_need_register_atfork_specified = TRUE;
3342  }
3343 } // __kmp_stg_parse_init_at_fork
3344 
3345 static void __kmp_stg_print_init_at_fork(kmp_str_buf_t *buffer,
3346  char const *name, void *data) {
3347  __kmp_stg_print_bool(buffer, name, __kmp_need_register_atfork_specified);
3348 } // __kmp_stg_print_init_at_fork
3349 
3350 // -----------------------------------------------------------------------------
3351 // KMP_SCHEDULE
3352 
3353 static void __kmp_stg_parse_schedule(char const *name, char const *value,
3354  void *data) {
3355 
3356  if (value != NULL) {
3357  size_t length = KMP_STRLEN(value);
3358  if (length > INT_MAX) {
3359  KMP_WARNING(LongValue, name);
3360  } else {
3361  const char *semicolon;
3362  if (value[length - 1] == '"' || value[length - 1] == '\'')
3363  KMP_WARNING(UnbalancedQuotes, name);
3364  do {
3365  char sentinel;
3366 
3367  semicolon = strchr(value, ';');
3368  if (*value && semicolon != value) {
3369  const char *comma = strchr(value, ',');
3370 
3371  if (comma) {
3372  ++comma;
3373  sentinel = ',';
3374  } else
3375  sentinel = ';';
3376  if (!__kmp_strcasecmp_with_sentinel("static", value, sentinel)) {
3377  if (!__kmp_strcasecmp_with_sentinel("greedy", comma, ';')) {
3378  __kmp_static = kmp_sch_static_greedy;
3379  continue;
3380  } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma,
3381  ';')) {
3382  __kmp_static = kmp_sch_static_balanced;
3383  continue;
3384  }
3385  } else if (!__kmp_strcasecmp_with_sentinel("guided", value,
3386  sentinel)) {
3387  if (!__kmp_strcasecmp_with_sentinel("iterative", comma, ';')) {
3388  __kmp_guided = kmp_sch_guided_iterative_chunked;
3389  continue;
3390  } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma,
3391  ';')) {
3392  /* analytical not allowed for too many threads */
3393  __kmp_guided = kmp_sch_guided_analytical_chunked;
3394  continue;
3395  }
3396  }
3397  KMP_WARNING(InvalidClause, name, value);
3398  } else
3399  KMP_WARNING(EmptyClause, name);
3400  } while ((value = semicolon ? semicolon + 1 : NULL));
3401  }
3402  }
3403 
3404 } // __kmp_stg_parse__schedule
3405 
3406 static void __kmp_stg_print_schedule(kmp_str_buf_t *buffer, char const *name,
3407  void *data) {
3408  if (__kmp_env_format) {
3409  KMP_STR_BUF_PRINT_NAME_EX(name);
3410  } else {
3411  __kmp_str_buf_print(buffer, " %s='", name);
3412  }
3413  if (__kmp_static == kmp_sch_static_greedy) {
3414  __kmp_str_buf_print(buffer, "%s", "static,greedy");
3415  } else if (__kmp_static == kmp_sch_static_balanced) {
3416  __kmp_str_buf_print(buffer, "%s", "static,balanced");
3417  }
3418  if (__kmp_guided == kmp_sch_guided_iterative_chunked) {
3419  __kmp_str_buf_print(buffer, ";%s'\n", "guided,iterative");
3420  } else if (__kmp_guided == kmp_sch_guided_analytical_chunked) {
3421  __kmp_str_buf_print(buffer, ";%s'\n", "guided,analytical");
3422  }
3423 } // __kmp_stg_print_schedule
3424 
3425 // -----------------------------------------------------------------------------
3426 // OMP_SCHEDULE
3427 
3428 static void __kmp_stg_parse_omp_schedule(char const *name, char const *value,
3429  void *data) {
3430  size_t length;
3431  if (value) {
3432  length = KMP_STRLEN(value);
3433  if (length) {
3434  const char *comma = strchr(value, ',');
3435  if (value[length - 1] == '"' || value[length - 1] == '\'')
3436  KMP_WARNING(UnbalancedQuotes, name);
3437  /* get the specified scheduling style */
3438  if (!__kmp_strcasecmp_with_sentinel("dynamic", value, ',')) /* DYNAMIC */
3439  __kmp_sched = kmp_sch_dynamic_chunked;
3440  else if (!__kmp_strcasecmp_with_sentinel("guided", value,
3441  ',')) /* GUIDED */
3442  __kmp_sched = kmp_sch_guided_chunked;
3443  // AC: TODO: add AUTO schedule, and pprobably remove TRAPEZOIDAL (OMP 3.0
3444  // does not allow it)
3445  else if (!__kmp_strcasecmp_with_sentinel("auto", value, ',')) { /* AUTO */
3446  __kmp_sched = kmp_sch_auto;
3447  if (comma) {
3448  __kmp_msg(kmp_ms_warning, KMP_MSG(IgnoreChunk, name, comma),
3449  __kmp_msg_null);
3450  comma = NULL;
3451  }
3452  } else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", value,
3453  ',')) /* TRAPEZOIDAL */
3454  __kmp_sched = kmp_sch_trapezoidal;
3455  else if (!__kmp_strcasecmp_with_sentinel("static", value,
3456  ',')) /* STATIC */
3457  __kmp_sched = kmp_sch_static;
3458 #if KMP_STATIC_STEAL_ENABLED
3459  else if (!__kmp_strcasecmp_with_sentinel("static_steal", value, ','))
3460  __kmp_sched = kmp_sch_static_steal;
3461 #endif
3462  else {
3463  KMP_WARNING(StgInvalidValue, name, value);
3464  value = NULL; /* skip processing of comma */
3465  }
3466  if (value && comma) {
3467  if (__kmp_sched == kmp_sch_static)
3468  __kmp_sched = kmp_sch_static_chunked;
3469  ++comma;
3470  __kmp_chunk = __kmp_str_to_int(comma, 0);
3471  if (__kmp_chunk < 1) {
3472  __kmp_chunk = KMP_DEFAULT_CHUNK;
3473  __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidChunk, name, comma),
3474  __kmp_msg_null);
3475  KMP_INFORM(Using_int_Value, name, __kmp_chunk);
3476  // AC: next block commented out until KMP_DEFAULT_CHUNK !=
3477  // KMP_MIN_CHUNK (to improve code coverage :)
3478  // The default chunk size is 1 according to standard, thus making
3479  // KMP_MIN_CHUNK not 1 we would introduce mess:
3480  // wrong chunk becomes 1, but it will be impossible to explicitely
3481  // set 1, because it becomes KMP_MIN_CHUNK...
3482  // } else if ( __kmp_chunk < KMP_MIN_CHUNK ) {
3483  // __kmp_chunk = KMP_MIN_CHUNK;
3484  } else if (__kmp_chunk > KMP_MAX_CHUNK) {
3485  __kmp_chunk = KMP_MAX_CHUNK;
3486  __kmp_msg(kmp_ms_warning, KMP_MSG(LargeChunk, name, comma),
3487  __kmp_msg_null);
3488  KMP_INFORM(Using_int_Value, name, __kmp_chunk);
3489  }
3490  }
3491  } else
3492  KMP_WARNING(EmptyString, name);
3493  }
3494  K_DIAG(1, ("__kmp_static == %d\n", __kmp_static))
3495  K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided))
3496  K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched))
3497  K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk))
3498 } // __kmp_stg_parse_omp_schedule
3499 
3500 static void __kmp_stg_print_omp_schedule(kmp_str_buf_t *buffer,
3501  char const *name, void *data) {
3502  if (__kmp_env_format) {
3503  KMP_STR_BUF_PRINT_NAME_EX(name);
3504  } else {
3505  __kmp_str_buf_print(buffer, " %s='", name);
3506  }
3507  if (__kmp_chunk) {
3508  switch (__kmp_sched) {
3509  case kmp_sch_dynamic_chunked:
3510  __kmp_str_buf_print(buffer, "%s,%d'\n", "dynamic", __kmp_chunk);
3511  break;
3512  case kmp_sch_guided_iterative_chunked:
3513  case kmp_sch_guided_analytical_chunked:
3514  __kmp_str_buf_print(buffer, "%s,%d'\n", "guided", __kmp_chunk);
3515  break;
3516  case kmp_sch_trapezoidal:
3517  __kmp_str_buf_print(buffer, "%s,%d'\n", "trapezoidal", __kmp_chunk);
3518  break;
3519  case kmp_sch_static:
3520  case kmp_sch_static_chunked:
3521  case kmp_sch_static_balanced:
3522  case kmp_sch_static_greedy:
3523  __kmp_str_buf_print(buffer, "%s,%d'\n", "static", __kmp_chunk);
3524  break;
3525  case kmp_sch_static_steal:
3526  __kmp_str_buf_print(buffer, "%s,%d'\n", "static_steal", __kmp_chunk);
3527  break;
3528  case kmp_sch_auto:
3529  __kmp_str_buf_print(buffer, "%s,%d'\n", "auto", __kmp_chunk);
3530  break;
3531  }
3532  } else {
3533  switch (__kmp_sched) {
3534  case kmp_sch_dynamic_chunked:
3535  __kmp_str_buf_print(buffer, "%s'\n", "dynamic");
3536  break;
3537  case kmp_sch_guided_iterative_chunked:
3538  case kmp_sch_guided_analytical_chunked:
3539  __kmp_str_buf_print(buffer, "%s'\n", "guided");
3540  break;
3541  case kmp_sch_trapezoidal:
3542  __kmp_str_buf_print(buffer, "%s'\n", "trapezoidal");
3543  break;
3544  case kmp_sch_static:
3545  case kmp_sch_static_chunked:
3546  case kmp_sch_static_balanced:
3547  case kmp_sch_static_greedy:
3548  __kmp_str_buf_print(buffer, "%s'\n", "static");
3549  break;
3550  case kmp_sch_static_steal:
3551  __kmp_str_buf_print(buffer, "%s'\n", "static_steal");
3552  break;
3553  case kmp_sch_auto:
3554  __kmp_str_buf_print(buffer, "%s'\n", "auto");
3555  break;
3556  }
3557  }
3558 } // __kmp_stg_print_omp_schedule
3559 
3560 // -----------------------------------------------------------------------------
3561 // KMP_ATOMIC_MODE
3562 
3563 static void __kmp_stg_parse_atomic_mode(char const *name, char const *value,
3564  void *data) {
3565  // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP
3566  // compatibility mode.
3567  int mode = 0;
3568  int max = 1;
3569 #ifdef KMP_GOMP_COMPAT
3570  max = 2;
3571 #endif /* KMP_GOMP_COMPAT */
3572  __kmp_stg_parse_int(name, value, 0, max, &mode);
3573  // TODO; parse_int is not very suitable for this case. In case of overflow it
3574  // is better to use
3575  // 0 rather that max value.
3576  if (mode > 0) {
3577  __kmp_atomic_mode = mode;
3578  }
3579 } // __kmp_stg_parse_atomic_mode
3580 
3581 static void __kmp_stg_print_atomic_mode(kmp_str_buf_t *buffer, char const *name,
3582  void *data) {
3583  __kmp_stg_print_int(buffer, name, __kmp_atomic_mode);
3584 } // __kmp_stg_print_atomic_mode
3585 
3586 // -----------------------------------------------------------------------------
3587 // KMP_CONSISTENCY_CHECK
3588 
3589 static void __kmp_stg_parse_consistency_check(char const *name,
3590  char const *value, void *data) {
3591  if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {
3592  // Note, this will not work from kmp_set_defaults because th_cons stack was
3593  // not allocated
3594  // for existed thread(s) thus the first __kmp_push_<construct> will break
3595  // with assertion.
3596  // TODO: allocate th_cons if called from kmp_set_defaults.
3597  __kmp_env_consistency_check = TRUE;
3598  } else if (!__kmp_strcasecmp_with_sentinel("none", value, 0)) {
3599  __kmp_env_consistency_check = FALSE;
3600  } else {
3601  KMP_WARNING(StgInvalidValue, name, value);
3602  }
3603 } // __kmp_stg_parse_consistency_check
3604 
3605 static void __kmp_stg_print_consistency_check(kmp_str_buf_t *buffer,
3606  char const *name, void *data) {
3607 #if KMP_DEBUG
3608  const char *value = NULL;
3609 
3610  if (__kmp_env_consistency_check) {
3611  value = "all";
3612  } else {
3613  value = "none";
3614  }
3615 
3616  if (value != NULL) {
3617  __kmp_stg_print_str(buffer, name, value);
3618  }
3619 #endif /* KMP_DEBUG */
3620 } // __kmp_stg_print_consistency_check
3621 
3622 #if USE_ITT_BUILD
3623 // -----------------------------------------------------------------------------
3624 // KMP_ITT_PREPARE_DELAY
3625 
3626 #if USE_ITT_NOTIFY
3627 
3628 static void __kmp_stg_parse_itt_prepare_delay(char const *name,
3629  char const *value, void *data) {
3630  // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop
3631  // iterations.
3632  int delay = 0;
3633  __kmp_stg_parse_int(name, value, 0, INT_MAX, &delay);
3634  __kmp_itt_prepare_delay = delay;
3635 } // __kmp_str_parse_itt_prepare_delay
3636 
3637 static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t *buffer,
3638  char const *name, void *data) {
3639  __kmp_stg_print_uint64(buffer, name, __kmp_itt_prepare_delay);
3640 
3641 } // __kmp_str_print_itt_prepare_delay
3642 
3643 #endif // USE_ITT_NOTIFY
3644 #endif /* USE_ITT_BUILD */
3645 
3646 // -----------------------------------------------------------------------------
3647 // KMP_MALLOC_POOL_INCR
3648 
3649 static void __kmp_stg_parse_malloc_pool_incr(char const *name,
3650  char const *value, void *data) {
3651  __kmp_stg_parse_size(name, value, KMP_MIN_MALLOC_POOL_INCR,
3652  KMP_MAX_MALLOC_POOL_INCR, NULL, &__kmp_malloc_pool_incr,
3653  1);
3654 } // __kmp_stg_parse_malloc_pool_incr
3655 
3656 static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t *buffer,
3657  char const *name, void *data) {
3658  __kmp_stg_print_size(buffer, name, __kmp_malloc_pool_incr);
3659 
3660 } // _kmp_stg_print_malloc_pool_incr
3661 
3662 #ifdef KMP_DEBUG
3663 
3664 // -----------------------------------------------------------------------------
3665 // KMP_PAR_RANGE
3666 
3667 static void __kmp_stg_parse_par_range_env(char const *name, char const *value,
3668  void *data) {
3669  __kmp_stg_parse_par_range(name, value, &__kmp_par_range,
3670  __kmp_par_range_routine, __kmp_par_range_filename,
3671  &__kmp_par_range_lb, &__kmp_par_range_ub);
3672 } // __kmp_stg_parse_par_range_env
3673 
3674 static void __kmp_stg_print_par_range_env(kmp_str_buf_t *buffer,
3675  char const *name, void *data) {
3676  if (__kmp_par_range != 0) {
3677  __kmp_stg_print_str(buffer, name, par_range_to_print);
3678  }
3679 } // __kmp_stg_print_par_range_env
3680 
3681 // -----------------------------------------------------------------------------
3682 // KMP_YIELD_CYCLE, KMP_YIELD_ON, KMP_YIELD_OFF
3683 
3684 static void __kmp_stg_parse_yield_cycle(char const *name, char const *value,
3685  void *data) {
3686  int flag = __kmp_yield_cycle;
3687  __kmp_stg_parse_bool(name, value, &flag);
3688  __kmp_yield_cycle = flag;
3689 } // __kmp_stg_parse_yield_cycle
3690 
3691 static void __kmp_stg_print_yield_cycle(kmp_str_buf_t *buffer, char const *name,
3692  void *data) {
3693  __kmp_stg_print_bool(buffer, name, __kmp_yield_cycle);
3694 } // __kmp_stg_print_yield_cycle
3695 
3696 static void __kmp_stg_parse_yield_on(char const *name, char const *value,
3697  void *data) {
3698  __kmp_stg_parse_int(name, value, 2, INT_MAX, &__kmp_yield_on_count);
3699 } // __kmp_stg_parse_yield_on
3700 
3701 static void __kmp_stg_print_yield_on(kmp_str_buf_t *buffer, char const *name,
3702  void *data) {
3703  __kmp_stg_print_int(buffer, name, __kmp_yield_on_count);
3704 } // __kmp_stg_print_yield_on
3705 
3706 static void __kmp_stg_parse_yield_off(char const *name, char const *value,
3707  void *data) {
3708  __kmp_stg_parse_int(name, value, 2, INT_MAX, &__kmp_yield_off_count);
3709 } // __kmp_stg_parse_yield_off
3710 
3711 static void __kmp_stg_print_yield_off(kmp_str_buf_t *buffer, char const *name,
3712  void *data) {
3713  __kmp_stg_print_int(buffer, name, __kmp_yield_off_count);
3714 } // __kmp_stg_print_yield_off
3715 
3716 #endif
3717 
3718 // -----------------------------------------------------------------------------
3719 // KMP_INIT_WAIT, KMP_NEXT_WAIT
3720 
3721 static void __kmp_stg_parse_init_wait(char const *name, char const *value,
3722  void *data) {
3723  int wait;
3724  KMP_ASSERT((__kmp_init_wait & 1) == 0);
3725  wait = __kmp_init_wait / 2;
3726  __kmp_stg_parse_int(name, value, KMP_MIN_INIT_WAIT, KMP_MAX_INIT_WAIT, &wait);
3727  __kmp_init_wait = wait * 2;
3728  KMP_ASSERT((__kmp_init_wait & 1) == 0);
3729  __kmp_yield_init = __kmp_init_wait;
3730 } // __kmp_stg_parse_init_wait
3731 
3732 static void __kmp_stg_print_init_wait(kmp_str_buf_t *buffer, char const *name,
3733  void *data) {
3734  __kmp_stg_print_int(buffer, name, __kmp_init_wait);
3735 } // __kmp_stg_print_init_wait
3736 
3737 static void __kmp_stg_parse_next_wait(char const *name, char const *value,
3738  void *data) {
3739  int wait;
3740  KMP_ASSERT((__kmp_next_wait & 1) == 0);
3741  wait = __kmp_next_wait / 2;
3742  __kmp_stg_parse_int(name, value, KMP_MIN_NEXT_WAIT, KMP_MAX_NEXT_WAIT, &wait);
3743  __kmp_next_wait = wait * 2;
3744  KMP_ASSERT((__kmp_next_wait & 1) == 0);
3745  __kmp_yield_next = __kmp_next_wait;
3746 } // __kmp_stg_parse_next_wait
3747 
3748 static void __kmp_stg_print_next_wait(kmp_str_buf_t *buffer, char const *name,
3749  void *data) {
3750  __kmp_stg_print_int(buffer, name, __kmp_next_wait);
3751 } //__kmp_stg_print_next_wait
3752 
3753 // -----------------------------------------------------------------------------
3754 // KMP_GTID_MODE
3755 
3756 static void __kmp_stg_parse_gtid_mode(char const *name, char const *value,
3757  void *data) {
3758  // Modes:
3759  // 0 -- do not change default
3760  // 1 -- sp search
3761  // 2 -- use "keyed" TLS var, i.e.
3762  // pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
3763  // 3 -- __declspec(thread) TLS var in tdata section
3764  int mode = 0;
3765  int max = 2;
3766 #ifdef KMP_TDATA_GTID
3767  max = 3;
3768 #endif /* KMP_TDATA_GTID */
3769  __kmp_stg_parse_int(name, value, 0, max, &mode);
3770  // TODO; parse_int is not very suitable for this case. In case of overflow it
3771  // is better to use 0 rather that max value.
3772  if (mode == 0) {
3773  __kmp_adjust_gtid_mode = TRUE;
3774  } else {
3775  __kmp_gtid_mode = mode;
3776  __kmp_adjust_gtid_mode = FALSE;
3777  }
3778 } // __kmp_str_parse_gtid_mode
3779 
3780 static void __kmp_stg_print_gtid_mode(kmp_str_buf_t *buffer, char const *name,
3781  void *data) {
3782  if (__kmp_adjust_gtid_mode) {
3783  __kmp_stg_print_int(buffer, name, 0);
3784  } else {
3785  __kmp_stg_print_int(buffer, name, __kmp_gtid_mode);
3786  }
3787 } // __kmp_stg_print_gtid_mode
3788 
3789 // -----------------------------------------------------------------------------
3790 // KMP_NUM_LOCKS_IN_BLOCK
3791 
3792 static void __kmp_stg_parse_lock_block(char const *name, char const *value,
3793  void *data) {
3794  __kmp_stg_parse_int(name, value, 0, KMP_INT_MAX, &__kmp_num_locks_in_block);
3795 } // __kmp_str_parse_lock_block
3796 
3797 static void __kmp_stg_print_lock_block(kmp_str_buf_t *buffer, char const *name,
3798  void *data) {
3799  __kmp_stg_print_int(buffer, name, __kmp_num_locks_in_block);
3800 } // __kmp_stg_print_lock_block
3801 
3802 // -----------------------------------------------------------------------------
3803 // KMP_LOCK_KIND
3804 
3805 #if KMP_USE_DYNAMIC_LOCK
3806 #define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a)
3807 #else
3808 #define KMP_STORE_LOCK_SEQ(a)
3809 #endif
3810 
3811 static void __kmp_stg_parse_lock_kind(char const *name, char const *value,
3812  void *data) {
3813  if (__kmp_init_user_locks) {
3814  KMP_WARNING(EnvLockWarn, name);
3815  return;
3816  }
3817 
3818  if (__kmp_str_match("tas", 2, value) ||
3819  __kmp_str_match("test and set", 2, value) ||
3820  __kmp_str_match("test_and_set", 2, value) ||
3821  __kmp_str_match("test-and-set", 2, value) ||
3822  __kmp_str_match("test andset", 2, value) ||
3823  __kmp_str_match("test_andset", 2, value) ||
3824  __kmp_str_match("test-andset", 2, value) ||
3825  __kmp_str_match("testand set", 2, value) ||
3826  __kmp_str_match("testand_set", 2, value) ||
3827  __kmp_str_match("testand-set", 2, value) ||
3828  __kmp_str_match("testandset", 2, value)) {
3829  __kmp_user_lock_kind = lk_tas;
3830  KMP_STORE_LOCK_SEQ(tas);
3831  }
3832 #if KMP_USE_FUTEX
3833  else if (__kmp_str_match("futex", 1, value)) {
3834  if (__kmp_futex_determine_capable()) {
3835  __kmp_user_lock_kind = lk_futex;
3836  KMP_STORE_LOCK_SEQ(futex);
3837  } else {
3838  KMP_WARNING(FutexNotSupported, name, value);
3839  }
3840  }
3841 #endif
3842  else if (__kmp_str_match("ticket", 2, value)) {
3843  __kmp_user_lock_kind = lk_ticket;
3844  KMP_STORE_LOCK_SEQ(ticket);
3845  } else if (__kmp_str_match("queuing", 1, value) ||
3846  __kmp_str_match("queue", 1, value)) {
3847  __kmp_user_lock_kind = lk_queuing;
3848  KMP_STORE_LOCK_SEQ(queuing);
3849  } else if (__kmp_str_match("drdpa ticket", 1, value) ||
3850  __kmp_str_match("drdpa_ticket", 1, value) ||
3851  __kmp_str_match("drdpa-ticket", 1, value) ||
3852  __kmp_str_match("drdpaticket", 1, value) ||
3853  __kmp_str_match("drdpa", 1, value)) {
3854  __kmp_user_lock_kind = lk_drdpa;
3855  KMP_STORE_LOCK_SEQ(drdpa);
3856  }
3857 #if KMP_USE_ADAPTIVE_LOCKS
3858  else if (__kmp_str_match("adaptive", 1, value)) {
3859  if (__kmp_cpuinfo.rtm) { // ??? Is cpuinfo available here?
3860  __kmp_user_lock_kind = lk_adaptive;
3861  KMP_STORE_LOCK_SEQ(adaptive);
3862  } else {
3863  KMP_WARNING(AdaptiveNotSupported, name, value);
3864  __kmp_user_lock_kind = lk_queuing;
3865  KMP_STORE_LOCK_SEQ(queuing);
3866  }
3867  }
3868 #endif // KMP_USE_ADAPTIVE_LOCKS
3869 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
3870  else if (__kmp_str_match("rtm", 1, value)) {
3871  if (__kmp_cpuinfo.rtm) {
3872  __kmp_user_lock_kind = lk_rtm;
3873  KMP_STORE_LOCK_SEQ(rtm);
3874  } else {
3875  KMP_WARNING(AdaptiveNotSupported, name, value);
3876  __kmp_user_lock_kind = lk_queuing;
3877  KMP_STORE_LOCK_SEQ(queuing);
3878  }
3879  } else if (__kmp_str_match("hle", 1, value)) {
3880  __kmp_user_lock_kind = lk_hle;
3881  KMP_STORE_LOCK_SEQ(hle);
3882  }
3883 #endif
3884  else {
3885  KMP_WARNING(StgInvalidValue, name, value);
3886  }
3887 }
3888 
3889 static void __kmp_stg_print_lock_kind(kmp_str_buf_t *buffer, char const *name,
3890  void *data) {
3891  const char *value = NULL;
3892 
3893  switch (__kmp_user_lock_kind) {
3894  case lk_default:
3895  value = "default";
3896  break;
3897 
3898  case lk_tas:
3899  value = "tas";
3900  break;
3901 
3902 #if KMP_USE_FUTEX
3903  case lk_futex:
3904  value = "futex";
3905  break;
3906 #endif
3907 
3908 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
3909  case lk_rtm:
3910  value = "rtm";
3911  break;
3912 
3913  case lk_hle:
3914  value = "hle";
3915  break;
3916 #endif
3917 
3918  case lk_ticket:
3919  value = "ticket";
3920  break;
3921 
3922  case lk_queuing:
3923  value = "queuing";
3924  break;
3925 
3926  case lk_drdpa:
3927  value = "drdpa";
3928  break;
3929 #if KMP_USE_ADAPTIVE_LOCKS
3930  case lk_adaptive:
3931  value = "adaptive";
3932  break;
3933 #endif
3934  }
3935 
3936  if (value != NULL) {
3937  __kmp_stg_print_str(buffer, name, value);
3938  }
3939 }
3940 
3941 // -----------------------------------------------------------------------------
3942 // KMP_SPIN_BACKOFF_PARAMS
3943 
3944 // KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick
3945 // for machine pause)
3946 static void __kmp_stg_parse_spin_backoff_params(const char *name,
3947  const char *value, void *data) {
3948  const char *next = value;
3949 
3950  int total = 0; // Count elements that were set. It'll be used as an array size
3951  int prev_comma = FALSE; // For correct processing sequential commas
3952  int i;
3953 
3954  kmp_uint32 max_backoff = __kmp_spin_backoff_params.max_backoff;
3955  kmp_uint32 min_tick = __kmp_spin_backoff_params.min_tick;
3956 
3957  // Run only 3 iterations because it is enough to read two values or find a
3958  // syntax error
3959  for (i = 0; i < 3; i++) {
3960  SKIP_WS(next);
3961 
3962  if (*next == '\0') {
3963  break;
3964  }
3965  // Next character is not an integer or not a comma OR number of values > 2
3966  // => end of list
3967  if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
3968  KMP_WARNING(EnvSyntaxError, name, value);
3969  return;
3970  }
3971  // The next character is ','
3972  if (*next == ',') {
3973  // ',' is the fisrt character
3974  if (total == 0 || prev_comma) {
3975  total++;
3976  }
3977  prev_comma = TRUE;
3978  next++; // skip ','
3979  SKIP_WS(next);
3980  }
3981  // Next character is a digit
3982  if (*next >= '0' && *next <= '9') {
3983  int num;
3984  const char *buf = next;
3985  char const *msg = NULL;
3986  prev_comma = FALSE;
3987  SKIP_DIGITS(next);
3988  total++;
3989 
3990  const char *tmp = next;
3991  SKIP_WS(tmp);
3992  if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
3993  KMP_WARNING(EnvSpacesNotAllowed, name, value);
3994  return;
3995  }
3996 
3997  num = __kmp_str_to_int(buf, *next);
3998  if (num <= 0) { // The number of retries should be > 0
3999  msg = KMP_I18N_STR(ValueTooSmall);
4000  num = 1;
4001  } else if (num > KMP_INT_MAX) {
4002  msg = KMP_I18N_STR(ValueTooLarge);
4003  num = KMP_INT_MAX;
4004  }
4005  if (msg != NULL) {
4006  // Message is not empty. Print warning.
4007  KMP_WARNING(ParseSizeIntWarn, name, value, msg);
4008  KMP_INFORM(Using_int_Value, name, num);
4009  }
4010  if (total == 1) {
4011  max_backoff = num;
4012  } else if (total == 2) {
4013  min_tick = num;
4014  }
4015  }
4016  }
4017  KMP_DEBUG_ASSERT(total > 0);
4018  if (total <= 0) {
4019  KMP_WARNING(EnvSyntaxError, name, value);
4020  return;
4021  }
4022  __kmp_spin_backoff_params.max_backoff = max_backoff;
4023  __kmp_spin_backoff_params.min_tick = min_tick;
4024 }
4025 
4026 static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t *buffer,
4027  char const *name, void *data) {
4028  if (__kmp_env_format) {
4029  KMP_STR_BUF_PRINT_NAME_EX(name);
4030  } else {
4031  __kmp_str_buf_print(buffer, " %s='", name);
4032  }
4033  __kmp_str_buf_print(buffer, "%d,%d'\n", __kmp_spin_backoff_params.max_backoff,
4034  __kmp_spin_backoff_params.min_tick);
4035 }
4036 
4037 #if KMP_USE_ADAPTIVE_LOCKS
4038 
4039 // -----------------------------------------------------------------------------
4040 // KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE
4041 
4042 // Parse out values for the tunable parameters from a string of the form
4043 // KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]
4044 static void __kmp_stg_parse_adaptive_lock_props(const char *name,
4045  const char *value, void *data) {
4046  int max_retries = 0;
4047  int max_badness = 0;
4048 
4049  const char *next = value;
4050 
4051  int total = 0; // Count elements that were set. It'll be used as an array size
4052  int prev_comma = FALSE; // For correct processing sequential commas
4053  int i;
4054 
4055  // Save values in the structure __kmp_speculative_backoff_params
4056  // Run only 3 iterations because it is enough to read two values or find a
4057  // syntax error
4058  for (i = 0; i < 3; i++) {
4059  SKIP_WS(next);
4060 
4061  if (*next == '\0') {
4062  break;
4063  }
4064  // Next character is not an integer or not a comma OR number of values > 2
4065  // => end of list
4066  if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {
4067  KMP_WARNING(EnvSyntaxError, name, value);
4068  return;
4069  }
4070  // The next character is ','
4071  if (*next == ',') {
4072  // ',' is the fisrt character
4073  if (total == 0 || prev_comma) {
4074  total++;
4075  }
4076  prev_comma = TRUE;
4077  next++; // skip ','
4078  SKIP_WS(next);
4079  }
4080  // Next character is a digit
4081  if (*next >= '0' && *next <= '9') {
4082  int num;
4083  const char *buf = next;
4084  char const *msg = NULL;
4085  prev_comma = FALSE;
4086  SKIP_DIGITS(next);
4087  total++;
4088 
4089  const char *tmp = next;
4090  SKIP_WS(tmp);
4091  if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {
4092  KMP_WARNING(EnvSpacesNotAllowed, name, value);
4093  return;
4094  }
4095 
4096  num = __kmp_str_to_int(buf, *next);
4097  if (num < 0) { // The number of retries should be >= 0
4098  msg = KMP_I18N_STR(ValueTooSmall);
4099  num = 1;
4100  } else if (num > KMP_INT_MAX) {
4101  msg = KMP_I18N_STR(ValueTooLarge);
4102  num = KMP_INT_MAX;
4103  }
4104  if (msg != NULL) {
4105  // Message is not empty. Print warning.
4106  KMP_WARNING(ParseSizeIntWarn, name, value, msg);
4107  KMP_INFORM(Using_int_Value, name, num);
4108  }
4109  if (total == 1) {
4110  max_retries = num;
4111  } else if (total == 2) {
4112  max_badness = num;
4113  }
4114  }
4115  }
4116  KMP_DEBUG_ASSERT(total > 0);
4117  if (total <= 0) {
4118  KMP_WARNING(EnvSyntaxError, name, value);
4119  return;
4120  }
4121  __kmp_adaptive_backoff_params.max_soft_retries = max_retries;
4122  __kmp_adaptive_backoff_params.max_badness = max_badness;
4123 }
4124 
4125 static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t *buffer,
4126  char const *name, void *data) {
4127  if (__kmp_env_format) {
4128  KMP_STR_BUF_PRINT_NAME_EX(name);
4129  } else {
4130  __kmp_str_buf_print(buffer, " %s='", name);
4131  }
4132  __kmp_str_buf_print(buffer, "%d,%d'\n",
4133  __kmp_adaptive_backoff_params.max_soft_retries,
4134  __kmp_adaptive_backoff_params.max_badness);
4135 } // __kmp_stg_print_adaptive_lock_props
4136 
4137 #if KMP_DEBUG_ADAPTIVE_LOCKS
4138 
4139 static void __kmp_stg_parse_speculative_statsfile(char const *name,
4140  char const *value,
4141  void *data) {
4142  __kmp_stg_parse_file(name, value, "", &__kmp_speculative_statsfile);
4143 } // __kmp_stg_parse_speculative_statsfile
4144 
4145 static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t *buffer,
4146  char const *name,
4147  void *data) {
4148  if (__kmp_str_match("-", 0, __kmp_speculative_statsfile)) {
4149  __kmp_stg_print_str(buffer, name, "stdout");
4150  } else {
4151  __kmp_stg_print_str(buffer, name, __kmp_speculative_statsfile);
4152  }
4153 
4154 } // __kmp_stg_print_speculative_statsfile
4155 
4156 #endif // KMP_DEBUG_ADAPTIVE_LOCKS
4157 
4158 #endif // KMP_USE_ADAPTIVE_LOCKS
4159 
4160 // -----------------------------------------------------------------------------
4161 // KMP_HW_SUBSET (was KMP_PLACE_THREADS)
4162 
4163 // The longest observable sequense of items is
4164 // Socket-Node-Tile-Core-Thread
4165 // So, let's limit to 5 levels for now
4166 // The input string is usually short enough, let's use 512 limit for now
4167 #define MAX_T_LEVEL 5
4168 #define MAX_STR_LEN 512
4169 static void __kmp_stg_parse_hw_subset(char const *name, char const *value,
4170  void *data) {
4171  // Value example: 1s,5c@3,2T
4172  // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core"
4173  kmp_setting_t **rivals = (kmp_setting_t **)data;
4174  if (strcmp(name, "KMP_PLACE_THREADS") == 0) {
4175  KMP_INFORM(EnvVarDeprecated, name, "KMP_HW_SUBSET");
4176  }
4177  if (__kmp_stg_check_rivals(name, value, rivals)) {
4178  return;
4179  }
4180 
4181  char *components[MAX_T_LEVEL];
4182  char const *digits = "0123456789";
4183  char input[MAX_STR_LEN];
4184  size_t len = 0, mlen = MAX_STR_LEN;
4185  int level = 0;
4186  // Canonize the string (remove spaces, unify delimiters, etc.)
4187  char *pos = CCAST(char *, value);
4188  while (*pos && mlen) {
4189  if (*pos != ' ') { // skip spaces
4190  if (len == 0 && *pos == ':') {
4191  __kmp_hws_abs_flag = 1; // if the first symbol is ":", skip it
4192  } else {
4193  input[len] = toupper(*pos);
4194  if (input[len] == 'X')
4195  input[len] = ','; // unify delimiters of levels
4196  if (input[len] == 'O' && strchr(digits, *(pos + 1)))
4197  input[len] = '@'; // unify delimiters of offset
4198  len++;
4199  }
4200  }
4201  mlen--;
4202  pos++;
4203  }
4204  if (len == 0 || mlen == 0)
4205  goto err; // contents is either empty or too long
4206  input[len] = '\0';
4207  __kmp_hws_requested = 1; // mark that subset requested
4208  // Split by delimiter
4209  pos = input;
4210  components[level++] = pos;
4211  while ((pos = strchr(pos, ','))) {
4212  *pos = '\0'; // modify input and avoid more copying
4213  components[level++] = ++pos; // expect something after ","
4214  if (level > MAX_T_LEVEL)
4215  goto err; // too many components provided
4216  }
4217  // Check each component
4218  for (int i = 0; i < level; ++i) {
4219  int offset = 0;
4220  int num = atoi(components[i]); // each component should start with a number
4221  if ((pos = strchr(components[i], '@'))) {
4222  offset = atoi(pos + 1); // save offset
4223  *pos = '\0'; // cut the offset from the component
4224  }
4225  pos = components[i] + strspn(components[i], digits);
4226  if (pos == components[i])
4227  goto err;
4228  // detect the component type
4229  switch (*pos) {
4230  case 'S': // Socket
4231  if (__kmp_hws_socket.num > 0)
4232  goto err; // duplicate is not allowed
4233  __kmp_hws_socket.num = num;
4234  __kmp_hws_socket.offset = offset;
4235  break;
4236  case 'N': // NUMA Node
4237  if (__kmp_hws_node.num > 0)
4238  goto err; // duplicate is not allowed
4239  __kmp_hws_node.num = num;
4240  __kmp_hws_node.offset = offset;
4241  break;
4242  case 'L': // Cache
4243  if (*(pos + 1) == '2') { // L2 - Tile
4244  if (__kmp_hws_tile.num > 0)
4245  goto err; // duplicate is not allowed
4246  __kmp_hws_tile.num = num;
4247  __kmp_hws_tile.offset = offset;
4248  } else if (*(pos + 1) == '3') { // L3 - Socket
4249  if (__kmp_hws_socket.num > 0)
4250  goto err; // duplicate is not allowed
4251  __kmp_hws_socket.num = num;
4252  __kmp_hws_socket.offset = offset;
4253  } else if (*(pos + 1) == '1') { // L1 - Core
4254  if (__kmp_hws_core.num > 0)
4255  goto err; // duplicate is not allowed
4256  __kmp_hws_core.num = num;
4257  __kmp_hws_core.offset = offset;
4258  }
4259  break;
4260  case 'C': // Core (or Cache?)
4261  if (*(pos + 1) != 'A') {
4262  if (__kmp_hws_core.num > 0)
4263  goto err; // duplicate is not allowed
4264  __kmp_hws_core.num = num;
4265  __kmp_hws_core.offset = offset;
4266  } else { // Cache
4267  char *d = pos + strcspn(pos, digits); // find digit
4268  if (*d == '2') { // L2 - Tile
4269  if (__kmp_hws_tile.num > 0)
4270  goto err; // duplicate is not allowed
4271  __kmp_hws_tile.num = num;
4272  __kmp_hws_tile.offset = offset;
4273  } else if (*d == '3') { // L3 - Socket
4274  if (__kmp_hws_socket.num > 0)
4275  goto err; // duplicate is not allowed
4276  __kmp_hws_socket.num = num;
4277  __kmp_hws_socket.offset = offset;
4278  } else if (*d == '1') { // L1 - Core
4279  if (__kmp_hws_core.num > 0)
4280  goto err; // duplicate is not allowed
4281  __kmp_hws_core.num = num;
4282  __kmp_hws_core.offset = offset;
4283  } else {
4284  goto err;
4285  }
4286  }
4287  break;
4288  case 'T': // Thread
4289  if (__kmp_hws_proc.num > 0)
4290  goto err; // duplicate is not allowed
4291  __kmp_hws_proc.num = num;
4292  __kmp_hws_proc.offset = offset;
4293  break;
4294  default:
4295  goto err;
4296  }
4297  }
4298  return;
4299 err:
4300  KMP_WARNING(AffHWSubsetInvalid, name, value);
4301  __kmp_hws_requested = 0; // mark that subset not requested
4302  return;
4303 }
4304 
4305 static void __kmp_stg_print_hw_subset(kmp_str_buf_t *buffer, char const *name,
4306  void *data) {
4307  if (__kmp_hws_requested) {
4308  int comma = 0;
4309  kmp_str_buf_t buf;
4310  __kmp_str_buf_init(&buf);
4311  if (__kmp_env_format)
4312  KMP_STR_BUF_PRINT_NAME_EX(name);
4313  else
4314  __kmp_str_buf_print(buffer, " %s='", name);
4315  if (__kmp_hws_socket.num) {
4316  __kmp_str_buf_print(&buf, "%ds", __kmp_hws_socket.num);
4317  if (__kmp_hws_socket.offset)
4318  __kmp_str_buf_print(&buf, "@%d", __kmp_hws_socket.offset);
4319  comma = 1;
4320  }
4321  if (__kmp_hws_node.num) {
4322  __kmp_str_buf_print(&buf, "%s%dn", comma ? "," : "", __kmp_hws_node.num);
4323  if (__kmp_hws_node.offset)
4324  __kmp_str_buf_print(&buf, "@%d", __kmp_hws_node.offset);
4325  comma = 1;
4326  }
4327  if (__kmp_hws_tile.num) {
4328  __kmp_str_buf_print(&buf, "%s%dL2", comma ? "," : "", __kmp_hws_tile.num);
4329  if (__kmp_hws_tile.offset)
4330  __kmp_str_buf_print(&buf, "@%d", __kmp_hws_tile.offset);
4331  comma = 1;
4332  }
4333  if (__kmp_hws_core.num) {
4334  __kmp_str_buf_print(&buf, "%s%dc", comma ? "," : "", __kmp_hws_core.num);
4335  if (__kmp_hws_core.offset)
4336  __kmp_str_buf_print(&buf, "@%d", __kmp_hws_core.offset);
4337  comma = 1;
4338  }
4339  if (__kmp_hws_proc.num)
4340  __kmp_str_buf_print(&buf, "%s%dt", comma ? "," : "", __kmp_hws_proc.num);
4341  __kmp_str_buf_print(buffer, "%s'\n", buf.str);
4342  __kmp_str_buf_free(&buf);
4343  }
4344 }
4345 
4346 #if USE_ITT_BUILD
4347 // -----------------------------------------------------------------------------
4348 // KMP_FORKJOIN_FRAMES
4349 
4350 static void __kmp_stg_parse_forkjoin_frames(char const *name, char const *value,
4351  void *data) {
4352  __kmp_stg_parse_bool(name, value, &__kmp_forkjoin_frames);
4353 } // __kmp_stg_parse_forkjoin_frames
4354 
4355 static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t *buffer,
4356  char const *name, void *data) {
4357  __kmp_stg_print_bool(buffer, name, __kmp_forkjoin_frames);
4358 } // __kmp_stg_print_forkjoin_frames
4359 
4360 // -----------------------------------------------------------------------------
4361 // KMP_FORKJOIN_FRAMES_MODE
4362 
4363 static void __kmp_stg_parse_forkjoin_frames_mode(char const *name,
4364  char const *value,
4365  void *data) {
4366  __kmp_stg_parse_int(name, value, 0, 3, &__kmp_forkjoin_frames_mode);
4367 } // __kmp_stg_parse_forkjoin_frames
4368 
4369 static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t *buffer,
4370  char const *name, void *data) {
4371  __kmp_stg_print_int(buffer, name, __kmp_forkjoin_frames_mode);
4372 } // __kmp_stg_print_forkjoin_frames
4373 #endif /* USE_ITT_BUILD */
4374 
4375 // -----------------------------------------------------------------------------
4376 // OMP_DISPLAY_ENV
4377 
4378 #if OMP_40_ENABLED
4379 
4380 static void __kmp_stg_parse_omp_display_env(char const *name, char const *value,
4381  void *data) {
4382  if (__kmp_str_match("VERBOSE", 1, value)) {
4383  __kmp_display_env_verbose = TRUE;
4384  } else {
4385  __kmp_stg_parse_bool(name, value, &__kmp_display_env);
4386  }
4387 
4388 } // __kmp_stg_parse_omp_display_env
4389 
4390 static void __kmp_stg_print_omp_display_env(kmp_str_buf_t *buffer,
4391  char const *name, void *data) {
4392  if (__kmp_display_env_verbose) {
4393  __kmp_stg_print_str(buffer, name, "VERBOSE");
4394  } else {
4395  __kmp_stg_print_bool(buffer, name, __kmp_display_env);
4396  }
4397 } // __kmp_stg_print_omp_display_env
4398 
4399 static void __kmp_stg_parse_omp_cancellation(char const *name,
4400  char const *value, void *data) {
4401  if (TCR_4(__kmp_init_parallel)) {
4402  KMP_WARNING(EnvParallelWarn, name);
4403  return;
4404  } // read value before first parallel only
4405  __kmp_stg_parse_bool(name, value, &__kmp_omp_cancellation);
4406 } // __kmp_stg_parse_omp_cancellation
4407 
4408 static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t *buffer,
4409  char const *name, void *data) {
4410  __kmp_stg_print_bool(buffer, name, __kmp_omp_cancellation);
4411 } // __kmp_stg_print_omp_cancellation
4412 
4413 #endif
4414 
4415 #if OMP_50_ENABLED && OMPT_SUPPORT
4416 
4417 static char *__kmp_tool_libraries = NULL;
4418 
4419 static void __kmp_stg_parse_omp_tool_libraries(char const *name,
4420  char const *value, void *data) {
4421  __kmp_stg_parse_str(name, value, &__kmp_tool_libraries);
4422 } // __kmp_stg_parse_omp_tool_libraries
4423 
4424 static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t *buffer,
4425  char const *name, void *data) {
4426  if (__kmp_tool_libraries)
4427  __kmp_stg_print_str(buffer, name, __kmp_tool_libraries);
4428  else {
4429  if (__kmp_env_format) {
4430  KMP_STR_BUF_PRINT_NAME;
4431  } else {
4432  __kmp_str_buf_print(buffer, " %s", name);
4433  }
4434  __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));
4435  }
4436 } // __kmp_stg_print_omp_tool_libraries
4437 
4438 #endif
4439 
4440 // Table.
4441 
4442 static kmp_setting_t __kmp_stg_table[] = {
4443 
4444  {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit, NULL, NULL, 0, 0},
4445  {"KMP_BLOCKTIME", __kmp_stg_parse_blocktime, __kmp_stg_print_blocktime,
4446  NULL, 0, 0},
4447  {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok,
4448  __kmp_stg_print_duplicate_lib_ok, NULL, 0, 0},
4449  {"KMP_LIBRARY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy,
4450  NULL, 0, 0},
4451  {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit,
4452  __kmp_stg_print_device_thread_limit, NULL, 0, 0},
4453 #if KMP_USE_MONITOR
4454  {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize,
4455  __kmp_stg_print_monitor_stacksize, NULL, 0, 0},
4456 #endif
4457  {"KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL,
4458  0, 0},
4459  {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset,
4460  __kmp_stg_print_stackoffset, NULL, 0, 0},
4461  {"KMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,
4462  NULL, 0, 0},
4463  {"KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL,
4464  0, 0},
4465  {"KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0,
4466  0},
4467  {"KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL,
4468  0, 0},
4469 
4470  {"OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0},
4471  {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads,
4472  __kmp_stg_print_num_threads, NULL, 0, 0},
4473  {"OMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,
4474  NULL, 0, 0},
4475 
4476  {"KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0,
4477  0},
4478  {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing,
4479  __kmp_stg_print_task_stealing, NULL, 0, 0},
4480  {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels,
4481  __kmp_stg_print_max_active_levels, NULL, 0, 0},
4482 #if OMP_40_ENABLED
4483  {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device,
4484  __kmp_stg_print_default_device, NULL, 0, 0},
4485 #endif
4486 #if OMP_50_ENABLED
4487  {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload,
4488  __kmp_stg_print_target_offload, NULL, 0, 0},
4489 #endif
4490 #if OMP_45_ENABLED
4491  {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority,
4492  __kmp_stg_print_max_task_priority, NULL, 0, 0},
4493  {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks,
4494  __kmp_stg_print_taskloop_min_tasks, NULL, 0, 0},
4495 #endif
4496  {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit,
4497  __kmp_stg_print_thread_limit, NULL, 0, 0},
4498  {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit,
4499  __kmp_stg_print_teams_thread_limit, NULL, 0, 0},
4500  {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy,
4501  __kmp_stg_print_wait_policy, NULL, 0, 0},
4502  {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers,
4503  __kmp_stg_print_disp_buffers, NULL, 0, 0},
4504 #if KMP_NESTED_HOT_TEAMS
4505  {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level,
4506  __kmp_stg_print_hot_teams_level, NULL, 0, 0},
4507  {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode,
4508  __kmp_stg_print_hot_teams_mode, NULL, 0, 0},
4509 #endif // KMP_NESTED_HOT_TEAMS
4510 
4511 #if KMP_HANDLE_SIGNALS
4512  {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals,
4513  __kmp_stg_print_handle_signals, NULL, 0, 0},
4514 #endif
4515 
4516 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
4517  {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control,
4518  __kmp_stg_print_inherit_fp_control, NULL, 0, 0},
4519 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
4520 
4521 #ifdef KMP_GOMP_COMPAT
4522  {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0},
4523 #endif
4524 
4525 #ifdef KMP_DEBUG
4526  {"KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0,
4527  0},
4528  {"KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0,
4529  0},
4530  {"KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0,
4531  0},
4532  {"KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0,
4533  0},
4534  {"KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0,
4535  0},
4536  {"KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0,
4537  0},
4538  {"KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0},
4539  {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf,
4540  NULL, 0, 0},
4541  {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic,
4542  __kmp_stg_print_debug_buf_atomic, NULL, 0, 0},
4543  {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars,
4544  __kmp_stg_print_debug_buf_chars, NULL, 0, 0},
4545  {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines,
4546  __kmp_stg_print_debug_buf_lines, NULL, 0, 0},
4547  {"KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0},
4548 
4549  {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env,
4550  __kmp_stg_print_par_range_env, NULL, 0, 0},
4551  {"KMP_YIELD_CYCLE", __kmp_stg_parse_yield_cycle,
4552  __kmp_stg_print_yield_cycle, NULL, 0, 0},
4553  {"KMP_YIELD_ON", __kmp_stg_parse_yield_on, __kmp_stg_print_yield_on, NULL,
4554  0, 0},
4555  {"KMP_YIELD_OFF", __kmp_stg_parse_yield_off, __kmp_stg_print_yield_off,
4556  NULL, 0, 0},
4557 #endif // KMP_DEBUG
4558 
4559  {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc,
4560  __kmp_stg_print_align_alloc, NULL, 0, 0},
4561 
4562  {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
4563  __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
4564  {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
4565  __kmp_stg_print_barrier_pattern, NULL, 0, 0},
4566  {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,
4567  __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
4568  {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
4569  __kmp_stg_print_barrier_pattern, NULL, 0, 0},
4570 #if KMP_FAST_REDUCTION_BARRIER
4571  {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit,
4572  __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},
4573  {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,
4574  __kmp_stg_print_barrier_pattern, NULL, 0, 0},
4575 #endif
4576 
4577  {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay,
4578  __kmp_stg_print_abort_delay, NULL, 0, 0},
4579  {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file,
4580  __kmp_stg_print_cpuinfo_file, NULL, 0, 0},
4581  {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction,
4582  __kmp_stg_print_force_reduction, NULL, 0, 0},
4583  {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction,
4584  __kmp_stg_print_force_reduction, NULL, 0, 0},
4585  {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map,
4586  __kmp_stg_print_storage_map, NULL, 0, 0},
4587  {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate,
4588  __kmp_stg_print_all_threadprivate, NULL, 0, 0},
4589  {"KMP_FOREIGN_THREADS_THREADPRIVATE",
4590  __kmp_stg_parse_foreign_threads_threadprivate,
4591  __kmp_stg_print_foreign_threads_threadprivate, NULL, 0, 0},
4592 
4593 #if KMP_AFFINITY_SUPPORTED
4594  {"KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL,
4595  0, 0},
4596 #ifdef KMP_GOMP_COMPAT
4597  {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL,
4598  /* no print */ NULL, 0, 0},
4599 #endif /* KMP_GOMP_COMPAT */
4600 #if OMP_40_ENABLED
4601  {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,
4602  NULL, 0, 0},
4603  {"OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0},
4604 #else
4605  {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, NULL, /* no print */ NULL, 0,
4606  0},
4607 #endif /* OMP_40_ENABLED */
4608 
4609  {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method,
4610  __kmp_stg_print_topology_method, NULL, 0, 0},
4611 
4612 #else
4613 
4614 // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
4615 // OMP_PROC_BIND and proc-bind-var are supported, however.
4616 #if OMP_40_ENABLED
4617  {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,
4618  NULL, 0, 0},
4619 #endif
4620 
4621 #endif // KMP_AFFINITY_SUPPORTED
4622 
4623  {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork,
4624  __kmp_stg_print_init_at_fork, NULL, 0, 0},
4625  {"KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL,
4626  0, 0},
4627  {"OMP_SCHEDULE", __kmp_stg_parse_omp_schedule, __kmp_stg_print_omp_schedule,
4628  NULL, 0, 0},
4629  {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode,
4630  __kmp_stg_print_atomic_mode, NULL, 0, 0},
4631  {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check,
4632  __kmp_stg_print_consistency_check, NULL, 0, 0},
4633 
4634 #if USE_ITT_BUILD && USE_ITT_NOTIFY
4635  {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay,
4636  __kmp_stg_print_itt_prepare_delay, NULL, 0, 0},
4637 #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
4638  {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr,
4639  __kmp_stg_print_malloc_pool_incr, NULL, 0, 0},
4640  {"KMP_INIT_WAIT", __kmp_stg_parse_init_wait, __kmp_stg_print_init_wait,
4641  NULL, 0, 0},
4642  {"KMP_NEXT_WAIT", __kmp_stg_parse_next_wait, __kmp_stg_print_next_wait,
4643  NULL, 0, 0},
4644  {"KMP_GTID_MODE", __kmp_stg_parse_gtid_mode, __kmp_stg_print_gtid_mode,
4645  NULL, 0, 0},
4646  {"OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic, __kmp_stg_print_omp_dynamic,
4647  NULL, 0, 0},
4648  {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode,
4649  __kmp_stg_print_kmp_dynamic_mode, NULL, 0, 0},
4650 
4651 #ifdef USE_LOAD_BALANCE
4652  {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval,
4653  __kmp_stg_print_ld_balance_interval, NULL, 0, 0},
4654 #endif
4655 
4656  {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block,
4657  __kmp_stg_print_lock_block, NULL, 0, 0},
4658  {"KMP_LOCK_KIND", __kmp_stg_parse_lock_kind, __kmp_stg_print_lock_kind,
4659  NULL, 0, 0},
4660  {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params,
4661  __kmp_stg_print_spin_backoff_params, NULL, 0, 0},
4662 #if KMP_USE_ADAPTIVE_LOCKS
4663  {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props,
4664  __kmp_stg_print_adaptive_lock_props, NULL, 0, 0},
4665 #if KMP_DEBUG_ADAPTIVE_LOCKS
4666  {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile,
4667  __kmp_stg_print_speculative_statsfile, NULL, 0, 0},
4668 #endif
4669 #endif // KMP_USE_ADAPTIVE_LOCKS
4670  {"KMP_PLACE_THREADS", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,
4671  NULL, 0, 0},
4672  {"KMP_HW_SUBSET", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,
4673  NULL, 0, 0},
4674 #if USE_ITT_BUILD
4675  {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames,
4676  __kmp_stg_print_forkjoin_frames, NULL, 0, 0},
4677  {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode,
4678  __kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0},
4679 #endif
4680 
4681 #if OMP_40_ENABLED
4682  {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env,
4683  __kmp_stg_print_omp_display_env, NULL, 0, 0},
4684  {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation,
4685  __kmp_stg_print_omp_cancellation, NULL, 0, 0},
4686 #endif
4687 
4688 #if OMP_50_ENABLED && OMPT_SUPPORT
4689  {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries,
4690  __kmp_stg_print_omp_tool_libraries, NULL, 0, 0},
4691 #endif
4692 
4693  {"", NULL, NULL, NULL, 0, 0}}; // settings
4694 
4695 static int const __kmp_stg_count =
4696  sizeof(__kmp_stg_table) / sizeof(kmp_setting_t);
4697 
4698 static inline kmp_setting_t *__kmp_stg_find(char const *name) {
4699 
4700  int i;
4701  if (name != NULL) {
4702  for (i = 0; i < __kmp_stg_count; ++i) {
4703  if (strcmp(__kmp_stg_table[i].name, name) == 0) {
4704  return &__kmp_stg_table[i];
4705  }
4706  }
4707  }
4708  return NULL;
4709 
4710 } // __kmp_stg_find
4711 
4712 static int __kmp_stg_cmp(void const *_a, void const *_b) {
4713  const kmp_setting_t *a = RCAST(const kmp_setting_t *, _a);
4714  const kmp_setting_t *b = RCAST(const kmp_setting_t *, _b);
4715 
4716  // Process KMP_AFFINITY last.
4717  // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
4718  if (strcmp(a->name, "KMP_AFFINITY") == 0) {
4719  if (strcmp(b->name, "KMP_AFFINITY") == 0) {
4720  return 0;
4721  }
4722  return 1;
4723  } else if (strcmp(b->name, "KMP_AFFINITY") == 0) {
4724  return -1;
4725  }
4726  return strcmp(a->name, b->name);
4727 } // __kmp_stg_cmp
4728 
4729 static void __kmp_stg_init(void) {
4730 
4731  static int initialized = 0;
4732 
4733  if (!initialized) {
4734 
4735  // Sort table.
4736  qsort(__kmp_stg_table, __kmp_stg_count - 1, sizeof(kmp_setting_t),
4737  __kmp_stg_cmp);
4738 
4739  { // Initialize *_STACKSIZE data.
4740  kmp_setting_t *kmp_stacksize =
4741  __kmp_stg_find("KMP_STACKSIZE"); // 1st priority.
4742 #ifdef KMP_GOMP_COMPAT
4743  kmp_setting_t *gomp_stacksize =
4744  __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority.
4745 #endif
4746  kmp_setting_t *omp_stacksize =
4747  __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority.
4748 
4749  // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
4750  // !!! Compiler does not understand rivals is used and optimizes out
4751  // assignments
4752  // !!! rivals[ i ++ ] = ...;
4753  static kmp_setting_t *volatile rivals[4];
4754  static kmp_stg_ss_data_t kmp_data = {1, CCAST(kmp_setting_t **, rivals)};
4755 #ifdef KMP_GOMP_COMPAT
4756  static kmp_stg_ss_data_t gomp_data = {1024,
4757  CCAST(kmp_setting_t **, rivals)};
4758 #endif
4759  static kmp_stg_ss_data_t omp_data = {1024,
4760  CCAST(kmp_setting_t **, rivals)};
4761  int i = 0;
4762 
4763  rivals[i++] = kmp_stacksize;
4764 #ifdef KMP_GOMP_COMPAT
4765  if (gomp_stacksize != NULL) {
4766  rivals[i++] = gomp_stacksize;
4767  }
4768 #endif
4769  rivals[i++] = omp_stacksize;
4770  rivals[i++] = NULL;
4771 
4772  kmp_stacksize->data = &kmp_data;
4773 #ifdef KMP_GOMP_COMPAT
4774  if (gomp_stacksize != NULL) {
4775  gomp_stacksize->data = &gomp_data;
4776  }
4777 #endif
4778  omp_stacksize->data = &omp_data;
4779  }
4780 
4781  { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
4782  kmp_setting_t *kmp_library =
4783  __kmp_stg_find("KMP_LIBRARY"); // 1st priority.
4784  kmp_setting_t *omp_wait_policy =
4785  __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority.
4786 
4787  // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
4788  static kmp_setting_t *volatile rivals[3];
4789  static kmp_stg_wp_data_t kmp_data = {0, CCAST(kmp_setting_t **, rivals)};
4790  static kmp_stg_wp_data_t omp_data = {1, CCAST(kmp_setting_t **, rivals)};
4791  int i = 0;
4792 
4793  rivals[i++] = kmp_library;
4794  if (omp_wait_policy != NULL) {
4795  rivals[i++] = omp_wait_policy;
4796  }
4797  rivals[i++] = NULL;
4798 
4799  kmp_library->data = &kmp_data;
4800  if (omp_wait_policy != NULL) {
4801  omp_wait_policy->data = &omp_data;
4802  }
4803  }
4804 
4805  { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS
4806  kmp_setting_t *kmp_device_thread_limit =
4807  __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority.
4808  kmp_setting_t *kmp_all_threads =
4809  __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority.
4810 
4811  // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
4812  static kmp_setting_t *volatile rivals[3];
4813  int i = 0;
4814 
4815  rivals[i++] = kmp_device_thread_limit;
4816  rivals[i++] = kmp_all_threads;
4817  rivals[i++] = NULL;
4818 
4819  kmp_device_thread_limit->data = CCAST(kmp_setting_t **, rivals);
4820  kmp_all_threads->data = CCAST(kmp_setting_t **, rivals);
4821  }
4822 
4823  { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS
4824  // 1st priority
4825  kmp_setting_t *kmp_hw_subset = __kmp_stg_find("KMP_HW_SUBSET");
4826  // 2nd priority
4827  kmp_setting_t *kmp_place_threads = __kmp_stg_find("KMP_PLACE_THREADS");
4828 
4829  // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
4830  static kmp_setting_t *volatile rivals[3];
4831  int i = 0;
4832 
4833  rivals[i++] = kmp_hw_subset;
4834  rivals[i++] = kmp_place_threads;
4835  rivals[i++] = NULL;
4836 
4837  kmp_hw_subset->data = CCAST(kmp_setting_t **, rivals);
4838  kmp_place_threads->data = CCAST(kmp_setting_t **, rivals);
4839  }
4840 
4841 #if KMP_AFFINITY_SUPPORTED
4842  { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
4843  kmp_setting_t *kmp_affinity =
4844  __kmp_stg_find("KMP_AFFINITY"); // 1st priority.
4845  KMP_DEBUG_ASSERT(kmp_affinity != NULL);
4846 
4847 #ifdef KMP_GOMP_COMPAT
4848  kmp_setting_t *gomp_cpu_affinity =
4849  __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority.
4850  KMP_DEBUG_ASSERT(gomp_cpu_affinity != NULL);
4851 #endif
4852 
4853  kmp_setting_t *omp_proc_bind =
4854  __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority.
4855  KMP_DEBUG_ASSERT(omp_proc_bind != NULL);
4856 
4857  // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
4858  static kmp_setting_t *volatile rivals[4];
4859  int i = 0;
4860 
4861  rivals[i++] = kmp_affinity;
4862 
4863 #ifdef KMP_GOMP_COMPAT
4864  rivals[i++] = gomp_cpu_affinity;
4865  gomp_cpu_affinity->data = CCAST(kmp_setting_t **, rivals);
4866 #endif
4867 
4868  rivals[i++] = omp_proc_bind;
4869  omp_proc_bind->data = CCAST(kmp_setting_t **, rivals);
4870  rivals[i++] = NULL;
4871 
4872 #if OMP_40_ENABLED
4873  static kmp_setting_t *volatile places_rivals[4];
4874  i = 0;
4875 
4876  kmp_setting_t *omp_places = __kmp_stg_find("OMP_PLACES"); // 3rd priority.
4877  KMP_DEBUG_ASSERT(omp_places != NULL);
4878 
4879  places_rivals[i++] = kmp_affinity;
4880 #ifdef KMP_GOMP_COMPAT
4881  places_rivals[i++] = gomp_cpu_affinity;
4882 #endif
4883  places_rivals[i++] = omp_places;
4884  omp_places->data = CCAST(kmp_setting_t **, places_rivals);
4885  places_rivals[i++] = NULL;
4886 #endif
4887  }
4888 #else
4889 // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
4890 // OMP_PLACES not supported yet.
4891 #endif // KMP_AFFINITY_SUPPORTED
4892 
4893  { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
4894  kmp_setting_t *kmp_force_red =
4895  __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority.
4896  kmp_setting_t *kmp_determ_red =
4897  __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority.
4898 
4899  // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
4900  static kmp_setting_t *volatile rivals[3];
4901  static kmp_stg_fr_data_t force_data = {1,
4902  CCAST(kmp_setting_t **, rivals)};
4903  static kmp_stg_fr_data_t determ_data = {0,
4904  CCAST(kmp_setting_t **, rivals)};
4905  int i = 0;
4906 
4907  rivals[i++] = kmp_force_red;
4908  if (kmp_determ_red != NULL) {
4909  rivals[i++] = kmp_determ_red;
4910  }
4911  rivals[i++] = NULL;
4912 
4913  kmp_force_red->data = &force_data;
4914  if (kmp_determ_red != NULL) {
4915  kmp_determ_red->data = &determ_data;
4916  }
4917  }
4918 
4919  initialized = 1;
4920  }
4921 
4922  // Reset flags.
4923  int i;
4924  for (i = 0; i < __kmp_stg_count; ++i) {
4925  __kmp_stg_table[i].set = 0;
4926  }
4927 
4928 } // __kmp_stg_init
4929 
4930 static void __kmp_stg_parse(char const *name, char const *value) {
4931  // On Windows* OS there are some nameless variables like "C:=C:\" (yeah,
4932  // really nameless, they are presented in environment block as
4933  // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
4934  if (name[0] == 0) {
4935  return;
4936  }
4937 
4938  if (value != NULL) {
4939  kmp_setting_t *setting = __kmp_stg_find(name);
4940  if (setting != NULL) {
4941  setting->parse(name, value, setting->data);
4942  setting->defined = 1;
4943  }
4944  }
4945 
4946 } // __kmp_stg_parse
4947 
4948 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
4949  char const *name, // Name of variable.
4950  char const *value, // Value of the variable.
4951  kmp_setting_t **rivals // List of rival settings (must include current one).
4952  ) {
4953 
4954  if (rivals == NULL) {
4955  return 0;
4956  }
4957 
4958  // Loop thru higher priority settings (listed before current).
4959  int i = 0;
4960  for (; strcmp(rivals[i]->name, name) != 0; i++) {
4961  KMP_DEBUG_ASSERT(rivals[i] != NULL);
4962 
4963 #if KMP_AFFINITY_SUPPORTED
4964  if (rivals[i] == __kmp_affinity_notype) {
4965  // If KMP_AFFINITY is specified without a type name,
4966  // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
4967  continue;
4968  }
4969 #endif
4970 
4971  if (rivals[i]->set) {
4972  KMP_WARNING(StgIgnored, name, rivals[i]->name);
4973  return 1;
4974  }
4975  }
4976 
4977  ++i; // Skip current setting.
4978  return 0;
4979 
4980 } // __kmp_stg_check_rivals
4981 
4982 static int __kmp_env_toPrint(char const *name, int flag) {
4983  int rc = 0;
4984  kmp_setting_t *setting = __kmp_stg_find(name);
4985  if (setting != NULL) {
4986  rc = setting->defined;
4987  if (flag >= 0) {
4988  setting->defined = flag;
4989  }
4990  }
4991  return rc;
4992 }
4993 
4994 static void __kmp_aux_env_initialize(kmp_env_blk_t *block) {
4995 
4996  char const *value;
4997 
4998  /* OMP_NUM_THREADS */
4999  value = __kmp_env_blk_var(block, "OMP_NUM_THREADS");
5000  if (value) {
5001  ompc_set_num_threads(__kmp_dflt_team_nth);
5002  }
5003 
5004  /* KMP_BLOCKTIME */
5005  value = __kmp_env_blk_var(block, "KMP_BLOCKTIME");
5006  if (value) {
5007  kmpc_set_blocktime(__kmp_dflt_blocktime);
5008  }
5009 
5010  /* OMP_NESTED */
5011  value = __kmp_env_blk_var(block, "OMP_NESTED");
5012  if (value) {
5013  ompc_set_nested(__kmp_dflt_nested);
5014  }
5015 
5016  /* OMP_DYNAMIC */
5017  value = __kmp_env_blk_var(block, "OMP_DYNAMIC");
5018  if (value) {
5019  ompc_set_dynamic(__kmp_global.g.g_dynamic);
5020  }
5021 }
5022 
5023 void __kmp_env_initialize(char const *string) {
5024 
5025  kmp_env_blk_t block;
5026  int i;
5027 
5028  __kmp_stg_init();
5029 
5030  // Hack!!!
5031  if (string == NULL) {
5032  // __kmp_max_nth = __kmp_sys_max_nth;
5033  __kmp_threads_capacity =
5034  __kmp_initial_threads_capacity(__kmp_dflt_team_nth_ub);
5035  }
5036  __kmp_env_blk_init(&block, string);
5037 
5038  // update the set flag on all entries that have an env var
5039  for (i = 0; i < block.count; ++i) {
5040  if ((block.vars[i].name == NULL) || (*block.vars[i].name == '\0')) {
5041  continue;
5042  }
5043  if (block.vars[i].value == NULL) {
5044  continue;
5045  }
5046  kmp_setting_t *setting = __kmp_stg_find(block.vars[i].name);
5047  if (setting != NULL) {
5048  setting->set = 1;
5049  }
5050  }
5051 
5052  // We need to know if blocktime was set when processing OMP_WAIT_POLICY
5053  blocktime_str = __kmp_env_blk_var(&block, "KMP_BLOCKTIME");
5054 
5055  // Special case. If we parse environment, not a string, process KMP_WARNINGS
5056  // first.
5057  if (string == NULL) {
5058  char const *name = "KMP_WARNINGS";
5059  char const *value = __kmp_env_blk_var(&block, name);
5060  __kmp_stg_parse(name, value);
5061  }
5062 
5063 #if KMP_AFFINITY_SUPPORTED
5064  // Special case. KMP_AFFINITY is not a rival to other affinity env vars
5065  // if no affinity type is specified. We want to allow
5066  // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when
5067  // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
5068  // affinity mechanism.
5069  __kmp_affinity_notype = NULL;
5070  char const *aff_str = __kmp_env_blk_var(&block, "KMP_AFFINITY");
5071  if (aff_str != NULL) {
5072 // Check if the KMP_AFFINITY type is specified in the string.
5073 // We just search the string for "compact", "scatter", etc.
5074 // without really parsing the string. The syntax of the
5075 // KMP_AFFINITY env var is such that none of the affinity
5076 // type names can appear anywhere other that the type
5077 // specifier, even as substrings.
5078 //
5079 // I can't find a case-insensitive version of strstr on Windows* OS.
5080 // Use the case-sensitive version for now.
5081 
5082 #if KMP_OS_WINDOWS
5083 #define FIND strstr
5084 #else
5085 #define FIND strcasestr
5086 #endif
5087 
5088  if ((FIND(aff_str, "none") == NULL) &&
5089  (FIND(aff_str, "physical") == NULL) &&
5090  (FIND(aff_str, "logical") == NULL) &&
5091  (FIND(aff_str, "compact") == NULL) &&
5092  (FIND(aff_str, "scatter") == NULL) &&
5093  (FIND(aff_str, "explicit") == NULL) &&
5094  (FIND(aff_str, "balanced") == NULL) &&
5095  (FIND(aff_str, "disabled") == NULL)) {
5096  __kmp_affinity_notype = __kmp_stg_find("KMP_AFFINITY");
5097  } else {
5098  // A new affinity type is specified.
5099  // Reset the affinity flags to their default values,
5100  // in case this is called from kmp_set_defaults().
5101  __kmp_affinity_type = affinity_default;
5102  __kmp_affinity_gran = affinity_gran_default;
5103  __kmp_affinity_top_method = affinity_top_method_default;
5104  __kmp_affinity_respect_mask = affinity_respect_mask_default;
5105  }
5106 #undef FIND
5107 
5108 #if OMP_40_ENABLED
5109  // Also reset the affinity flags if OMP_PROC_BIND is specified.
5110  aff_str = __kmp_env_blk_var(&block, "OMP_PROC_BIND");
5111  if (aff_str != NULL) {
5112  __kmp_affinity_type = affinity_default;
5113  __kmp_affinity_gran = affinity_gran_default;
5114  __kmp_affinity_top_method = affinity_top_method_default;
5115  __kmp_affinity_respect_mask = affinity_respect_mask_default;
5116  }
5117 #endif /* OMP_40_ENABLED */
5118  }
5119 
5120 #endif /* KMP_AFFINITY_SUPPORTED */
5121 
5122 #if OMP_40_ENABLED
5123  // Set up the nested proc bind type vector.
5124  if (__kmp_nested_proc_bind.bind_types == NULL) {
5125  __kmp_nested_proc_bind.bind_types =
5126  (kmp_proc_bind_t *)KMP_INTERNAL_MALLOC(sizeof(kmp_proc_bind_t));
5127  if (__kmp_nested_proc_bind.bind_types == NULL) {
5128  KMP_FATAL(MemoryAllocFailed);
5129  }
5130  __kmp_nested_proc_bind.size = 1;
5131  __kmp_nested_proc_bind.used = 1;
5132 #if KMP_AFFINITY_SUPPORTED
5133  __kmp_nested_proc_bind.bind_types[0] = proc_bind_default;
5134 #else
5135  // default proc bind is false if affinity not supported
5136  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5137 #endif
5138  }
5139 #endif /* OMP_40_ENABLED */
5140 
5141  // Now process all of the settings.
5142  for (i = 0; i < block.count; ++i) {
5143  __kmp_stg_parse(block.vars[i].name, block.vars[i].value);
5144  }
5145 
5146  // If user locks have been allocated yet, don't reset the lock vptr table.
5147  if (!__kmp_init_user_locks) {
5148  if (__kmp_user_lock_kind == lk_default) {
5149  __kmp_user_lock_kind = lk_queuing;
5150  }
5151 #if KMP_USE_DYNAMIC_LOCK
5152  __kmp_init_dynamic_user_locks();
5153 #else
5154  __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);
5155 #endif
5156  } else {
5157  KMP_DEBUG_ASSERT(string != NULL); // kmp_set_defaults() was called
5158  KMP_DEBUG_ASSERT(__kmp_user_lock_kind != lk_default);
5159 // Binds lock functions again to follow the transition between different
5160 // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
5161 // as we do not allow lock kind changes after making a call to any
5162 // user lock functions (true).
5163 #if KMP_USE_DYNAMIC_LOCK
5164  __kmp_init_dynamic_user_locks();
5165 #else
5166  __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);
5167 #endif
5168  }
5169 
5170 #if KMP_AFFINITY_SUPPORTED
5171 
5172  if (!TCR_4(__kmp_init_middle)) {
5173 #if KMP_USE_HWLOC
5174  // Force using hwloc when either tiles or numa nodes requested within
5175  // KMP_HW_SUBSET and no other topology method is requested
5176  if ((__kmp_hws_node.num > 0 || __kmp_hws_tile.num > 0 ||
5177  __kmp_affinity_gran == affinity_gran_tile) &&
5178  (__kmp_affinity_top_method == affinity_top_method_default)) {
5179  __kmp_affinity_top_method = affinity_top_method_hwloc;
5180  }
5181 #endif
5182  // Determine if the machine/OS is actually capable of supporting
5183  // affinity.
5184  const char *var = "KMP_AFFINITY";
5185  KMPAffinity::pick_api();
5186 #if KMP_USE_HWLOC
5187  // If Hwloc topology discovery was requested but affinity was also disabled,
5188  // then tell user that Hwloc request is being ignored and use default
5189  // topology discovery method.
5190  if (__kmp_affinity_top_method == affinity_top_method_hwloc &&
5191  __kmp_affinity_dispatch->get_api_type() != KMPAffinity::HWLOC) {
5192  KMP_WARNING(AffIgnoringHwloc, var);
5193  __kmp_affinity_top_method = affinity_top_method_all;
5194  }
5195 #endif
5196  if (__kmp_affinity_type == affinity_disabled) {
5197  KMP_AFFINITY_DISABLE();
5198  } else if (!KMP_AFFINITY_CAPABLE()) {
5199  __kmp_affinity_dispatch->determine_capable(var);
5200  if (!KMP_AFFINITY_CAPABLE()) {
5201  if (__kmp_affinity_verbose ||
5202  (__kmp_affinity_warnings &&
5203  (__kmp_affinity_type != affinity_default) &&
5204  (__kmp_affinity_type != affinity_none) &&
5205  (__kmp_affinity_type != affinity_disabled))) {
5206  KMP_WARNING(AffNotSupported, var);
5207  }
5208  __kmp_affinity_type = affinity_disabled;
5209  __kmp_affinity_respect_mask = 0;
5210  __kmp_affinity_gran = affinity_gran_fine;
5211  }
5212  }
5213 
5214 #if OMP_40_ENABLED
5215  if (__kmp_affinity_type == affinity_disabled) {
5216  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5217  } else if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_true) {
5218  // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
5219  __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread;
5220  }
5221 #endif /* OMP_40_ENABLED */
5222 
5223  if (KMP_AFFINITY_CAPABLE()) {
5224 
5225 #if KMP_GROUP_AFFINITY
5226  // This checks to see if the initial affinity mask is equal
5227  // to a single windows processor group. If it is, then we do
5228  // not respect the initial affinity mask and instead, use the
5229  // entire machine.
5230  bool exactly_one_group = false;
5231  if (__kmp_num_proc_groups > 1) {
5232  int group;
5233  bool within_one_group;
5234  // Get the initial affinity mask and determine if it is
5235  // contained within a single group.
5236  kmp_affin_mask_t *init_mask;
5237  KMP_CPU_ALLOC(init_mask);
5238  __kmp_get_system_affinity(init_mask, TRUE);
5239  group = __kmp_get_proc_group(init_mask);
5240  within_one_group = (group >= 0);
5241  // If the initial affinity is within a single group,
5242  // then determine if it is equal to that single group.
5243  if (within_one_group) {
5244  DWORD num_bits_in_group = __kmp_GetActiveProcessorCount(group);
5245  int num_bits_in_mask = 0;
5246  for (int bit = init_mask->begin(); bit != init_mask->end();
5247  bit = init_mask->next(bit))
5248  num_bits_in_mask++;
5249  exactly_one_group = (num_bits_in_group == num_bits_in_mask);
5250  }
5251  KMP_CPU_FREE(init_mask);
5252  }
5253 
5254  // Handle the Win 64 group affinity stuff if there are multiple
5255  // processor groups, or if the user requested it, and OMP 4.0
5256  // affinity is not in effect.
5257  if (((__kmp_num_proc_groups > 1) &&
5258  (__kmp_affinity_type == affinity_default)
5259 #if OMP_40_ENABLED
5260  && (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default))
5261 #endif
5262  || (__kmp_affinity_top_method == affinity_top_method_group)) {
5263  if (__kmp_affinity_respect_mask == affinity_respect_mask_default &&
5264  exactly_one_group) {
5265  __kmp_affinity_respect_mask = FALSE;
5266  }
5267  if (__kmp_affinity_type == affinity_default) {
5268  __kmp_affinity_type = affinity_compact;
5269 #if OMP_40_ENABLED
5270  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5271 #endif
5272  }
5273  if (__kmp_affinity_top_method == affinity_top_method_default) {
5274  if (__kmp_affinity_gran == affinity_gran_default) {
5275  __kmp_affinity_top_method = affinity_top_method_group;
5276  __kmp_affinity_gran = affinity_gran_group;
5277  } else if (__kmp_affinity_gran == affinity_gran_group) {
5278  __kmp_affinity_top_method = affinity_top_method_group;
5279  } else {
5280  __kmp_affinity_top_method = affinity_top_method_all;
5281  }
5282  } else if (__kmp_affinity_top_method == affinity_top_method_group) {
5283  if (__kmp_affinity_gran == affinity_gran_default) {
5284  __kmp_affinity_gran = affinity_gran_group;
5285  } else if ((__kmp_affinity_gran != affinity_gran_group) &&
5286  (__kmp_affinity_gran != affinity_gran_fine) &&
5287  (__kmp_affinity_gran != affinity_gran_thread)) {
5288  const char *str = NULL;
5289  switch (__kmp_affinity_gran) {
5290  case affinity_gran_core:
5291  str = "core";
5292  break;
5293  case affinity_gran_package:
5294  str = "package";
5295  break;
5296  case affinity_gran_node:
5297  str = "node";
5298  break;
5299  case affinity_gran_tile:
5300  str = "tile";
5301  break;
5302  default:
5303  KMP_DEBUG_ASSERT(0);
5304  }
5305  KMP_WARNING(AffGranTopGroup, var, str);
5306  __kmp_affinity_gran = affinity_gran_fine;
5307  }
5308  } else {
5309  if (__kmp_affinity_gran == affinity_gran_default) {
5310  __kmp_affinity_gran = affinity_gran_core;
5311  } else if (__kmp_affinity_gran == affinity_gran_group) {
5312  const char *str = NULL;
5313  switch (__kmp_affinity_type) {
5314  case affinity_physical:
5315  str = "physical";
5316  break;
5317  case affinity_logical:
5318  str = "logical";
5319  break;
5320  case affinity_compact:
5321  str = "compact";
5322  break;
5323  case affinity_scatter:
5324  str = "scatter";
5325  break;
5326  case affinity_explicit:
5327  str = "explicit";
5328  break;
5329  // No MIC on windows, so no affinity_balanced case
5330  default:
5331  KMP_DEBUG_ASSERT(0);
5332  }
5333  KMP_WARNING(AffGranGroupType, var, str);
5334  __kmp_affinity_gran = affinity_gran_core;
5335  }
5336  }
5337  } else
5338 
5339 #endif /* KMP_GROUP_AFFINITY */
5340 
5341  {
5342  if (__kmp_affinity_respect_mask == affinity_respect_mask_default) {
5343 #if KMP_GROUP_AFFINITY
5344  if (__kmp_num_proc_groups > 1 && exactly_one_group) {
5345  __kmp_affinity_respect_mask = FALSE;
5346  } else
5347 #endif /* KMP_GROUP_AFFINITY */
5348  {
5349  __kmp_affinity_respect_mask = TRUE;
5350  }
5351  }
5352 #if OMP_40_ENABLED
5353  if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) &&
5354  (__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) {
5355  if (__kmp_affinity_type == affinity_default) {
5356  __kmp_affinity_type = affinity_compact;
5357  __kmp_affinity_dups = FALSE;
5358  }
5359  } else
5360 #endif /* OMP_40_ENABLED */
5361  if (__kmp_affinity_type == affinity_default) {
5362 #if OMP_40_ENABLED
5363 #if KMP_MIC_SUPPORTED
5364  if (__kmp_mic_type != non_mic) {
5365  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5366  } else
5367 #endif
5368  {
5369  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5370  }
5371 #endif /* OMP_40_ENABLED */
5372 #if KMP_MIC_SUPPORTED
5373  if (__kmp_mic_type != non_mic) {
5374  __kmp_affinity_type = affinity_scatter;
5375  } else
5376 #endif
5377  {
5378  __kmp_affinity_type = affinity_none;
5379  }
5380  }
5381  if ((__kmp_affinity_gran == affinity_gran_default) &&
5382  (__kmp_affinity_gran_levels < 0)) {
5383 #if KMP_MIC_SUPPORTED
5384  if (__kmp_mic_type != non_mic) {
5385  __kmp_affinity_gran = affinity_gran_fine;
5386  } else
5387 #endif
5388  {
5389  __kmp_affinity_gran = affinity_gran_core;
5390  }
5391  }
5392  if (__kmp_affinity_top_method == affinity_top_method_default) {
5393  __kmp_affinity_top_method = affinity_top_method_all;
5394  }
5395  }
5396  }
5397 
5398  K_DIAG(1, ("__kmp_affinity_type == %d\n", __kmp_affinity_type));
5399  K_DIAG(1, ("__kmp_affinity_compact == %d\n", __kmp_affinity_compact));
5400  K_DIAG(1, ("__kmp_affinity_offset == %d\n", __kmp_affinity_offset));
5401  K_DIAG(1, ("__kmp_affinity_verbose == %d\n", __kmp_affinity_verbose));
5402  K_DIAG(1, ("__kmp_affinity_warnings == %d\n", __kmp_affinity_warnings));
5403  K_DIAG(1, ("__kmp_affinity_respect_mask == %d\n",
5404  __kmp_affinity_respect_mask));
5405  K_DIAG(1, ("__kmp_affinity_gran == %d\n", __kmp_affinity_gran));
5406 
5407  KMP_DEBUG_ASSERT(__kmp_affinity_type != affinity_default);
5408 #if OMP_40_ENABLED
5409  KMP_DEBUG_ASSERT(__kmp_nested_proc_bind.bind_types[0] != proc_bind_default);
5410  K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n",
5411  __kmp_nested_proc_bind.bind_types[0]));
5412 #endif
5413  }
5414 
5415 #endif /* KMP_AFFINITY_SUPPORTED */
5416 
5417  if (__kmp_version) {
5418  __kmp_print_version_1();
5419  }
5420 
5421  // Post-initialization step: some env. vars need their value's further
5422  // processing
5423  if (string != NULL) { // kmp_set_defaults() was called
5424  __kmp_aux_env_initialize(&block);
5425  }
5426 
5427  __kmp_env_blk_free(&block);
5428 
5429  KMP_MB();
5430 
5431 } // __kmp_env_initialize
5432 
5433 void __kmp_env_print() {
5434 
5435  kmp_env_blk_t block;
5436  int i;
5437  kmp_str_buf_t buffer;
5438 
5439  __kmp_stg_init();
5440  __kmp_str_buf_init(&buffer);
5441 
5442  __kmp_env_blk_init(&block, NULL);
5443  __kmp_env_blk_sort(&block);
5444 
5445  // Print real environment values.
5446  __kmp_str_buf_print(&buffer, "\n%s\n\n", KMP_I18N_STR(UserSettings));
5447  for (i = 0; i < block.count; ++i) {
5448  char const *name = block.vars[i].name;
5449  char const *value = block.vars[i].value;
5450  if ((KMP_STRLEN(name) > 4 && strncmp(name, "KMP_", 4) == 0) ||
5451  strncmp(name, "OMP_", 4) == 0
5452 #ifdef KMP_GOMP_COMPAT
5453  || strncmp(name, "GOMP_", 5) == 0
5454 #endif // KMP_GOMP_COMPAT
5455  ) {
5456  __kmp_str_buf_print(&buffer, " %s=%s\n", name, value);
5457  }
5458  }
5459  __kmp_str_buf_print(&buffer, "\n");
5460 
5461  // Print internal (effective) settings.
5462  __kmp_str_buf_print(&buffer, "%s\n\n", KMP_I18N_STR(EffectiveSettings));
5463  for (int i = 0; i < __kmp_stg_count; ++i) {
5464  if (__kmp_stg_table[i].print != NULL) {
5465  __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
5466  __kmp_stg_table[i].data);
5467  }
5468  }
5469 
5470  __kmp_printf("%s", buffer.str);
5471 
5472  __kmp_env_blk_free(&block);
5473  __kmp_str_buf_free(&buffer);
5474 
5475  __kmp_printf("\n");
5476 
5477 } // __kmp_env_print
5478 
5479 #if OMP_40_ENABLED
5480 void __kmp_env_print_2() {
5481 
5482  kmp_env_blk_t block;
5483  kmp_str_buf_t buffer;
5484 
5485  __kmp_env_format = 1;
5486 
5487  __kmp_stg_init();
5488  __kmp_str_buf_init(&buffer);
5489 
5490  __kmp_env_blk_init(&block, NULL);
5491  __kmp_env_blk_sort(&block);
5492 
5493  __kmp_str_buf_print(&buffer, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin));
5494  __kmp_str_buf_print(&buffer, " _OPENMP='%d'\n", __kmp_openmp_version);
5495 
5496  for (int i = 0; i < __kmp_stg_count; ++i) {
5497  if (__kmp_stg_table[i].print != NULL &&
5498  ((__kmp_display_env &&
5499  strncmp(__kmp_stg_table[i].name, "OMP_", 4) == 0) ||
5500  __kmp_display_env_verbose)) {
5501  __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,
5502  __kmp_stg_table[i].data);
5503  }
5504  }
5505 
5506  __kmp_str_buf_print(&buffer, "%s\n", KMP_I18N_STR(DisplayEnvEnd));
5507  __kmp_str_buf_print(&buffer, "\n");
5508 
5509  __kmp_printf("%s", buffer.str);
5510 
5511  __kmp_env_blk_free(&block);
5512  __kmp_str_buf_free(&buffer);
5513 
5514  __kmp_printf("\n");
5515 
5516 } // __kmp_env_print_2
5517 #endif // OMP_40_ENABLED
5518 
5519 // end of file