brintos

brintos / llvm-project-archived public Read only

0
0
Text · 225.3 KiB · b6e7e9c Raw
6626 lines · cpp
1/*2 * kmp_settings.cpp -- Initialize environment variables3 */4 5//===----------------------------------------------------------------------===//6//7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.8// See https://llvm.org/LICENSE.txt for license information.9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception10//11//===----------------------------------------------------------------------===//12 13#include "kmp.h"14#include "kmp_affinity.h"15#include "kmp_atomic.h"16#if KMP_USE_HIER_SCHED17#include "kmp_dispatch_hier.h"18#endif19#include "kmp_environment.h"20#include "kmp_i18n.h"21#include "kmp_io.h"22#include "kmp_itt.h"23#include "kmp_lock.h"24#include "kmp_settings.h"25#include "kmp_str.h"26#include "kmp_wrapper_getpid.h"27#include <ctype.h> // toupper()28#if OMPD_SUPPORT29#include "ompd-specific.h"30#endif31 32static int __kmp_env_toPrint(char const *name, int flag);33 34bool __kmp_env_format = 0; // 0 - old format; 1 - new format35 36// -----------------------------------------------------------------------------37// Helper string functions. Subject to move to kmp_str.38 39#ifdef USE_LOAD_BALANCE40static double __kmp_convert_to_double(char const *s) {41  double result;42 43  if (KMP_SSCANF(s, "%lf", &result) < 1) {44    result = 0.0;45  }46 47  return result;48}49#endif50 51#ifdef KMP_DEBUG52static unsigned int __kmp_readstr_with_sentinel(char *dest, char const *src,53                                                size_t len, char sentinel) {54  unsigned int i;55  for (i = 0; i < len; i++) {56    if ((*src == '\0') || (*src == sentinel)) {57      break;58    }59    *(dest++) = *(src++);60  }61  *dest = '\0';62  return i;63}64#endif65 66static int __kmp_match_with_sentinel(char const *a, char const *b, size_t len,67                                     char sentinel) {68  size_t l = 0;69 70  if (a == NULL)71    a = "";72  if (b == NULL)73    b = "";74  while (*a && *b && *b != sentinel) {75    char ca = *a, cb = *b;76 77    if (ca >= 'a' && ca <= 'z')78      ca -= 'a' - 'A';79    if (cb >= 'a' && cb <= 'z')80      cb -= 'a' - 'A';81    if (ca != cb)82      return FALSE;83    ++l;84    ++a;85    ++b;86  }87  return l >= len;88}89 90// Expected usage:91//     token is the token to check for.92//     buf is the string being parsed.93//     *end returns the char after the end of the token.94//        it is not modified unless a match occurs.95//96// Example 1:97//98//     if (__kmp_match_str("token", buf, *end) {99//         <do something>100//         buf = end;101//     }102//103//  Example 2:104//105//     if (__kmp_match_str("token", buf, *end) {106//         char *save = **end;107//         **end = sentinel;108//         <use any of the __kmp*_with_sentinel() functions>109//         **end = save;110//         buf = end;111//     }112 113static int __kmp_match_str(char const *token, char const *buf,114                           const char **end) {115 116  KMP_ASSERT(token != NULL);117  KMP_ASSERT(buf != NULL);118  KMP_ASSERT(end != NULL);119 120  while (*token && *buf) {121    char ct = *token, cb = *buf;122 123    if (ct >= 'a' && ct <= 'z')124      ct -= 'a' - 'A';125    if (cb >= 'a' && cb <= 'z')126      cb -= 'a' - 'A';127    if (ct != cb)128      return FALSE;129    ++token;130    ++buf;131  }132  if (*token) {133    return FALSE;134  }135  *end = buf;136  return TRUE;137}138 139#if KMP_OS_DARWIN140static size_t __kmp_round4k(size_t size) {141  size_t _4k = 4 * 1024;142  if (size & (_4k - 1)) {143    size &= ~(_4k - 1);144    if (size <= KMP_SIZE_T_MAX - _4k) {145      size += _4k; // Round up if there is no overflow.146    }147  }148  return size;149} // __kmp_round4k150#endif151 152static int __kmp_strcasecmp_with_sentinel(char const *a, char const *b,153                                          char sentinel) {154  if (a == NULL)155    a = "";156  if (b == NULL)157    b = "";158  while (*a && *b && *b != sentinel) {159    char ca = *a, cb = *b;160 161    if (ca >= 'a' && ca <= 'z')162      ca -= 'a' - 'A';163    if (cb >= 'a' && cb <= 'z')164      cb -= 'a' - 'A';165    if (ca != cb)166      return (int)(unsigned char)*a - (int)(unsigned char)*b;167    ++a;168    ++b;169  }170  return *a                       ? (*b && *b != sentinel)171                                        ? (int)(unsigned char)*a - (int)(unsigned char)*b172                                        : 1173         : (*b && *b != sentinel) ? -1174                                  : 0;175}176 177// =============================================================================178// Table structures and helper functions.179 180typedef struct __kmp_setting kmp_setting_t;181typedef struct __kmp_stg_ss_data kmp_stg_ss_data_t;182typedef struct __kmp_stg_wp_data kmp_stg_wp_data_t;183typedef struct __kmp_stg_fr_data kmp_stg_fr_data_t;184 185typedef void (*kmp_stg_parse_func_t)(char const *name, char const *value,186                                     void *data);187typedef void (*kmp_stg_print_func_t)(kmp_str_buf_t *buffer, char const *name,188                                     void *data);189 190struct __kmp_setting {191  char const *name; // Name of setting (environment variable).192  kmp_stg_parse_func_t parse; // Parser function.193  kmp_stg_print_func_t print; // Print function.194  void *data; // Data passed to parser and printer.195  int set; // Variable set during this "session"196  //     (__kmp_env_initialize() or kmp_set_defaults() call).197  int defined; // Variable set in any "session".198}; // struct __kmp_setting199 200struct __kmp_stg_ss_data {201  size_t factor; // Default factor: 1 for KMP_STACKSIZE, 1024 for others.202  kmp_setting_t **rivals; // Array of pointers to rivals (including itself).203}; // struct __kmp_stg_ss_data204 205struct __kmp_stg_wp_data {206  int omp; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY.207  kmp_setting_t **rivals; // Array of pointers to rivals (including itself).208}; // struct __kmp_stg_wp_data209 210struct __kmp_stg_fr_data {211  int force; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION.212  kmp_setting_t **rivals; // Array of pointers to rivals (including itself).213}; // struct __kmp_stg_fr_data214 215static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.216    char const *name, // Name of variable.217    char const *value, // Value of the variable.218    kmp_setting_t **rivals // List of rival settings (must include current one).219);220 221// Helper struct that trims heading/trailing white spaces222struct kmp_trimmed_str_t {223  kmp_str_buf_t buf;224  kmp_trimmed_str_t(const char *str) {225    __kmp_str_buf_init(&buf);226    size_t len = KMP_STRLEN(str);227    if (len == 0)228      return;229    const char *begin = str;230    const char *end = str + KMP_STRLEN(str) - 1;231    SKIP_WS(begin);232    while (begin < end && *end == ' ')233      end--;234    __kmp_str_buf_cat(&buf, begin, end - begin + 1);235  }236  ~kmp_trimmed_str_t() { __kmp_str_buf_free(&buf); }237  const char *get() { return buf.str; }238};239 240// -----------------------------------------------------------------------------241// Helper parse functions.242 243static void __kmp_stg_parse_bool(char const *name, char const *value,244                                 int *out) {245  if (__kmp_str_match_true(value)) {246    *out = TRUE;247  } else if (__kmp_str_match_false(value)) {248    *out = FALSE;249  } else {250    __kmp_msg(kmp_ms_warning, KMP_MSG(BadBoolValue, name, value),251              KMP_HNT(ValidBoolValues), __kmp_msg_null);252  }253} // __kmp_stg_parse_bool254 255// placed here in order to use __kmp_round4k static function256void __kmp_check_stksize(size_t *val) {257  // if system stack size is too big then limit the size for worker threads258#if KMP_OS_AIX259  if (*val > KMP_DEFAULT_STKSIZE * 2) // Use 2 times, 16 is too large for AIX.260    *val = KMP_DEFAULT_STKSIZE * 2;261#else262  if (*val > KMP_DEFAULT_STKSIZE * 16) // just a heuristics...263    *val = KMP_DEFAULT_STKSIZE * 16;264#endif265  if (*val < __kmp_sys_min_stksize)266    *val = __kmp_sys_min_stksize;267  if (*val > KMP_MAX_STKSIZE)268    *val = KMP_MAX_STKSIZE; // dead code currently, but may work in future269#if KMP_OS_DARWIN270  *val = __kmp_round4k(*val);271#endif // KMP_OS_DARWIN272}273 274static void __kmp_stg_parse_size(char const *name, char const *value,275                                 size_t size_min, size_t size_max,276                                 int *is_specified, size_t *out,277                                 size_t factor) {278  char const *msg = NULL;279#if KMP_OS_DARWIN280  size_min = __kmp_round4k(size_min);281  size_max = __kmp_round4k(size_max);282#endif // KMP_OS_DARWIN283  if (value) {284    if (is_specified != NULL) {285      *is_specified = 1;286    }287    __kmp_str_to_size(value, out, factor, &msg);288    if (msg == NULL) {289      if (*out > size_max) {290        *out = size_max;291        msg = KMP_I18N_STR(ValueTooLarge);292      } else if (*out < size_min) {293        *out = size_min;294        msg = KMP_I18N_STR(ValueTooSmall);295      } else {296#if KMP_OS_DARWIN297        size_t round4k = __kmp_round4k(*out);298        if (*out != round4k) {299          *out = round4k;300          msg = KMP_I18N_STR(NotMultiple4K);301        }302#endif303      }304    } else {305      // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to306      // size_max silently.307      if (*out < size_min) {308        *out = size_max;309      } else if (*out > size_max) {310        *out = size_max;311      }312    }313    if (msg != NULL) {314      // Message is not empty. Print warning.315      kmp_str_buf_t buf;316      __kmp_str_buf_init(&buf);317      __kmp_str_buf_print_size(&buf, *out);318      KMP_WARNING(ParseSizeIntWarn, name, value, msg);319      KMP_INFORM(Using_str_Value, name, buf.str);320      __kmp_str_buf_free(&buf);321    }322  }323} // __kmp_stg_parse_size324 325static void __kmp_stg_parse_str(char const *name, char const *value,326                                char **out) {327  __kmp_str_free(out);328  *out = __kmp_str_format("%s", value);329} // __kmp_stg_parse_str330 331static void __kmp_stg_parse_int(332    char const333        *name, // I: Name of environment variable (used in warning messages).334    char const *value, // I: Value of environment variable to parse.335    int min, // I: Minimum allowed value.336    int max, // I: Maximum allowed value.337    int *out // O: Output (parsed) value.338) {339  char const *msg = NULL;340  kmp_uint64 uint = *out;341  __kmp_str_to_uint(value, &uint, &msg);342  if (msg == NULL) {343    if (uint < (unsigned int)min) {344      msg = KMP_I18N_STR(ValueTooSmall);345      uint = min;346    } else if (uint > (unsigned int)max) {347      msg = KMP_I18N_STR(ValueTooLarge);348      uint = max;349    }350  } else {351    // If overflow occurred msg contains error message and uint is very big. Cut352    // tmp it to INT_MAX.353    if (uint < (unsigned int)min) {354      uint = min;355    } else if (uint > (unsigned int)max) {356      uint = max;357    }358  }359  if (msg != NULL) {360    // Message is not empty. Print warning.361    kmp_str_buf_t buf;362    KMP_WARNING(ParseSizeIntWarn, name, value, msg);363    __kmp_str_buf_init(&buf);364    __kmp_str_buf_print(&buf, "%" KMP_UINT64_SPEC "", uint);365    KMP_INFORM(Using_uint64_Value, name, buf.str);366    __kmp_str_buf_free(&buf);367  }368  __kmp_type_convert(uint, out);369} // __kmp_stg_parse_int370 371#if KMP_DEBUG_ADAPTIVE_LOCKS372static void __kmp_stg_parse_file(char const *name, char const *value,373                                 const char *suffix, char **out) {374  char buffer[256];375  char *t;376  int hasSuffix;377  __kmp_str_free(out);378  t = (char *)strrchr(value, '.');379  hasSuffix = t && __kmp_str_eqf(t, suffix);380  t = __kmp_str_format("%s%s", value, hasSuffix ? "" : suffix);381  __kmp_expand_file_name(buffer, sizeof(buffer), t);382  __kmp_str_free(&t);383  *out = __kmp_str_format("%s", buffer);384} // __kmp_stg_parse_file385#endif386 387#ifdef KMP_DEBUG388static char *par_range_to_print = NULL;389 390static void __kmp_stg_parse_par_range(char const *name, char const *value,391                                      int *out_range, char *out_routine,392                                      char *out_file, int *out_lb,393                                      int *out_ub) {394  const char *par_range_value;395  size_t len = KMP_STRLEN(value) + 1;396  par_range_to_print = (char *)KMP_INTERNAL_MALLOC(len + 1);397  KMP_STRNCPY_S(par_range_to_print, len + 1, value, len + 1);398  __kmp_par_range = +1;399  __kmp_par_range_lb = 0;400  __kmp_par_range_ub = INT_MAX;401  for (;;) {402    unsigned int len;403    if (!value || *value == '\0') {404      break;405    }406    if (!__kmp_strcasecmp_with_sentinel("routine", value, '=')) {407      par_range_value = strchr(value, '=') + 1;408      if (!par_range_value)409        goto par_range_error;410      value = par_range_value;411      len = __kmp_readstr_with_sentinel(out_routine, value,412                                        KMP_PAR_RANGE_ROUTINE_LEN - 1, ',');413      if (len == 0) {414        goto par_range_error;415      }416      value = strchr(value, ',');417      if (value != NULL) {418        value++;419      }420      continue;421    }422    if (!__kmp_strcasecmp_with_sentinel("filename", value, '=')) {423      par_range_value = strchr(value, '=') + 1;424      if (!par_range_value)425        goto par_range_error;426      value = par_range_value;427      len = __kmp_readstr_with_sentinel(out_file, value,428                                        KMP_PAR_RANGE_FILENAME_LEN - 1, ',');429      if (len == 0) {430        goto par_range_error;431      }432      value = strchr(value, ',');433      if (value != NULL) {434        value++;435      }436      continue;437    }438    if ((!__kmp_strcasecmp_with_sentinel("range", value, '=')) ||439        (!__kmp_strcasecmp_with_sentinel("incl_range", value, '='))) {440      par_range_value = strchr(value, '=') + 1;441      if (!par_range_value)442        goto par_range_error;443      value = par_range_value;444      if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {445        goto par_range_error;446      }447      *out_range = +1;448      value = strchr(value, ',');449      if (value != NULL) {450        value++;451      }452      continue;453    }454    if (!__kmp_strcasecmp_with_sentinel("excl_range", value, '=')) {455      par_range_value = strchr(value, '=') + 1;456      if (!par_range_value)457        goto par_range_error;458      value = par_range_value;459      if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) {460        goto par_range_error;461      }462      *out_range = -1;463      value = strchr(value, ',');464      if (value != NULL) {465        value++;466      }467      continue;468    }469  par_range_error:470    KMP_WARNING(ParRangeSyntax, name);471    __kmp_par_range = 0;472    break;473  }474} // __kmp_stg_parse_par_range475#endif476 477int __kmp_initial_threads_capacity(int req_nproc) {478  int nth = 32;479 480  /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),481   * __kmp_max_nth) */482  if (nth < (4 * req_nproc))483    nth = (4 * req_nproc);484  if (nth < (4 * __kmp_xproc))485    nth = (4 * __kmp_xproc);486 487  // If hidden helper task is enabled, we initialize the thread capacity with488  // extra __kmp_hidden_helper_threads_num.489  if (__kmp_enable_hidden_helper) {490    nth += __kmp_hidden_helper_threads_num;491  }492 493  if (nth > __kmp_max_nth)494    nth = __kmp_max_nth;495 496  return nth;497}498 499int __kmp_default_tp_capacity(int req_nproc, int max_nth,500                              int all_threads_specified) {501  int nth = 128;502 503  if (all_threads_specified)504    return max_nth;505  /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),506   * __kmp_max_nth ) */507  if (nth < (4 * req_nproc))508    nth = (4 * req_nproc);509  if (nth < (4 * __kmp_xproc))510    nth = (4 * __kmp_xproc);511 512  if (nth > __kmp_max_nth)513    nth = __kmp_max_nth;514 515  return nth;516}517 518// -----------------------------------------------------------------------------519// Helper print functions.520 521static void __kmp_stg_print_bool(kmp_str_buf_t *buffer, char const *name,522                                 int value) {523  if (__kmp_env_format) {524    KMP_STR_BUF_PRINT_BOOL;525  } else {526    __kmp_str_buf_print(buffer, "   %s=%s\n", name, value ? "true" : "false");527  }528} // __kmp_stg_print_bool529 530static void __kmp_stg_print_int(kmp_str_buf_t *buffer, char const *name,531                                int value) {532  if (__kmp_env_format) {533    KMP_STR_BUF_PRINT_INT;534  } else {535    __kmp_str_buf_print(buffer, "   %s=%d\n", name, value);536  }537} // __kmp_stg_print_int538 539static void __kmp_stg_print_uint64(kmp_str_buf_t *buffer, char const *name,540                                   kmp_uint64 value) {541  if (__kmp_env_format) {542    KMP_STR_BUF_PRINT_UINT64;543  } else {544    __kmp_str_buf_print(buffer, "   %s=%" KMP_UINT64_SPEC "\n", name, value);545  }546} // __kmp_stg_print_uint64547 548static void __kmp_stg_print_str(kmp_str_buf_t *buffer, char const *name,549                                char const *value) {550  if (__kmp_env_format) {551    KMP_STR_BUF_PRINT_STR;552  } else {553    __kmp_str_buf_print(buffer, "   %s=%s\n", name, value);554  }555} // __kmp_stg_print_str556 557static void __kmp_stg_print_size(kmp_str_buf_t *buffer, char const *name,558                                 size_t value) {559  if (__kmp_env_format) {560    KMP_STR_BUF_PRINT_NAME_EX(name);561    __kmp_str_buf_print_size(buffer, value);562    __kmp_str_buf_print(buffer, "'\n");563  } else {564    __kmp_str_buf_print(buffer, "   %s=", name);565    __kmp_str_buf_print_size(buffer, value);566    __kmp_str_buf_print(buffer, "\n");567    return;568  }569} // __kmp_stg_print_size570 571// =============================================================================572// Parse and print functions.573 574// -----------------------------------------------------------------------------575// KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS576 577static void __kmp_stg_parse_device_thread_limit(char const *name,578                                                char const *value, void *data) {579  kmp_setting_t **rivals = (kmp_setting_t **)data;580  int rc;581  if (strcmp(name, "KMP_ALL_THREADS") == 0) {582    KMP_INFORM(EnvVarDeprecated, name, "KMP_DEVICE_THREAD_LIMIT");583  }584  rc = __kmp_stg_check_rivals(name, value, rivals);585  if (rc) {586    return;587  }588  if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {589    __kmp_max_nth = __kmp_xproc;590    __kmp_allThreadsSpecified = 1;591  } else {592    __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_max_nth);593    __kmp_allThreadsSpecified = 0;594  }595  K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth));596 597} // __kmp_stg_parse_device_thread_limit598 599static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t *buffer,600                                                char const *name, void *data) {601  __kmp_stg_print_int(buffer, name, __kmp_max_nth);602} // __kmp_stg_print_device_thread_limit603 604// -----------------------------------------------------------------------------605// OMP_THREAD_LIMIT606static void __kmp_stg_parse_thread_limit(char const *name, char const *value,607                                         void *data) {608  __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_cg_max_nth);609  K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth));610 611} // __kmp_stg_parse_thread_limit612 613static void __kmp_stg_print_thread_limit(kmp_str_buf_t *buffer,614                                         char const *name, void *data) {615  __kmp_stg_print_int(buffer, name, __kmp_cg_max_nth);616} // __kmp_stg_print_thread_limit617 618// -----------------------------------------------------------------------------619// OMP_NUM_TEAMS620static void __kmp_stg_parse_nteams(char const *name, char const *value,621                                   void *data) {622  __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_nteams);623  K_DIAG(1, ("__kmp_nteams == %d\n", __kmp_nteams));624} // __kmp_stg_parse_nteams625 626static void __kmp_stg_print_nteams(kmp_str_buf_t *buffer, char const *name,627                                   void *data) {628  __kmp_stg_print_int(buffer, name, __kmp_nteams);629} // __kmp_stg_print_nteams630 631// -----------------------------------------------------------------------------632// OMP_TEAMS_THREAD_LIMIT633static void __kmp_stg_parse_teams_th_limit(char const *name, char const *value,634                                           void *data) {635  __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth,636                      &__kmp_teams_thread_limit);637  K_DIAG(1, ("__kmp_teams_thread_limit == %d\n", __kmp_teams_thread_limit));638} // __kmp_stg_parse_teams_th_limit639 640static void __kmp_stg_print_teams_th_limit(kmp_str_buf_t *buffer,641                                           char const *name, void *data) {642  __kmp_stg_print_int(buffer, name, __kmp_teams_thread_limit);643} // __kmp_stg_print_teams_th_limit644 645// -----------------------------------------------------------------------------646// KMP_TEAMS_THREAD_LIMIT647static void __kmp_stg_parse_teams_thread_limit(char const *name,648                                               char const *value, void *data) {649  __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_teams_max_nth);650} // __kmp_stg_teams_thread_limit651 652static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t *buffer,653                                               char const *name, void *data) {654  __kmp_stg_print_int(buffer, name, __kmp_teams_max_nth);655} // __kmp_stg_print_teams_thread_limit656 657// -----------------------------------------------------------------------------658// KMP_USE_YIELD659static void __kmp_stg_parse_use_yield(char const *name, char const *value,660                                      void *data) {661  __kmp_stg_parse_int(name, value, 0, 2, &__kmp_use_yield);662  __kmp_use_yield_exp_set = 1;663} // __kmp_stg_parse_use_yield664 665static void __kmp_stg_print_use_yield(kmp_str_buf_t *buffer, char const *name,666                                      void *data) {667  __kmp_stg_print_int(buffer, name, __kmp_use_yield);668} // __kmp_stg_print_use_yield669 670// -----------------------------------------------------------------------------671// KMP_BLOCKTIME672 673static void __kmp_stg_parse_blocktime(char const *name, char const *value,674                                      void *data) {675  const char *buf = value;676  const char *next;677  const int ms_mult = 1000;678  int multiplier = 1;679  int num;680 681  // Read integer blocktime value682  SKIP_WS(buf);683  if ((*buf >= '0') && (*buf <= '9')) {684    next = buf;685    SKIP_DIGITS(next);686    num = __kmp_basic_str_to_int(buf);687    KMP_ASSERT(num >= 0);688    buf = next;689    SKIP_WS(buf);690  } else {691    num = -1;692  }693 694  // Read units: note that __kmp_dflt_blocktime units is now us695  next = buf;696  if (*buf == '\0' || __kmp_match_str("ms", buf, &next)) {697    // units are in ms; convert698    __kmp_dflt_blocktime = ms_mult * num;699    __kmp_blocktime_units = 'm';700    multiplier = ms_mult;701  } else if (__kmp_match_str("us", buf, &next)) {702    // units are in us703    __kmp_dflt_blocktime = num;704    __kmp_blocktime_units = 'u';705  } else if (__kmp_match_str("infinite", buf, &next) ||706             __kmp_match_str("infinity", buf, &next)) {707    // units are in ms708    __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;709    __kmp_blocktime_units = 'm';710    multiplier = ms_mult;711  } else {712    KMP_WARNING(StgInvalidValue, name, value);713    // default units are in ms714    __kmp_dflt_blocktime = ms_mult * num;715    __kmp_blocktime_units = 'm';716    multiplier = ms_mult;717  }718 719  if (num < 0 && __kmp_dflt_blocktime < 0) { // num out of range720    __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME; // now in us721    __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidValue, name, value),722              __kmp_msg_null);723    // Inform in appropriate units724    KMP_INFORM(Using_int_Value, name, __kmp_dflt_blocktime / multiplier);725    __kmp_env_blocktime = FALSE; // Revert to default as if var not set.726  } else if (num > 0 && __kmp_dflt_blocktime < 0) { // overflow727    __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;728    __kmp_msg(kmp_ms_warning, KMP_MSG(LargeValue, name, value), __kmp_msg_null);729    KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime / multiplier);730    __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified.731  } else {732    if (__kmp_dflt_blocktime < KMP_MIN_BLOCKTIME) {733      __kmp_dflt_blocktime = KMP_MIN_BLOCKTIME;734      __kmp_msg(kmp_ms_warning, KMP_MSG(SmallValue, name, value),735                __kmp_msg_null);736      KMP_INFORM(MinValueUsing, name, __kmp_dflt_blocktime / multiplier);737    } else if (__kmp_dflt_blocktime > KMP_MAX_BLOCKTIME) {738      __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;739      __kmp_msg(kmp_ms_warning, KMP_MSG(LargeValue, name, value),740                __kmp_msg_null);741      KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime / multiplier);742    }743    __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified.744  }745#if KMP_USE_MONITOR746  // calculate number of monitor thread wakeup intervals corresponding to747  // blocktime.748  __kmp_monitor_wakeups =749      KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);750  __kmp_bt_intervals =751      KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups);752#endif753  K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime));754  if (__kmp_env_blocktime) {755    K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime));756  }757} // __kmp_stg_parse_blocktime758 759static void __kmp_stg_print_blocktime(kmp_str_buf_t *buffer, char const *name,760                                      void *data) {761  int num = __kmp_dflt_blocktime;762  if (__kmp_blocktime_units == 'm') {763    num = num / 1000;764  }765  if (__kmp_env_format) {766    KMP_STR_BUF_PRINT_NAME_EX(name);767  } else {768    __kmp_str_buf_print(buffer, "   %s=", name);769  }770  __kmp_str_buf_print(buffer, "%d", num);771  __kmp_str_buf_print(buffer, "%cs\n", __kmp_blocktime_units);772} // __kmp_stg_print_blocktime773 774// -----------------------------------------------------------------------------775// KMP_DUPLICATE_LIB_OK776 777static void __kmp_stg_parse_duplicate_lib_ok(char const *name,778                                             char const *value, void *data) {779  /* actually this variable is not supported, put here for compatibility with780     earlier builds and for static/dynamic combination */781  __kmp_stg_parse_bool(name, value, &__kmp_duplicate_library_ok);782} // __kmp_stg_parse_duplicate_lib_ok783 784static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t *buffer,785                                             char const *name, void *data) {786  __kmp_stg_print_bool(buffer, name, __kmp_duplicate_library_ok);787} // __kmp_stg_print_duplicate_lib_ok788 789// -----------------------------------------------------------------------------790// KMP_INHERIT_FP_CONTROL791 792#if KMP_ARCH_X86 || KMP_ARCH_X86_64793 794static void __kmp_stg_parse_inherit_fp_control(char const *name,795                                               char const *value, void *data) {796  __kmp_stg_parse_bool(name, value, &__kmp_inherit_fp_control);797} // __kmp_stg_parse_inherit_fp_control798 799static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t *buffer,800                                               char const *name, void *data) {801#if KMP_DEBUG802  __kmp_stg_print_bool(buffer, name, __kmp_inherit_fp_control);803#endif /* KMP_DEBUG */804} // __kmp_stg_print_inherit_fp_control805 806#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */807 808// Used for OMP_WAIT_POLICY809static char const *blocktime_str = NULL;810 811// -----------------------------------------------------------------------------812// KMP_LIBRARY, OMP_WAIT_POLICY813 814static void __kmp_stg_parse_wait_policy(char const *name, char const *value,815                                        void *data) {816 817  kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data;818  int rc;819 820  rc = __kmp_stg_check_rivals(name, value, wait->rivals);821  if (rc) {822    return;823  }824 825  if (wait->omp) {826    if (__kmp_str_match("ACTIVE", 1, value)) {827      __kmp_library = library_turnaround;828      if (blocktime_str == NULL) {829        // KMP_BLOCKTIME not specified, so set default to "infinite".830        __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;831      }832    } else if (__kmp_str_match("PASSIVE", 1, value)) {833      __kmp_library = library_throughput;834      __kmp_wpolicy_passive = true; /* allow sleep while active tasking */835      if (blocktime_str == NULL) {836        // KMP_BLOCKTIME not specified, so set default to 0.837        __kmp_dflt_blocktime = 0;838      }839    } else {840      KMP_WARNING(StgInvalidValue, name, value);841    }842  } else {843    if (__kmp_str_match("serial", 1, value)) { /* S */844      __kmp_library = library_serial;845    } else if (__kmp_str_match("throughput", 2, value)) { /* TH */846      __kmp_library = library_throughput;847      if (blocktime_str == NULL) {848        // KMP_BLOCKTIME not specified, so set default to 0.849        __kmp_dflt_blocktime = 0;850      }851    } else if (__kmp_str_match("turnaround", 2, value)) { /* TU */852      __kmp_library = library_turnaround;853    } else if (__kmp_str_match("dedicated", 1, value)) { /* D */854      __kmp_library = library_turnaround;855    } else if (__kmp_str_match("multiuser", 1, value)) { /* M */856      __kmp_library = library_throughput;857      if (blocktime_str == NULL) {858        // KMP_BLOCKTIME not specified, so set default to 0.859        __kmp_dflt_blocktime = 0;860      }861    } else {862      KMP_WARNING(StgInvalidValue, name, value);863    }864  }865} // __kmp_stg_parse_wait_policy866 867static void __kmp_stg_print_wait_policy(kmp_str_buf_t *buffer, char const *name,868                                        void *data) {869 870  kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data;871  char const *value = NULL;872 873  if (wait->omp) {874    switch (__kmp_library) {875    case library_turnaround: {876      value = "ACTIVE";877    } break;878    case library_throughput: {879      value = "PASSIVE";880    } break;881    case library_none:882    case library_serial: {883      value = NULL;884    } break;885    }886  } else {887    switch (__kmp_library) {888    case library_serial: {889      value = "serial";890    } break;891    case library_turnaround: {892      value = "turnaround";893    } break;894    case library_throughput: {895      value = "throughput";896    } break;897    case library_none: {898      value = NULL;899    } break;900    }901  }902  if (value != NULL) {903    __kmp_stg_print_str(buffer, name, value);904  }905 906} // __kmp_stg_print_wait_policy907 908#if KMP_USE_MONITOR909// -----------------------------------------------------------------------------910// KMP_MONITOR_STACKSIZE911 912static void __kmp_stg_parse_monitor_stacksize(char const *name,913                                              char const *value, void *data) {914  __kmp_stg_parse_size(name, value, __kmp_sys_min_stksize, KMP_MAX_STKSIZE,915                       NULL, &__kmp_monitor_stksize, 1);916} // __kmp_stg_parse_monitor_stacksize917 918static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t *buffer,919                                              char const *name, void *data) {920  if (__kmp_env_format) {921    if (__kmp_monitor_stksize > 0)922      KMP_STR_BUF_PRINT_NAME_EX(name);923    else924      KMP_STR_BUF_PRINT_NAME;925  } else {926    __kmp_str_buf_print(buffer, "   %s", name);927  }928  if (__kmp_monitor_stksize > 0) {929    __kmp_str_buf_print_size(buffer, __kmp_monitor_stksize);930  } else {931    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));932  }933  if (__kmp_env_format && __kmp_monitor_stksize) {934    __kmp_str_buf_print(buffer, "'\n");935  }936} // __kmp_stg_print_monitor_stacksize937#endif // KMP_USE_MONITOR938 939// -----------------------------------------------------------------------------940// KMP_SETTINGS941 942static void __kmp_stg_parse_settings(char const *name, char const *value,943                                     void *data) {944  __kmp_stg_parse_bool(name, value, &__kmp_settings);945} // __kmp_stg_parse_settings946 947static void __kmp_stg_print_settings(kmp_str_buf_t *buffer, char const *name,948                                     void *data) {949  __kmp_stg_print_bool(buffer, name, __kmp_settings);950} // __kmp_stg_print_settings951 952// -----------------------------------------------------------------------------953// KMP_STACKPAD954 955static void __kmp_stg_parse_stackpad(char const *name, char const *value,956                                     void *data) {957  __kmp_stg_parse_int(name, // Env var name958                      value, // Env var value959                      KMP_MIN_STKPADDING, // Min value960                      KMP_MAX_STKPADDING, // Max value961                      &__kmp_stkpadding // Var to initialize962  );963} // __kmp_stg_parse_stackpad964 965static void __kmp_stg_print_stackpad(kmp_str_buf_t *buffer, char const *name,966                                     void *data) {967  __kmp_stg_print_int(buffer, name, __kmp_stkpadding);968} // __kmp_stg_print_stackpad969 970// -----------------------------------------------------------------------------971// KMP_STACKOFFSET972 973static void __kmp_stg_parse_stackoffset(char const *name, char const *value,974                                        void *data) {975  __kmp_stg_parse_size(name, // Env var name976                       value, // Env var value977                       KMP_MIN_STKOFFSET, // Min value978                       KMP_MAX_STKOFFSET, // Max value979                       NULL, //980                       &__kmp_stkoffset, // Var to initialize981                       1);982} // __kmp_stg_parse_stackoffset983 984static void __kmp_stg_print_stackoffset(kmp_str_buf_t *buffer, char const *name,985                                        void *data) {986  __kmp_stg_print_size(buffer, name, __kmp_stkoffset);987} // __kmp_stg_print_stackoffset988 989// -----------------------------------------------------------------------------990// KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE991 992static void __kmp_stg_parse_stacksize(char const *name, char const *value,993                                      void *data) {994 995  kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data;996  int rc;997 998  rc = __kmp_stg_check_rivals(name, value, stacksize->rivals);999  if (rc) {1000    return;1001  }1002  __kmp_stg_parse_size(name, // Env var name1003                       value, // Env var value1004                       __kmp_sys_min_stksize, // Min value1005                       KMP_MAX_STKSIZE, // Max value1006                       &__kmp_env_stksize, //1007                       &__kmp_stksize, // Var to initialize1008                       stacksize->factor);1009 1010} // __kmp_stg_parse_stacksize1011 1012// This function is called for printing both KMP_STACKSIZE (factor is 1) and1013// OMP_STACKSIZE (factor is 1024). Currently it is not possible to print1014// OMP_STACKSIZE value in bytes. We can consider adding this possibility by a1015// customer request in future.1016static void __kmp_stg_print_stacksize(kmp_str_buf_t *buffer, char const *name,1017                                      void *data) {1018  kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data;1019  if (__kmp_env_format) {1020    KMP_STR_BUF_PRINT_NAME_EX(name);1021    __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024)1022                                         ? __kmp_stksize / stacksize->factor1023                                         : __kmp_stksize);1024    __kmp_str_buf_print(buffer, "'\n");1025  } else {1026    __kmp_str_buf_print(buffer, "   %s=", name);1027    __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024)1028                                         ? __kmp_stksize / stacksize->factor1029                                         : __kmp_stksize);1030    __kmp_str_buf_print(buffer, "\n");1031  }1032} // __kmp_stg_print_stacksize1033 1034// -----------------------------------------------------------------------------1035// KMP_VERSION1036 1037static void __kmp_stg_parse_version(char const *name, char const *value,1038                                    void *data) {1039  __kmp_stg_parse_bool(name, value, &__kmp_version);1040} // __kmp_stg_parse_version1041 1042static void __kmp_stg_print_version(kmp_str_buf_t *buffer, char const *name,1043                                    void *data) {1044  __kmp_stg_print_bool(buffer, name, __kmp_version);1045} // __kmp_stg_print_version1046 1047// -----------------------------------------------------------------------------1048// KMP_WARNINGS1049 1050static void __kmp_stg_parse_warnings(char const *name, char const *value,1051                                     void *data) {1052  __kmp_stg_parse_bool(name, value, &__kmp_generate_warnings);1053  if (__kmp_generate_warnings != kmp_warnings_off) {1054    // AC: only 0/1 values documented, so reset to explicit to distinguish from1055    // default setting1056    __kmp_generate_warnings = kmp_warnings_explicit;1057  }1058} // __kmp_stg_parse_warnings1059 1060static void __kmp_stg_print_warnings(kmp_str_buf_t *buffer, char const *name,1061                                     void *data) {1062  // AC: TODO: change to print_int? (needs documentation change)1063  __kmp_stg_print_bool(buffer, name, __kmp_generate_warnings);1064} // __kmp_stg_print_warnings1065 1066// -----------------------------------------------------------------------------1067// KMP_NESTING_MODE1068 1069static void __kmp_stg_parse_nesting_mode(char const *name, char const *value,1070                                         void *data) {1071  __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_nesting_mode);1072#if KMP_HWLOC_ENABLED1073  if (__kmp_nesting_mode > 0)1074    __kmp_affinity_top_method = affinity_top_method_hwloc;1075#endif // KMP_HWLOC_ENABLED1076} // __kmp_stg_parse_nesting_mode1077 1078static void __kmp_stg_print_nesting_mode(kmp_str_buf_t *buffer,1079                                         char const *name, void *data) {1080  if (__kmp_env_format) {1081    KMP_STR_BUF_PRINT_NAME;1082  } else {1083    __kmp_str_buf_print(buffer, "   %s", name);1084  }1085  __kmp_str_buf_print(buffer, "=%d\n", __kmp_nesting_mode);1086} // __kmp_stg_print_nesting_mode1087 1088// -----------------------------------------------------------------------------1089// OMP_NESTED, OMP_NUM_THREADS1090 1091static void __kmp_stg_parse_nested(char const *name, char const *value,1092                                   void *data) {1093  int nested;1094  KMP_INFORM(EnvVarDeprecated, name, "OMP_MAX_ACTIVE_LEVELS");1095  __kmp_stg_parse_bool(name, value, &nested);1096  if (nested) {1097    if (!__kmp_dflt_max_active_levels_set)1098      __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;1099  } else { // nesting explicitly turned off1100    __kmp_dflt_max_active_levels = 1;1101    __kmp_dflt_max_active_levels_set = true;1102  }1103} // __kmp_stg_parse_nested1104 1105static void __kmp_stg_print_nested(kmp_str_buf_t *buffer, char const *name,1106                                   void *data) {1107  if (__kmp_env_format) {1108    KMP_STR_BUF_PRINT_NAME;1109  } else {1110    __kmp_str_buf_print(buffer, "   %s", name);1111  }1112  __kmp_str_buf_print(buffer, ": deprecated; max-active-levels-var=%d\n",1113                      __kmp_dflt_max_active_levels);1114} // __kmp_stg_print_nested1115 1116static void __kmp_parse_nested_num_threads(const char *var, const char *env,1117                                           kmp_nested_nthreads_t *nth_array) {1118  const char *next = env;1119  const char *scan = next;1120 1121  int total = 0; // Count elements that were set. It'll be used as an array size1122  int prev_comma = FALSE; // For correct processing sequential commas1123 1124  // Count the number of values in the env. var string1125  for (;;) {1126    SKIP_WS(next);1127 1128    if (*next == '\0') {1129      break;1130    }1131    // Next character is not an integer or not a comma => end of list1132    if (((*next < '0') || (*next > '9')) && (*next != ',')) {1133      KMP_WARNING(NthSyntaxError, var, env);1134      return;1135    }1136    // The next character is ','1137    if (*next == ',') {1138      // ',' is the first character1139      if (total == 0 || prev_comma) {1140        total++;1141      }1142      prev_comma = TRUE;1143      next++; // skip ','1144      SKIP_WS(next);1145    }1146    // Next character is a digit1147    if (*next >= '0' && *next <= '9') {1148      prev_comma = FALSE;1149      SKIP_DIGITS(next);1150      total++;1151      const char *tmp = next;1152      SKIP_WS(tmp);1153      if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {1154        KMP_WARNING(NthSpacesNotAllowed, var, env);1155        return;1156      }1157    }1158  }1159  if (!__kmp_dflt_max_active_levels_set && total > 1)1160    __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;1161  if (total <= 0) {1162    KMP_WARNING(NthSyntaxError, var, env);1163    return;1164  }1165 1166  // Check if the nested nthreads array exists1167  if (!nth_array->nth) {1168    // Allocate an array of double size1169    nth_array->nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total * 2);1170    if (nth_array->nth == NULL) {1171      KMP_FATAL(MemoryAllocFailed);1172    }1173    nth_array->size = total * 2;1174  } else {1175    if (nth_array->size < total) {1176      // Increase the array size1177      do {1178        nth_array->size *= 2;1179      } while (nth_array->size < total);1180 1181      nth_array->nth = (int *)KMP_INTERNAL_REALLOC(1182          nth_array->nth, sizeof(int) * nth_array->size);1183      if (nth_array->nth == NULL) {1184        KMP_FATAL(MemoryAllocFailed);1185      }1186    }1187  }1188  nth_array->used = total;1189  int i = 0;1190 1191  prev_comma = FALSE;1192  total = 0;1193  // Save values in the array1194  for (;;) {1195    SKIP_WS(scan);1196    if (*scan == '\0') {1197      break;1198    }1199    // The next character is ','1200    if (*scan == ',') {1201      // ',' in the beginning of the list1202      if (total == 0) {1203        // The value is supposed to be equal to __kmp_avail_proc but it is1204        // unknown at the moment.1205        // So let's put a placeholder (#threads = 0) to correct it later.1206        nth_array->nth[i++] = 0;1207        total++;1208      } else if (prev_comma) {1209        // Num threads is inherited from the previous level1210        nth_array->nth[i] = nth_array->nth[i - 1];1211        i++;1212        total++;1213      }1214      prev_comma = TRUE;1215      scan++; // skip ','1216      SKIP_WS(scan);1217    }1218    // Next character is a digit1219    if (*scan >= '0' && *scan <= '9') {1220      int num;1221      const char *buf = scan;1222      char const *msg = NULL;1223      prev_comma = FALSE;1224      SKIP_DIGITS(scan);1225      total++;1226 1227      num = __kmp_str_to_int(buf, *scan);1228      if (num < KMP_MIN_NTH) {1229        msg = KMP_I18N_STR(ValueTooSmall);1230        num = KMP_MIN_NTH;1231      } else if (num > __kmp_sys_max_nth) {1232        msg = KMP_I18N_STR(ValueTooLarge);1233        num = __kmp_sys_max_nth;1234      }1235      if (msg != NULL) {1236        // Message is not empty. Print warning.1237        KMP_WARNING(ParseSizeIntWarn, var, env, msg);1238        KMP_INFORM(Using_int_Value, var, num);1239      }1240      nth_array->nth[i++] = num;1241    }1242  }1243}1244 1245static void __kmp_stg_parse_num_threads(char const *name, char const *value,1246                                        void *data) {1247  // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers!1248  if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {1249    // The array of 1 element1250    if (!__kmp_nested_nth.nth) {1251      __kmp_nested_nth.nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int));1252      __kmp_nested_nth.size = 1;1253    }1254    __kmp_nested_nth.used = 1;1255    __kmp_nested_nth.nth[0] = __kmp_dflt_team_nth = __kmp_dflt_team_nth_ub =1256        __kmp_xproc;1257  } else {1258    __kmp_parse_nested_num_threads(name, value, &__kmp_nested_nth);1259    if (__kmp_nested_nth.nth) {1260      __kmp_dflt_team_nth = __kmp_nested_nth.nth[0];1261      if (__kmp_dflt_team_nth_ub < __kmp_dflt_team_nth) {1262        __kmp_dflt_team_nth_ub = __kmp_dflt_team_nth;1263      }1264    }1265  }1266  K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth));1267} // __kmp_stg_parse_num_threads1268 1269#if OMPX_TASKGRAPH1270static void __kmp_stg_parse_max_tdgs(char const *name, char const *value,1271                                     void *data) {1272  __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_max_tdgs);1273} // __kmp_stg_parse_max_tdgs1274 1275static void __kmp_std_print_max_tdgs(kmp_str_buf_t *buffer, char const *name,1276                                     void *data) {1277  __kmp_stg_print_int(buffer, name, __kmp_max_tdgs);1278} // __kmp_std_print_max_tdgs1279 1280static void __kmp_stg_parse_tdg_dot(char const *name, char const *value,1281                                   void *data) {1282  __kmp_stg_parse_bool(name, value, &__kmp_tdg_dot);1283} // __kmp_stg_parse_tdg_dot1284 1285static void __kmp_stg_print_tdg_dot(kmp_str_buf_t *buffer, char const *name,1286                                   void *data) {1287  __kmp_stg_print_bool(buffer, name, __kmp_tdg_dot);1288} // __kmp_stg_print_tdg_dot1289#endif1290 1291static void __kmp_stg_parse_num_hidden_helper_threads(char const *name,1292                                                      char const *value,1293                                                      void *data) {1294  __kmp_stg_parse_int(name, value, 0, 16, &__kmp_hidden_helper_threads_num);1295  // If the number of hidden helper threads is zero, we disable hidden helper1296  // task1297  if (__kmp_hidden_helper_threads_num == 0) {1298    __kmp_enable_hidden_helper = FALSE;1299  } else {1300    // Since the main thread of hidden helper team does not participate1301    // in tasks execution let's increment the number of threads by one1302    // so that requested number of threads do actual job.1303    __kmp_hidden_helper_threads_num++;1304  }1305} // __kmp_stg_parse_num_hidden_helper_threads1306 1307static void __kmp_stg_print_num_hidden_helper_threads(kmp_str_buf_t *buffer,1308                                                      char const *name,1309                                                      void *data) {1310  if (__kmp_hidden_helper_threads_num == 0) {1311    __kmp_stg_print_int(buffer, name, __kmp_hidden_helper_threads_num);1312  } else {1313    KMP_DEBUG_ASSERT(__kmp_hidden_helper_threads_num > 1);1314    // Let's exclude the main thread of hidden helper team and print1315    // number of worker threads those do actual job.1316    __kmp_stg_print_int(buffer, name, __kmp_hidden_helper_threads_num - 1);1317  }1318} // __kmp_stg_print_num_hidden_helper_threads1319 1320static void __kmp_stg_parse_use_hidden_helper(char const *name,1321                                              char const *value, void *data) {1322  __kmp_stg_parse_bool(name, value, &__kmp_enable_hidden_helper);1323#if !KMP_OS_LINUX1324  __kmp_enable_hidden_helper = FALSE;1325  K_DIAG(1,1326         ("__kmp_stg_parse_use_hidden_helper: Disable hidden helper task on "1327          "non-Linux platform although it is enabled by user explicitly.\n"));1328#endif1329} // __kmp_stg_parse_use_hidden_helper1330 1331static void __kmp_stg_print_use_hidden_helper(kmp_str_buf_t *buffer,1332                                              char const *name, void *data) {1333  __kmp_stg_print_bool(buffer, name, __kmp_enable_hidden_helper);1334} // __kmp_stg_print_use_hidden_helper1335 1336static void __kmp_stg_print_num_threads(kmp_str_buf_t *buffer, char const *name,1337                                        void *data) {1338  if (__kmp_env_format) {1339    KMP_STR_BUF_PRINT_NAME;1340  } else {1341    __kmp_str_buf_print(buffer, "   %s", name);1342  }1343  if (__kmp_nested_nth.used) {1344    kmp_str_buf_t buf;1345    __kmp_str_buf_init(&buf);1346    for (int i = 0; i < __kmp_nested_nth.used; i++) {1347      __kmp_str_buf_print(&buf, "%d", __kmp_nested_nth.nth[i]);1348      if (i < __kmp_nested_nth.used - 1) {1349        __kmp_str_buf_print(&buf, ",");1350      }1351    }1352    __kmp_str_buf_print(buffer, "='%s'\n", buf.str);1353    __kmp_str_buf_free(&buf);1354  } else {1355    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));1356  }1357} // __kmp_stg_print_num_threads1358 1359// -----------------------------------------------------------------------------1360// OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS,1361 1362static void __kmp_stg_parse_tasking(char const *name, char const *value,1363                                    void *data) {1364  __kmp_stg_parse_int(name, value, 0, (int)tskm_max,1365                      (int *)&__kmp_tasking_mode);1366  // KMP_TASKING=1 (task barrier) doesn't work anymore, change to task_teams (2)1367  if (__kmp_tasking_mode == tskm_extra_barrier) {1368    KMP_WARNING(StgInvalidValue, name, value);1369    __kmp_tasking_mode = tskm_task_teams;1370  }1371} // __kmp_stg_parse_tasking1372 1373static void __kmp_stg_print_tasking(kmp_str_buf_t *buffer, char const *name,1374                                    void *data) {1375  __kmp_stg_print_int(buffer, name, __kmp_tasking_mode);1376} // __kmp_stg_print_tasking1377 1378static void __kmp_stg_parse_task_stealing(char const *name, char const *value,1379                                          void *data) {1380  __kmp_stg_parse_int(name, value, 0, 1,1381                      (int *)&__kmp_task_stealing_constraint);1382} // __kmp_stg_parse_task_stealing1383 1384static void __kmp_stg_print_task_stealing(kmp_str_buf_t *buffer,1385                                          char const *name, void *data) {1386  __kmp_stg_print_int(buffer, name, __kmp_task_stealing_constraint);1387} // __kmp_stg_print_task_stealing1388 1389static void __kmp_stg_parse_max_active_levels(char const *name,1390                                              char const *value, void *data) {1391  kmp_uint64 tmp_dflt = 0;1392  char const *msg = NULL;1393  if (!__kmp_dflt_max_active_levels_set) {1394    // Don't overwrite __kmp_dflt_max_active_levels if we get an invalid setting1395    __kmp_str_to_uint(value, &tmp_dflt, &msg);1396    if (msg != NULL) { // invalid setting; print warning and ignore1397      KMP_WARNING(ParseSizeIntWarn, name, value, msg);1398    } else if (tmp_dflt > KMP_MAX_ACTIVE_LEVELS_LIMIT) {1399      // invalid setting; print warning and ignore1400      msg = KMP_I18N_STR(ValueTooLarge);1401      KMP_WARNING(ParseSizeIntWarn, name, value, msg);1402    } else { // valid setting1403      __kmp_type_convert(tmp_dflt, &(__kmp_dflt_max_active_levels));1404      __kmp_dflt_max_active_levels_set = true;1405    }1406  }1407} // __kmp_stg_parse_max_active_levels1408 1409static void __kmp_stg_print_max_active_levels(kmp_str_buf_t *buffer,1410                                              char const *name, void *data) {1411  __kmp_stg_print_int(buffer, name, __kmp_dflt_max_active_levels);1412} // __kmp_stg_print_max_active_levels1413 1414// -----------------------------------------------------------------------------1415// OpenMP 4.0: OMP_DEFAULT_DEVICE1416static void __kmp_stg_parse_default_device(char const *name, char const *value,1417                                           void *data) {1418  __kmp_stg_parse_int(name, value, 0, KMP_MAX_DEFAULT_DEVICE_LIMIT,1419                      &__kmp_default_device);1420} // __kmp_stg_parse_default_device1421 1422static void __kmp_stg_print_default_device(kmp_str_buf_t *buffer,1423                                           char const *name, void *data) {1424  __kmp_stg_print_int(buffer, name, __kmp_default_device);1425} // __kmp_stg_print_default_device1426 1427// -----------------------------------------------------------------------------1428// OpenMP 5.0: OMP_TARGET_OFFLOAD1429static void __kmp_stg_parse_target_offload(char const *name, char const *value,1430                                           void *data) {1431  kmp_trimmed_str_t value_str(value);1432  const char *scan = value_str.get();1433  __kmp_target_offload = tgt_default;1434 1435  if (*scan == '\0')1436    return;1437 1438  if (!__kmp_strcasecmp_with_sentinel("mandatory", scan, 0)) {1439    __kmp_target_offload = tgt_mandatory;1440  } else if (!__kmp_strcasecmp_with_sentinel("disabled", scan, 0)) {1441    __kmp_target_offload = tgt_disabled;1442  } else if (!__kmp_strcasecmp_with_sentinel("default", scan, 0)) {1443    __kmp_target_offload = tgt_default;1444  } else {1445    KMP_WARNING(SyntaxErrorUsing, name, "DEFAULT");1446  }1447} // __kmp_stg_parse_target_offload1448 1449static void __kmp_stg_print_target_offload(kmp_str_buf_t *buffer,1450                                           char const *name, void *data) {1451  const char *value = NULL;1452  if (__kmp_target_offload == tgt_default)1453    value = "DEFAULT";1454  else if (__kmp_target_offload == tgt_mandatory)1455    value = "MANDATORY";1456  else if (__kmp_target_offload == tgt_disabled)1457    value = "DISABLED";1458  KMP_DEBUG_ASSERT(value);1459  if (__kmp_env_format) {1460    KMP_STR_BUF_PRINT_NAME;1461  } else {1462    __kmp_str_buf_print(buffer, "   %s", name);1463  }1464  __kmp_str_buf_print(buffer, "=%s\n", value);1465} // __kmp_stg_print_target_offload1466 1467// -----------------------------------------------------------------------------1468// OpenMP 4.5: OMP_MAX_TASK_PRIORITY1469static void __kmp_stg_parse_max_task_priority(char const *name,1470                                              char const *value, void *data) {1471  __kmp_stg_parse_int(name, value, 0, KMP_MAX_TASK_PRIORITY_LIMIT,1472                      &__kmp_max_task_priority);1473} // __kmp_stg_parse_max_task_priority1474 1475static void __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer,1476                                              char const *name, void *data) {1477  __kmp_stg_print_int(buffer, name, __kmp_max_task_priority);1478} // __kmp_stg_print_max_task_priority1479 1480// KMP_TASKLOOP_MIN_TASKS1481// taskloop threshold to switch from recursive to linear tasks creation1482static void __kmp_stg_parse_taskloop_min_tasks(char const *name,1483                                               char const *value, void *data) {1484  int tmp = 0;1485  __kmp_stg_parse_int(name, value, 0, INT_MAX, &tmp);1486  __kmp_taskloop_min_tasks = tmp;1487} // __kmp_stg_parse_taskloop_min_tasks1488 1489static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t *buffer,1490                                               char const *name, void *data) {1491  __kmp_stg_print_uint64(buffer, name, __kmp_taskloop_min_tasks);1492} // __kmp_stg_print_taskloop_min_tasks1493 1494// -----------------------------------------------------------------------------1495// KMP_DISP_NUM_BUFFERS1496static void __kmp_stg_parse_disp_buffers(char const *name, char const *value,1497                                         void *data) {1498  if (TCR_4(__kmp_init_serial)) {1499    KMP_WARNING(EnvSerialWarn, name);1500    return;1501  } // read value before serial initialization only1502  __kmp_stg_parse_int(name, value, KMP_MIN_DISP_NUM_BUFF, KMP_MAX_DISP_NUM_BUFF,1503                      &__kmp_dispatch_num_buffers);1504} // __kmp_stg_parse_disp_buffers1505 1506static void __kmp_stg_print_disp_buffers(kmp_str_buf_t *buffer,1507                                         char const *name, void *data) {1508  __kmp_stg_print_int(buffer, name, __kmp_dispatch_num_buffers);1509} // __kmp_stg_print_disp_buffers1510 1511// -----------------------------------------------------------------------------1512// KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE1513 1514static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value,1515                                            void *data) {1516  if (TCR_4(__kmp_init_parallel)) {1517    KMP_WARNING(EnvParallelWarn, name);1518    return;1519  } // read value before first parallel only1520  __kmp_stg_parse_int(name, value, 0, 1024, &__kmp_hot_teams_max_level);1521 1522} // __kmp_stg_parse_hot_teams_level1523 1524static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t *buffer,1525                                            char const *name, void *data) {1526  __kmp_stg_print_int(buffer, name, __kmp_hot_teams_max_level);1527} // __kmp_stg_print_hot_teams_level1528 1529static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value,1530                                           void *data) {1531  if (TCR_4(__kmp_init_parallel)) {1532    KMP_WARNING(EnvParallelWarn, name);1533    return;1534  } // read value before first parallel only1535  __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT,1536                      &__kmp_hot_teams_mode);1537} // __kmp_stg_parse_hot_teams_mode1538 1539static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t *buffer,1540                                           char const *name, void *data) {1541  __kmp_stg_print_int(buffer, name, __kmp_hot_teams_mode);1542} // __kmp_stg_print_hot_teams_mode1543 1544// -----------------------------------------------------------------------------1545// KMP_HANDLE_SIGNALS1546 1547#if KMP_HANDLE_SIGNALS1548 1549static void __kmp_stg_parse_handle_signals(char const *name, char const *value,1550                                           void *data) {1551  __kmp_stg_parse_bool(name, value, &__kmp_handle_signals);1552} // __kmp_stg_parse_handle_signals1553 1554static void __kmp_stg_print_handle_signals(kmp_str_buf_t *buffer,1555                                           char const *name, void *data) {1556  __kmp_stg_print_bool(buffer, name, __kmp_handle_signals);1557} // __kmp_stg_print_handle_signals1558 1559#endif // KMP_HANDLE_SIGNALS1560 1561// -----------------------------------------------------------------------------1562// KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG1563 1564#ifdef KMP_DEBUG1565 1566#define KMP_STG_X_DEBUG(x)                                                     \1567  static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \1568                                          void *data) {                        \1569    __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug);            \1570  } /* __kmp_stg_parse_x_debug */                                              \1571  static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer,               \1572                                          char const *name, void *data) {      \1573    __kmp_stg_print_int(buffer, name, kmp_##x##_debug);                        \1574  } /* __kmp_stg_print_x_debug */1575 1576KMP_STG_X_DEBUG(a)1577KMP_STG_X_DEBUG(b)1578KMP_STG_X_DEBUG(c)1579KMP_STG_X_DEBUG(d)1580KMP_STG_X_DEBUG(e)1581KMP_STG_X_DEBUG(f)1582 1583#undef KMP_STG_X_DEBUG1584 1585static void __kmp_stg_parse_debug(char const *name, char const *value,1586                                  void *data) {1587  int debug = 0;1588  __kmp_stg_parse_int(name, value, 0, INT_MAX, &debug);1589  if (kmp_a_debug < debug) {1590    kmp_a_debug = debug;1591  }1592  if (kmp_b_debug < debug) {1593    kmp_b_debug = debug;1594  }1595  if (kmp_c_debug < debug) {1596    kmp_c_debug = debug;1597  }1598  if (kmp_d_debug < debug) {1599    kmp_d_debug = debug;1600  }1601  if (kmp_e_debug < debug) {1602    kmp_e_debug = debug;1603  }1604  if (kmp_f_debug < debug) {1605    kmp_f_debug = debug;1606  }1607} // __kmp_stg_parse_debug1608 1609static void __kmp_stg_parse_debug_buf(char const *name, char const *value,1610                                      void *data) {1611  __kmp_stg_parse_bool(name, value, &__kmp_debug_buf);1612  // !!! TODO: Move buffer initialization of this file! It may works1613  // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or1614  // KMP_DEBUG_BUF_CHARS.1615  if (__kmp_debug_buf) {1616    int i;1617    int elements = __kmp_debug_buf_lines * __kmp_debug_buf_chars;1618 1619    /* allocate and initialize all entries in debug buffer to empty */1620    __kmp_debug_buffer = (char *)__kmp_page_allocate(elements * sizeof(char));1621    for (i = 0; i < elements; i += __kmp_debug_buf_chars)1622      __kmp_debug_buffer[i] = '\0';1623 1624    __kmp_debug_count = 0;1625  }1626  K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf));1627} // __kmp_stg_parse_debug_buf1628 1629static void __kmp_stg_print_debug_buf(kmp_str_buf_t *buffer, char const *name,1630                                      void *data) {1631  __kmp_stg_print_bool(buffer, name, __kmp_debug_buf);1632} // __kmp_stg_print_debug_buf1633 1634static void __kmp_stg_parse_debug_buf_atomic(char const *name,1635                                             char const *value, void *data) {1636  __kmp_stg_parse_bool(name, value, &__kmp_debug_buf_atomic);1637} // __kmp_stg_parse_debug_buf_atomic1638 1639static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t *buffer,1640                                             char const *name, void *data) {1641  __kmp_stg_print_bool(buffer, name, __kmp_debug_buf_atomic);1642} // __kmp_stg_print_debug_buf_atomic1643 1644static void __kmp_stg_parse_debug_buf_chars(char const *name, char const *value,1645                                            void *data) {1646  __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_CHARS_MIN, INT_MAX,1647                      &__kmp_debug_buf_chars);1648} // __kmp_stg_debug_parse_buf_chars1649 1650static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t *buffer,1651                                            char const *name, void *data) {1652  __kmp_stg_print_int(buffer, name, __kmp_debug_buf_chars);1653} // __kmp_stg_print_debug_buf_chars1654 1655static void __kmp_stg_parse_debug_buf_lines(char const *name, char const *value,1656                                            void *data) {1657  __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_LINES_MIN, INT_MAX,1658                      &__kmp_debug_buf_lines);1659} // __kmp_stg_parse_debug_buf_lines1660 1661static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t *buffer,1662                                            char const *name, void *data) {1663  __kmp_stg_print_int(buffer, name, __kmp_debug_buf_lines);1664} // __kmp_stg_print_debug_buf_lines1665 1666static void __kmp_stg_parse_diag(char const *name, char const *value,1667                                 void *data) {1668  __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_diag);1669} // __kmp_stg_parse_diag1670 1671static void __kmp_stg_print_diag(kmp_str_buf_t *buffer, char const *name,1672                                 void *data) {1673  __kmp_stg_print_int(buffer, name, kmp_diag);1674} // __kmp_stg_print_diag1675 1676#endif // KMP_DEBUG1677 1678// -----------------------------------------------------------------------------1679// KMP_ALIGN_ALLOC1680 1681static void __kmp_stg_parse_align_alloc(char const *name, char const *value,1682                                        void *data) {1683  __kmp_stg_parse_size(name, value, CACHE_LINE, INT_MAX, NULL,1684                       &__kmp_align_alloc, 1);1685  // Must be power of 21686  if (__kmp_align_alloc == 0 || ((__kmp_align_alloc - 1) & __kmp_align_alloc)) {1687    KMP_WARNING(StgInvalidValue, name, value);1688    __kmp_align_alloc = CACHE_LINE;1689  }1690} // __kmp_stg_parse_align_alloc1691 1692static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name,1693                                        void *data) {1694  __kmp_stg_print_size(buffer, name, __kmp_align_alloc);1695} // __kmp_stg_print_align_alloc1696 1697// -----------------------------------------------------------------------------1698// KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER1699 1700// TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from1701// parse and print functions, pass required info through data argument.1702 1703static void __kmp_stg_parse_barrier_branch_bit(char const *name,1704                                               char const *value, void *data) {1705  const char *var;1706 1707  /* ---------- Barrier branch bit control ------------ */1708  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {1709    var = __kmp_barrier_branch_bit_env_name[i];1710    if ((strcmp(var, name) == 0) && (value != 0)) {1711      char *comma;1712 1713      comma = CCAST(char *, strchr(value, ','));1714      __kmp_barrier_gather_branch_bits[i] =1715          (kmp_uint32)__kmp_str_to_int(value, ',');1716      /* is there a specified release parameter? */1717      if (comma == NULL) {1718        __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;1719      } else {1720        __kmp_barrier_release_branch_bits[i] =1721            (kmp_uint32)__kmp_str_to_int(comma + 1, 0);1722        if (__kmp_barrier_release_branch_bits[i] == 0 ||1723            __kmp_barrier_release_branch_bits[i] > KMP_MAX_BRANCH_BITS) {1724          __kmp_msg(kmp_ms_warning,1725                    KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),1726                    __kmp_msg_null);1727          __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt;1728        }1729      }1730      if (__kmp_barrier_gather_branch_bits[i] == 0 ||1731          __kmp_barrier_gather_branch_bits[i] > KMP_MAX_BRANCH_BITS) {1732        KMP_WARNING(BarrGatherValueInvalid, name, value);1733        KMP_INFORM(Using_uint_Value, name, __kmp_barrier_gather_bb_dflt);1734        __kmp_barrier_gather_branch_bits[i] = __kmp_barrier_gather_bb_dflt;1735      }1736    }1737    K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[i],1738               __kmp_barrier_gather_branch_bits[i],1739               __kmp_barrier_release_branch_bits[i]))1740  }1741} // __kmp_stg_parse_barrier_branch_bit1742 1743static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t *buffer,1744                                               char const *name, void *data) {1745  const char *var;1746  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {1747    var = __kmp_barrier_branch_bit_env_name[i];1748    if (strcmp(var, name) == 0) {1749      if (__kmp_env_format) {1750        KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name[i]);1751      } else {1752        __kmp_str_buf_print(buffer, "   %s='",1753                            __kmp_barrier_branch_bit_env_name[i]);1754      }1755      __kmp_str_buf_print(buffer, "%d,%d'\n",1756                          __kmp_barrier_gather_branch_bits[i],1757                          __kmp_barrier_release_branch_bits[i]);1758    }1759  }1760} // __kmp_stg_print_barrier_branch_bit1761 1762// ----------------------------------------------------------------------------1763// KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN,1764// KMP_REDUCTION_BARRIER_PATTERN1765 1766// TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and1767// print functions, pass required data to functions through data argument.1768 1769static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value,1770                                            void *data) {1771  const char *var;1772  /* ---------- Barrier method control ------------ */1773 1774  static int dist_req = 0, non_dist_req = 0;1775  static bool warn = 1;1776  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {1777    var = __kmp_barrier_pattern_env_name[i];1778 1779    if ((strcmp(var, name) == 0) && (value != 0)) {1780      int j;1781      char *comma = CCAST(char *, strchr(value, ','));1782 1783      /* handle first parameter: gather pattern */1784      for (j = bp_linear_bar; j < bp_last_bar; j++) {1785        if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name[j], value, 1,1786                                      ',')) {1787          if (j == bp_dist_bar) {1788            dist_req++;1789          } else {1790            non_dist_req++;1791          }1792          __kmp_barrier_gather_pattern[i] = (kmp_bar_pat_e)j;1793          break;1794        }1795      }1796      if (j == bp_last_bar) {1797        KMP_WARNING(BarrGatherValueInvalid, name, value);1798        KMP_INFORM(Using_str_Value, name,1799                   __kmp_barrier_pattern_name[bp_linear_bar]);1800      }1801 1802      /* handle second parameter: release pattern */1803      if (comma != NULL) {1804        for (j = bp_linear_bar; j < bp_last_bar; j++) {1805          if (__kmp_str_match(__kmp_barrier_pattern_name[j], 1, comma + 1)) {1806            if (j == bp_dist_bar) {1807              dist_req++;1808            } else {1809              non_dist_req++;1810            }1811            __kmp_barrier_release_pattern[i] = (kmp_bar_pat_e)j;1812            break;1813          }1814        }1815        if (j == bp_last_bar) {1816          __kmp_msg(kmp_ms_warning,1817                    KMP_MSG(BarrReleaseValueInvalid, name, comma + 1),1818                    __kmp_msg_null);1819          KMP_INFORM(Using_str_Value, name,1820                     __kmp_barrier_pattern_name[bp_linear_bar]);1821        }1822      }1823    }1824  }1825  if (dist_req != 0) {1826    // set all barriers to dist1827    if ((non_dist_req != 0) && warn) {1828      KMP_INFORM(BarrierPatternOverride, name,1829                 __kmp_barrier_pattern_name[bp_dist_bar]);1830      warn = 0;1831    }1832    for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {1833      if (__kmp_barrier_release_pattern[i] != bp_dist_bar)1834        __kmp_barrier_release_pattern[i] = bp_dist_bar;1835      if (__kmp_barrier_gather_pattern[i] != bp_dist_bar)1836        __kmp_barrier_gather_pattern[i] = bp_dist_bar;1837    }1838  }1839} // __kmp_stg_parse_barrier_pattern1840 1841static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t *buffer,1842                                            char const *name, void *data) {1843  const char *var;1844  for (int i = bs_plain_barrier; i < bs_last_barrier; i++) {1845    var = __kmp_barrier_pattern_env_name[i];1846    if (strcmp(var, name) == 0) {1847      int j = __kmp_barrier_gather_pattern[i];1848      int k = __kmp_barrier_release_pattern[i];1849      if (__kmp_env_format) {1850        KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name[i]);1851      } else {1852        __kmp_str_buf_print(buffer, "   %s='",1853                            __kmp_barrier_pattern_env_name[i]);1854      }1855      KMP_DEBUG_ASSERT(j < bp_last_bar && k < bp_last_bar);1856      __kmp_str_buf_print(buffer, "%s,%s'\n", __kmp_barrier_pattern_name[j],1857                          __kmp_barrier_pattern_name[k]);1858    }1859  }1860} // __kmp_stg_print_barrier_pattern1861 1862// -----------------------------------------------------------------------------1863// KMP_ABORT_DELAY1864 1865static void __kmp_stg_parse_abort_delay(char const *name, char const *value,1866                                        void *data) {1867  // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is1868  // milliseconds.1869  int delay = __kmp_abort_delay / 1000;1870  __kmp_stg_parse_int(name, value, 0, INT_MAX / 1000, &delay);1871  __kmp_abort_delay = delay * 1000;1872} // __kmp_stg_parse_abort_delay1873 1874static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name,1875                                        void *data) {1876  __kmp_stg_print_int(buffer, name, __kmp_abort_delay);1877} // __kmp_stg_print_abort_delay1878 1879// -----------------------------------------------------------------------------1880// KMP_CPUINFO_FILE1881 1882static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value,1883                                         void *data) {1884#if KMP_AFFINITY_SUPPORTED1885  __kmp_stg_parse_str(name, value, &__kmp_cpuinfo_file);1886  K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file));1887#endif1888} //__kmp_stg_parse_cpuinfo_file1889 1890static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t *buffer,1891                                         char const *name, void *data) {1892#if KMP_AFFINITY_SUPPORTED1893  if (__kmp_env_format) {1894    KMP_STR_BUF_PRINT_NAME;1895  } else {1896    __kmp_str_buf_print(buffer, "   %s", name);1897  }1898  if (__kmp_cpuinfo_file) {1899    __kmp_str_buf_print(buffer, "='%s'\n", __kmp_cpuinfo_file);1900  } else {1901    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));1902  }1903#endif1904} //__kmp_stg_print_cpuinfo_file1905 1906// -----------------------------------------------------------------------------1907// KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION1908 1909static void __kmp_stg_parse_force_reduction(char const *name, char const *value,1910                                            void *data) {1911  kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;1912  int rc;1913 1914  rc = __kmp_stg_check_rivals(name, value, reduction->rivals);1915  if (rc) {1916    return;1917  }1918  if (reduction->force) {1919    if (value != 0) {1920      if (__kmp_str_match("critical", 0, value))1921        __kmp_force_reduction_method = critical_reduce_block;1922      else if (__kmp_str_match("atomic", 0, value))1923        __kmp_force_reduction_method = atomic_reduce_block;1924      else if (__kmp_str_match("tree", 0, value))1925        __kmp_force_reduction_method = tree_reduce_block;1926      else {1927        KMP_FATAL(UnknownForceReduction, name, value);1928      }1929    }1930  } else {1931    __kmp_stg_parse_bool(name, value, &__kmp_determ_red);1932    if (__kmp_determ_red) {1933      __kmp_force_reduction_method = tree_reduce_block;1934    } else {1935      __kmp_force_reduction_method = reduction_method_not_defined;1936    }1937  }1938  K_DIAG(1, ("__kmp_force_reduction_method == %d\n",1939             __kmp_force_reduction_method));1940} // __kmp_stg_parse_force_reduction1941 1942static void __kmp_stg_print_force_reduction(kmp_str_buf_t *buffer,1943                                            char const *name, void *data) {1944 1945  kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data;1946  if (reduction->force) {1947    if (__kmp_force_reduction_method == critical_reduce_block) {1948      __kmp_stg_print_str(buffer, name, "critical");1949    } else if (__kmp_force_reduction_method == atomic_reduce_block) {1950      __kmp_stg_print_str(buffer, name, "atomic");1951    } else if (__kmp_force_reduction_method == tree_reduce_block) {1952      __kmp_stg_print_str(buffer, name, "tree");1953    } else {1954      if (__kmp_env_format) {1955        KMP_STR_BUF_PRINT_NAME;1956      } else {1957        __kmp_str_buf_print(buffer, "   %s", name);1958      }1959      __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));1960    }1961  } else {1962    __kmp_stg_print_bool(buffer, name, __kmp_determ_red);1963  }1964 1965} // __kmp_stg_print_force_reduction1966 1967// -----------------------------------------------------------------------------1968// KMP_STORAGE_MAP1969 1970static void __kmp_stg_parse_storage_map(char const *name, char const *value,1971                                        void *data) {1972  if (__kmp_str_match("verbose", 1, value)) {1973    __kmp_storage_map = TRUE;1974    __kmp_storage_map_verbose = TRUE;1975    __kmp_storage_map_verbose_specified = TRUE;1976 1977  } else {1978    __kmp_storage_map_verbose = FALSE;1979    __kmp_stg_parse_bool(name, value, &__kmp_storage_map); // !!!1980  }1981} // __kmp_stg_parse_storage_map1982 1983static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name,1984                                        void *data) {1985  if (__kmp_storage_map_verbose || __kmp_storage_map_verbose_specified) {1986    __kmp_stg_print_str(buffer, name, "verbose");1987  } else {1988    __kmp_stg_print_bool(buffer, name, __kmp_storage_map);1989  }1990} // __kmp_stg_print_storage_map1991 1992// -----------------------------------------------------------------------------1993// KMP_ALL_THREADPRIVATE1994 1995static void __kmp_stg_parse_all_threadprivate(char const *name,1996                                              char const *value, void *data) {1997  __kmp_stg_parse_int(name, value,1998                      __kmp_allThreadsSpecified ? __kmp_max_nth : 1,1999                      __kmp_max_nth, &__kmp_tp_capacity);2000} // __kmp_stg_parse_all_threadprivate2001 2002static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t *buffer,2003                                              char const *name, void *data) {2004  __kmp_stg_print_int(buffer, name, __kmp_tp_capacity);2005}2006 2007// -----------------------------------------------------------------------------2008// KMP_FOREIGN_THREADS_THREADPRIVATE2009 2010static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name,2011                                                          char const *value,2012                                                          void *data) {2013  __kmp_stg_parse_bool(name, value, &__kmp_foreign_tp);2014} // __kmp_stg_parse_foreign_threads_threadprivate2015 2016static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t *buffer,2017                                                          char const *name,2018                                                          void *data) {2019  __kmp_stg_print_bool(buffer, name, __kmp_foreign_tp);2020} // __kmp_stg_print_foreign_threads_threadprivate2021 2022// -----------------------------------------------------------------------------2023// KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD2024 2025static inline const char *2026__kmp_hw_get_core_type_keyword(kmp_hw_core_type_t type) {2027  switch (type) {2028  case KMP_HW_CORE_TYPE_UNKNOWN:2029  case KMP_HW_MAX_NUM_CORE_TYPES:2030    return "unknown";2031#if KMP_ARCH_X86 || KMP_ARCH_X86_642032  case KMP_HW_CORE_TYPE_ATOM:2033    return "intel_atom";2034  case KMP_HW_CORE_TYPE_CORE:2035    return "intel_core";2036#endif2037  }2038  KMP_ASSERT2(false, "Unhandled kmp_hw_core_type_t enumeration");2039  KMP_BUILTIN_UNREACHABLE;2040}2041 2042#if KMP_AFFINITY_SUPPORTED2043// Parse the proc id list.  Return TRUE if successful, FALSE otherwise.2044static int __kmp_parse_affinity_proc_id_list(const char *var, const char *env,2045                                             const char **nextEnv,2046                                             char **proclist) {2047  const char *scan = env;2048  const char *next = scan;2049  int empty = TRUE;2050 2051  *proclist = NULL;2052 2053  for (;;) {2054    int start, end, stride;2055 2056    SKIP_WS(scan);2057    next = scan;2058    if (*next == '\0') {2059      break;2060    }2061 2062    if (*next == '{') {2063      int num;2064      next++; // skip '{'2065      SKIP_WS(next);2066      scan = next;2067 2068      // Read the first integer in the set.2069      if ((*next < '0') || (*next > '9')) {2070        KMP_WARNING(AffSyntaxError, var);2071        return FALSE;2072      }2073      SKIP_DIGITS(next);2074      num = __kmp_str_to_int(scan, *next);2075      KMP_ASSERT(num >= 0);2076 2077      for (;;) {2078        // Check for end of set.2079        SKIP_WS(next);2080        if (*next == '}') {2081          next++; // skip '}'2082          break;2083        }2084 2085        // Skip optional comma.2086        if (*next == ',') {2087          next++;2088        }2089        SKIP_WS(next);2090 2091        // Read the next integer in the set.2092        scan = next;2093        if ((*next < '0') || (*next > '9')) {2094          KMP_WARNING(AffSyntaxError, var);2095          return FALSE;2096        }2097 2098        SKIP_DIGITS(next);2099        num = __kmp_str_to_int(scan, *next);2100        KMP_ASSERT(num >= 0);2101      }2102      empty = FALSE;2103 2104      SKIP_WS(next);2105      if (*next == ',') {2106        next++;2107      }2108      scan = next;2109      continue;2110    }2111 2112    // Next character is not an integer => end of list2113    if ((*next < '0') || (*next > '9')) {2114      if (empty) {2115        KMP_WARNING(AffSyntaxError, var);2116        return FALSE;2117      }2118      break;2119    }2120 2121    // Read the first integer.2122    SKIP_DIGITS(next);2123    start = __kmp_str_to_int(scan, *next);2124    KMP_ASSERT(start >= 0);2125    SKIP_WS(next);2126 2127    // If this isn't a range, then go on.2128    if (*next != '-') {2129      empty = FALSE;2130 2131      // Skip optional comma.2132      if (*next == ',') {2133        next++;2134      }2135      scan = next;2136      continue;2137    }2138 2139    // This is a range.  Skip over the '-' and read in the 2nd int.2140    next++; // skip '-'2141    SKIP_WS(next);2142    scan = next;2143    if ((*next < '0') || (*next > '9')) {2144      KMP_WARNING(AffSyntaxError, var);2145      return FALSE;2146    }2147    SKIP_DIGITS(next);2148    end = __kmp_str_to_int(scan, *next);2149    KMP_ASSERT(end >= 0);2150 2151    // Check for a stride parameter2152    stride = 1;2153    SKIP_WS(next);2154    if (*next == ':') {2155      // A stride is specified.  Skip over the ':" and read the 3rd int.2156      int sign = +1;2157      next++; // skip ':'2158      SKIP_WS(next);2159      scan = next;2160      if (*next == '-') {2161        sign = -1;2162        next++;2163        SKIP_WS(next);2164        scan = next;2165      }2166      if ((*next < '0') || (*next > '9')) {2167        KMP_WARNING(AffSyntaxError, var);2168        return FALSE;2169      }2170      SKIP_DIGITS(next);2171      stride = __kmp_str_to_int(scan, *next);2172      KMP_ASSERT(stride >= 0);2173      stride *= sign;2174    }2175 2176    // Do some range checks.2177    if (stride == 0) {2178      KMP_WARNING(AffZeroStride, var);2179      return FALSE;2180    }2181    if (stride > 0) {2182      if (start > end) {2183        KMP_WARNING(AffStartGreaterEnd, var, start, end);2184        return FALSE;2185      }2186    } else {2187      if (start < end) {2188        KMP_WARNING(AffStrideLessZero, var, start, end);2189        return FALSE;2190      }2191    }2192    if ((end - start) / stride > 65536) {2193      KMP_WARNING(AffRangeTooBig, var, end, start, stride);2194      return FALSE;2195    }2196 2197    empty = FALSE;2198 2199    // Skip optional comma.2200    SKIP_WS(next);2201    if (*next == ',') {2202      next++;2203    }2204    scan = next;2205  }2206 2207  *nextEnv = next;2208 2209  {2210    ptrdiff_t len = next - env;2211    char *retlist = (char *)KMP_INTERNAL_MALLOC((len + 1) * sizeof(char));2212    KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));2213    retlist[len] = '\0';2214    *proclist = retlist;2215  }2216  return TRUE;2217}2218 2219// If KMP_AFFINITY is specified without a type, then2220// __kmp_affinity_notype should point to its setting.2221static kmp_setting_t *__kmp_affinity_notype = NULL;2222 2223static void __kmp_parse_affinity_env(char const *name, char const *value,2224                                     kmp_affinity_t *out_affinity) {2225  char *buffer = NULL; // Copy of env var value.2226  char *buf = NULL; // Buffer for strtok_r() function.2227  char *next = NULL; // end of token / start of next.2228  const char *start; // start of current token (for err msgs)2229  int count = 0; // Counter of parsed integer numbers.2230  int number[2]; // Parsed numbers.2231 2232  // Guards.2233  int type = 0;2234  int proclist = 0;2235  int verbose = 0;2236  int warnings = 0;2237  int respect = 0;2238  int gran = 0;2239  int dups = 0;2240  int reset = 0;2241  bool set = false;2242 2243  KMP_ASSERT(value != NULL);2244 2245  if (TCR_4(__kmp_init_middle)) {2246    KMP_WARNING(EnvMiddleWarn, name);2247    __kmp_env_toPrint(name, 0);2248    return;2249  }2250  __kmp_env_toPrint(name, 1);2251 2252  buffer =2253      __kmp_str_format("%s", value); // Copy env var to keep original intact.2254  buf = buffer;2255  SKIP_WS(buf);2256 2257// Helper macros.2258 2259// If we see a parse error, emit a warning and scan to the next ",".2260//2261// FIXME - there's got to be a better way to print an error2262// message, hopefully without overwriting peices of buf.2263#define EMIT_WARN(skip, errlist)                                               \2264  {                                                                            \2265    char ch;                                                                   \2266    if (skip) {                                                                \2267      SKIP_TO(next, ',');                                                      \2268    }                                                                          \2269    ch = *next;                                                                \2270    *next = '\0';                                                              \2271    KMP_WARNING errlist;                                                       \2272    *next = ch;                                                                \2273    if (skip) {                                                                \2274      if (ch == ',')                                                           \2275        next++;                                                                \2276    }                                                                          \2277    buf = next;                                                                \2278  }2279 2280#define _set_param(_guard, _var, _val)                                         \2281  {                                                                            \2282    if (_guard == 0) {                                                         \2283      _var = _val;                                                             \2284    } else {                                                                   \2285      EMIT_WARN(FALSE, (AffParamDefined, name, start));                        \2286    }                                                                          \2287    ++_guard;                                                                  \2288  }2289 2290#define set_type(val) _set_param(type, out_affinity->type, val)2291#define set_verbose(val) _set_param(verbose, out_affinity->flags.verbose, val)2292#define set_warnings(val)                                                      \2293  _set_param(warnings, out_affinity->flags.warnings, val)2294#define set_respect(val) _set_param(respect, out_affinity->flags.respect, val)2295#define set_dups(val) _set_param(dups, out_affinity->flags.dups, val)2296#define set_proclist(val) _set_param(proclist, out_affinity->proclist, val)2297#define set_reset(val) _set_param(reset, out_affinity->flags.reset, val)2298 2299#define set_gran(val, levels)                                                  \2300  {                                                                            \2301    if (gran == 0) {                                                           \2302      out_affinity->gran = val;                                                \2303      out_affinity->gran_levels = levels;                                      \2304    } else {                                                                   \2305      EMIT_WARN(FALSE, (AffParamDefined, name, start));                        \2306    }                                                                          \2307    ++gran;                                                                    \2308  }2309 2310  KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&2311                   (__kmp_nested_proc_bind.used > 0));2312 2313  while (*buf != '\0') {2314    start = next = buf;2315 2316    if (__kmp_match_str("none", buf, CCAST(const char **, &next))) {2317      set_type(affinity_none);2318      __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;2319      buf = next;2320    } else if (__kmp_match_str("scatter", buf, CCAST(const char **, &next))) {2321      set_type(affinity_scatter);2322      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2323      buf = next;2324    } else if (__kmp_match_str("compact", buf, CCAST(const char **, &next))) {2325      set_type(affinity_compact);2326      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2327      buf = next;2328    } else if (__kmp_match_str("logical", buf, CCAST(const char **, &next))) {2329      set_type(affinity_logical);2330      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2331      buf = next;2332    } else if (__kmp_match_str("physical", buf, CCAST(const char **, &next))) {2333      set_type(affinity_physical);2334      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2335      buf = next;2336    } else if (__kmp_match_str("explicit", buf, CCAST(const char **, &next))) {2337      set_type(affinity_explicit);2338      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2339      buf = next;2340    } else if (__kmp_match_str("balanced", buf, CCAST(const char **, &next))) {2341      set_type(affinity_balanced);2342      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2343      buf = next;2344    } else if (__kmp_match_str("disabled", buf, CCAST(const char **, &next))) {2345      set_type(affinity_disabled);2346      __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;2347      buf = next;2348    } else if (__kmp_match_str("verbose", buf, CCAST(const char **, &next))) {2349      set_verbose(TRUE);2350      buf = next;2351    } else if (__kmp_match_str("noverbose", buf, CCAST(const char **, &next))) {2352      set_verbose(FALSE);2353      buf = next;2354    } else if (__kmp_match_str("warnings", buf, CCAST(const char **, &next))) {2355      set_warnings(TRUE);2356      buf = next;2357    } else if (__kmp_match_str("nowarnings", buf,2358                               CCAST(const char **, &next))) {2359      set_warnings(FALSE);2360      buf = next;2361    } else if (__kmp_match_str("respect", buf, CCAST(const char **, &next))) {2362      set_respect(TRUE);2363      buf = next;2364    } else if (__kmp_match_str("norespect", buf, CCAST(const char **, &next))) {2365      set_respect(FALSE);2366      buf = next;2367    } else if (__kmp_match_str("reset", buf, CCAST(const char **, &next))) {2368      set_reset(TRUE);2369      buf = next;2370    } else if (__kmp_match_str("noreset", buf, CCAST(const char **, &next))) {2371      set_reset(FALSE);2372      buf = next;2373    } else if (__kmp_match_str("duplicates", buf,2374                               CCAST(const char **, &next)) ||2375               __kmp_match_str("dups", buf, CCAST(const char **, &next))) {2376      set_dups(TRUE);2377      buf = next;2378    } else if (__kmp_match_str("noduplicates", buf,2379                               CCAST(const char **, &next)) ||2380               __kmp_match_str("nodups", buf, CCAST(const char **, &next))) {2381      set_dups(FALSE);2382      buf = next;2383    } else if (__kmp_match_str("granularity", buf,2384                               CCAST(const char **, &next)) ||2385               __kmp_match_str("gran", buf, CCAST(const char **, &next))) {2386      SKIP_WS(next);2387      if (*next != '=') {2388        EMIT_WARN(TRUE, (AffInvalidParam, name, start));2389        continue;2390      }2391      next++; // skip '='2392      SKIP_WS(next);2393 2394      buf = next;2395 2396      // Have to try core_type and core_efficiency matches first since "core"2397      // will register as core granularity with "extra chars"2398      if (__kmp_match_str("core_type", buf, CCAST(const char **, &next))) {2399        set_gran(KMP_HW_CORE, -1);2400        out_affinity->flags.core_types_gran = 1;2401        buf = next;2402        set = true;2403      } else if (__kmp_match_str("core_efficiency", buf,2404                                 CCAST(const char **, &next)) ||2405                 __kmp_match_str("core_eff", buf,2406                                 CCAST(const char **, &next))) {2407        set_gran(KMP_HW_CORE, -1);2408        out_affinity->flags.core_effs_gran = 1;2409        buf = next;2410        set = true;2411      }2412      if (!set) {2413        // Try any hardware topology type for granularity2414        KMP_FOREACH_HW_TYPE(type) {2415          const char *name = __kmp_hw_get_keyword(type);2416          if (__kmp_match_str(name, buf, CCAST(const char **, &next))) {2417            set_gran(type, -1);2418            buf = next;2419            set = true;2420            break;2421          }2422        }2423      }2424      if (!set) {2425        // Support older names for different granularity layers2426        if (__kmp_match_str("fine", buf, CCAST(const char **, &next))) {2427          set_gran(KMP_HW_THREAD, -1);2428          buf = next;2429          set = true;2430        } else if (__kmp_match_str("package", buf,2431                                   CCAST(const char **, &next))) {2432          set_gran(KMP_HW_SOCKET, -1);2433          buf = next;2434          set = true;2435        } else if (__kmp_match_str("node", buf, CCAST(const char **, &next))) {2436          set_gran(KMP_HW_NUMA, -1);2437          buf = next;2438          set = true;2439#if KMP_GROUP_AFFINITY2440        } else if (__kmp_match_str("group", buf, CCAST(const char **, &next))) {2441          set_gran(KMP_HW_PROC_GROUP, -1);2442          buf = next;2443          set = true;2444#endif /* KMP_GROUP AFFINITY */2445        } else if ((*buf >= '0') && (*buf <= '9')) {2446          int n;2447          next = buf;2448          SKIP_DIGITS(next);2449          n = __kmp_str_to_int(buf, *next);2450          KMP_ASSERT(n >= 0);2451          buf = next;2452          set_gran(KMP_HW_UNKNOWN, n);2453          set = true;2454        } else {2455          EMIT_WARN(TRUE, (AffInvalidParam, name, start));2456          continue;2457        }2458      }2459    } else if (__kmp_match_str("proclist", buf, CCAST(const char **, &next))) {2460      char *temp_proclist;2461 2462      SKIP_WS(next);2463      if (*next != '=') {2464        EMIT_WARN(TRUE, (AffInvalidParam, name, start));2465        continue;2466      }2467      next++; // skip '='2468      SKIP_WS(next);2469      if (*next != '[') {2470        EMIT_WARN(TRUE, (AffInvalidParam, name, start));2471        continue;2472      }2473      next++; // skip '['2474      buf = next;2475      if (!__kmp_parse_affinity_proc_id_list(2476              name, buf, CCAST(const char **, &next), &temp_proclist)) {2477        // warning already emitted.2478        SKIP_TO(next, ']');2479        if (*next == ']')2480          next++;2481        SKIP_TO(next, ',');2482        if (*next == ',')2483          next++;2484        buf = next;2485        continue;2486      }2487      if (*next != ']') {2488        EMIT_WARN(TRUE, (AffInvalidParam, name, start));2489        continue;2490      }2491      next++; // skip ']'2492      set_proclist(temp_proclist);2493    } else if ((*buf >= '0') && (*buf <= '9')) {2494      // Parse integer numbers -- permute and offset.2495      int n;2496      next = buf;2497      SKIP_DIGITS(next);2498      n = __kmp_str_to_int(buf, *next);2499      KMP_ASSERT(n >= 0);2500      buf = next;2501      if (count < 2) {2502        number[count] = n;2503      } else {2504        KMP_WARNING(AffManyParams, name, start);2505      }2506      ++count;2507    } else {2508      EMIT_WARN(TRUE, (AffInvalidParam, name, start));2509      continue;2510    }2511 2512    SKIP_WS(next);2513    if (*next == ',') {2514      next++;2515      SKIP_WS(next);2516    } else if (*next != '\0') {2517      const char *temp = next;2518      EMIT_WARN(TRUE, (ParseExtraCharsWarn, name, temp));2519      continue;2520    }2521    buf = next;2522  } // while2523 2524#undef EMIT_WARN2525#undef _set_param2526#undef set_type2527#undef set_verbose2528#undef set_warnings2529#undef set_respect2530#undef set_granularity2531#undef set_reset2532 2533  __kmp_str_free(&buffer);2534 2535  if (proclist) {2536    if (!type) {2537      KMP_WARNING(AffProcListNoType, name);2538      out_affinity->type = affinity_explicit;2539      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2540    } else if (out_affinity->type != affinity_explicit) {2541      KMP_WARNING(AffProcListNotExplicit, name);2542      KMP_ASSERT(out_affinity->proclist != NULL);2543      KMP_INTERNAL_FREE(out_affinity->proclist);2544      out_affinity->proclist = NULL;2545    }2546  }2547  switch (out_affinity->type) {2548  case affinity_logical:2549  case affinity_physical: {2550    if (count > 0) {2551      out_affinity->offset = number[0];2552    }2553    if (count > 1) {2554      KMP_WARNING(AffManyParamsForLogic, name, number[1]);2555    }2556  } break;2557  case affinity_balanced: {2558    if (count > 0) {2559      out_affinity->compact = number[0];2560    }2561    if (count > 1) {2562      out_affinity->offset = number[1];2563    }2564 2565    if (__kmp_affinity.gran == KMP_HW_UNKNOWN) {2566      int verbose = out_affinity->flags.verbose;2567      int warnings = out_affinity->flags.warnings;2568#if KMP_MIC_SUPPORTED2569      if (__kmp_mic_type != non_mic) {2570        if (verbose || warnings) {2571          KMP_WARNING(AffGranUsing, out_affinity->env_var, "fine");2572        }2573        out_affinity->gran = KMP_HW_THREAD;2574      } else2575#endif2576      {2577        if (verbose || warnings) {2578          KMP_WARNING(AffGranUsing, out_affinity->env_var, "core");2579        }2580        out_affinity->gran = KMP_HW_CORE;2581      }2582    }2583  } break;2584  case affinity_scatter:2585  case affinity_compact: {2586    if (count > 0) {2587      out_affinity->compact = number[0];2588    }2589    if (count > 1) {2590      out_affinity->offset = number[1];2591    }2592  } break;2593  case affinity_explicit: {2594    if (out_affinity->proclist == NULL) {2595      KMP_WARNING(AffNoProcList, name);2596      out_affinity->type = affinity_none;2597    }2598    if (count > 0) {2599      KMP_WARNING(AffNoParam, name, "explicit");2600    }2601  } break;2602  case affinity_none: {2603    if (count > 0) {2604      KMP_WARNING(AffNoParam, name, "none");2605    }2606  } break;2607  case affinity_disabled: {2608    if (count > 0) {2609      KMP_WARNING(AffNoParam, name, "disabled");2610    }2611  } break;2612  case affinity_default: {2613    if (count > 0) {2614      KMP_WARNING(AffNoParam, name, "default");2615    }2616  } break;2617  default: {2618    KMP_ASSERT(0);2619  }2620  }2621} // __kmp_parse_affinity_env2622 2623static void __kmp_stg_parse_affinity(char const *name, char const *value,2624                                     void *data) {2625  kmp_setting_t **rivals = (kmp_setting_t **)data;2626  int rc;2627 2628  rc = __kmp_stg_check_rivals(name, value, rivals);2629  if (rc) {2630    return;2631  }2632 2633  __kmp_parse_affinity_env(name, value, &__kmp_affinity);2634 2635} // __kmp_stg_parse_affinity2636static void __kmp_stg_parse_hh_affinity(char const *name, char const *value,2637                                        void *data) {2638  __kmp_parse_affinity_env(name, value, &__kmp_hh_affinity);2639  // Warn about unused parts of hidden helper affinity settings if specified.2640  if (__kmp_hh_affinity.flags.reset) {2641    KMP_WARNING(AffInvalidParam, name, "reset");2642  }2643  if (__kmp_hh_affinity.flags.respect != affinity_respect_mask_default) {2644    KMP_WARNING(AffInvalidParam, name, "respect");2645  }2646}2647 2648static void __kmp_print_affinity_env(kmp_str_buf_t *buffer, char const *name,2649                                     const kmp_affinity_t &affinity) {2650  bool is_hh_affinity = (&affinity == &__kmp_hh_affinity);2651  if (__kmp_env_format) {2652    KMP_STR_BUF_PRINT_NAME_EX(name);2653  } else {2654    __kmp_str_buf_print(buffer, "   %s='", name);2655  }2656  if (affinity.flags.verbose) {2657    __kmp_str_buf_print(buffer, "%s,", "verbose");2658  } else {2659    __kmp_str_buf_print(buffer, "%s,", "noverbose");2660  }2661  if (affinity.flags.warnings) {2662    __kmp_str_buf_print(buffer, "%s,", "warnings");2663  } else {2664    __kmp_str_buf_print(buffer, "%s,", "nowarnings");2665  }2666  if (KMP_AFFINITY_CAPABLE()) {2667    // Hidden helper affinity does not affect global reset2668    // or respect flags. That is still solely controlled by KMP_AFFINITY.2669    if (!is_hh_affinity) {2670      if (affinity.flags.respect) {2671        __kmp_str_buf_print(buffer, "%s,", "respect");2672      } else {2673        __kmp_str_buf_print(buffer, "%s,", "norespect");2674      }2675      if (affinity.flags.reset) {2676        __kmp_str_buf_print(buffer, "%s,", "reset");2677      } else {2678        __kmp_str_buf_print(buffer, "%s,", "noreset");2679      }2680    }2681    __kmp_str_buf_print(buffer, "granularity=");2682    if (affinity.flags.core_types_gran)2683      __kmp_str_buf_print(buffer, "core_type,");2684    else if (affinity.flags.core_effs_gran) {2685      __kmp_str_buf_print(buffer, "core_eff,");2686    } else {2687      __kmp_str_buf_print(2688          buffer, "%s,", __kmp_hw_get_keyword(affinity.gran, /*plural=*/false));2689    }2690  }2691  if (!KMP_AFFINITY_CAPABLE()) {2692    __kmp_str_buf_print(buffer, "%s", "disabled");2693  } else {2694    int compact = affinity.compact;2695    int offset = affinity.offset;2696    switch (affinity.type) {2697    case affinity_none:2698      __kmp_str_buf_print(buffer, "%s", "none");2699      break;2700    case affinity_physical:2701      __kmp_str_buf_print(buffer, "%s,%d", "physical", offset);2702      break;2703    case affinity_logical:2704      __kmp_str_buf_print(buffer, "%s,%d", "logical", offset);2705      break;2706    case affinity_compact:2707      __kmp_str_buf_print(buffer, "%s,%d,%d", "compact", compact, offset);2708      break;2709    case affinity_scatter:2710      __kmp_str_buf_print(buffer, "%s,%d,%d", "scatter", compact, offset);2711      break;2712    case affinity_explicit:2713      __kmp_str_buf_print(buffer, "%s=[%s],%s", "proclist", affinity.proclist,2714                          "explicit");2715      break;2716    case affinity_balanced:2717      __kmp_str_buf_print(buffer, "%s,%d,%d", "balanced", compact, offset);2718      break;2719    case affinity_disabled:2720      __kmp_str_buf_print(buffer, "%s", "disabled");2721      break;2722    case affinity_default:2723      __kmp_str_buf_print(buffer, "%s", "default");2724      break;2725    default:2726      __kmp_str_buf_print(buffer, "%s", "<unknown>");2727      break;2728    }2729  }2730  __kmp_str_buf_print(buffer, "'\n");2731} //__kmp_stg_print_affinity2732 2733static void __kmp_stg_print_affinity(kmp_str_buf_t *buffer, char const *name,2734                                     void *data) {2735  __kmp_print_affinity_env(buffer, name, __kmp_affinity);2736}2737static void __kmp_stg_print_hh_affinity(kmp_str_buf_t *buffer, char const *name,2738                                        void *data) {2739  __kmp_print_affinity_env(buffer, name, __kmp_hh_affinity);2740}2741 2742#ifdef KMP_GOMP_COMPAT2743 2744static void __kmp_stg_parse_gomp_cpu_affinity(char const *name,2745                                              char const *value, void *data) {2746  const char *next = NULL;2747  char *temp_proclist;2748  kmp_setting_t **rivals = (kmp_setting_t **)data;2749  int rc;2750 2751  rc = __kmp_stg_check_rivals(name, value, rivals);2752  if (rc) {2753    return;2754  }2755 2756  if (TCR_4(__kmp_init_middle)) {2757    KMP_WARNING(EnvMiddleWarn, name);2758    __kmp_env_toPrint(name, 0);2759    return;2760  }2761 2762  __kmp_env_toPrint(name, 1);2763 2764  if (__kmp_parse_affinity_proc_id_list(name, value, &next, &temp_proclist)) {2765    SKIP_WS(next);2766    if (*next == '\0') {2767      // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...2768      __kmp_affinity.proclist = temp_proclist;2769      __kmp_affinity.type = affinity_explicit;2770      __kmp_affinity.gran = KMP_HW_THREAD;2771      __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;2772    } else {2773      KMP_WARNING(AffSyntaxError, name);2774      if (temp_proclist != NULL) {2775        KMP_INTERNAL_FREE((void *)temp_proclist);2776      }2777    }2778  } else {2779    // Warning already emitted2780    __kmp_affinity.type = affinity_none;2781    __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;2782  }2783} // __kmp_stg_parse_gomp_cpu_affinity2784 2785#endif /* KMP_GOMP_COMPAT */2786 2787/*-----------------------------------------------------------------------------2788The OMP_PLACES proc id list parser. Here is the grammar:2789 2790place_list := place2791place_list := place , place_list2792place := num2793place := place : num2794place := place : num : signed2795place := { subplacelist }2796place := ! place                  // (lowest priority)2797subplace_list := subplace2798subplace_list := subplace , subplace_list2799subplace := num2800subplace := num : num2801subplace := num : num : signed2802signed := num2803signed := + signed2804signed := - signed2805-----------------------------------------------------------------------------*/2806 2807// Return TRUE if successful parse, FALSE otherwise2808static int __kmp_parse_subplace_list(const char *var, const char **scan) {2809  const char *next;2810 2811  for (;;) {2812    int start, count, stride;2813 2814    //2815    // Read in the starting proc id2816    //2817    SKIP_WS(*scan);2818    if ((**scan < '0') || (**scan > '9')) {2819      return FALSE;2820    }2821    next = *scan;2822    SKIP_DIGITS(next);2823    start = __kmp_str_to_int(*scan, *next);2824    KMP_ASSERT(start >= 0);2825    *scan = next;2826 2827    // valid follow sets are ',' ':' and '}'2828    SKIP_WS(*scan);2829    if (**scan == '}') {2830      break;2831    }2832    if (**scan == ',') {2833      (*scan)++; // skip ','2834      continue;2835    }2836    if (**scan != ':') {2837      return FALSE;2838    }2839    (*scan)++; // skip ':'2840 2841    // Read count parameter2842    SKIP_WS(*scan);2843    if ((**scan < '0') || (**scan > '9')) {2844      return FALSE;2845    }2846    next = *scan;2847    SKIP_DIGITS(next);2848    count = __kmp_str_to_int(*scan, *next);2849    KMP_ASSERT(count >= 0);2850    *scan = next;2851 2852    // valid follow sets are ',' ':' and '}'2853    SKIP_WS(*scan);2854    if (**scan == '}') {2855      break;2856    }2857    if (**scan == ',') {2858      (*scan)++; // skip ','2859      continue;2860    }2861    if (**scan != ':') {2862      return FALSE;2863    }2864    (*scan)++; // skip ':'2865 2866    // Read stride parameter2867    int sign = +1;2868    for (;;) {2869      SKIP_WS(*scan);2870      if (**scan == '+') {2871        (*scan)++; // skip '+'2872        continue;2873      }2874      if (**scan == '-') {2875        sign *= -1;2876        (*scan)++; // skip '-'2877        continue;2878      }2879      break;2880    }2881    SKIP_WS(*scan);2882    if ((**scan < '0') || (**scan > '9')) {2883      return FALSE;2884    }2885    next = *scan;2886    SKIP_DIGITS(next);2887    stride = __kmp_str_to_int(*scan, *next);2888    KMP_ASSERT(stride >= 0);2889    *scan = next;2890    stride *= sign;2891 2892    // valid follow sets are ',' and '}'2893    SKIP_WS(*scan);2894    if (**scan == '}') {2895      break;2896    }2897    if (**scan == ',') {2898      (*scan)++; // skip ','2899      continue;2900    }2901    return FALSE;2902  }2903  return TRUE;2904}2905 2906// Return TRUE if successful parse, FALSE otherwise2907static int __kmp_parse_place(const char *var, const char **scan) {2908  const char *next;2909 2910  // valid follow sets are '{' '!' and num2911  SKIP_WS(*scan);2912  if (**scan == '{') {2913    (*scan)++; // skip '{'2914    if (!__kmp_parse_subplace_list(var, scan)) {2915      return FALSE;2916    }2917    if (**scan != '}') {2918      return FALSE;2919    }2920    (*scan)++; // skip '}'2921  } else if (**scan == '!') {2922    (*scan)++; // skip '!'2923    return __kmp_parse_place(var, scan); //'!' has lower precedence than ':'2924  } else if ((**scan >= '0') && (**scan <= '9')) {2925    next = *scan;2926    SKIP_DIGITS(next);2927    int proc = __kmp_str_to_int(*scan, *next);2928    KMP_ASSERT(proc >= 0);2929    *scan = next;2930  } else {2931    return FALSE;2932  }2933  return TRUE;2934}2935 2936// Return TRUE if successful parse, FALSE otherwise2937static int __kmp_parse_place_list(const char *var, const char *env,2938                                  char **place_list) {2939  const char *scan = env;2940  const char *next = scan;2941 2942  for (;;) {2943    int count, stride;2944 2945    if (!__kmp_parse_place(var, &scan)) {2946      return FALSE;2947    }2948 2949    // valid follow sets are ',' ':' and EOL2950    SKIP_WS(scan);2951    if (*scan == '\0') {2952      break;2953    }2954    if (*scan == ',') {2955      scan++; // skip ','2956      continue;2957    }2958    if (*scan != ':') {2959      return FALSE;2960    }2961    scan++; // skip ':'2962 2963    // Read count parameter2964    SKIP_WS(scan);2965    if ((*scan < '0') || (*scan > '9')) {2966      return FALSE;2967    }2968    next = scan;2969    SKIP_DIGITS(next);2970    count = __kmp_str_to_int(scan, *next);2971    KMP_ASSERT(count >= 0);2972    scan = next;2973 2974    // valid follow sets are ',' ':' and EOL2975    SKIP_WS(scan);2976    if (*scan == '\0') {2977      break;2978    }2979    if (*scan == ',') {2980      scan++; // skip ','2981      continue;2982    }2983    if (*scan != ':') {2984      return FALSE;2985    }2986    scan++; // skip ':'2987 2988    // Read stride parameter2989    int sign = +1;2990    for (;;) {2991      SKIP_WS(scan);2992      if (*scan == '+') {2993        scan++; // skip '+'2994        continue;2995      }2996      if (*scan == '-') {2997        sign *= -1;2998        scan++; // skip '-'2999        continue;3000      }3001      break;3002    }3003    SKIP_WS(scan);3004    if ((*scan < '0') || (*scan > '9')) {3005      return FALSE;3006    }3007    next = scan;3008    SKIP_DIGITS(next);3009    stride = __kmp_str_to_int(scan, *next);3010    KMP_ASSERT(stride >= 0);3011    scan = next;3012    stride *= sign;3013 3014    // valid follow sets are ',' and EOL3015    SKIP_WS(scan);3016    if (*scan == '\0') {3017      break;3018    }3019    if (*scan == ',') {3020      scan++; // skip ','3021      continue;3022    }3023 3024    return FALSE;3025  }3026 3027  {3028    ptrdiff_t len = scan - env;3029    char *retlist = (char *)KMP_INTERNAL_MALLOC((len + 1) * sizeof(char));3030    KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char));3031    retlist[len] = '\0';3032    *place_list = retlist;3033  }3034  return TRUE;3035}3036 3037static inline void __kmp_places_set(enum affinity_type type, kmp_hw_t kind) {3038  __kmp_affinity.type = type;3039  __kmp_affinity.gran = kind;3040  __kmp_affinity.flags.dups = FALSE;3041  __kmp_affinity.flags.omp_places = TRUE;3042}3043 3044static void __kmp_places_syntax_error_fallback(char const *name,3045                                               kmp_hw_t kind) {3046  const char *str = __kmp_hw_get_catalog_string(kind, /*plural=*/true);3047  KMP_WARNING(SyntaxErrorUsing, name, str);3048  __kmp_places_set(affinity_compact, kind);3049  if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default)3050    __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;3051}3052 3053static void __kmp_stg_parse_places(char const *name, char const *value,3054                                   void *data) {3055  struct kmp_place_t {3056    const char *name;3057    kmp_hw_t type;3058  };3059  int count;3060  bool set = false;3061  const char *scan = value;3062  const char *next = scan;3063  kmp_place_t std_places[] = {{"threads", KMP_HW_THREAD},3064                              {"cores", KMP_HW_CORE},3065                              {"numa_domains", KMP_HW_NUMA},3066                              {"ll_caches", KMP_HW_LLC},3067                              {"sockets", KMP_HW_SOCKET}};3068  kmp_setting_t **rivals = (kmp_setting_t **)data;3069  int rc;3070 3071  rc = __kmp_stg_check_rivals(name, value, rivals);3072  if (rc) {3073    return;3074  }3075 3076  // Standard choices3077  for (size_t i = 0; i < sizeof(std_places) / sizeof(std_places[0]); ++i) {3078    const kmp_place_t &place = std_places[i];3079    if (__kmp_match_str(place.name, scan, &next)) {3080      scan = next;3081      __kmp_places_set(affinity_compact, place.type);3082      set = true;3083      // Parse core attribute if it exists3084      if (KMP_HW_MAX_NUM_CORE_TYPES > 1) {3085        SKIP_WS(scan);3086        if (*scan == ':') {3087          if (place.type != KMP_HW_CORE) {3088            __kmp_places_syntax_error_fallback(name, place.type);3089            return;3090          }3091          scan++; // skip ':'3092          SKIP_WS(scan);3093#if KMP_ARCH_X86 || KMP_ARCH_X86_643094          if (__kmp_match_str("intel_core", scan, &next)) {3095            __kmp_affinity.core_attr_gran.core_type = KMP_HW_CORE_TYPE_CORE;3096            __kmp_affinity.core_attr_gran.valid = 1;3097            scan = next;3098          } else if (__kmp_match_str("intel_atom", scan, &next)) {3099            __kmp_affinity.core_attr_gran.core_type = KMP_HW_CORE_TYPE_ATOM;3100            __kmp_affinity.core_attr_gran.valid = 1;3101            scan = next;3102          } else3103#endif3104              if (__kmp_match_str("eff", scan, &next)) {3105            int eff;3106            if (!isdigit(*next)) {3107              __kmp_places_syntax_error_fallback(name, place.type);3108              return;3109            }3110            scan = next;3111            SKIP_DIGITS(next);3112            eff = __kmp_str_to_int(scan, *next);3113            if (eff < 0) {3114              __kmp_places_syntax_error_fallback(name, place.type);3115              return;3116            }3117            if (eff >= KMP_HW_MAX_NUM_CORE_EFFS)3118              eff = KMP_HW_MAX_NUM_CORE_EFFS - 1;3119            __kmp_affinity.core_attr_gran.core_eff = eff;3120            __kmp_affinity.core_attr_gran.valid = 1;3121            scan = next;3122          }3123          if (!__kmp_affinity.core_attr_gran.valid) {3124            __kmp_places_syntax_error_fallback(name, place.type);3125            return;3126          }3127        }3128      }3129      break;3130    }3131  }3132  // Implementation choices for OMP_PLACES based on internal types3133  if (!set) {3134    KMP_FOREACH_HW_TYPE(type) {3135      const char *name = __kmp_hw_get_keyword(type, true);3136      if (__kmp_match_str("unknowns", scan, &next))3137        continue;3138      if (__kmp_match_str(name, scan, &next)) {3139        scan = next;3140        __kmp_places_set(affinity_compact, type);3141        set = true;3142        break;3143      }3144    }3145  }3146  // Implementation choices for OMP_PLACES based on core attributes3147  if (!set) {3148    if (__kmp_match_str("core_types", scan, &next)) {3149      scan = next;3150      if (*scan != '\0') {3151        KMP_WARNING(ParseExtraCharsWarn, name, scan);3152      }3153      __kmp_places_set(affinity_compact, KMP_HW_CORE);3154      __kmp_affinity.flags.core_types_gran = 1;3155      set = true;3156    } else if (__kmp_match_str("core_effs", scan, &next) ||3157               __kmp_match_str("core_efficiencies", scan, &next)) {3158      scan = next;3159      if (*scan != '\0') {3160        KMP_WARNING(ParseExtraCharsWarn, name, scan);3161      }3162      __kmp_places_set(affinity_compact, KMP_HW_CORE);3163      __kmp_affinity.flags.core_effs_gran = 1;3164      set = true;3165    }3166  }3167  // Explicit place list3168  if (!set) {3169    if (__kmp_affinity.proclist != NULL) {3170      KMP_INTERNAL_FREE((void *)__kmp_affinity.proclist);3171      __kmp_affinity.proclist = NULL;3172    }3173    if (__kmp_parse_place_list(name, value, &__kmp_affinity.proclist)) {3174      __kmp_places_set(affinity_explicit, KMP_HW_THREAD);3175    } else {3176      // Syntax error fallback3177      __kmp_places_syntax_error_fallback(name, KMP_HW_CORE);3178    }3179    if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {3180      __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;3181    }3182    return;3183  }3184 3185  kmp_hw_t gran = __kmp_affinity.gran;3186  if (__kmp_affinity.gran != KMP_HW_UNKNOWN) {3187    gran = __kmp_affinity.gran;3188  } else {3189    gran = KMP_HW_CORE;3190  }3191 3192  if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {3193    __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;3194  }3195 3196  SKIP_WS(scan);3197  if (*scan == '\0') {3198    return;3199  }3200 3201  // Parse option count parameter in parentheses3202  if (*scan != '(') {3203    __kmp_places_syntax_error_fallback(name, gran);3204    return;3205  }3206  scan++; // skip '('3207 3208  SKIP_WS(scan);3209  next = scan;3210  SKIP_DIGITS(next);3211  count = __kmp_str_to_int(scan, *next);3212  KMP_ASSERT(count >= 0);3213  scan = next;3214 3215  SKIP_WS(scan);3216  if (*scan != ')') {3217    __kmp_places_syntax_error_fallback(name, gran);3218    return;3219  }3220  scan++; // skip ')'3221 3222  SKIP_WS(scan);3223  if (*scan != '\0') {3224    KMP_WARNING(ParseExtraCharsWarn, name, scan);3225  }3226  __kmp_affinity_num_places = count;3227}3228 3229static void __kmp_stg_print_places(kmp_str_buf_t *buffer, char const *name,3230                                   void *data) {3231  enum affinity_type type = __kmp_affinity.type;3232  const char *proclist = __kmp_affinity.proclist;3233  kmp_hw_t gran = __kmp_affinity.gran;3234 3235  if (__kmp_env_format) {3236    KMP_STR_BUF_PRINT_NAME;3237  } else {3238    __kmp_str_buf_print(buffer, "   %s", name);3239  }3240  if ((__kmp_nested_proc_bind.used == 0) ||3241      (__kmp_nested_proc_bind.bind_types == NULL) ||3242      (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)) {3243    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));3244  } else if (type == affinity_explicit) {3245    if (proclist != NULL) {3246      __kmp_str_buf_print(buffer, "='%s'\n", proclist);3247    } else {3248      __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));3249    }3250  } else if (type == affinity_compact) {3251    int num;3252    if (__kmp_affinity.num_masks > 0) {3253      num = __kmp_affinity.num_masks;3254    } else if (__kmp_affinity_num_places > 0) {3255      num = __kmp_affinity_num_places;3256    } else {3257      num = 0;3258    }3259    if (gran != KMP_HW_UNKNOWN) {3260      // If core_types or core_effs, just print and return3261      if (__kmp_affinity.flags.core_types_gran) {3262        __kmp_str_buf_print(buffer, "='%s'\n", "core_types");3263        return;3264      }3265      if (__kmp_affinity.flags.core_effs_gran) {3266        __kmp_str_buf_print(buffer, "='%s'\n", "core_effs");3267        return;3268      }3269 3270      // threads, cores, sockets, cores:<attribute>, etc.3271      const char *name = __kmp_hw_get_keyword(gran, true);3272      __kmp_str_buf_print(buffer, "='%s", name);3273 3274      // Add core attributes if it exists3275      if (__kmp_affinity.core_attr_gran.valid) {3276        kmp_hw_core_type_t ct =3277            (kmp_hw_core_type_t)__kmp_affinity.core_attr_gran.core_type;3278        int eff = __kmp_affinity.core_attr_gran.core_eff;3279        if (ct != KMP_HW_CORE_TYPE_UNKNOWN) {3280          const char *ct_name = __kmp_hw_get_core_type_keyword(ct);3281          __kmp_str_buf_print(buffer, ":%s", ct_name);3282        } else if (eff >= 0 && eff < KMP_HW_MAX_NUM_CORE_EFFS) {3283          __kmp_str_buf_print(buffer, ":eff%d", eff);3284        }3285      }3286 3287      // Add the '(#)' part if it exists3288      if (num > 0)3289        __kmp_str_buf_print(buffer, "(%d)", num);3290      __kmp_str_buf_print(buffer, "'\n");3291    } else {3292      __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));3293    }3294  } else {3295    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));3296  }3297}3298 3299static void __kmp_stg_parse_topology_method(char const *name, char const *value,3300                                            void *data) {3301  if (__kmp_str_match("all", 1, value)) {3302    __kmp_affinity_top_method = affinity_top_method_all;3303  }3304#if KMP_HWLOC_ENABLED3305  else if (__kmp_str_match("hwloc", 1, value)) {3306    __kmp_affinity_top_method = affinity_top_method_hwloc;3307  }3308#endif // KMP_HWLOC_ENABLED3309#if KMP_ARCH_X86 || KMP_ARCH_X86_643310  else if (__kmp_str_match("cpuid_leaf31", 12, value) ||3311           __kmp_str_match("cpuid 1f", 8, value) ||3312           __kmp_str_match("cpuid 31", 8, value) ||3313           __kmp_str_match("cpuid1f", 7, value) ||3314           __kmp_str_match("cpuid31", 7, value) ||3315           __kmp_str_match("leaf 1f", 7, value) ||3316           __kmp_str_match("leaf 31", 7, value) ||3317           __kmp_str_match("leaf1f", 6, value) ||3318           __kmp_str_match("leaf31", 6, value)) {3319    __kmp_affinity_top_method = affinity_top_method_x2apicid_1f;3320  } else if (__kmp_str_match("x2apic id", 9, value) ||3321             __kmp_str_match("x2apic_id", 9, value) ||3322             __kmp_str_match("x2apic-id", 9, value) ||3323             __kmp_str_match("x2apicid", 8, value) ||3324             __kmp_str_match("cpuid leaf 11", 13, value) ||3325             __kmp_str_match("cpuid_leaf_11", 13, value) ||3326             __kmp_str_match("cpuid-leaf-11", 13, value) ||3327             __kmp_str_match("cpuid leaf11", 12, value) ||3328             __kmp_str_match("cpuid_leaf11", 12, value) ||3329             __kmp_str_match("cpuid-leaf11", 12, value) ||3330             __kmp_str_match("cpuidleaf 11", 12, value) ||3331             __kmp_str_match("cpuidleaf_11", 12, value) ||3332             __kmp_str_match("cpuidleaf-11", 12, value) ||3333             __kmp_str_match("cpuidleaf11", 11, value) ||3334             __kmp_str_match("cpuid 11", 8, value) ||3335             __kmp_str_match("cpuid_11", 8, value) ||3336             __kmp_str_match("cpuid-11", 8, value) ||3337             __kmp_str_match("cpuid11", 7, value) ||3338             __kmp_str_match("leaf 11", 7, value) ||3339             __kmp_str_match("leaf_11", 7, value) ||3340             __kmp_str_match("leaf-11", 7, value) ||3341             __kmp_str_match("leaf11", 6, value)) {3342    __kmp_affinity_top_method = affinity_top_method_x2apicid;3343  } else if (__kmp_str_match("apic id", 7, value) ||3344             __kmp_str_match("apic_id", 7, value) ||3345             __kmp_str_match("apic-id", 7, value) ||3346             __kmp_str_match("apicid", 6, value) ||3347             __kmp_str_match("cpuid leaf 4", 12, value) ||3348             __kmp_str_match("cpuid_leaf_4", 12, value) ||3349             __kmp_str_match("cpuid-leaf-4", 12, value) ||3350             __kmp_str_match("cpuid leaf4", 11, value) ||3351             __kmp_str_match("cpuid_leaf4", 11, value) ||3352             __kmp_str_match("cpuid-leaf4", 11, value) ||3353             __kmp_str_match("cpuidleaf 4", 11, value) ||3354             __kmp_str_match("cpuidleaf_4", 11, value) ||3355             __kmp_str_match("cpuidleaf-4", 11, value) ||3356             __kmp_str_match("cpuidleaf4", 10, value) ||3357             __kmp_str_match("cpuid 4", 7, value) ||3358             __kmp_str_match("cpuid_4", 7, value) ||3359             __kmp_str_match("cpuid-4", 7, value) ||3360             __kmp_str_match("cpuid4", 6, value) ||3361             __kmp_str_match("leaf 4", 6, value) ||3362             __kmp_str_match("leaf_4", 6, value) ||3363             __kmp_str_match("leaf-4", 6, value) ||3364             __kmp_str_match("leaf4", 5, value)) {3365    __kmp_affinity_top_method = affinity_top_method_apicid;3366  }3367#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */3368  else if (__kmp_str_match("/proc/cpuinfo", 2, value) ||3369           __kmp_str_match("cpuinfo", 5, value)) {3370    __kmp_affinity_top_method = affinity_top_method_cpuinfo;3371  }3372#if KMP_GROUP_AFFINITY3373  else if (__kmp_str_match("group", 1, value)) {3374    KMP_WARNING(StgDeprecatedValue, name, value, "all");3375    __kmp_affinity_top_method = affinity_top_method_group;3376  }3377#endif /* KMP_GROUP_AFFINITY */3378  else if (__kmp_str_match("flat", 1, value)) {3379    __kmp_affinity_top_method = affinity_top_method_flat;3380  } else {3381    KMP_WARNING(StgInvalidValue, name, value);3382  }3383} // __kmp_stg_parse_topology_method3384 3385static void __kmp_stg_print_topology_method(kmp_str_buf_t *buffer,3386                                            char const *name, void *data) {3387  char const *value = NULL;3388 3389  switch (__kmp_affinity_top_method) {3390  case affinity_top_method_default:3391    value = "default";3392    break;3393 3394  case affinity_top_method_all:3395    value = "all";3396    break;3397 3398#if KMP_ARCH_X86 || KMP_ARCH_X86_643399  case affinity_top_method_x2apicid_1f:3400    value = "x2APIC id leaf 0x1f";3401    break;3402 3403  case affinity_top_method_x2apicid:3404    value = "x2APIC id leaf 0xb";3405    break;3406 3407  case affinity_top_method_apicid:3408    value = "APIC id";3409    break;3410#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */3411 3412#if KMP_HWLOC_ENABLED3413  case affinity_top_method_hwloc:3414    value = "hwloc";3415    break;3416#endif // KMP_HWLOC_ENABLED3417 3418  case affinity_top_method_cpuinfo:3419    value = "cpuinfo";3420    break;3421 3422#if KMP_GROUP_AFFINITY3423  case affinity_top_method_group:3424    value = "group";3425    break;3426#endif /* KMP_GROUP_AFFINITY */3427 3428  case affinity_top_method_flat:3429    value = "flat";3430    break;3431  }3432 3433  if (value != NULL) {3434    __kmp_stg_print_str(buffer, name, value);3435  }3436} // __kmp_stg_print_topology_method3437 3438// KMP_TEAMS_PROC_BIND3439struct kmp_proc_bind_info_t {3440  const char *name;3441  kmp_proc_bind_t proc_bind;3442};3443static kmp_proc_bind_info_t proc_bind_table[] = {3444    {"spread", proc_bind_spread},3445    {"true", proc_bind_spread},3446    {"close", proc_bind_close},3447    // teams-bind = false means "replicate the primary thread's affinity"3448    {"false", proc_bind_primary},3449    {"primary", proc_bind_primary}};3450static void __kmp_stg_parse_teams_proc_bind(char const *name, char const *value,3451                                            void *data) {3452  int valid;3453  const char *end;3454  valid = 0;3455  for (size_t i = 0; i < sizeof(proc_bind_table) / sizeof(proc_bind_table[0]);3456       ++i) {3457    if (__kmp_match_str(proc_bind_table[i].name, value, &end)) {3458      __kmp_teams_proc_bind = proc_bind_table[i].proc_bind;3459      valid = 1;3460      break;3461    }3462  }3463  if (!valid) {3464    KMP_WARNING(StgInvalidValue, name, value);3465  }3466}3467static void __kmp_stg_print_teams_proc_bind(kmp_str_buf_t *buffer,3468                                            char const *name, void *data) {3469  const char *value = KMP_I18N_STR(NotDefined);3470  for (size_t i = 0; i < sizeof(proc_bind_table) / sizeof(proc_bind_table[0]);3471       ++i) {3472    if (__kmp_teams_proc_bind == proc_bind_table[i].proc_bind) {3473      value = proc_bind_table[i].name;3474      break;3475    }3476  }3477  __kmp_stg_print_str(buffer, name, value);3478}3479#endif /* KMP_AFFINITY_SUPPORTED */3480 3481// OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*3482// OMP_PLACES / place-partition-var is not.3483static void __kmp_stg_parse_proc_bind(char const *name, char const *value,3484                                      void *data) {3485  kmp_setting_t **rivals = (kmp_setting_t **)data;3486  int rc;3487 3488  rc = __kmp_stg_check_rivals(name, value, rivals);3489  if (rc) {3490    return;3491  }3492 3493  // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.3494  KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) &&3495                   (__kmp_nested_proc_bind.used > 0));3496 3497  const char *buf = value;3498  const char *next;3499 3500  SKIP_WS(buf);3501 3502  next = buf;3503  if (__kmp_match_str("disabled", buf, &next)) {3504    buf = next;3505    SKIP_WS(buf);3506#if KMP_AFFINITY_SUPPORTED3507    __kmp_affinity.type = affinity_disabled;3508#endif /* KMP_AFFINITY_SUPPORTED */3509    __kmp_nested_proc_bind.used = 1;3510    __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;3511  } else if (__kmp_match_str("false", buf, &next)) {3512    buf = next;3513    SKIP_WS(buf);3514#if KMP_AFFINITY_SUPPORTED3515    __kmp_affinity.type = affinity_none;3516#endif /* KMP_AFFINITY_SUPPORTED */3517    __kmp_nested_proc_bind.used = 1;3518    __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;3519  } else if (__kmp_match_str("true", buf, &next)) {3520    buf = next;3521    SKIP_WS(buf);3522    __kmp_nested_proc_bind.used = 1;3523    __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;3524  } else {3525    // Count the number of values in the env var string3526    const char *scan;3527    int nelem = 1;3528    for (scan = buf; *scan != '\0'; scan++) {3529      if (*scan == ',') {3530        nelem++;3531      }3532    }3533 3534    // Create / expand the nested proc_bind array as needed3535    if (__kmp_nested_proc_bind.size < nelem) {3536      __kmp_nested_proc_bind.bind_types =3537          (kmp_proc_bind_t *)KMP_INTERNAL_REALLOC(3538              __kmp_nested_proc_bind.bind_types,3539              sizeof(kmp_proc_bind_t) * nelem);3540      if (__kmp_nested_proc_bind.bind_types == NULL) {3541        KMP_FATAL(MemoryAllocFailed);3542      }3543      __kmp_nested_proc_bind.size = nelem;3544    }3545    __kmp_nested_proc_bind.used = nelem;3546 3547    if (nelem > 1 && !__kmp_dflt_max_active_levels_set)3548      __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT;3549 3550    // Save values in the nested proc_bind array3551    int i = 0;3552    for (;;) {3553      enum kmp_proc_bind_t bind;3554 3555      if (__kmp_match_str("master", buf, &next) ||3556          __kmp_match_str("primary", buf, &next)) {3557        buf = next;3558        SKIP_WS(buf);3559        bind = proc_bind_primary;3560      } else if (__kmp_match_str("close", buf, &next)) {3561        buf = next;3562        SKIP_WS(buf);3563        bind = proc_bind_close;3564      } else if (__kmp_match_str("spread", buf, &next)) {3565        buf = next;3566        SKIP_WS(buf);3567        bind = proc_bind_spread;3568      } else {3569        KMP_WARNING(StgInvalidValue, name, value);3570        __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;3571        __kmp_nested_proc_bind.used = 1;3572        return;3573      }3574 3575      __kmp_nested_proc_bind.bind_types[i++] = bind;3576      if (i >= nelem) {3577        break;3578      }3579      if (*buf != ',') {3580        KMP_WARNING(ParseExtraCharsWarn, name, buf);3581        while (*buf != ',')3582          buf++;3583      }3584      buf++;3585      SKIP_WS(buf);3586    }3587    SKIP_WS(buf);3588  }3589  if (*buf != '\0') {3590    KMP_WARNING(ParseExtraCharsWarn, name, buf);3591  }3592}3593 3594static void __kmp_stg_print_proc_bind(kmp_str_buf_t *buffer, char const *name,3595                                      void *data) {3596  int nelem = __kmp_nested_proc_bind.used;3597  if (__kmp_env_format) {3598    KMP_STR_BUF_PRINT_NAME;3599  } else {3600    __kmp_str_buf_print(buffer, "   %s", name);3601  }3602  if (nelem == 0) {3603    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));3604  } else {3605    int i;3606    __kmp_str_buf_print(buffer, "='", name);3607    for (i = 0; i < nelem; i++) {3608      switch (__kmp_nested_proc_bind.bind_types[i]) {3609      case proc_bind_false:3610        __kmp_str_buf_print(buffer, "false");3611        break;3612 3613      case proc_bind_true:3614        __kmp_str_buf_print(buffer, "true");3615        break;3616 3617      case proc_bind_primary:3618        __kmp_str_buf_print(buffer, "primary");3619        break;3620 3621      case proc_bind_close:3622        __kmp_str_buf_print(buffer, "close");3623        break;3624 3625      case proc_bind_spread:3626        __kmp_str_buf_print(buffer, "spread");3627        break;3628 3629      case proc_bind_intel:3630        __kmp_str_buf_print(buffer, "intel");3631        break;3632 3633      case proc_bind_default:3634        __kmp_str_buf_print(buffer, "default");3635        break;3636      }3637      if (i < nelem - 1) {3638        __kmp_str_buf_print(buffer, ",");3639      }3640    }3641    __kmp_str_buf_print(buffer, "'\n");3642  }3643}3644 3645static void __kmp_stg_parse_display_affinity(char const *name,3646                                             char const *value, void *data) {3647  __kmp_stg_parse_bool(name, value, &__kmp_display_affinity);3648}3649static void __kmp_stg_print_display_affinity(kmp_str_buf_t *buffer,3650                                             char const *name, void *data) {3651  __kmp_stg_print_bool(buffer, name, __kmp_display_affinity);3652}3653static void __kmp_stg_parse_affinity_format(char const *name, char const *value,3654                                            void *data) {3655  size_t length = KMP_STRLEN(value);3656  __kmp_strncpy_truncate(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, value,3657                         length);3658}3659static void __kmp_stg_print_affinity_format(kmp_str_buf_t *buffer,3660                                            char const *name, void *data) {3661  if (__kmp_env_format) {3662    KMP_STR_BUF_PRINT_NAME_EX(name);3663  } else {3664    __kmp_str_buf_print(buffer, "   %s='", name);3665  }3666  __kmp_str_buf_print(buffer, "%s'\n", __kmp_affinity_format);3667}3668 3669/*-----------------------------------------------------------------------------3670OMP_ALLOCATOR sets default allocator. Here is the grammar:3671 3672<allocator>        |= <predef-allocator> | <predef-mem-space> |3673                      <predef-mem-space>:<traits>3674<traits>           |= <trait>=<value> | <trait>=<value>,<traits>3675<predef-allocator> |= omp_default_mem_alloc | omp_large_cap_mem_alloc |3676                      omp_const_mem_alloc | omp_high_bw_mem_alloc |3677                      omp_low_lat_mem_alloc | omp_cgroup_mem_alloc |3678                      omp_pteam_mem_alloc | omp_thread_mem_alloc3679<predef-mem-space> |= omp_default_mem_space | omp_large_cap_mem_space |3680                      omp_const_mem_space | omp_high_bw_mem_space |3681                      omp_low_lat_mem_space3682<trait>            |= sync_hint | alignment | access | pool_size | fallback |3683                      fb_data | pinned | partition3684<value>            |= one of the allowed values of trait |3685                      non-negative integer | <predef-allocator>3686-----------------------------------------------------------------------------*/3687 3688static void __kmp_stg_parse_allocator(char const *name, char const *value,3689                                      void *data) {3690  const char *buf = value;3691  const char *next, *scan, *start;3692  char *key;3693  omp_allocator_handle_t al;3694  omp_memspace_handle_t ms = omp_default_mem_space;3695  bool is_memspace = false;3696  int ntraits = 0, count = 0;3697 3698  SKIP_WS(buf);3699  next = buf;3700  const char *delim = strchr(buf, ':');3701  const char *predef_mem_space = strstr(buf, "mem_space");3702 3703  bool is_memalloc = (!predef_mem_space && !delim) ? true : false;3704 3705  // Count the number of traits in the env var string3706  if (delim) {3707    ntraits = 1;3708    for (scan = buf; *scan != '\0'; scan++) {3709      if (*scan == ',')3710        ntraits++;3711    }3712  }3713  omp_alloctrait_t *traits =3714      (omp_alloctrait_t *)KMP_ALLOCA(ntraits * sizeof(omp_alloctrait_t));3715 3716// Helper macros3717#define IS_POWER_OF_TWO(n) (((n) & ((n)-1)) == 0)3718 3719#define GET_NEXT(sentinel)                                                     \3720  {                                                                            \3721    SKIP_WS(next);                                                             \3722    if (*next == sentinel)                                                     \3723      next++;                                                                  \3724    SKIP_WS(next);                                                             \3725    scan = next;                                                               \3726  }3727 3728#define SKIP_PAIR(key)                                                         \3729  {                                                                            \3730    char const str_delimiter[] = {',', 0};                                     \3731    char *value = __kmp_str_token(CCAST(char *, scan), str_delimiter,          \3732                                  CCAST(char **, &next));                      \3733    KMP_WARNING(StgInvalidValue, key, value);                                  \3734    ntraits--;                                                                 \3735    SKIP_WS(next);                                                             \3736    scan = next;                                                               \3737  }3738 3739#define SET_KEY()                                                              \3740  {                                                                            \3741    char const str_delimiter[] = {'=', 0};                                     \3742    key = __kmp_str_token(CCAST(char *, start), str_delimiter,                 \3743                          CCAST(char **, &next));                              \3744    scan = next;                                                               \3745  }3746 3747  scan = next;3748  while (*next != '\0') {3749    if (is_memalloc ||3750        __kmp_match_str("fb_data", scan, &next)) { // allocator check3751      start = scan;3752      GET_NEXT('=');3753      // check HBW and LCAP first as the only non-default supported3754      if (__kmp_match_str("omp_high_bw_mem_alloc", scan, &next)) {3755        SKIP_WS(next);3756        if (is_memalloc) {3757          if (__kmp_hwloc_available || __kmp_memkind_available) {3758            __kmp_def_allocator = omp_high_bw_mem_alloc;3759            return;3760          } else {3761            KMP_WARNING(OmpNoAllocator, "omp_high_bw_mem_alloc");3762          }3763        } else {3764          traits[count].key = omp_atk_fb_data;3765          traits[count].value = RCAST(omp_uintptr_t, omp_high_bw_mem_alloc);3766        }3767      } else if (__kmp_match_str("omp_large_cap_mem_alloc", scan, &next)) {3768        SKIP_WS(next);3769        if (is_memalloc) {3770          if (__kmp_hwloc_available || __kmp_memkind_available) {3771            __kmp_def_allocator = omp_large_cap_mem_alloc;3772            return;3773          } else {3774            KMP_WARNING(OmpNoAllocator, "omp_large_cap_mem_alloc");3775          }3776        } else {3777          traits[count].key = omp_atk_fb_data;3778          traits[count].value = RCAST(omp_uintptr_t, omp_large_cap_mem_alloc);3779        }3780      } else if (__kmp_match_str("omp_default_mem_alloc", scan, &next)) {3781        // default requested3782        SKIP_WS(next);3783        if (!is_memalloc) {3784          traits[count].key = omp_atk_fb_data;3785          traits[count].value = RCAST(omp_uintptr_t, omp_default_mem_alloc);3786        }3787      } else if (__kmp_match_str("omp_const_mem_alloc", scan, &next)) {3788        SKIP_WS(next);3789        if (is_memalloc) {3790          KMP_WARNING(OmpNoAllocator, "omp_const_mem_alloc");3791        } else {3792          traits[count].key = omp_atk_fb_data;3793          traits[count].value = RCAST(omp_uintptr_t, omp_const_mem_alloc);3794        }3795      } else if (__kmp_match_str("omp_low_lat_mem_alloc", scan, &next)) {3796        SKIP_WS(next);3797        if (is_memalloc) {3798          KMP_WARNING(OmpNoAllocator, "omp_low_lat_mem_alloc");3799        } else {3800          traits[count].key = omp_atk_fb_data;3801          traits[count].value = RCAST(omp_uintptr_t, omp_low_lat_mem_alloc);3802        }3803      } else if (__kmp_match_str("omp_cgroup_mem_alloc", scan, &next)) {3804        SKIP_WS(next);3805        if (is_memalloc) {3806          KMP_WARNING(OmpNoAllocator, "omp_cgroup_mem_alloc");3807        } else {3808          traits[count].key = omp_atk_fb_data;3809          traits[count].value = RCAST(omp_uintptr_t, omp_cgroup_mem_alloc);3810        }3811      } else if (__kmp_match_str("omp_pteam_mem_alloc", scan, &next)) {3812        SKIP_WS(next);3813        if (is_memalloc) {3814          KMP_WARNING(OmpNoAllocator, "omp_pteam_mem_alloc");3815        } else {3816          traits[count].key = omp_atk_fb_data;3817          traits[count].value = RCAST(omp_uintptr_t, omp_pteam_mem_alloc);3818        }3819      } else if (__kmp_match_str("omp_thread_mem_alloc", scan, &next)) {3820        SKIP_WS(next);3821        if (is_memalloc) {3822          KMP_WARNING(OmpNoAllocator, "omp_thread_mem_alloc");3823        } else {3824          traits[count].key = omp_atk_fb_data;3825          traits[count].value = RCAST(omp_uintptr_t, omp_thread_mem_alloc);3826        }3827      } else {3828        if (!is_memalloc) {3829          SET_KEY();3830          SKIP_PAIR(key);3831          continue;3832        }3833      }3834      if (is_memalloc) {3835        __kmp_def_allocator = omp_default_mem_alloc;3836        if (next == buf || *next != '\0') {3837          // either no match or extra symbols present after the matched token3838          KMP_WARNING(StgInvalidValue, name, value);3839        }3840        return;3841      } else {3842        ++count;3843        if (count == ntraits)3844          break;3845        GET_NEXT(',');3846      }3847    } else { // memspace3848      if (!is_memspace) {3849        if (__kmp_match_str("omp_default_mem_space", scan, &next)) {3850          SKIP_WS(next);3851          ms = omp_default_mem_space;3852        } else if (__kmp_match_str("omp_large_cap_mem_space", scan, &next)) {3853          SKIP_WS(next);3854          ms = omp_large_cap_mem_space;3855        } else if (__kmp_match_str("omp_const_mem_space", scan, &next)) {3856          SKIP_WS(next);3857          ms = omp_const_mem_space;3858        } else if (__kmp_match_str("omp_high_bw_mem_space", scan, &next)) {3859          SKIP_WS(next);3860          ms = omp_high_bw_mem_space;3861        } else if (__kmp_match_str("omp_low_lat_mem_space", scan, &next)) {3862          SKIP_WS(next);3863          ms = omp_low_lat_mem_space;3864        } else {3865          __kmp_def_allocator = omp_default_mem_alloc;3866          if (next == buf || *next != '\0') {3867            // either no match or extra symbols present after the matched token3868            KMP_WARNING(StgInvalidValue, name, value);3869          }3870          return;3871        }3872        is_memspace = true;3873      }3874      if (delim) { // traits3875        GET_NEXT(':');3876        start = scan;3877        if (__kmp_match_str("sync_hint", scan, &next)) {3878          GET_NEXT('=');3879          traits[count].key = omp_atk_sync_hint;3880          if (__kmp_match_str("contended", scan, &next)) {3881            traits[count].value = omp_atv_contended;3882          } else if (__kmp_match_str("uncontended", scan, &next)) {3883            traits[count].value = omp_atv_uncontended;3884          } else if (__kmp_match_str("serialized", scan, &next)) {3885            traits[count].value = omp_atv_serialized;3886          } else if (__kmp_match_str("private", scan, &next)) {3887            traits[count].value = omp_atv_private;3888          } else {3889            SET_KEY();3890            SKIP_PAIR(key);3891            continue;3892          }3893        } else if (__kmp_match_str("alignment", scan, &next)) {3894          GET_NEXT('=');3895          if (!isdigit(*next)) {3896            SET_KEY();3897            SKIP_PAIR(key);3898            continue;3899          }3900          SKIP_DIGITS(next);3901          int n = __kmp_str_to_int(scan, ',');3902          if (n < 0 || !IS_POWER_OF_TWO(n)) {3903            SET_KEY();3904            SKIP_PAIR(key);3905            continue;3906          }3907          traits[count].key = omp_atk_alignment;3908          traits[count].value = n;3909        } else if (__kmp_match_str("access", scan, &next)) {3910          GET_NEXT('=');3911          traits[count].key = omp_atk_access;3912          if (__kmp_match_str("all", scan, &next)) {3913            traits[count].value = omp_atv_all;3914          } else if (__kmp_match_str("cgroup", scan, &next)) {3915            traits[count].value = omp_atv_cgroup;3916          } else if (__kmp_match_str("pteam", scan, &next)) {3917            traits[count].value = omp_atv_pteam;3918          } else if (__kmp_match_str("thread", scan, &next)) {3919            traits[count].value = omp_atv_thread;3920          } else {3921            SET_KEY();3922            SKIP_PAIR(key);3923            continue;3924          }3925        } else if (__kmp_match_str("pool_size", scan, &next)) {3926          GET_NEXT('=');3927          if (!isdigit(*next)) {3928            SET_KEY();3929            SKIP_PAIR(key);3930            continue;3931          }3932          SKIP_DIGITS(next);3933          int n = __kmp_str_to_int(scan, ',');3934          if (n < 0) {3935            SET_KEY();3936            SKIP_PAIR(key);3937            continue;3938          }3939          traits[count].key = omp_atk_pool_size;3940          traits[count].value = n;3941        } else if (__kmp_match_str("fallback", scan, &next)) {3942          GET_NEXT('=');3943          traits[count].key = omp_atk_fallback;3944          if (__kmp_match_str("default_mem_fb", scan, &next)) {3945            traits[count].value = omp_atv_default_mem_fb;3946          } else if (__kmp_match_str("null_fb", scan, &next)) {3947            traits[count].value = omp_atv_null_fb;3948          } else if (__kmp_match_str("abort_fb", scan, &next)) {3949            traits[count].value = omp_atv_abort_fb;3950          } else if (__kmp_match_str("allocator_fb", scan, &next)) {3951            traits[count].value = omp_atv_allocator_fb;3952          } else {3953            SET_KEY();3954            SKIP_PAIR(key);3955            continue;3956          }3957        } else if (__kmp_match_str("pinned", scan, &next)) {3958          GET_NEXT('=');3959          traits[count].key = omp_atk_pinned;3960          if (__kmp_str_match_true(next)) {3961            traits[count].value = omp_atv_true;3962          } else if (__kmp_str_match_false(next)) {3963            traits[count].value = omp_atv_false;3964          } else {3965            SET_KEY();3966            SKIP_PAIR(key);3967            continue;3968          }3969        } else if (__kmp_match_str("partition", scan, &next)) {3970          GET_NEXT('=');3971          traits[count].key = omp_atk_partition;3972          if (__kmp_match_str("environment", scan, &next)) {3973            traits[count].value = omp_atv_environment;3974          } else if (__kmp_match_str("nearest", scan, &next)) {3975            traits[count].value = omp_atv_nearest;3976          } else if (__kmp_match_str("blocked", scan, &next)) {3977            traits[count].value = omp_atv_blocked;3978          } else if (__kmp_match_str("interleaved", scan, &next)) {3979            traits[count].value = omp_atv_interleaved;3980          } else {3981            SET_KEY();3982            SKIP_PAIR(key);3983            continue;3984          }3985        } else {3986          SET_KEY();3987          SKIP_PAIR(key);3988          continue;3989        }3990        SKIP_WS(next);3991        ++count;3992        if (count == ntraits)3993          break;3994        GET_NEXT(',');3995      } // traits3996    } // memspace3997  } // while3998  al = __kmpc_init_allocator(__kmp_get_gtid(), ms, ntraits, traits);3999  __kmp_def_allocator = (al == omp_null_allocator) ? omp_default_mem_alloc : al;4000}4001 4002static void __kmp_stg_print_allocator(kmp_str_buf_t *buffer, char const *name,4003                                      void *data) {4004  if (__kmp_def_allocator == omp_default_mem_alloc) {4005    __kmp_stg_print_str(buffer, name, "omp_default_mem_alloc");4006  } else if (__kmp_def_allocator == omp_high_bw_mem_alloc) {4007    __kmp_stg_print_str(buffer, name, "omp_high_bw_mem_alloc");4008  } else if (__kmp_def_allocator == omp_large_cap_mem_alloc) {4009    __kmp_stg_print_str(buffer, name, "omp_large_cap_mem_alloc");4010  } else if (__kmp_def_allocator == omp_const_mem_alloc) {4011    __kmp_stg_print_str(buffer, name, "omp_const_mem_alloc");4012  } else if (__kmp_def_allocator == omp_low_lat_mem_alloc) {4013    __kmp_stg_print_str(buffer, name, "omp_low_lat_mem_alloc");4014  } else if (__kmp_def_allocator == omp_cgroup_mem_alloc) {4015    __kmp_stg_print_str(buffer, name, "omp_cgroup_mem_alloc");4016  } else if (__kmp_def_allocator == omp_pteam_mem_alloc) {4017    __kmp_stg_print_str(buffer, name, "omp_pteam_mem_alloc");4018  } else if (__kmp_def_allocator == omp_thread_mem_alloc) {4019    __kmp_stg_print_str(buffer, name, "omp_thread_mem_alloc");4020  }4021}4022 4023// -----------------------------------------------------------------------------4024// OMP_DYNAMIC4025 4026static void __kmp_stg_parse_omp_dynamic(char const *name, char const *value,4027                                        void *data) {4028  __kmp_stg_parse_bool(name, value, &(__kmp_global.g.g_dynamic));4029} // __kmp_stg_parse_omp_dynamic4030 4031static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t *buffer, char const *name,4032                                        void *data) {4033  __kmp_stg_print_bool(buffer, name, __kmp_global.g.g_dynamic);4034} // __kmp_stg_print_omp_dynamic4035 4036static void __kmp_stg_parse_kmp_dynamic_mode(char const *name,4037                                             char const *value, void *data) {4038  if (TCR_4(__kmp_init_parallel)) {4039    KMP_WARNING(EnvParallelWarn, name);4040    __kmp_env_toPrint(name, 0);4041    return;4042  }4043#ifdef USE_LOAD_BALANCE4044  else if (__kmp_str_match("load balance", 2, value) ||4045           __kmp_str_match("load_balance", 2, value) ||4046           __kmp_str_match("load-balance", 2, value) ||4047           __kmp_str_match("loadbalance", 2, value) ||4048           __kmp_str_match("balance", 1, value)) {4049    __kmp_global.g.g_dynamic_mode = dynamic_load_balance;4050  }4051#endif /* USE_LOAD_BALANCE */4052  else if (__kmp_str_match("thread limit", 1, value) ||4053           __kmp_str_match("thread_limit", 1, value) ||4054           __kmp_str_match("thread-limit", 1, value) ||4055           __kmp_str_match("threadlimit", 1, value) ||4056           __kmp_str_match("limit", 2, value)) {4057    __kmp_global.g.g_dynamic_mode = dynamic_thread_limit;4058  } else if (__kmp_str_match("random", 1, value)) {4059    __kmp_global.g.g_dynamic_mode = dynamic_random;4060  } else {4061    KMP_WARNING(StgInvalidValue, name, value);4062  }4063} //__kmp_stg_parse_kmp_dynamic_mode4064 4065static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t *buffer,4066                                             char const *name, void *data) {4067#if KMP_DEBUG4068  if (__kmp_global.g.g_dynamic_mode == dynamic_default) {4069    __kmp_str_buf_print(buffer, "   %s: %s \n", name, KMP_I18N_STR(NotDefined));4070  }4071#ifdef USE_LOAD_BALANCE4072  else if (__kmp_global.g.g_dynamic_mode == dynamic_load_balance) {4073    __kmp_stg_print_str(buffer, name, "load balance");4074  }4075#endif /* USE_LOAD_BALANCE */4076  else if (__kmp_global.g.g_dynamic_mode == dynamic_thread_limit) {4077    __kmp_stg_print_str(buffer, name, "thread limit");4078  } else if (__kmp_global.g.g_dynamic_mode == dynamic_random) {4079    __kmp_stg_print_str(buffer, name, "random");4080  } else {4081    KMP_ASSERT(0);4082  }4083#endif /* KMP_DEBUG */4084} // __kmp_stg_print_kmp_dynamic_mode4085 4086#ifdef USE_LOAD_BALANCE4087 4088// -----------------------------------------------------------------------------4089// KMP_LOAD_BALANCE_INTERVAL4090 4091static void __kmp_stg_parse_ld_balance_interval(char const *name,4092                                                char const *value, void *data) {4093  double interval = __kmp_convert_to_double(value);4094  if (interval >= 0) {4095    __kmp_load_balance_interval = interval;4096  } else {4097    KMP_WARNING(StgInvalidValue, name, value);4098  }4099} // __kmp_stg_parse_load_balance_interval4100 4101static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t *buffer,4102                                                char const *name, void *data) {4103#if KMP_DEBUG4104  __kmp_str_buf_print(buffer, "   %s=%8.6f\n", name,4105                      __kmp_load_balance_interval);4106#endif /* KMP_DEBUG */4107} // __kmp_stg_print_load_balance_interval4108 4109#endif /* USE_LOAD_BALANCE */4110 4111// -----------------------------------------------------------------------------4112// KMP_INIT_AT_FORK4113 4114static void __kmp_stg_parse_init_at_fork(char const *name, char const *value,4115                                         void *data) {4116  __kmp_stg_parse_bool(name, value, &__kmp_need_register_atfork);4117  if (__kmp_need_register_atfork) {4118    __kmp_need_register_atfork_specified = TRUE;4119  }4120} // __kmp_stg_parse_init_at_fork4121 4122static void __kmp_stg_print_init_at_fork(kmp_str_buf_t *buffer,4123                                         char const *name, void *data) {4124  __kmp_stg_print_bool(buffer, name, __kmp_need_register_atfork_specified);4125} // __kmp_stg_print_init_at_fork4126 4127// -----------------------------------------------------------------------------4128// KMP_SCHEDULE4129 4130static void __kmp_stg_parse_schedule(char const *name, char const *value,4131                                     void *data) {4132 4133  if (value != NULL) {4134    size_t length = KMP_STRLEN(value);4135    if (length > INT_MAX) {4136      KMP_WARNING(LongValue, name);4137    } else {4138      const char *semicolon;4139      if (value[length - 1] == '"' || value[length - 1] == '\'')4140        KMP_WARNING(UnbalancedQuotes, name);4141      do {4142        char sentinel;4143 4144        semicolon = strchr(value, ';');4145        if (*value && semicolon != value) {4146          const char *comma = strchr(value, ',');4147 4148          if (comma) {4149            ++comma;4150            sentinel = ',';4151          } else4152            sentinel = ';';4153          if (!__kmp_strcasecmp_with_sentinel("static", value, sentinel)) {4154            if (!__kmp_strcasecmp_with_sentinel("greedy", comma, ';')) {4155              __kmp_static = kmp_sch_static_greedy;4156              continue;4157            } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma,4158                                                       ';')) {4159              __kmp_static = kmp_sch_static_balanced;4160              continue;4161            }4162          } else if (!__kmp_strcasecmp_with_sentinel("guided", value,4163                                                     sentinel)) {4164            if (!__kmp_strcasecmp_with_sentinel("iterative", comma, ';')) {4165              __kmp_guided = kmp_sch_guided_iterative_chunked;4166              continue;4167            } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma,4168                                                       ';')) {4169              /* analytical not allowed for too many threads */4170              __kmp_guided = kmp_sch_guided_analytical_chunked;4171              continue;4172            }4173          }4174          KMP_WARNING(InvalidClause, name, value);4175        } else4176          KMP_WARNING(EmptyClause, name);4177      } while ((value = semicolon ? semicolon + 1 : NULL));4178    }4179  }4180 4181} // __kmp_stg_parse__schedule4182 4183static void __kmp_stg_print_schedule(kmp_str_buf_t *buffer, char const *name,4184                                     void *data) {4185  if (__kmp_env_format) {4186    KMP_STR_BUF_PRINT_NAME_EX(name);4187  } else {4188    __kmp_str_buf_print(buffer, "   %s='", name);4189  }4190  if (__kmp_static == kmp_sch_static_greedy) {4191    __kmp_str_buf_print(buffer, "%s", "static,greedy");4192  } else if (__kmp_static == kmp_sch_static_balanced) {4193    __kmp_str_buf_print(buffer, "%s", "static,balanced");4194  }4195  if (__kmp_guided == kmp_sch_guided_iterative_chunked) {4196    __kmp_str_buf_print(buffer, ";%s'\n", "guided,iterative");4197  } else if (__kmp_guided == kmp_sch_guided_analytical_chunked) {4198    __kmp_str_buf_print(buffer, ";%s'\n", "guided,analytical");4199  }4200} // __kmp_stg_print_schedule4201 4202// -----------------------------------------------------------------------------4203// OMP_SCHEDULE4204 4205static inline void __kmp_omp_schedule_restore() {4206#if KMP_USE_HIER_SCHED4207  __kmp_hier_scheds.deallocate();4208#endif4209  __kmp_chunk = 0;4210  __kmp_sched = kmp_sch_default;4211}4212 4213// if parse_hier = true:4214//    Parse [HW,][modifier:]kind[,chunk]4215// else:4216//    Parse [modifier:]kind[,chunk]4217static const char *__kmp_parse_single_omp_schedule(const char *name,4218                                                   const char *value,4219                                                   bool parse_hier = false) {4220  /* get the specified scheduling style */4221  const char *ptr = value;4222  const char *delim;4223  int chunk = 0;4224  enum sched_type sched = kmp_sch_default;4225  if (*ptr == '\0')4226    return NULL;4227  delim = ptr;4228  while (*delim != ',' && *delim != ':' && *delim != '\0')4229    delim++;4230#if KMP_USE_HIER_SCHED4231  kmp_hier_layer_e layer = kmp_hier_layer_e::LAYER_THREAD;4232  if (parse_hier) {4233    if (*delim == ',') {4234      if (!__kmp_strcasecmp_with_sentinel("L1", ptr, ',')) {4235        layer = kmp_hier_layer_e::LAYER_L1;4236      } else if (!__kmp_strcasecmp_with_sentinel("L2", ptr, ',')) {4237        layer = kmp_hier_layer_e::LAYER_L2;4238      } else if (!__kmp_strcasecmp_with_sentinel("L3", ptr, ',')) {4239        layer = kmp_hier_layer_e::LAYER_L3;4240      } else if (!__kmp_strcasecmp_with_sentinel("NUMA", ptr, ',')) {4241        layer = kmp_hier_layer_e::LAYER_NUMA;4242      }4243    }4244    if (layer != kmp_hier_layer_e::LAYER_THREAD && *delim != ',') {4245      // If there is no comma after the layer, then this schedule is invalid4246      KMP_WARNING(StgInvalidValue, name, value);4247      __kmp_omp_schedule_restore();4248      return NULL;4249    } else if (layer != kmp_hier_layer_e::LAYER_THREAD) {4250      ptr = ++delim;4251      while (*delim != ',' && *delim != ':' && *delim != '\0')4252        delim++;4253    }4254  }4255#endif // KMP_USE_HIER_SCHED4256  // Read in schedule modifier if specified4257  enum sched_type sched_modifier = (enum sched_type)0;4258  if (*delim == ':') {4259    if (!__kmp_strcasecmp_with_sentinel("monotonic", ptr, *delim)) {4260      sched_modifier = sched_type::kmp_sch_modifier_monotonic;4261      ptr = ++delim;4262      while (*delim != ',' && *delim != ':' && *delim != '\0')4263        delim++;4264    } else if (!__kmp_strcasecmp_with_sentinel("nonmonotonic", ptr, *delim)) {4265      sched_modifier = sched_type::kmp_sch_modifier_nonmonotonic;4266      ptr = ++delim;4267      while (*delim != ',' && *delim != ':' && *delim != '\0')4268        delim++;4269    } else if (!parse_hier) {4270      // If there is no proper schedule modifier, then this schedule is invalid4271      KMP_WARNING(StgInvalidValue, name, value);4272      __kmp_omp_schedule_restore();4273      return NULL;4274    }4275  }4276  // Read in schedule kind (required)4277  if (!__kmp_strcasecmp_with_sentinel("dynamic", ptr, *delim))4278    sched = kmp_sch_dynamic_chunked;4279  else if (!__kmp_strcasecmp_with_sentinel("guided", ptr, *delim))4280    sched = kmp_sch_guided_chunked;4281  // AC: TODO: probably remove TRAPEZOIDAL (OMP 3.0 does not allow it)4282  else if (!__kmp_strcasecmp_with_sentinel("auto", ptr, *delim))4283    sched = kmp_sch_auto;4284  else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", ptr, *delim))4285    sched = kmp_sch_trapezoidal;4286  else if (!__kmp_strcasecmp_with_sentinel("static", ptr, *delim))4287    sched = kmp_sch_static;4288#if KMP_STATIC_STEAL_ENABLED4289  else if (!__kmp_strcasecmp_with_sentinel("static_steal", ptr, *delim)) {4290    // replace static_steal with dynamic to better cope with ordered loops4291    sched = kmp_sch_dynamic_chunked;4292    sched_modifier = sched_type::kmp_sch_modifier_nonmonotonic;4293  }4294#endif4295  else {4296    // If there is no proper schedule kind, then this schedule is invalid4297    KMP_WARNING(StgInvalidValue, name, value);4298    __kmp_omp_schedule_restore();4299    return NULL;4300  }4301 4302  // Read in schedule chunk size if specified4303  if (*delim == ',') {4304    ptr = delim + 1;4305    SKIP_WS(ptr);4306    if (!isdigit(*ptr)) {4307      // If there is no chunk after comma, then this schedule is invalid4308      KMP_WARNING(StgInvalidValue, name, value);4309      __kmp_omp_schedule_restore();4310      return NULL;4311    }4312    SKIP_DIGITS(ptr);4313    // auto schedule should not specify chunk size4314    if (sched == kmp_sch_auto) {4315      __kmp_msg(kmp_ms_warning, KMP_MSG(IgnoreChunk, name, delim),4316                __kmp_msg_null);4317    } else {4318      if (sched == kmp_sch_static)4319        sched = kmp_sch_static_chunked;4320      chunk = __kmp_str_to_int(delim + 1, *ptr);4321      if (chunk < 1) {4322        chunk = KMP_DEFAULT_CHUNK;4323        __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidChunk, name, delim),4324                  __kmp_msg_null);4325        KMP_INFORM(Using_int_Value, name, __kmp_chunk);4326        // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK4327        // (to improve code coverage :)4328        // The default chunk size is 1 according to standard, thus making4329        // KMP_MIN_CHUNK not 1 we would introduce mess:4330        // wrong chunk becomes 1, but it will be impossible to explicitly set4331        // to 1 because it becomes KMP_MIN_CHUNK...4332        // } else if ( chunk < KMP_MIN_CHUNK ) {4333        //   chunk = KMP_MIN_CHUNK;4334      } else if (chunk > KMP_MAX_CHUNK) {4335        chunk = KMP_MAX_CHUNK;4336        __kmp_msg(kmp_ms_warning, KMP_MSG(LargeChunk, name, delim),4337                  __kmp_msg_null);4338        KMP_INFORM(Using_int_Value, name, chunk);4339      }4340    }4341  } else {4342    ptr = delim;4343  }4344 4345  SCHEDULE_SET_MODIFIERS(sched, sched_modifier);4346 4347#if KMP_USE_HIER_SCHED4348  if (layer != kmp_hier_layer_e::LAYER_THREAD) {4349    __kmp_hier_scheds.append(sched, chunk, layer);4350  } else4351#endif4352  {4353    __kmp_chunk = chunk;4354    __kmp_sched = sched;4355  }4356  return ptr;4357}4358 4359static void __kmp_stg_parse_omp_schedule(char const *name, char const *value,4360                                         void *data) {4361  size_t length;4362  const char *ptr = value;4363  if (ptr) {4364    SKIP_WS(ptr);4365    length = KMP_STRLEN(value);4366    if (length) {4367      if (value[length - 1] == '"' || value[length - 1] == '\'')4368        KMP_WARNING(UnbalancedQuotes, name);4369/* get the specified scheduling style */4370#if KMP_USE_HIER_SCHED4371      if (!__kmp_strcasecmp_with_sentinel("EXPERIMENTAL", ptr, ' ')) {4372        SKIP_TOKEN(ptr);4373        SKIP_WS(ptr);4374        while ((ptr = __kmp_parse_single_omp_schedule(name, ptr, true))) {4375          while (*ptr == ' ' || *ptr == '\t' || *ptr == ':')4376            ptr++;4377          if (*ptr == '\0')4378            break;4379        }4380      } else4381#endif4382        __kmp_parse_single_omp_schedule(name, ptr);4383    } else4384      KMP_WARNING(EmptyString, name);4385  }4386#if KMP_USE_HIER_SCHED4387  __kmp_hier_scheds.sort();4388#endif4389  K_DIAG(1, ("__kmp_static == %d\n", __kmp_static))4390  K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided))4391  K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched))4392  K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk))4393} // __kmp_stg_parse_omp_schedule4394 4395static void __kmp_stg_print_omp_schedule(kmp_str_buf_t *buffer,4396                                         char const *name, void *data) {4397  if (__kmp_env_format) {4398    KMP_STR_BUF_PRINT_NAME_EX(name);4399  } else {4400    __kmp_str_buf_print(buffer, "   %s='", name);4401  }4402  enum sched_type sched = SCHEDULE_WITHOUT_MODIFIERS(__kmp_sched);4403  if (SCHEDULE_HAS_MONOTONIC(__kmp_sched)) {4404    __kmp_str_buf_print(buffer, "monotonic:");4405  } else if (SCHEDULE_HAS_NONMONOTONIC(__kmp_sched)) {4406    __kmp_str_buf_print(buffer, "nonmonotonic:");4407  }4408  if (__kmp_chunk) {4409    switch (sched) {4410    case kmp_sch_dynamic_chunked:4411      __kmp_str_buf_print(buffer, "%s,%d'\n", "dynamic", __kmp_chunk);4412      break;4413    case kmp_sch_guided_iterative_chunked:4414    case kmp_sch_guided_analytical_chunked:4415      __kmp_str_buf_print(buffer, "%s,%d'\n", "guided", __kmp_chunk);4416      break;4417    case kmp_sch_trapezoidal:4418      __kmp_str_buf_print(buffer, "%s,%d'\n", "trapezoidal", __kmp_chunk);4419      break;4420    case kmp_sch_static:4421    case kmp_sch_static_chunked:4422    case kmp_sch_static_balanced:4423    case kmp_sch_static_greedy:4424      __kmp_str_buf_print(buffer, "%s,%d'\n", "static", __kmp_chunk);4425      break;4426    case kmp_sch_static_steal:4427      __kmp_str_buf_print(buffer, "%s,%d'\n", "static_steal", __kmp_chunk);4428      break;4429    case kmp_sch_auto:4430      __kmp_str_buf_print(buffer, "%s,%d'\n", "auto", __kmp_chunk);4431      break;4432    default:4433      KMP_ASSERT2(false, "Unhandled sched_type enumeration");4434      KMP_BUILTIN_UNREACHABLE;4435      break;4436    }4437  } else {4438    switch (sched) {4439    case kmp_sch_dynamic_chunked:4440      __kmp_str_buf_print(buffer, "%s'\n", "dynamic");4441      break;4442    case kmp_sch_guided_iterative_chunked:4443    case kmp_sch_guided_analytical_chunked:4444      __kmp_str_buf_print(buffer, "%s'\n", "guided");4445      break;4446    case kmp_sch_trapezoidal:4447      __kmp_str_buf_print(buffer, "%s'\n", "trapezoidal");4448      break;4449    case kmp_sch_static:4450    case kmp_sch_static_chunked:4451    case kmp_sch_static_balanced:4452    case kmp_sch_static_greedy:4453      __kmp_str_buf_print(buffer, "%s'\n", "static");4454      break;4455    case kmp_sch_static_steal:4456      __kmp_str_buf_print(buffer, "%s'\n", "static_steal");4457      break;4458    case kmp_sch_auto:4459      __kmp_str_buf_print(buffer, "%s'\n", "auto");4460      break;4461    default:4462      KMP_ASSERT2(false, "Unhandled sched_type enumeration");4463      KMP_BUILTIN_UNREACHABLE;4464      break;4465    }4466  }4467} // __kmp_stg_print_omp_schedule4468 4469#if KMP_USE_HIER_SCHED4470// -----------------------------------------------------------------------------4471// KMP_DISP_HAND_THREAD4472static void __kmp_stg_parse_kmp_hand_thread(char const *name, char const *value,4473                                            void *data) {4474  __kmp_stg_parse_bool(name, value, &(__kmp_dispatch_hand_threading));4475} // __kmp_stg_parse_kmp_hand_thread4476 4477static void __kmp_stg_print_kmp_hand_thread(kmp_str_buf_t *buffer,4478                                            char const *name, void *data) {4479  __kmp_stg_print_bool(buffer, name, __kmp_dispatch_hand_threading);4480} // __kmp_stg_print_kmp_hand_thread4481#endif4482 4483// -----------------------------------------------------------------------------4484// KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE4485static void __kmp_stg_parse_kmp_force_monotonic(char const *name,4486                                                char const *value, void *data) {4487  __kmp_stg_parse_bool(name, value, &(__kmp_force_monotonic));4488} // __kmp_stg_parse_kmp_force_monotonic4489 4490static void __kmp_stg_print_kmp_force_monotonic(kmp_str_buf_t *buffer,4491                                                char const *name, void *data) {4492  __kmp_stg_print_bool(buffer, name, __kmp_force_monotonic);4493} // __kmp_stg_print_kmp_force_monotonic4494 4495// -----------------------------------------------------------------------------4496// KMP_ATOMIC_MODE4497 4498static void __kmp_stg_parse_atomic_mode(char const *name, char const *value,4499                                        void *data) {4500  // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP4501  // compatibility mode.4502  int mode = 0;4503  int max = 1;4504#ifdef KMP_GOMP_COMPAT4505  max = 2;4506#endif /* KMP_GOMP_COMPAT */4507  __kmp_stg_parse_int(name, value, 0, max, &mode);4508  // TODO; parse_int is not very suitable for this case. In case of overflow it4509  // is better to use4510  // 0 rather that max value.4511  if (mode > 0) {4512    __kmp_atomic_mode = mode;4513  }4514} // __kmp_stg_parse_atomic_mode4515 4516static void __kmp_stg_print_atomic_mode(kmp_str_buf_t *buffer, char const *name,4517                                        void *data) {4518  __kmp_stg_print_int(buffer, name, __kmp_atomic_mode);4519} // __kmp_stg_print_atomic_mode4520 4521// -----------------------------------------------------------------------------4522// KMP_CONSISTENCY_CHECK4523 4524static void __kmp_stg_parse_consistency_check(char const *name,4525                                              char const *value, void *data) {4526  if (TCR_4(__kmp_init_serial)) {4527    KMP_WARNING(EnvSerialWarn, name);4528    return;4529  } // read value before serial initialization only4530  if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) {4531    // Note, this will not work from kmp_set_defaults because th_cons stack was4532    // not allocated4533    // for existed thread(s) thus the first __kmp_push_<construct> will break4534    // with assertion.4535    // TODO: allocate th_cons if called from kmp_set_defaults.4536    __kmp_env_consistency_check = TRUE;4537  } else if (!__kmp_strcasecmp_with_sentinel("none", value, 0)) {4538    __kmp_env_consistency_check = FALSE;4539  } else {4540    KMP_WARNING(StgInvalidValue, name, value);4541  }4542} // __kmp_stg_parse_consistency_check4543 4544static void __kmp_stg_print_consistency_check(kmp_str_buf_t *buffer,4545                                              char const *name, void *data) {4546#if KMP_DEBUG4547  const char *value = NULL;4548 4549  if (__kmp_env_consistency_check) {4550    value = "all";4551  } else {4552    value = "none";4553  }4554 4555  if (value != NULL) {4556    __kmp_stg_print_str(buffer, name, value);4557  }4558#endif /* KMP_DEBUG */4559} // __kmp_stg_print_consistency_check4560 4561#if USE_ITT_BUILD4562// -----------------------------------------------------------------------------4563// KMP_ITT_PREPARE_DELAY4564 4565#if USE_ITT_NOTIFY4566 4567static void __kmp_stg_parse_itt_prepare_delay(char const *name,4568                                              char const *value, void *data) {4569  // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop4570  // iterations.4571  int delay = 0;4572  __kmp_stg_parse_int(name, value, 0, INT_MAX, &delay);4573  __kmp_itt_prepare_delay = delay;4574} // __kmp_str_parse_itt_prepare_delay4575 4576static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t *buffer,4577                                              char const *name, void *data) {4578  __kmp_stg_print_uint64(buffer, name, __kmp_itt_prepare_delay);4579 4580} // __kmp_str_print_itt_prepare_delay4581 4582#endif // USE_ITT_NOTIFY4583#endif /* USE_ITT_BUILD */4584 4585// -----------------------------------------------------------------------------4586// KMP_MALLOC_POOL_INCR4587 4588static void __kmp_stg_parse_malloc_pool_incr(char const *name,4589                                             char const *value, void *data) {4590  __kmp_stg_parse_size(name, value, KMP_MIN_MALLOC_POOL_INCR,4591                       KMP_MAX_MALLOC_POOL_INCR, NULL, &__kmp_malloc_pool_incr,4592                       1);4593} // __kmp_stg_parse_malloc_pool_incr4594 4595static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t *buffer,4596                                             char const *name, void *data) {4597  __kmp_stg_print_size(buffer, name, __kmp_malloc_pool_incr);4598 4599} // _kmp_stg_print_malloc_pool_incr4600 4601#ifdef KMP_DEBUG4602 4603// -----------------------------------------------------------------------------4604// KMP_PAR_RANGE4605 4606static void __kmp_stg_parse_par_range_env(char const *name, char const *value,4607                                          void *data) {4608  __kmp_stg_parse_par_range(name, value, &__kmp_par_range,4609                            __kmp_par_range_routine, __kmp_par_range_filename,4610                            &__kmp_par_range_lb, &__kmp_par_range_ub);4611} // __kmp_stg_parse_par_range_env4612 4613static void __kmp_stg_print_par_range_env(kmp_str_buf_t *buffer,4614                                          char const *name, void *data) {4615  if (__kmp_par_range != 0) {4616    __kmp_stg_print_str(buffer, name, par_range_to_print);4617  }4618} // __kmp_stg_print_par_range_env4619 4620#endif4621 4622// -----------------------------------------------------------------------------4623// KMP_GTID_MODE4624 4625static void __kmp_stg_parse_gtid_mode(char const *name, char const *value,4626                                      void *data) {4627  // Modes:4628  //   0 -- do not change default4629  //   1 -- sp search4630  //   2 -- use "keyed" TLS var, i.e.4631  //        pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)4632  //   3 -- __declspec(thread) TLS var in tdata section4633  int mode = 0;4634  int max = 2;4635#ifdef KMP_TDATA_GTID4636  max = 3;4637#endif /* KMP_TDATA_GTID */4638  __kmp_stg_parse_int(name, value, 0, max, &mode);4639  // TODO; parse_int is not very suitable for this case. In case of overflow it4640  // is better to use 0 rather that max value.4641  if (mode == 0) {4642    __kmp_adjust_gtid_mode = TRUE;4643  } else {4644    __kmp_gtid_mode = mode;4645    __kmp_adjust_gtid_mode = FALSE;4646  }4647} // __kmp_str_parse_gtid_mode4648 4649static void __kmp_stg_print_gtid_mode(kmp_str_buf_t *buffer, char const *name,4650                                      void *data) {4651  if (__kmp_adjust_gtid_mode) {4652    __kmp_stg_print_int(buffer, name, 0);4653  } else {4654    __kmp_stg_print_int(buffer, name, __kmp_gtid_mode);4655  }4656} // __kmp_stg_print_gtid_mode4657 4658// -----------------------------------------------------------------------------4659// KMP_NUM_LOCKS_IN_BLOCK4660 4661static void __kmp_stg_parse_lock_block(char const *name, char const *value,4662                                       void *data) {4663  __kmp_stg_parse_int(name, value, 0, KMP_INT_MAX, &__kmp_num_locks_in_block);4664} // __kmp_str_parse_lock_block4665 4666static void __kmp_stg_print_lock_block(kmp_str_buf_t *buffer, char const *name,4667                                       void *data) {4668  __kmp_stg_print_int(buffer, name, __kmp_num_locks_in_block);4669} // __kmp_stg_print_lock_block4670 4671// -----------------------------------------------------------------------------4672// KMP_LOCK_KIND4673 4674#if KMP_USE_DYNAMIC_LOCK4675#define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a)4676#else4677#define KMP_STORE_LOCK_SEQ(a)4678#endif4679 4680static void __kmp_stg_parse_lock_kind(char const *name, char const *value,4681                                      void *data) {4682  if (__kmp_init_user_locks) {4683    KMP_WARNING(EnvLockWarn, name);4684    return;4685  }4686 4687  if (__kmp_str_match("tas", 2, value) ||4688      __kmp_str_match("test and set", 2, value) ||4689      __kmp_str_match("test_and_set", 2, value) ||4690      __kmp_str_match("test-and-set", 2, value) ||4691      __kmp_str_match("test andset", 2, value) ||4692      __kmp_str_match("test_andset", 2, value) ||4693      __kmp_str_match("test-andset", 2, value) ||4694      __kmp_str_match("testand set", 2, value) ||4695      __kmp_str_match("testand_set", 2, value) ||4696      __kmp_str_match("testand-set", 2, value) ||4697      __kmp_str_match("testandset", 2, value)) {4698    __kmp_user_lock_kind = lk_tas;4699    KMP_STORE_LOCK_SEQ(tas);4700  }4701#if KMP_USE_FUTEX4702  else if (__kmp_str_match("futex", 1, value)) {4703    if (__kmp_futex_determine_capable()) {4704      __kmp_user_lock_kind = lk_futex;4705      KMP_STORE_LOCK_SEQ(futex);4706    } else {4707      KMP_WARNING(FutexNotSupported, name, value);4708    }4709  }4710#endif4711  else if (__kmp_str_match("ticket", 2, value)) {4712    __kmp_user_lock_kind = lk_ticket;4713    KMP_STORE_LOCK_SEQ(ticket);4714  } else if (__kmp_str_match("queuing", 1, value) ||4715             __kmp_str_match("queue", 1, value)) {4716    __kmp_user_lock_kind = lk_queuing;4717    KMP_STORE_LOCK_SEQ(queuing);4718  } else if (__kmp_str_match("drdpa ticket", 1, value) ||4719             __kmp_str_match("drdpa_ticket", 1, value) ||4720             __kmp_str_match("drdpa-ticket", 1, value) ||4721             __kmp_str_match("drdpaticket", 1, value) ||4722             __kmp_str_match("drdpa", 1, value)) {4723    __kmp_user_lock_kind = lk_drdpa;4724    KMP_STORE_LOCK_SEQ(drdpa);4725  }4726#if KMP_USE_ADAPTIVE_LOCKS4727  else if (__kmp_str_match("adaptive", 1, value)) {4728    if (__kmp_cpuinfo.flags.rtm) { // ??? Is cpuinfo available here?4729      __kmp_user_lock_kind = lk_adaptive;4730      KMP_STORE_LOCK_SEQ(adaptive);4731    } else {4732      KMP_WARNING(AdaptiveNotSupported, name, value);4733      __kmp_user_lock_kind = lk_queuing;4734      KMP_STORE_LOCK_SEQ(queuing);4735    }4736  }4737#endif // KMP_USE_ADAPTIVE_LOCKS4738#if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX4739  else if (__kmp_str_match("rtm_queuing", 1, value)) {4740    if (__kmp_cpuinfo.flags.rtm) {4741      __kmp_user_lock_kind = lk_rtm_queuing;4742      KMP_STORE_LOCK_SEQ(rtm_queuing);4743    } else {4744      KMP_WARNING(AdaptiveNotSupported, name, value);4745      __kmp_user_lock_kind = lk_queuing;4746      KMP_STORE_LOCK_SEQ(queuing);4747    }4748  } else if (__kmp_str_match("rtm_spin", 1, value)) {4749    if (__kmp_cpuinfo.flags.rtm) {4750      __kmp_user_lock_kind = lk_rtm_spin;4751      KMP_STORE_LOCK_SEQ(rtm_spin);4752    } else {4753      KMP_WARNING(AdaptiveNotSupported, name, value);4754      __kmp_user_lock_kind = lk_tas;4755      KMP_STORE_LOCK_SEQ(queuing);4756    }4757  } else if (__kmp_str_match("hle", 1, value)) {4758    __kmp_user_lock_kind = lk_hle;4759    KMP_STORE_LOCK_SEQ(hle);4760  }4761#endif4762  else {4763    KMP_WARNING(StgInvalidValue, name, value);4764  }4765}4766 4767static void __kmp_stg_print_lock_kind(kmp_str_buf_t *buffer, char const *name,4768                                      void *data) {4769  const char *value = NULL;4770 4771  switch (__kmp_user_lock_kind) {4772  case lk_default:4773    value = "default";4774    break;4775 4776  case lk_tas:4777    value = "tas";4778    break;4779 4780#if KMP_USE_FUTEX4781  case lk_futex:4782    value = "futex";4783    break;4784#endif4785 4786#if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX4787  case lk_rtm_queuing:4788    value = "rtm_queuing";4789    break;4790 4791  case lk_rtm_spin:4792    value = "rtm_spin";4793    break;4794 4795  case lk_hle:4796    value = "hle";4797    break;4798#endif4799 4800  case lk_ticket:4801    value = "ticket";4802    break;4803 4804  case lk_queuing:4805    value = "queuing";4806    break;4807 4808  case lk_drdpa:4809    value = "drdpa";4810    break;4811#if KMP_USE_ADAPTIVE_LOCKS4812  case lk_adaptive:4813    value = "adaptive";4814    break;4815#endif4816  }4817 4818  if (value != NULL) {4819    __kmp_stg_print_str(buffer, name, value);4820  }4821}4822 4823// -----------------------------------------------------------------------------4824// KMP_SPIN_BACKOFF_PARAMS4825 4826// KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick4827// for machine pause)4828static void __kmp_stg_parse_spin_backoff_params(const char *name,4829                                                const char *value, void *data) {4830  const char *next = value;4831 4832  int total = 0; // Count elements that were set. It'll be used as an array size4833  int prev_comma = FALSE; // For correct processing sequential commas4834  int i;4835 4836  kmp_uint32 max_backoff = __kmp_spin_backoff_params.max_backoff;4837  kmp_uint32 min_tick = __kmp_spin_backoff_params.min_tick;4838 4839  // Run only 3 iterations because it is enough to read two values or find a4840  // syntax error4841  for (i = 0; i < 3; i++) {4842    SKIP_WS(next);4843 4844    if (*next == '\0') {4845      break;4846    }4847    // Next character is not an integer or not a comma OR number of values > 24848    // => end of list4849    if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {4850      KMP_WARNING(EnvSyntaxError, name, value);4851      return;4852    }4853    // The next character is ','4854    if (*next == ',') {4855      // ',' is the first character4856      if (total == 0 || prev_comma) {4857        total++;4858      }4859      prev_comma = TRUE;4860      next++; // skip ','4861      SKIP_WS(next);4862    }4863    // Next character is a digit4864    if (*next >= '0' && *next <= '9') {4865      int num;4866      const char *buf = next;4867      char const *msg = NULL;4868      prev_comma = FALSE;4869      SKIP_DIGITS(next);4870      total++;4871 4872      const char *tmp = next;4873      SKIP_WS(tmp);4874      if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {4875        KMP_WARNING(EnvSpacesNotAllowed, name, value);4876        return;4877      }4878 4879      num = __kmp_str_to_int(buf, *next);4880      if (num <= 0) { // The number of retries should be > 04881        msg = KMP_I18N_STR(ValueTooSmall);4882        num = 1;4883      }4884      if (msg != NULL) {4885        // Message is not empty. Print warning.4886        KMP_WARNING(ParseSizeIntWarn, name, value, msg);4887        KMP_INFORM(Using_int_Value, name, num);4888      }4889      if (total == 1) {4890        max_backoff = num;4891      } else if (total == 2) {4892        min_tick = num;4893      }4894    }4895  }4896  if (total <= 0) {4897    KMP_WARNING(EnvSyntaxError, name, value);4898    return;4899  }4900  __kmp_spin_backoff_params.max_backoff = max_backoff;4901  __kmp_spin_backoff_params.min_tick = min_tick;4902}4903 4904static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t *buffer,4905                                                char const *name, void *data) {4906  if (__kmp_env_format) {4907    KMP_STR_BUF_PRINT_NAME_EX(name);4908  } else {4909    __kmp_str_buf_print(buffer, "   %s='", name);4910  }4911  __kmp_str_buf_print(buffer, "%d,%d'\n", __kmp_spin_backoff_params.max_backoff,4912                      __kmp_spin_backoff_params.min_tick);4913}4914 4915#if KMP_USE_ADAPTIVE_LOCKS4916 4917// -----------------------------------------------------------------------------4918// KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE4919 4920// Parse out values for the tunable parameters from a string of the form4921// KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]4922static void __kmp_stg_parse_adaptive_lock_props(const char *name,4923                                                const char *value, void *data) {4924  int max_retries = 0;4925  int max_badness = 0;4926 4927  const char *next = value;4928 4929  int total = 0; // Count elements that were set. It'll be used as an array size4930  int prev_comma = FALSE; // For correct processing sequential commas4931  int i;4932 4933  // Save values in the structure __kmp_speculative_backoff_params4934  // Run only 3 iterations because it is enough to read two values or find a4935  // syntax error4936  for (i = 0; i < 3; i++) {4937    SKIP_WS(next);4938 4939    if (*next == '\0') {4940      break;4941    }4942    // Next character is not an integer or not a comma OR number of values > 24943    // => end of list4944    if (((*next < '0' || *next > '9') && *next != ',') || total > 2) {4945      KMP_WARNING(EnvSyntaxError, name, value);4946      return;4947    }4948    // The next character is ','4949    if (*next == ',') {4950      // ',' is the first character4951      if (total == 0 || prev_comma) {4952        total++;4953      }4954      prev_comma = TRUE;4955      next++; // skip ','4956      SKIP_WS(next);4957    }4958    // Next character is a digit4959    if (*next >= '0' && *next <= '9') {4960      int num;4961      const char *buf = next;4962      char const *msg = NULL;4963      prev_comma = FALSE;4964      SKIP_DIGITS(next);4965      total++;4966 4967      const char *tmp = next;4968      SKIP_WS(tmp);4969      if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) {4970        KMP_WARNING(EnvSpacesNotAllowed, name, value);4971        return;4972      }4973 4974      num = __kmp_str_to_int(buf, *next);4975      if (num < 0) { // The number of retries should be >= 04976        msg = KMP_I18N_STR(ValueTooSmall);4977        num = 1;4978      }4979      if (msg != NULL) {4980        // Message is not empty. Print warning.4981        KMP_WARNING(ParseSizeIntWarn, name, value, msg);4982        KMP_INFORM(Using_int_Value, name, num);4983      }4984      if (total == 1) {4985        max_retries = num;4986      } else if (total == 2) {4987        max_badness = num;4988      }4989    }4990  }4991  if (total <= 0) {4992    KMP_WARNING(EnvSyntaxError, name, value);4993    return;4994  }4995  __kmp_adaptive_backoff_params.max_soft_retries = max_retries;4996  __kmp_adaptive_backoff_params.max_badness = max_badness;4997}4998 4999static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t *buffer,5000                                                char const *name, void *data) {5001  if (__kmp_env_format) {5002    KMP_STR_BUF_PRINT_NAME_EX(name);5003  } else {5004    __kmp_str_buf_print(buffer, "   %s='", name);5005  }5006  __kmp_str_buf_print(buffer, "%d,%d'\n",5007                      __kmp_adaptive_backoff_params.max_soft_retries,5008                      __kmp_adaptive_backoff_params.max_badness);5009} // __kmp_stg_print_adaptive_lock_props5010 5011#if KMP_DEBUG_ADAPTIVE_LOCKS5012 5013static void __kmp_stg_parse_speculative_statsfile(char const *name,5014                                                  char const *value,5015                                                  void *data) {5016  __kmp_stg_parse_file(name, value, "",5017                       CCAST(char **, &__kmp_speculative_statsfile));5018} // __kmp_stg_parse_speculative_statsfile5019 5020static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t *buffer,5021                                                  char const *name,5022                                                  void *data) {5023  if (__kmp_str_match("-", 0, __kmp_speculative_statsfile)) {5024    __kmp_stg_print_str(buffer, name, "stdout");5025  } else {5026    __kmp_stg_print_str(buffer, name, __kmp_speculative_statsfile);5027  }5028 5029} // __kmp_stg_print_speculative_statsfile5030 5031#endif // KMP_DEBUG_ADAPTIVE_LOCKS5032 5033#endif // KMP_USE_ADAPTIVE_LOCKS5034 5035// -----------------------------------------------------------------------------5036// KMP_HW_SUBSET (was KMP_PLACE_THREADS)5037// 2s16c,2t => 2S16C,2T => 2S16C \0 2T5038 5039// Return KMP_HW_SUBSET preferred hardware type in case a token is ambiguously5040// short. The original KMP_HW_SUBSET environment variable had single letters:5041// s, c, t for sockets, cores, threads repsectively.5042static kmp_hw_t __kmp_hw_subset_break_tie(const kmp_hw_t *possible,5043                                          size_t num_possible) {5044  for (size_t i = 0; i < num_possible; ++i) {5045    if (possible[i] == KMP_HW_THREAD)5046      return KMP_HW_THREAD;5047    else if (possible[i] == KMP_HW_CORE)5048      return KMP_HW_CORE;5049    else if (possible[i] == KMP_HW_SOCKET)5050      return KMP_HW_SOCKET;5051  }5052  return KMP_HW_UNKNOWN;5053}5054 5055// Return hardware type from string or HW_UNKNOWN if string cannot be parsed5056// This algorithm is very forgiving to the user in that, the instant it can5057// reduce the search space to one, it assumes that is the topology level the5058// user wanted, even if it is misspelled later in the token.5059static kmp_hw_t __kmp_stg_parse_hw_subset_name(char const *token) {5060  size_t index, num_possible, token_length;5061  kmp_hw_t possible[KMP_HW_LAST];5062  const char *end;5063 5064  // Find the end of the hardware token string5065  end = token;5066  token_length = 0;5067  while (isalnum(*end) || *end == '_') {5068    token_length++;5069    end++;5070  }5071 5072  // Set the possibilities to all hardware types5073  num_possible = 0;5074  KMP_FOREACH_HW_TYPE(type) { possible[num_possible++] = type; }5075 5076  // Eliminate hardware types by comparing the front of the token5077  // with hardware names5078  // In most cases, the first letter in the token will indicate exactly5079  // which hardware type is parsed, e.g., 'C' = Core5080  index = 0;5081  while (num_possible > 1 && index < token_length) {5082    size_t n = num_possible;5083    char token_char = (char)toupper(token[index]);5084    for (size_t i = 0; i < n; ++i) {5085      const char *s;5086      kmp_hw_t type = possible[i];5087      s = __kmp_hw_get_keyword(type, false);5088      if (index < KMP_STRLEN(s)) {5089        char c = (char)toupper(s[index]);5090        // Mark hardware types for removal when the characters do not match5091        if (c != token_char) {5092          possible[i] = KMP_HW_UNKNOWN;5093          num_possible--;5094        }5095      }5096    }5097    // Remove hardware types that this token cannot be5098    size_t start = 0;5099    for (size_t i = 0; i < n; ++i) {5100      if (possible[i] != KMP_HW_UNKNOWN) {5101        kmp_hw_t temp = possible[i];5102        possible[i] = possible[start];5103        possible[start] = temp;5104        start++;5105      }5106    }5107    KMP_ASSERT(start == num_possible);5108    index++;5109  }5110 5111  // Attempt to break a tie if user has very short token5112  // (e.g., is 'T' tile or thread?)5113  if (num_possible > 1)5114    return __kmp_hw_subset_break_tie(possible, num_possible);5115  if (num_possible == 1)5116    return possible[0];5117  return KMP_HW_UNKNOWN;5118}5119 5120// The longest observable sequence of items can only be HW_LAST length5121// The input string is usually short enough, let's use 512 limit for now5122#define MAX_T_LEVEL KMP_HW_LAST5123#define MAX_STR_LEN 5125124static void __kmp_stg_parse_hw_subset(char const *name, char const *value,5125                                      void *data) {5126  // Value example: 1s,5c@3,2T5127  // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core"5128  kmp_setting_t **rivals = (kmp_setting_t **)data;5129  if (strcmp(name, "KMP_PLACE_THREADS") == 0) {5130    KMP_INFORM(EnvVarDeprecated, name, "KMP_HW_SUBSET");5131  }5132  if (__kmp_stg_check_rivals(name, value, rivals)) {5133    return;5134  }5135 5136  char *components[MAX_T_LEVEL];5137  char const *digits = "0123456789";5138  char input[MAX_STR_LEN];5139  size_t len = 0, mlen = MAX_STR_LEN;5140  int level = 0;5141  bool absolute = false;5142  // Canonicalize the string (remove spaces, unify delimiters, etc.)5143  char *pos = CCAST(char *, value);5144  while (*pos && mlen) {5145    if (*pos != ' ') { // skip spaces5146      if (len == 0 && *pos == ':') {5147        absolute = true;5148      } else {5149        input[len] = (char)(toupper(*pos));5150        if (input[len] == 'X')5151          input[len] = ','; // unify delimiters of levels5152        if (input[len] == 'O' && strchr(digits, *(pos + 1)))5153          input[len] = '@'; // unify delimiters of offset5154        len++;5155      }5156    }5157    mlen--;5158    pos++;5159  }5160  if (len == 0 || mlen == 0) {5161    goto err; // contents is either empty or too long5162  }5163  input[len] = '\0';5164  // Split by delimiter5165  pos = input;5166  components[level++] = pos;5167  while ((pos = strchr(pos, ','))) {5168    if (level >= MAX_T_LEVEL)5169      goto err; // too many components provided5170    *pos = '\0'; // modify input and avoid more copying5171    components[level++] = ++pos; // expect something after ","5172  }5173 5174  __kmp_hw_subset = kmp_hw_subset_t::allocate();5175  if (absolute)5176    __kmp_hw_subset->set_absolute();5177 5178  // Check each component5179  for (int i = 0; i < level; ++i) {5180    int core_level = 0;5181    char *core_components[MAX_T_LEVEL];5182    // Split possible core components by '&' delimiter5183    pos = components[i];5184    core_components[core_level++] = pos;5185    while ((pos = strchr(pos, '&'))) {5186      if (core_level >= MAX_T_LEVEL)5187        goto err; // too many different core types5188      *pos = '\0'; // modify input and avoid more copying5189      core_components[core_level++] = ++pos; // expect something after '&'5190    }5191 5192    for (int j = 0; j < core_level; ++j) {5193      char *offset_ptr;5194      char *attr_ptr;5195      int offset = 0;5196      kmp_hw_attr_t attr;5197      int num;5198      // components may begin with an optional count of the number of resources5199      if (isdigit(*core_components[j])) {5200        num = atoi(core_components[j]);5201        if (num <= 0) {5202          goto err; // only positive integers are valid for count5203        }5204        pos = core_components[j] + strspn(core_components[j], digits);5205      } else if (*core_components[j] == '*') {5206        num = kmp_hw_subset_t::USE_ALL;5207        pos = core_components[j] + 1;5208      } else {5209        num = kmp_hw_subset_t::USE_ALL;5210        pos = core_components[j];5211      }5212 5213      offset_ptr = strchr(core_components[j], '@');5214      attr_ptr = strchr(core_components[j], ':');5215 5216      if (offset_ptr) {5217        offset = atoi(offset_ptr + 1); // save offset5218        *offset_ptr = '\0'; // cut the offset from the component5219      }5220      if (attr_ptr) {5221        attr.clear();5222        // save the attribute5223#if KMP_ARCH_X86 || KMP_ARCH_X86_645224        if (__kmp_str_match("intel_core", -1, attr_ptr + 1)) {5225          attr.set_core_type(KMP_HW_CORE_TYPE_CORE);5226        } else if (__kmp_str_match("intel_atom", -1, attr_ptr + 1)) {5227          attr.set_core_type(KMP_HW_CORE_TYPE_ATOM);5228        } else5229#endif5230        if (__kmp_str_match("eff", 3, attr_ptr + 1)) {5231          const char *number = attr_ptr + 1;5232          // skip the eff[iciency] token5233          while (isalpha(*number))5234            number++;5235          if (!isdigit(*number)) {5236            goto err;5237          }5238          int efficiency = atoi(number);5239          attr.set_core_eff(efficiency);5240        } else {5241          goto err;5242        }5243        *attr_ptr = '\0'; // cut the attribute from the component5244      }5245      // detect the component type5246      kmp_hw_t type = __kmp_stg_parse_hw_subset_name(pos);5247      if (type == KMP_HW_UNKNOWN) {5248        goto err;5249      }5250      // Only the core type can have attributes5251      if (attr && type != KMP_HW_CORE)5252        goto err;5253      // Must allow core be specified more than once5254      if (type != KMP_HW_CORE && __kmp_hw_subset->specified(type)) {5255        goto err;5256      }5257      __kmp_hw_subset->push_back(num, type, offset, attr);5258    }5259  }5260  return;5261err:5262  KMP_WARNING(AffHWSubsetInvalid, name, value);5263  if (__kmp_hw_subset) {5264    kmp_hw_subset_t::deallocate(__kmp_hw_subset);5265    __kmp_hw_subset = nullptr;5266  }5267  return;5268}5269 5270static void __kmp_stg_print_hw_subset(kmp_str_buf_t *buffer, char const *name,5271                                      void *data) {5272  kmp_str_buf_t buf;5273  int depth;5274  if (!__kmp_hw_subset)5275    return;5276  __kmp_str_buf_init(&buf);5277  if (__kmp_env_format)5278    KMP_STR_BUF_PRINT_NAME_EX(name);5279  else5280    __kmp_str_buf_print(buffer, "   %s='", name);5281 5282  depth = __kmp_hw_subset->get_depth();5283  for (int i = 0; i < depth; ++i) {5284    const auto &item = __kmp_hw_subset->at(i);5285    if (i > 0)5286      __kmp_str_buf_print(&buf, "%c", ',');5287    for (int j = 0; j < item.num_attrs; ++j) {5288      __kmp_str_buf_print(&buf, "%s%d%s", (j > 0 ? "&" : ""), item.num[j],5289                          __kmp_hw_get_keyword(item.type));5290      if (item.attr[j].is_core_type_valid())5291        __kmp_str_buf_print(5292            &buf, ":%s",5293            __kmp_hw_get_core_type_keyword(item.attr[j].get_core_type()));5294      if (item.attr[j].is_core_eff_valid())5295        __kmp_str_buf_print(&buf, ":eff%d", item.attr[j].get_core_eff());5296      if (item.offset[j])5297        __kmp_str_buf_print(&buf, "@%d", item.offset[j]);5298    }5299  }5300  __kmp_str_buf_print(buffer, "%s'\n", buf.str);5301  __kmp_str_buf_free(&buf);5302}5303 5304#if USE_ITT_BUILD5305// -----------------------------------------------------------------------------5306// KMP_FORKJOIN_FRAMES5307 5308static void __kmp_stg_parse_forkjoin_frames(char const *name, char const *value,5309                                            void *data) {5310  __kmp_stg_parse_bool(name, value, &__kmp_forkjoin_frames);5311} // __kmp_stg_parse_forkjoin_frames5312 5313static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t *buffer,5314                                            char const *name, void *data) {5315  __kmp_stg_print_bool(buffer, name, __kmp_forkjoin_frames);5316} // __kmp_stg_print_forkjoin_frames5317 5318// -----------------------------------------------------------------------------5319// KMP_FORKJOIN_FRAMES_MODE5320 5321static void __kmp_stg_parse_forkjoin_frames_mode(char const *name,5322                                                 char const *value,5323                                                 void *data) {5324  __kmp_stg_parse_int(name, value, 0, 3, &__kmp_forkjoin_frames_mode);5325} // __kmp_stg_parse_forkjoin_frames5326 5327static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t *buffer,5328                                                 char const *name, void *data) {5329  __kmp_stg_print_int(buffer, name, __kmp_forkjoin_frames_mode);5330} // __kmp_stg_print_forkjoin_frames5331#endif /* USE_ITT_BUILD */5332 5333// -----------------------------------------------------------------------------5334// KMP_ENABLE_TASK_THROTTLING5335 5336static void __kmp_stg_parse_task_throttling(char const *name, char const *value,5337                                            void *data) {5338  __kmp_stg_parse_bool(name, value, &__kmp_enable_task_throttling);5339} // __kmp_stg_parse_task_throttling5340 5341static void __kmp_stg_print_task_throttling(kmp_str_buf_t *buffer,5342                                            char const *name, void *data) {5343  __kmp_stg_print_bool(buffer, name, __kmp_enable_task_throttling);5344} // __kmp_stg_print_task_throttling5345 5346#if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT5347// -----------------------------------------------------------------------------5348// KMP_USER_LEVEL_MWAIT5349 5350static void __kmp_stg_parse_user_level_mwait(char const *name,5351                                             char const *value, void *data) {5352  __kmp_stg_parse_bool(name, value, &__kmp_user_level_mwait);5353} // __kmp_stg_parse_user_level_mwait5354 5355static void __kmp_stg_print_user_level_mwait(kmp_str_buf_t *buffer,5356                                             char const *name, void *data) {5357  __kmp_stg_print_bool(buffer, name, __kmp_user_level_mwait);5358} // __kmp_stg_print_user_level_mwait5359 5360// -----------------------------------------------------------------------------5361// KMP_MWAIT_HINTS5362 5363static void __kmp_stg_parse_mwait_hints(char const *name, char const *value,5364                                        void *data) {5365  __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_mwait_hints);5366} // __kmp_stg_parse_mwait_hints5367 5368static void __kmp_stg_print_mwait_hints(kmp_str_buf_t *buffer, char const *name,5369                                        void *data) {5370  __kmp_stg_print_int(buffer, name, __kmp_mwait_hints);5371} // __kmp_stg_print_mwait_hints5372 5373#endif // KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT5374 5375#if KMP_HAVE_UMWAIT5376// -----------------------------------------------------------------------------5377// KMP_TPAUSE5378// 0 = don't use TPAUSE, 1 = use C0.1 state, 2 = use C0.2 state5379 5380static void __kmp_stg_parse_tpause(char const *name, char const *value,5381                                   void *data) {5382  __kmp_stg_parse_int(name, value, 0, INT_MAX, &__kmp_tpause_state);5383  if (__kmp_tpause_state != 0) {5384    // The actual hint passed to tpause is: 0 for C0.2 and 1 for C0.15385    if (__kmp_tpause_state == 2) // use C0.25386      __kmp_tpause_hint = 0; // default was set to 1 for C0.15387  }5388} // __kmp_stg_parse_tpause5389 5390static void __kmp_stg_print_tpause(kmp_str_buf_t *buffer, char const *name,5391                                   void *data) {5392  __kmp_stg_print_int(buffer, name, __kmp_tpause_state);5393} // __kmp_stg_print_tpause5394#endif // KMP_HAVE_UMWAIT5395 5396// -----------------------------------------------------------------------------5397// OMP_DISPLAY_ENV5398 5399static void __kmp_stg_parse_omp_display_env(char const *name, char const *value,5400                                            void *data) {5401  if (__kmp_str_match("VERBOSE", 1, value)) {5402    __kmp_display_env_verbose = TRUE;5403  } else {5404    __kmp_stg_parse_bool(name, value, &__kmp_display_env);5405  }5406} // __kmp_stg_parse_omp_display_env5407 5408static void __kmp_stg_print_omp_display_env(kmp_str_buf_t *buffer,5409                                            char const *name, void *data) {5410  if (__kmp_display_env_verbose) {5411    __kmp_stg_print_str(buffer, name, "VERBOSE");5412  } else {5413    __kmp_stg_print_bool(buffer, name, __kmp_display_env);5414  }5415} // __kmp_stg_print_omp_display_env5416 5417static void __kmp_stg_parse_omp_cancellation(char const *name,5418                                             char const *value, void *data) {5419  if (TCR_4(__kmp_init_parallel)) {5420    KMP_WARNING(EnvParallelWarn, name);5421    return;5422  } // read value before first parallel only5423  __kmp_stg_parse_bool(name, value, &__kmp_omp_cancellation);5424} // __kmp_stg_parse_omp_cancellation5425 5426static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t *buffer,5427                                             char const *name, void *data) {5428  __kmp_stg_print_bool(buffer, name, __kmp_omp_cancellation);5429} // __kmp_stg_print_omp_cancellation5430 5431#if OMPT_SUPPORT5432int __kmp_tool = 1;5433 5434static void __kmp_stg_parse_omp_tool(char const *name, char const *value,5435                                     void *data) {5436  __kmp_stg_parse_bool(name, value, &__kmp_tool);5437} // __kmp_stg_parse_omp_tool5438 5439static void __kmp_stg_print_omp_tool(kmp_str_buf_t *buffer, char const *name,5440                                     void *data) {5441  if (__kmp_env_format) {5442    KMP_STR_BUF_PRINT_BOOL_EX(name, __kmp_tool, "enabled", "disabled");5443  } else {5444    __kmp_str_buf_print(buffer, "   %s=%s\n", name,5445                        __kmp_tool ? "enabled" : "disabled");5446  }5447} // __kmp_stg_print_omp_tool5448 5449char *__kmp_tool_libraries = NULL;5450 5451static void __kmp_stg_parse_omp_tool_libraries(char const *name,5452                                               char const *value, void *data) {5453  __kmp_stg_parse_str(name, value, &__kmp_tool_libraries);5454} // __kmp_stg_parse_omp_tool_libraries5455 5456static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t *buffer,5457                                               char const *name, void *data) {5458  if (__kmp_tool_libraries)5459    __kmp_stg_print_str(buffer, name, __kmp_tool_libraries);5460  else {5461    if (__kmp_env_format) {5462      KMP_STR_BUF_PRINT_NAME;5463    } else {5464      __kmp_str_buf_print(buffer, "   %s", name);5465    }5466    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));5467  }5468} // __kmp_stg_print_omp_tool_libraries5469 5470char *__kmp_tool_verbose_init = NULL;5471 5472static void __kmp_stg_parse_omp_tool_verbose_init(char const *name,5473                                                  char const *value,5474                                                  void *data) {5475  __kmp_stg_parse_str(name, value, &__kmp_tool_verbose_init);5476} // __kmp_stg_parse_omp_tool_libraries5477 5478static void __kmp_stg_print_omp_tool_verbose_init(kmp_str_buf_t *buffer,5479                                                  char const *name,5480                                                  void *data) {5481  if (__kmp_tool_verbose_init)5482    __kmp_stg_print_str(buffer, name, __kmp_tool_verbose_init);5483  else {5484    if (__kmp_env_format) {5485      KMP_STR_BUF_PRINT_NAME;5486    } else {5487      __kmp_str_buf_print(buffer, "   %s", name);5488    }5489    __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined));5490  }5491} // __kmp_stg_print_omp_tool_verbose_init5492 5493#endif5494 5495// Table.5496 5497static kmp_setting_t __kmp_stg_table[] = {5498 5499    {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit, NULL, NULL, 0, 0},5500    {"KMP_BLOCKTIME", __kmp_stg_parse_blocktime, __kmp_stg_print_blocktime,5501     NULL, 0, 0},5502    {"KMP_USE_YIELD", __kmp_stg_parse_use_yield, __kmp_stg_print_use_yield,5503     NULL, 0, 0},5504    {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok,5505     __kmp_stg_print_duplicate_lib_ok, NULL, 0, 0},5506    {"KMP_LIBRARY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy,5507     NULL, 0, 0},5508    {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit,5509     __kmp_stg_print_device_thread_limit, NULL, 0, 0},5510#if KMP_USE_MONITOR5511    {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize,5512     __kmp_stg_print_monitor_stacksize, NULL, 0, 0},5513#endif5514    {"KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL,5515     0, 0},5516    {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset,5517     __kmp_stg_print_stackoffset, NULL, 0, 0},5518    {"KMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,5519     NULL, 0, 0},5520    {"KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL,5521     0, 0},5522    {"KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0,5523     0},5524    {"KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL,5525     0, 0},5526 5527    {"KMP_NESTING_MODE", __kmp_stg_parse_nesting_mode,5528     __kmp_stg_print_nesting_mode, NULL, 0, 0},5529    {"OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0},5530    {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads,5531     __kmp_stg_print_num_threads, NULL, 0, 0},5532    {"OMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize,5533     NULL, 0, 0},5534 5535    {"KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0,5536     0},5537    {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing,5538     __kmp_stg_print_task_stealing, NULL, 0, 0},5539    {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels,5540     __kmp_stg_print_max_active_levels, NULL, 0, 0},5541    {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device,5542     __kmp_stg_print_default_device, NULL, 0, 0},5543    {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload,5544     __kmp_stg_print_target_offload, NULL, 0, 0},5545    {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority,5546     __kmp_stg_print_max_task_priority, NULL, 0, 0},5547    {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks,5548     __kmp_stg_print_taskloop_min_tasks, NULL, 0, 0},5549    {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit,5550     __kmp_stg_print_thread_limit, NULL, 0, 0},5551    {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit,5552     __kmp_stg_print_teams_thread_limit, NULL, 0, 0},5553    {"OMP_NUM_TEAMS", __kmp_stg_parse_nteams, __kmp_stg_print_nteams, NULL, 0,5554     0},5555    {"OMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_th_limit,5556     __kmp_stg_print_teams_th_limit, NULL, 0, 0},5557    {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy,5558     __kmp_stg_print_wait_policy, NULL, 0, 0},5559    {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers,5560     __kmp_stg_print_disp_buffers, NULL, 0, 0},5561    {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level,5562     __kmp_stg_print_hot_teams_level, NULL, 0, 0},5563    {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode,5564     __kmp_stg_print_hot_teams_mode, NULL, 0, 0},5565 5566#if KMP_HANDLE_SIGNALS5567    {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals,5568     __kmp_stg_print_handle_signals, NULL, 0, 0},5569#endif5570 5571#if KMP_ARCH_X86 || KMP_ARCH_X86_645572    {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control,5573     __kmp_stg_print_inherit_fp_control, NULL, 0, 0},5574#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */5575 5576#ifdef KMP_GOMP_COMPAT5577    {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0},5578#endif5579 5580#ifdef KMP_DEBUG5581    {"KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0,5582     0},5583    {"KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0,5584     0},5585    {"KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0,5586     0},5587    {"KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0,5588     0},5589    {"KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0,5590     0},5591    {"KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0,5592     0},5593    {"KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0},5594    {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf,5595     NULL, 0, 0},5596    {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic,5597     __kmp_stg_print_debug_buf_atomic, NULL, 0, 0},5598    {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars,5599     __kmp_stg_print_debug_buf_chars, NULL, 0, 0},5600    {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines,5601     __kmp_stg_print_debug_buf_lines, NULL, 0, 0},5602    {"KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0},5603 5604    {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env,5605     __kmp_stg_print_par_range_env, NULL, 0, 0},5606#endif // KMP_DEBUG5607 5608    {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc,5609     __kmp_stg_print_align_alloc, NULL, 0, 0},5610 5611    {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,5612     __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},5613    {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,5614     __kmp_stg_print_barrier_pattern, NULL, 0, 0},5615    {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit,5616     __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},5617    {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,5618     __kmp_stg_print_barrier_pattern, NULL, 0, 0},5619#if KMP_FAST_REDUCTION_BARRIER5620    {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit,5621     __kmp_stg_print_barrier_branch_bit, NULL, 0, 0},5622    {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern,5623     __kmp_stg_print_barrier_pattern, NULL, 0, 0},5624#endif5625 5626    {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay,5627     __kmp_stg_print_abort_delay, NULL, 0, 0},5628    {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file,5629     __kmp_stg_print_cpuinfo_file, NULL, 0, 0},5630    {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction,5631     __kmp_stg_print_force_reduction, NULL, 0, 0},5632    {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction,5633     __kmp_stg_print_force_reduction, NULL, 0, 0},5634    {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map,5635     __kmp_stg_print_storage_map, NULL, 0, 0},5636    {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate,5637     __kmp_stg_print_all_threadprivate, NULL, 0, 0},5638    {"KMP_FOREIGN_THREADS_THREADPRIVATE",5639     __kmp_stg_parse_foreign_threads_threadprivate,5640     __kmp_stg_print_foreign_threads_threadprivate, NULL, 0, 0},5641 5642#if KMP_AFFINITY_SUPPORTED5643    {"KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL,5644     0, 0},5645    {"KMP_HIDDEN_HELPER_AFFINITY", __kmp_stg_parse_hh_affinity,5646     __kmp_stg_print_hh_affinity, NULL, 0, 0},5647#ifdef KMP_GOMP_COMPAT5648    {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL,5649     /* no print */ NULL, 0, 0},5650#endif /* KMP_GOMP_COMPAT */5651    {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,5652     NULL, 0, 0},5653    {"KMP_TEAMS_PROC_BIND", __kmp_stg_parse_teams_proc_bind,5654     __kmp_stg_print_teams_proc_bind, NULL, 0, 0},5655    {"OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0},5656    {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method,5657     __kmp_stg_print_topology_method, NULL, 0, 0},5658 5659#else5660 5661    // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.5662    // OMP_PROC_BIND and proc-bind-var are supported, however.5663    {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind,5664     NULL, 0, 0},5665 5666#endif // KMP_AFFINITY_SUPPORTED5667    {"OMP_DISPLAY_AFFINITY", __kmp_stg_parse_display_affinity,5668     __kmp_stg_print_display_affinity, NULL, 0, 0},5669    {"OMP_AFFINITY_FORMAT", __kmp_stg_parse_affinity_format,5670     __kmp_stg_print_affinity_format, NULL, 0, 0},5671    {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork,5672     __kmp_stg_print_init_at_fork, NULL, 0, 0},5673    {"KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL,5674     0, 0},5675    {"OMP_SCHEDULE", __kmp_stg_parse_omp_schedule, __kmp_stg_print_omp_schedule,5676     NULL, 0, 0},5677#if KMP_USE_HIER_SCHED5678    {"KMP_DISP_HAND_THREAD", __kmp_stg_parse_kmp_hand_thread,5679     __kmp_stg_print_kmp_hand_thread, NULL, 0, 0},5680#endif5681    {"KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE",5682     __kmp_stg_parse_kmp_force_monotonic, __kmp_stg_print_kmp_force_monotonic,5683     NULL, 0, 0},5684    {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode,5685     __kmp_stg_print_atomic_mode, NULL, 0, 0},5686    {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check,5687     __kmp_stg_print_consistency_check, NULL, 0, 0},5688 5689#if USE_ITT_BUILD && USE_ITT_NOTIFY5690    {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay,5691     __kmp_stg_print_itt_prepare_delay, NULL, 0, 0},5692#endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */5693    {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr,5694     __kmp_stg_print_malloc_pool_incr, NULL, 0, 0},5695    {"KMP_GTID_MODE", __kmp_stg_parse_gtid_mode, __kmp_stg_print_gtid_mode,5696     NULL, 0, 0},5697    {"OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic, __kmp_stg_print_omp_dynamic,5698     NULL, 0, 0},5699    {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode,5700     __kmp_stg_print_kmp_dynamic_mode, NULL, 0, 0},5701 5702#ifdef USE_LOAD_BALANCE5703    {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval,5704     __kmp_stg_print_ld_balance_interval, NULL, 0, 0},5705#endif5706 5707    {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block,5708     __kmp_stg_print_lock_block, NULL, 0, 0},5709    {"KMP_LOCK_KIND", __kmp_stg_parse_lock_kind, __kmp_stg_print_lock_kind,5710     NULL, 0, 0},5711    {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params,5712     __kmp_stg_print_spin_backoff_params, NULL, 0, 0},5713#if KMP_USE_ADAPTIVE_LOCKS5714    {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props,5715     __kmp_stg_print_adaptive_lock_props, NULL, 0, 0},5716#if KMP_DEBUG_ADAPTIVE_LOCKS5717    {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile,5718     __kmp_stg_print_speculative_statsfile, NULL, 0, 0},5719#endif5720#endif // KMP_USE_ADAPTIVE_LOCKS5721    {"KMP_PLACE_THREADS", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,5722     NULL, 0, 0},5723    {"KMP_HW_SUBSET", __kmp_stg_parse_hw_subset, __kmp_stg_print_hw_subset,5724     NULL, 0, 0},5725#if USE_ITT_BUILD5726    {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames,5727     __kmp_stg_print_forkjoin_frames, NULL, 0, 0},5728    {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode,5729     __kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0},5730#endif5731    {"KMP_ENABLE_TASK_THROTTLING", __kmp_stg_parse_task_throttling,5732     __kmp_stg_print_task_throttling, NULL, 0, 0},5733 5734    {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env,5735     __kmp_stg_print_omp_display_env, NULL, 0, 0},5736    {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation,5737     __kmp_stg_print_omp_cancellation, NULL, 0, 0},5738    {"OMP_ALLOCATOR", __kmp_stg_parse_allocator, __kmp_stg_print_allocator,5739     NULL, 0, 0},5740    {"LIBOMP_USE_HIDDEN_HELPER_TASK", __kmp_stg_parse_use_hidden_helper,5741     __kmp_stg_print_use_hidden_helper, NULL, 0, 0},5742    {"LIBOMP_NUM_HIDDEN_HELPER_THREADS",5743     __kmp_stg_parse_num_hidden_helper_threads,5744     __kmp_stg_print_num_hidden_helper_threads, NULL, 0, 0},5745#if OMPX_TASKGRAPH5746    {"KMP_MAX_TDGS", __kmp_stg_parse_max_tdgs, __kmp_std_print_max_tdgs, NULL,5747     0, 0},5748    {"KMP_TDG_DOT", __kmp_stg_parse_tdg_dot, __kmp_stg_print_tdg_dot, NULL, 0,5749     0},5750#endif5751 5752#if OMPT_SUPPORT5753    {"OMP_TOOL", __kmp_stg_parse_omp_tool, __kmp_stg_print_omp_tool, NULL, 0,5754     0},5755    {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries,5756     __kmp_stg_print_omp_tool_libraries, NULL, 0, 0},5757    {"OMP_TOOL_VERBOSE_INIT", __kmp_stg_parse_omp_tool_verbose_init,5758     __kmp_stg_print_omp_tool_verbose_init, NULL, 0, 0},5759#endif5760 5761#if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT5762    {"KMP_USER_LEVEL_MWAIT", __kmp_stg_parse_user_level_mwait,5763     __kmp_stg_print_user_level_mwait, NULL, 0, 0},5764    {"KMP_MWAIT_HINTS", __kmp_stg_parse_mwait_hints,5765     __kmp_stg_print_mwait_hints, NULL, 0, 0},5766#endif5767 5768#if KMP_HAVE_UMWAIT5769    {"KMP_TPAUSE", __kmp_stg_parse_tpause, __kmp_stg_print_tpause, NULL, 0, 0},5770#endif5771    {"", NULL, NULL, NULL, 0, 0}}; // settings5772 5773static int const __kmp_stg_count =5774    sizeof(__kmp_stg_table) / sizeof(kmp_setting_t);5775 5776static inline kmp_setting_t *__kmp_stg_find(char const *name) {5777 5778  int i;5779  if (name != NULL) {5780    for (i = 0; i < __kmp_stg_count; ++i) {5781      if (strcmp(__kmp_stg_table[i].name, name) == 0) {5782        return &__kmp_stg_table[i];5783      }5784    }5785  }5786  return NULL;5787 5788} // __kmp_stg_find5789 5790static int __kmp_stg_cmp(void const *_a, void const *_b) {5791  const kmp_setting_t *a = RCAST(const kmp_setting_t *, _a);5792  const kmp_setting_t *b = RCAST(const kmp_setting_t *, _b);5793 5794  // Process KMP_AFFINITY last.5795  // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.5796  if (strcmp(a->name, "KMP_AFFINITY") == 0) {5797    if (strcmp(b->name, "KMP_AFFINITY") == 0) {5798      return 0;5799    }5800    return 1;5801  } else if (strcmp(b->name, "KMP_AFFINITY") == 0) {5802    return -1;5803  }5804  return strcmp(a->name, b->name);5805} // __kmp_stg_cmp5806 5807static void __kmp_stg_init(void) {5808 5809  static int initialized = 0;5810 5811  if (!initialized) {5812 5813    // Sort table.5814    qsort(__kmp_stg_table, __kmp_stg_count - 1, sizeof(kmp_setting_t),5815          __kmp_stg_cmp);5816 5817    { // Initialize *_STACKSIZE data.5818      kmp_setting_t *kmp_stacksize =5819          __kmp_stg_find("KMP_STACKSIZE"); // 1st priority.5820#ifdef KMP_GOMP_COMPAT5821      kmp_setting_t *gomp_stacksize =5822          __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority.5823#endif5824      kmp_setting_t *omp_stacksize =5825          __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority.5826 5827      // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.5828      // !!! Compiler does not understand rivals is used and optimizes out5829      // assignments5830      // !!!     rivals[ i ++ ] = ...;5831      static kmp_setting_t *volatile rivals[4];5832      static kmp_stg_ss_data_t kmp_data = {1, CCAST(kmp_setting_t **, rivals)};5833#ifdef KMP_GOMP_COMPAT5834      static kmp_stg_ss_data_t gomp_data = {1024,5835                                            CCAST(kmp_setting_t **, rivals)};5836#endif5837      static kmp_stg_ss_data_t omp_data = {1024,5838                                           CCAST(kmp_setting_t **, rivals)};5839      int i = 0;5840 5841      rivals[i++] = kmp_stacksize;5842#ifdef KMP_GOMP_COMPAT5843      if (gomp_stacksize != NULL) {5844        rivals[i++] = gomp_stacksize;5845      }5846#endif5847      rivals[i++] = omp_stacksize;5848      rivals[i++] = NULL;5849 5850      kmp_stacksize->data = &kmp_data;5851#ifdef KMP_GOMP_COMPAT5852      if (gomp_stacksize != NULL) {5853        gomp_stacksize->data = &gomp_data;5854      }5855#endif5856      omp_stacksize->data = &omp_data;5857    }5858 5859    { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.5860      kmp_setting_t *kmp_library =5861          __kmp_stg_find("KMP_LIBRARY"); // 1st priority.5862      kmp_setting_t *omp_wait_policy =5863          __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority.5864 5865      // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.5866      static kmp_setting_t *volatile rivals[3];5867      static kmp_stg_wp_data_t kmp_data = {0, CCAST(kmp_setting_t **, rivals)};5868      static kmp_stg_wp_data_t omp_data = {1, CCAST(kmp_setting_t **, rivals)};5869      int i = 0;5870 5871      rivals[i++] = kmp_library;5872      if (omp_wait_policy != NULL) {5873        rivals[i++] = omp_wait_policy;5874      }5875      rivals[i++] = NULL;5876 5877      kmp_library->data = &kmp_data;5878      if (omp_wait_policy != NULL) {5879        omp_wait_policy->data = &omp_data;5880      }5881    }5882 5883    { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS5884      kmp_setting_t *kmp_device_thread_limit =5885          __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority.5886      kmp_setting_t *kmp_all_threads =5887          __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority.5888 5889      // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.5890      static kmp_setting_t *volatile rivals[3];5891      int i = 0;5892 5893      rivals[i++] = kmp_device_thread_limit;5894      rivals[i++] = kmp_all_threads;5895      rivals[i++] = NULL;5896 5897      kmp_device_thread_limit->data = CCAST(kmp_setting_t **, rivals);5898      kmp_all_threads->data = CCAST(kmp_setting_t **, rivals);5899    }5900 5901    { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS5902      // 1st priority5903      kmp_setting_t *kmp_hw_subset = __kmp_stg_find("KMP_HW_SUBSET");5904      // 2nd priority5905      kmp_setting_t *kmp_place_threads = __kmp_stg_find("KMP_PLACE_THREADS");5906 5907      // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.5908      static kmp_setting_t *volatile rivals[3];5909      int i = 0;5910 5911      rivals[i++] = kmp_hw_subset;5912      rivals[i++] = kmp_place_threads;5913      rivals[i++] = NULL;5914 5915      kmp_hw_subset->data = CCAST(kmp_setting_t **, rivals);5916      kmp_place_threads->data = CCAST(kmp_setting_t **, rivals);5917    }5918 5919#if KMP_AFFINITY_SUPPORTED5920    { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.5921      kmp_setting_t *kmp_affinity =5922          __kmp_stg_find("KMP_AFFINITY"); // 1st priority.5923      KMP_DEBUG_ASSERT(kmp_affinity != NULL);5924 5925#ifdef KMP_GOMP_COMPAT5926      kmp_setting_t *gomp_cpu_affinity =5927          __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority.5928      KMP_DEBUG_ASSERT(gomp_cpu_affinity != NULL);5929#endif5930 5931      kmp_setting_t *omp_proc_bind =5932          __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority.5933      KMP_DEBUG_ASSERT(omp_proc_bind != NULL);5934 5935      // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.5936      static kmp_setting_t *volatile rivals[4];5937      int i = 0;5938 5939      rivals[i++] = kmp_affinity;5940 5941#ifdef KMP_GOMP_COMPAT5942      rivals[i++] = gomp_cpu_affinity;5943      gomp_cpu_affinity->data = CCAST(kmp_setting_t **, rivals);5944#endif5945 5946      rivals[i++] = omp_proc_bind;5947      omp_proc_bind->data = CCAST(kmp_setting_t **, rivals);5948      rivals[i++] = NULL;5949 5950      static kmp_setting_t *volatile places_rivals[4];5951      i = 0;5952 5953      kmp_setting_t *omp_places = __kmp_stg_find("OMP_PLACES"); // 3rd priority.5954      KMP_DEBUG_ASSERT(omp_places != NULL);5955 5956      places_rivals[i++] = kmp_affinity;5957#ifdef KMP_GOMP_COMPAT5958      places_rivals[i++] = gomp_cpu_affinity;5959#endif5960      places_rivals[i++] = omp_places;5961      omp_places->data = CCAST(kmp_setting_t **, places_rivals);5962      places_rivals[i++] = NULL;5963    }5964#else5965// KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.5966// OMP_PLACES not supported yet.5967#endif // KMP_AFFINITY_SUPPORTED5968 5969    { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.5970      kmp_setting_t *kmp_force_red =5971          __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority.5972      kmp_setting_t *kmp_determ_red =5973          __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority.5974 5975      // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.5976      static kmp_setting_t *volatile rivals[3];5977      static kmp_stg_fr_data_t force_data = {1,5978                                             CCAST(kmp_setting_t **, rivals)};5979      static kmp_stg_fr_data_t determ_data = {0,5980                                              CCAST(kmp_setting_t **, rivals)};5981      int i = 0;5982 5983      rivals[i++] = kmp_force_red;5984      if (kmp_determ_red != NULL) {5985        rivals[i++] = kmp_determ_red;5986      }5987      rivals[i++] = NULL;5988 5989      kmp_force_red->data = &force_data;5990      if (kmp_determ_red != NULL) {5991        kmp_determ_red->data = &determ_data;5992      }5993    }5994 5995    initialized = 1;5996  }5997 5998  // Reset flags.5999  int i;6000  for (i = 0; i < __kmp_stg_count; ++i) {6001    __kmp_stg_table[i].set = 0;6002  }6003 6004} // __kmp_stg_init6005 6006static void __kmp_stg_parse(char const *name, char const *value) {6007  // On Windows* OS there are some nameless variables like "C:=C:\" (yeah,6008  // really nameless, they are presented in environment block as6009  // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.6010  if (name[0] == 0) {6011    return;6012  }6013 6014  if (value != NULL) {6015    kmp_setting_t *setting = __kmp_stg_find(name);6016    if (setting != NULL) {6017      setting->parse(name, value, setting->data);6018      setting->defined = 1;6019    }6020  }6021 6022} // __kmp_stg_parse6023 6024static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.6025    char const *name, // Name of variable.6026    char const *value, // Value of the variable.6027    kmp_setting_t **rivals // List of rival settings (must include current one).6028) {6029 6030  if (rivals == NULL) {6031    return 0;6032  }6033 6034  // Loop thru higher priority settings (listed before current).6035  int i = 0;6036  for (; strcmp(rivals[i]->name, name) != 0; i++) {6037    KMP_DEBUG_ASSERT(rivals[i] != NULL);6038 6039#if KMP_AFFINITY_SUPPORTED6040    if (rivals[i] == __kmp_affinity_notype) {6041      // If KMP_AFFINITY is specified without a type name,6042      // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.6043      continue;6044    }6045#endif6046 6047    if (rivals[i]->set) {6048      KMP_WARNING(StgIgnored, name, rivals[i]->name);6049      return 1;6050    }6051  }6052 6053  ++i; // Skip current setting.6054  return 0;6055 6056} // __kmp_stg_check_rivals6057 6058static int __kmp_env_toPrint(char const *name, int flag) {6059  int rc = 0;6060  kmp_setting_t *setting = __kmp_stg_find(name);6061  if (setting != NULL) {6062    rc = setting->defined;6063    if (flag >= 0) {6064      setting->defined = flag;6065    }6066  }6067  return rc;6068}6069 6070#if defined(KMP_DEBUG) && KMP_AFFINITY_SUPPORTED6071static void __kmp_print_affinity_settings(const kmp_affinity_t *affinity) {6072  K_DIAG(1, ("%s:\n", affinity->env_var));6073  K_DIAG(1, ("    type     : %d\n", affinity->type));6074  K_DIAG(1, ("    compact  : %d\n", affinity->compact));6075  K_DIAG(1, ("    offset   : %d\n", affinity->offset));6076  K_DIAG(1, ("    verbose  : %u\n", affinity->flags.verbose));6077  K_DIAG(1, ("    warnings : %u\n", affinity->flags.warnings));6078  K_DIAG(1, ("    respect  : %u\n", affinity->flags.respect));6079  K_DIAG(1, ("    reset    : %u\n", affinity->flags.reset));6080  K_DIAG(1, ("    dups     : %u\n", affinity->flags.dups));6081  K_DIAG(1, ("    gran     : %d\n", (int)affinity->gran));6082  KMP_DEBUG_ASSERT(affinity->type != affinity_default);6083}6084#endif6085 6086static void __kmp_aux_env_initialize(kmp_env_blk_t *block) {6087 6088  char const *value;6089 6090  /* OMP_NUM_THREADS */6091  value = __kmp_env_blk_var(block, "OMP_NUM_THREADS");6092  if (value) {6093    ompc_set_num_threads(__kmp_dflt_team_nth);6094  }6095 6096  /* KMP_BLOCKTIME */6097  value = __kmp_env_blk_var(block, "KMP_BLOCKTIME");6098  if (value) {6099    int gtid, tid;6100    kmp_info_t *thread;6101 6102    gtid = __kmp_entry_gtid();6103    tid = __kmp_tid_from_gtid(gtid);6104    thread = __kmp_thread_from_gtid(gtid);6105    __kmp_aux_set_blocktime(__kmp_dflt_blocktime, thread, tid);6106  }6107 6108  /* OMP_NESTED */6109  value = __kmp_env_blk_var(block, "OMP_NESTED");6110  if (value) {6111    ompc_set_nested(__kmp_dflt_max_active_levels > 1);6112  }6113 6114  /* OMP_DYNAMIC */6115  value = __kmp_env_blk_var(block, "OMP_DYNAMIC");6116  if (value) {6117    ompc_set_dynamic(__kmp_global.g.g_dynamic);6118  }6119}6120 6121void __kmp_env_initialize(char const *string) {6122 6123  kmp_env_blk_t block;6124  int i;6125 6126  __kmp_stg_init();6127 6128  // Hack!!!6129  if (string == NULL) {6130    // __kmp_max_nth = __kmp_sys_max_nth;6131    __kmp_threads_capacity =6132        __kmp_initial_threads_capacity(__kmp_dflt_team_nth_ub);6133  }6134  __kmp_env_blk_init(&block, string);6135 6136  // update the set flag on all entries that have an env var6137  for (i = 0; i < block.count; ++i) {6138    if ((block.vars[i].name == NULL) || (*block.vars[i].name == '\0')) {6139      continue;6140    }6141    if (block.vars[i].value == NULL) {6142      continue;6143    }6144    kmp_setting_t *setting = __kmp_stg_find(block.vars[i].name);6145    if (setting != NULL) {6146      setting->set = 1;6147    }6148  }6149 6150  // We need to know if blocktime was set when processing OMP_WAIT_POLICY6151  blocktime_str = __kmp_env_blk_var(&block, "KMP_BLOCKTIME");6152 6153  // Special case. If we parse environment, not a string, process KMP_WARNINGS6154  // first.6155  if (string == NULL) {6156    char const *name = "KMP_WARNINGS";6157    char const *value = __kmp_env_blk_var(&block, name);6158    __kmp_stg_parse(name, value);6159  }6160 6161#if KMP_AFFINITY_SUPPORTED6162  // Special case. KMP_AFFINITY is not a rival to other affinity env vars6163  // if no affinity type is specified.  We want to allow6164  // KMP_AFFINITY=[no],verbose/[no]warnings/etc.  to be enabled when6165  // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.06166  // affinity mechanism.6167  __kmp_affinity_notype = NULL;6168  char const *aff_str = __kmp_env_blk_var(&block, "KMP_AFFINITY");6169  if (aff_str != NULL) {6170    // Check if the KMP_AFFINITY type is specified in the string.6171    // We just search the string for "compact", "scatter", etc.6172    // without really parsing the string.  The syntax of the6173    // KMP_AFFINITY env var is such that none of the affinity6174    // type names can appear anywhere other that the type6175    // specifier, even as substrings.6176    //6177    // I can't find a case-insensitive version of strstr on Windows* OS.6178    // Use the case-sensitive version for now. AIX does the same.6179 6180#if KMP_OS_WINDOWS || KMP_OS_AIX6181#define FIND strstr6182#else6183#define FIND strcasestr6184#endif6185 6186    if ((FIND(aff_str, "none") == NULL) &&6187        (FIND(aff_str, "physical") == NULL) &&6188        (FIND(aff_str, "logical") == NULL) &&6189        (FIND(aff_str, "compact") == NULL) &&6190        (FIND(aff_str, "scatter") == NULL) &&6191        (FIND(aff_str, "explicit") == NULL) &&6192        (FIND(aff_str, "balanced") == NULL) &&6193        (FIND(aff_str, "disabled") == NULL)) {6194      __kmp_affinity_notype = __kmp_stg_find("KMP_AFFINITY");6195    } else {6196      // A new affinity type is specified.6197      // Reset the affinity flags to their default values,6198      // in case this is called from kmp_set_defaults().6199      __kmp_affinity.type = affinity_default;6200      __kmp_affinity.gran = KMP_HW_UNKNOWN;6201      __kmp_affinity_top_method = affinity_top_method_default;6202      __kmp_affinity.flags.respect = affinity_respect_mask_default;6203    }6204#undef FIND6205 6206    // Also reset the affinity flags if OMP_PROC_BIND is specified.6207    aff_str = __kmp_env_blk_var(&block, "OMP_PROC_BIND");6208    if (aff_str != NULL) {6209      __kmp_affinity.type = affinity_default;6210      __kmp_affinity.gran = KMP_HW_UNKNOWN;6211      __kmp_affinity_top_method = affinity_top_method_default;6212      __kmp_affinity.flags.respect = affinity_respect_mask_default;6213    }6214  }6215 6216#endif /* KMP_AFFINITY_SUPPORTED */6217 6218  // Set up the nested proc bind type vector.6219  if (__kmp_nested_proc_bind.bind_types == NULL) {6220    __kmp_nested_proc_bind.bind_types =6221        (kmp_proc_bind_t *)KMP_INTERNAL_MALLOC(sizeof(kmp_proc_bind_t));6222    if (__kmp_nested_proc_bind.bind_types == NULL) {6223      KMP_FATAL(MemoryAllocFailed);6224    }6225    __kmp_nested_proc_bind.size = 1;6226    __kmp_nested_proc_bind.used = 1;6227#if KMP_AFFINITY_SUPPORTED6228    __kmp_nested_proc_bind.bind_types[0] = proc_bind_default;6229#else6230    // default proc bind is false if affinity not supported6231    __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;6232#endif6233  }6234 6235  // Set up the affinity format ICV6236  // Grab the default affinity format string from the message catalog6237  kmp_msg_t m =6238      __kmp_msg_format(kmp_i18n_msg_AffFormatDefault, "%P", "%i", "%n", "%A");6239  KMP_DEBUG_ASSERT(KMP_STRLEN(m.str) < KMP_AFFINITY_FORMAT_SIZE);6240 6241  if (__kmp_affinity_format == NULL) {6242    __kmp_affinity_format =6243        (char *)KMP_INTERNAL_MALLOC(sizeof(char) * KMP_AFFINITY_FORMAT_SIZE);6244  }6245  KMP_STRCPY_S(__kmp_affinity_format, KMP_AFFINITY_FORMAT_SIZE, m.str);6246  __kmp_str_free(&m.str);6247 6248  // Now process all of the settings.6249  for (i = 0; i < block.count; ++i) {6250    __kmp_stg_parse(block.vars[i].name, block.vars[i].value);6251  }6252 6253  // If user locks have been allocated yet, don't reset the lock vptr table.6254  if (!__kmp_init_user_locks) {6255    if (__kmp_user_lock_kind == lk_default) {6256      __kmp_user_lock_kind = lk_queuing;6257    }6258#if KMP_USE_DYNAMIC_LOCK6259    __kmp_init_dynamic_user_locks();6260#else6261    __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);6262#endif6263  } else {6264    KMP_DEBUG_ASSERT(string != NULL); // kmp_set_defaults() was called6265    KMP_DEBUG_ASSERT(__kmp_user_lock_kind != lk_default);6266// Binds lock functions again to follow the transition between different6267// KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long6268// as we do not allow lock kind changes after making a call to any6269// user lock functions (true).6270#if KMP_USE_DYNAMIC_LOCK6271    __kmp_init_dynamic_user_locks();6272#else6273    __kmp_set_user_lock_vptrs(__kmp_user_lock_kind);6274#endif6275  }6276 6277#if KMP_AFFINITY_SUPPORTED6278 6279  if (!TCR_4(__kmp_init_middle)) {6280#if KMP_HWLOC_ENABLED6281    // Force using hwloc when either tiles or numa nodes requested within6282    // KMP_HW_SUBSET or granularity setting and no other topology method6283    // is requested6284    if (__kmp_hw_subset &&6285        __kmp_affinity_top_method == affinity_top_method_default)6286      if (__kmp_hw_subset->specified(KMP_HW_NUMA) ||6287          __kmp_hw_subset->specified(KMP_HW_TILE) ||6288          __kmp_affinity.gran == KMP_HW_TILE ||6289          __kmp_affinity.gran == KMP_HW_NUMA)6290        __kmp_affinity_top_method = affinity_top_method_hwloc;6291    // Force using hwloc when tiles or numa nodes requested for OMP_PLACES6292    if (__kmp_affinity.gran == KMP_HW_NUMA ||6293        __kmp_affinity.gran == KMP_HW_TILE)6294      __kmp_affinity_top_method = affinity_top_method_hwloc;6295#endif // KMP_HWLOC_ENABLED6296    // Determine if the machine/OS is actually capable of supporting6297    // affinity.6298    const char *var = "KMP_AFFINITY";6299    KMPAffinity::pick_api();6300#if KMP_HWLOC_ENABLED6301    // If Hwloc topology discovery was requested but affinity was also disabled,6302    // then tell user that Hwloc request is being ignored and use default6303    // topology discovery method.6304    if (__kmp_affinity_top_method == affinity_top_method_hwloc &&6305        __kmp_affinity_dispatch->get_api_type() != KMPAffinity::HWLOC) {6306      KMP_WARNING(AffIgnoringHwloc, var);6307      __kmp_affinity_top_method = affinity_top_method_all;6308    }6309#endif // KMP_HWLOC_ENABLED6310    if (__kmp_affinity.type == affinity_disabled) {6311      KMP_AFFINITY_DISABLE();6312    } else if (!KMP_AFFINITY_CAPABLE()) {6313      __kmp_affinity_dispatch->determine_capable(var);6314      if (!KMP_AFFINITY_CAPABLE()) {6315        if (__kmp_affinity.flags.verbose ||6316            (__kmp_affinity.flags.warnings &&6317             (__kmp_affinity.type != affinity_default) &&6318             (__kmp_affinity.type != affinity_none) &&6319             (__kmp_affinity.type != affinity_disabled))) {6320          KMP_WARNING(AffNotSupported, var);6321        }6322        __kmp_affinity.type = affinity_disabled;6323        __kmp_affinity.flags.respect = FALSE;6324        __kmp_affinity.gran = KMP_HW_THREAD;6325      }6326    }6327 6328    if (__kmp_affinity.type == affinity_disabled) {6329      __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;6330    } else if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_true) {6331      // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.6332      __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread;6333    }6334 6335    if (KMP_AFFINITY_CAPABLE()) {6336 6337#if KMP_GROUP_AFFINITY6338      // This checks to see if the initial affinity mask is equal6339      // to a single windows processor group.  If it is, then we do6340      // not respect the initial affinity mask and instead, use the6341      // entire machine.6342      bool exactly_one_group = false;6343      if (__kmp_num_proc_groups > 1) {6344        int group;6345        bool within_one_group;6346        // Get the initial affinity mask and determine if it is6347        // contained within a single group.6348        kmp_affin_mask_t *init_mask;6349        KMP_CPU_ALLOC(init_mask);6350        __kmp_get_system_affinity(init_mask, TRUE);6351        group = __kmp_get_proc_group(init_mask);6352        within_one_group = (group >= 0);6353        // If the initial affinity is within a single group,6354        // then determine if it is equal to that single group.6355        if (within_one_group) {6356          DWORD num_bits_in_group = __kmp_GetActiveProcessorCount(group);6357          DWORD num_bits_in_mask = 0;6358          for (int bit = init_mask->begin(); bit != init_mask->end();6359               bit = init_mask->next(bit))6360            num_bits_in_mask++;6361          exactly_one_group = (num_bits_in_group == num_bits_in_mask);6362        }6363        KMP_CPU_FREE(init_mask);6364      }6365 6366      // Handle the Win 64 group affinity stuff if there are multiple6367      // processor groups, or if the user requested it, and OMP 4.06368      // affinity is not in effect.6369      if (__kmp_num_proc_groups > 1 &&6370          __kmp_affinity.type == affinity_default &&6371          __kmp_nested_proc_bind.bind_types[0] == proc_bind_default) {6372        // Do not respect the initial processor affinity mask if it is assigned6373        // exactly one Windows Processor Group since this is interpreted as the6374        // default OS assignment. Not respecting the mask allows the runtime to6375        // use all the logical processors in all groups.6376        if (__kmp_affinity.flags.respect == affinity_respect_mask_default &&6377            exactly_one_group) {6378          __kmp_affinity.flags.respect = FALSE;6379        }6380        // Use compact affinity with anticipation of pinning to at least the6381        // group granularity since threads can only be bound to one group.6382        if (__kmp_affinity.type == affinity_default) {6383          __kmp_affinity.type = affinity_compact;6384          __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;6385        }6386        if (__kmp_hh_affinity.type == affinity_default)6387          __kmp_hh_affinity.type = affinity_compact;6388        if (__kmp_affinity_top_method == affinity_top_method_default)6389          __kmp_affinity_top_method = affinity_top_method_all;6390        if (__kmp_affinity.gran == KMP_HW_UNKNOWN)6391          __kmp_affinity.gran = KMP_HW_PROC_GROUP;6392        if (__kmp_hh_affinity.gran == KMP_HW_UNKNOWN)6393          __kmp_hh_affinity.gran = KMP_HW_PROC_GROUP;6394      } else6395 6396#endif /* KMP_GROUP_AFFINITY */6397 6398      {6399        if (__kmp_affinity.flags.respect == affinity_respect_mask_default) {6400#if KMP_GROUP_AFFINITY6401          if (__kmp_num_proc_groups > 1 && exactly_one_group) {6402            __kmp_affinity.flags.respect = FALSE;6403          } else6404#endif /* KMP_GROUP_AFFINITY */6405          {6406            __kmp_affinity.flags.respect = TRUE;6407          }6408        }6409        if ((__kmp_nested_proc_bind.bind_types[0] != proc_bind_intel) &&6410            (__kmp_nested_proc_bind.bind_types[0] != proc_bind_default)) {6411          if (__kmp_nested_proc_bind.bind_types[0] == proc_bind_false)6412            __kmp_affinity.type = affinity_none;6413          if (__kmp_affinity.type == affinity_default) {6414            __kmp_affinity.type = affinity_compact;6415            __kmp_affinity.flags.dups = FALSE;6416          }6417        } else if (__kmp_affinity.type == affinity_default) {6418#if KMP_MIC_SUPPORTED6419          if (__kmp_mic_type != non_mic) {6420            __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;6421          } else6422#endif6423          {6424            __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;6425          }6426#if KMP_MIC_SUPPORTED6427          if (__kmp_mic_type != non_mic) {6428            __kmp_affinity.type = affinity_scatter;6429          } else6430#endif6431          {6432            __kmp_affinity.type = affinity_none;6433          }6434        }6435        if (__kmp_hh_affinity.type == affinity_default)6436          __kmp_hh_affinity.type = affinity_none;6437        if ((__kmp_affinity.gran == KMP_HW_UNKNOWN) &&6438            (__kmp_affinity.gran_levels < 0)) {6439#if KMP_MIC_SUPPORTED6440          if (__kmp_mic_type != non_mic) {6441            __kmp_affinity.gran = KMP_HW_THREAD;6442          } else6443#endif6444          {6445            __kmp_affinity.gran = KMP_HW_CORE;6446          }6447        }6448        if ((__kmp_hh_affinity.gran == KMP_HW_UNKNOWN) &&6449            (__kmp_hh_affinity.gran_levels < 0)) {6450#if KMP_MIC_SUPPORTED6451          if (__kmp_mic_type != non_mic) {6452            __kmp_hh_affinity.gran = KMP_HW_THREAD;6453          } else6454#endif6455          {6456            __kmp_hh_affinity.gran = KMP_HW_CORE;6457          }6458        }6459        if (__kmp_affinity_top_method == affinity_top_method_default) {6460          __kmp_affinity_top_method = affinity_top_method_all;6461        }6462      }6463    } else {6464      // If affinity is disabled, then still need to assign topology method6465      // to attempt machine detection and affinity types6466      if (__kmp_affinity_top_method == affinity_top_method_default)6467        __kmp_affinity_top_method = affinity_top_method_all;6468      if (__kmp_affinity.type == affinity_default)6469        __kmp_affinity.type = affinity_disabled;6470      if (__kmp_hh_affinity.type == affinity_default)6471        __kmp_hh_affinity.type = affinity_disabled;6472    }6473 6474#ifdef KMP_DEBUG6475    for (const kmp_affinity_t *affinity : __kmp_affinities)6476      __kmp_print_affinity_settings(affinity);6477    KMP_DEBUG_ASSERT(__kmp_nested_proc_bind.bind_types[0] != proc_bind_default);6478    K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n",6479               __kmp_nested_proc_bind.bind_types[0]));6480#endif6481  }6482 6483#endif /* KMP_AFFINITY_SUPPORTED */6484 6485  // Post-initialization step: some env. vars need their value's further6486  // processing6487  if (string != NULL) { // kmp_set_defaults() was called6488    __kmp_aux_env_initialize(&block);6489  }6490 6491  __kmp_env_blk_free(&block);6492 6493  KMP_MB();6494 6495} // __kmp_env_initialize6496 6497void __kmp_env_print() {6498 6499  kmp_env_blk_t block;6500  int i;6501  kmp_str_buf_t buffer;6502 6503  __kmp_stg_init();6504  __kmp_str_buf_init(&buffer);6505 6506  __kmp_env_blk_init(&block, NULL);6507  __kmp_env_blk_sort(&block);6508 6509  // Print real environment values.6510  __kmp_str_buf_print(&buffer, "\n%s\n\n", KMP_I18N_STR(UserSettings));6511  for (i = 0; i < block.count; ++i) {6512    char const *name = block.vars[i].name;6513    char const *value = block.vars[i].value;6514    if ((KMP_STRLEN(name) > 4 && strncmp(name, "KMP_", 4) == 0) ||6515        strncmp(name, "OMP_", 4) == 06516#ifdef KMP_GOMP_COMPAT6517        || strncmp(name, "GOMP_", 5) == 06518#endif // KMP_GOMP_COMPAT6519    ) {6520      __kmp_str_buf_print(&buffer, "   %s=%s\n", name, value);6521    }6522  }6523  __kmp_str_buf_print(&buffer, "\n");6524 6525  // Print internal (effective) settings.6526  __kmp_str_buf_print(&buffer, "%s\n\n", KMP_I18N_STR(EffectiveSettings));6527  for (int i = 0; i < __kmp_stg_count; ++i) {6528    if (__kmp_stg_table[i].print != NULL) {6529      __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,6530                               __kmp_stg_table[i].data);6531    }6532  }6533 6534  __kmp_printf("%s", buffer.str);6535 6536  __kmp_env_blk_free(&block);6537  __kmp_str_buf_free(&buffer);6538 6539  __kmp_printf("\n");6540 6541} // __kmp_env_print6542 6543void __kmp_env_print_2() {6544  __kmp_display_env_impl(__kmp_display_env, __kmp_display_env_verbose);6545} // __kmp_env_print_26546 6547void __kmp_display_env_impl(int display_env, int display_env_verbose) {6548  kmp_env_blk_t block;6549  kmp_str_buf_t buffer;6550 6551  __kmp_env_format = 1;6552 6553  __kmp_stg_init();6554  __kmp_str_buf_init(&buffer);6555 6556  __kmp_env_blk_init(&block, NULL);6557  __kmp_env_blk_sort(&block);6558 6559  __kmp_str_buf_print(&buffer, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin));6560  __kmp_str_buf_print(&buffer, "   _OPENMP='%d'\n", __kmp_openmp_version);6561 6562  for (int i = 0; i < __kmp_stg_count; ++i) {6563    if (__kmp_stg_table[i].print != NULL &&6564        ((display_env && strncmp(__kmp_stg_table[i].name, "OMP_", 4) == 0) ||6565         display_env_verbose)) {6566      __kmp_stg_table[i].print(&buffer, __kmp_stg_table[i].name,6567                               __kmp_stg_table[i].data);6568    }6569  }6570 6571  __kmp_str_buf_print(&buffer, "%s\n", KMP_I18N_STR(DisplayEnvEnd));6572  __kmp_str_buf_print(&buffer, "\n");6573 6574  __kmp_printf("%s", buffer.str);6575 6576  __kmp_env_blk_free(&block);6577  __kmp_str_buf_free(&buffer);6578 6579  __kmp_printf("\n");6580}6581 6582#if OMPD_SUPPORT6583// Dump environment variables for OMPD6584void __kmp_env_dump() {6585 6586  kmp_env_blk_t block;6587  kmp_str_buf_t buffer, env, notdefined;6588 6589  __kmp_stg_init();6590  __kmp_str_buf_init(&buffer);6591  __kmp_str_buf_init(&env);6592  __kmp_str_buf_init(&notdefined);6593 6594  __kmp_env_blk_init(&block, NULL);6595  __kmp_env_blk_sort(&block);6596 6597  __kmp_str_buf_print(&notdefined, ": %s", KMP_I18N_STR(NotDefined));6598 6599  for (int i = 0; i < __kmp_stg_count; ++i) {6600    if (__kmp_stg_table[i].print == NULL)6601      continue;6602    __kmp_str_buf_clear(&env);6603    __kmp_stg_table[i].print(&env, __kmp_stg_table[i].name,6604                             __kmp_stg_table[i].data);6605    if (env.used < 4) // valid definition must have indents (3) and a new line6606      continue;6607    if (strstr(env.str, notdefined.str))6608      // normalize the string6609      __kmp_str_buf_print(&buffer, "%s=undefined\n", __kmp_stg_table[i].name);6610    else6611      __kmp_str_buf_cat(&buffer, env.str + 3, env.used - 3);6612  }6613 6614  ompd_env_block = (char *)__kmp_allocate(buffer.used + 1);6615  KMP_MEMCPY(ompd_env_block, buffer.str, buffer.used + 1);6616  ompd_env_block_size = (ompd_size_t)KMP_STRLEN(ompd_env_block);6617 6618  __kmp_env_blk_free(&block);6619  __kmp_str_buf_free(&buffer);6620  __kmp_str_buf_free(&env);6621  __kmp_str_buf_free(&notdefined);6622}6623#endif // OMPD_SUPPORT6624 6625// end of file6626