| /* |
| * kmp_settings.cpp -- Initialize environment variables |
| */ |
| |
| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "kmp.h" |
| #include "kmp_affinity.h" |
| #include "kmp_atomic.h" |
| #if KMP_USE_HIER_SCHED |
| #include "kmp_dispatch_hier.h" |
| #endif |
| #include "kmp_environment.h" |
| #include "kmp_i18n.h" |
| #include "kmp_io.h" |
| #include "kmp_itt.h" |
| #include "kmp_lock.h" |
| #include "kmp_settings.h" |
| #include "kmp_str.h" |
| #include "kmp_wrapper_getpid.h" |
| #include <ctype.h> // toupper() |
| |
| static int __kmp_env_toPrint(char const *name, int flag); |
| |
| bool __kmp_env_format = 0; // 0 - old format; 1 - new format |
| |
| // ----------------------------------------------------------------------------- |
| // Helper string functions. Subject to move to kmp_str. |
| |
| #ifdef USE_LOAD_BALANCE |
| static double __kmp_convert_to_double(char const *s) { |
| double result; |
| |
| if (KMP_SSCANF(s, "%lf", &result) < 1) { |
| result = 0.0; |
| } |
| |
| return result; |
| } |
| #endif |
| |
| #ifdef KMP_DEBUG |
| static unsigned int __kmp_readstr_with_sentinel(char *dest, char const *src, |
| size_t len, char sentinel) { |
| unsigned int i; |
| for (i = 0; i < len; i++) { |
| if ((*src == '\0') || (*src == sentinel)) { |
| break; |
| } |
| *(dest++) = *(src++); |
| } |
| *dest = '\0'; |
| return i; |
| } |
| #endif |
| |
| static int __kmp_match_with_sentinel(char const *a, char const *b, size_t len, |
| char sentinel) { |
| size_t l = 0; |
| |
| if (a == NULL) |
| a = ""; |
| if (b == NULL) |
| b = ""; |
| while (*a && *b && *b != sentinel) { |
| char ca = *a, cb = *b; |
| |
| if (ca >= 'a' && ca <= 'z') |
| ca -= 'a' - 'A'; |
| if (cb >= 'a' && cb <= 'z') |
| cb -= 'a' - 'A'; |
| if (ca != cb) |
| return FALSE; |
| ++l; |
| ++a; |
| ++b; |
| } |
| return l >= len; |
| } |
| |
| // Expected usage: |
| // token is the token to check for. |
| // buf is the string being parsed. |
| // *end returns the char after the end of the token. |
| // it is not modified unless a match occurs. |
| // |
| // Example 1: |
| // |
| // if (__kmp_match_str("token", buf, *end) { |
| // <do something> |
| // buf = end; |
| // } |
| // |
| // Example 2: |
| // |
| // if (__kmp_match_str("token", buf, *end) { |
| // char *save = **end; |
| // **end = sentinel; |
| // <use any of the __kmp*_with_sentinel() functions> |
| // **end = save; |
| // buf = end; |
| // } |
| |
| static int __kmp_match_str(char const *token, char const *buf, |
| const char **end) { |
| |
| KMP_ASSERT(token != NULL); |
| KMP_ASSERT(buf != NULL); |
| KMP_ASSERT(end != NULL); |
| |
| while (*token && *buf) { |
| char ct = *token, cb = *buf; |
| |
| if (ct >= 'a' && ct <= 'z') |
| ct -= 'a' - 'A'; |
| if (cb >= 'a' && cb <= 'z') |
| cb -= 'a' - 'A'; |
| if (ct != cb) |
| return FALSE; |
| ++token; |
| ++buf; |
| } |
| if (*token) { |
| return FALSE; |
| } |
| *end = buf; |
| return TRUE; |
| } |
| |
| #if KMP_OS_DARWIN |
| static size_t __kmp_round4k(size_t size) { |
| size_t _4k = 4 * 1024; |
| if (size & (_4k - 1)) { |
| size &= ~(_4k - 1); |
| if (size <= KMP_SIZE_T_MAX - _4k) { |
| size += _4k; // Round up if there is no overflow. |
| } |
| } |
| return size; |
| } // __kmp_round4k |
| #endif |
| |
| /* Here, multipliers are like __kmp_convert_to_seconds, but floating-point |
| values are allowed, and the return value is in milliseconds. The default |
| multiplier is milliseconds. Returns INT_MAX only if the value specified |
| matches "infinit*". Returns -1 if specified string is invalid. */ |
| int __kmp_convert_to_milliseconds(char const *data) { |
| int ret, nvalues, factor; |
| char mult, extra; |
| double value; |
| |
| if (data == NULL) |
| return (-1); |
| if (__kmp_str_match("infinit", -1, data)) |
| return (INT_MAX); |
| value = (double)0.0; |
| mult = '\0'; |
| nvalues = KMP_SSCANF(data, "%lf%c%c", &value, &mult, &extra); |
| if (nvalues < 1) |
| return (-1); |
| if (nvalues == 1) |
| mult = '\0'; |
| if (nvalues == 3) |
| return (-1); |
| |
| if (value < 0) |
| return (-1); |
| |
| switch (mult) { |
| case '\0': |
| /* default is milliseconds */ |
| factor = 1; |
| break; |
| case 's': |
| case 'S': |
| factor = 1000; |
| break; |
| case 'm': |
| case 'M': |
| factor = 1000 * 60; |
| break; |
| case 'h': |
| case 'H': |
| factor = 1000 * 60 * 60; |
| break; |
| case 'd': |
| case 'D': |
| factor = 1000 * 24 * 60 * 60; |
| break; |
| default: |
| return (-1); |
| } |
| |
| if (value >= ((INT_MAX - 1) / factor)) |
| ret = INT_MAX - 1; /* Don't allow infinite value here */ |
| else |
| ret = (int)(value * (double)factor); /* truncate to int */ |
| |
| return ret; |
| } |
| |
| static int __kmp_strcasecmp_with_sentinel(char const *a, char const *b, |
| char sentinel) { |
| if (a == NULL) |
| a = ""; |
| if (b == NULL) |
| b = ""; |
| while (*a && *b && *b != sentinel) { |
| char ca = *a, cb = *b; |
| |
| if (ca >= 'a' && ca <= 'z') |
| ca -= 'a' - 'A'; |
| if (cb >= 'a' && cb <= 'z') |
| cb -= 'a' - 'A'; |
| if (ca != cb) |
| return (int)(unsigned char)*a - (int)(unsigned char)*b; |
| ++a; |
| ++b; |
| } |
| return *a |
| ? (*b && *b != sentinel) |
| ? (int)(unsigned char)*a - (int)(unsigned char)*b |
| : 1 |
| : (*b && *b != sentinel) ? -1 : 0; |
| } |
| |
| // ============================================================================= |
| // Table structures and helper functions. |
| |
| typedef struct __kmp_setting kmp_setting_t; |
| typedef struct __kmp_stg_ss_data kmp_stg_ss_data_t; |
| typedef struct __kmp_stg_wp_data kmp_stg_wp_data_t; |
| typedef struct __kmp_stg_fr_data kmp_stg_fr_data_t; |
| |
| typedef void (*kmp_stg_parse_func_t)(char const *name, char const *value, |
| void *data); |
| typedef void (*kmp_stg_print_func_t)(kmp_str_buf_t *buffer, char const *name, |
| void *data); |
| |
| struct __kmp_setting { |
| char const *name; // Name of setting (environment variable). |
| kmp_stg_parse_func_t parse; // Parser function. |
| kmp_stg_print_func_t print; // Print function. |
| void *data; // Data passed to parser and printer. |
| int set; // Variable set during this "session" |
| // (__kmp_env_initialize() or kmp_set_defaults() call). |
| int defined; // Variable set in any "session". |
| }; // struct __kmp_setting |
| |
| struct __kmp_stg_ss_data { |
| size_t factor; // Default factor: 1 for KMP_STACKSIZE, 1024 for others. |
| kmp_setting_t **rivals; // Array of pointers to rivals (including itself). |
| }; // struct __kmp_stg_ss_data |
| |
| struct __kmp_stg_wp_data { |
| int omp; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY. |
| kmp_setting_t **rivals; // Array of pointers to rivals (including itself). |
| }; // struct __kmp_stg_wp_data |
| |
| struct __kmp_stg_fr_data { |
| int force; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION. |
| kmp_setting_t **rivals; // Array of pointers to rivals (including itself). |
| }; // struct __kmp_stg_fr_data |
| |
| static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found. |
| char const *name, // Name of variable. |
| char const *value, // Value of the variable. |
| kmp_setting_t **rivals // List of rival settings (must include current one). |
| ); |
| |
| // ----------------------------------------------------------------------------- |
| // Helper parse functions. |
| |
| static void __kmp_stg_parse_bool(char const *name, char const *value, |
| int *out) { |
| if (__kmp_str_match_true(value)) { |
| *out = TRUE; |
| } else if (__kmp_str_match_false(value)) { |
| *out = FALSE; |
| } else { |
| __kmp_msg(kmp_ms_warning, KMP_MSG(BadBoolValue, name, value), |
| KMP_HNT(ValidBoolValues), __kmp_msg_null); |
| } |
| } // __kmp_stg_parse_bool |
| |
| // placed here in order to use __kmp_round4k static function |
| void __kmp_check_stksize(size_t *val) { |
| // if system stack size is too big then limit the size for worker threads |
| if (*val > KMP_DEFAULT_STKSIZE * 16) // just a heuristics... |
| *val = KMP_DEFAULT_STKSIZE * 16; |
| if (*val < KMP_MIN_STKSIZE) |
| *val = KMP_MIN_STKSIZE; |
| if (*val > KMP_MAX_STKSIZE) |
| *val = KMP_MAX_STKSIZE; // dead code currently, but may work in future |
| #if KMP_OS_DARWIN |
| *val = __kmp_round4k(*val); |
| #endif // KMP_OS_DARWIN |
| } |
| |
| static void __kmp_stg_parse_size(char const *name, char const *value, |
| size_t size_min, size_t size_max, |
| int *is_specified, size_t *out, |
| size_t factor) { |
| char const *msg = NULL; |
| #if KMP_OS_DARWIN |
| size_min = __kmp_round4k(size_min); |
| size_max = __kmp_round4k(size_max); |
| #endif // KMP_OS_DARWIN |
| if (value) { |
| if (is_specified != NULL) { |
| *is_specified = 1; |
| } |
| __kmp_str_to_size(value, out, factor, &msg); |
| if (msg == NULL) { |
| if (*out > size_max) { |
| *out = size_max; |
| msg = KMP_I18N_STR(ValueTooLarge); |
| } else if (*out < size_min) { |
| *out = size_min; |
| msg = KMP_I18N_STR(ValueTooSmall); |
| } else { |
| #if KMP_OS_DARWIN |
| size_t round4k = __kmp_round4k(*out); |
| if (*out != round4k) { |
| *out = round4k; |
| msg = KMP_I18N_STR(NotMultiple4K); |
| } |
| #endif |
| } |
| } else { |
| // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to |
| // size_max silently. |
| if (*out < size_min) { |
| *out = size_max; |
| } else if (*out > size_max) { |
| *out = size_max; |
| } |
| } |
| if (msg != NULL) { |
| // Message is not empty. Print warning. |
| kmp_str_buf_t buf; |
| __kmp_str_buf_init(&buf); |
| __kmp_str_buf_print_size(&buf, *out); |
| KMP_WARNING(ParseSizeIntWarn, name, value, msg); |
| KMP_INFORM(Using_str_Value, name, buf.str); |
| __kmp_str_buf_free(&buf); |
| } |
| } |
| } // __kmp_stg_parse_size |
| |
| static void __kmp_stg_parse_str(char const *name, char const *value, |
| char **out) { |
| __kmp_str_free(out); |
| *out = __kmp_str_format("%s", value); |
| } // __kmp_stg_parse_str |
| |
| static void __kmp_stg_parse_int( |
| char const |
| *name, // I: Name of environment variable (used in warning messages). |
| char const *value, // I: Value of environment variable to parse. |
| int min, // I: Miminal allowed value. |
| int max, // I: Maximum allowed value. |
| int *out // O: Output (parsed) value. |
| ) { |
| char const *msg = NULL; |
| kmp_uint64 uint = *out; |
| __kmp_str_to_uint(value, &uint, &msg); |
| if (msg == NULL) { |
| if (uint < (unsigned int)min) { |
| msg = KMP_I18N_STR(ValueTooSmall); |
| uint = min; |
| } else if (uint > (unsigned int)max) { |
| msg = KMP_I18N_STR(ValueTooLarge); |
| uint = max; |
| } |
| } else { |
| // If overflow occurred msg contains error message and uint is very big. Cut |
| // tmp it to INT_MAX. |
| if (uint < (unsigned int)min) { |
| uint = min; |
| } else if (uint > (unsigned int)max) { |
| uint = max; |
| } |
| } |
| if (msg != NULL) { |
| // Message is not empty. Print warning. |
| kmp_str_buf_t buf; |
| KMP_WARNING(ParseSizeIntWarn, name, value, msg); |
| __kmp_str_buf_init(&buf); |
| __kmp_str_buf_print(&buf, "%" KMP_UINT64_SPEC "", uint); |
| KMP_INFORM(Using_uint64_Value, name, buf.str); |
| __kmp_str_buf_free(&buf); |
| } |
| *out = uint; |
| } // __kmp_stg_parse_int |
| |
| #if KMP_DEBUG_ADAPTIVE_LOCKS |
| static void __kmp_stg_parse_file(char const *name, char const *value, |
| const char *suffix, char **out) { |
| char buffer[256]; |
| char *t; |
| int hasSuffix; |
| __kmp_str_free(out); |
| t = (char *)strrchr(value, '.'); |
| hasSuffix = t && __kmp_str_eqf(t, suffix); |
| t = __kmp_str_format("%s%s", value, hasSuffix ? "" : suffix); |
| __kmp_expand_file_name(buffer, sizeof(buffer), t); |
| __kmp_str_free(&t); |
| *out = __kmp_str_format("%s", buffer); |
| } // __kmp_stg_parse_file |
| #endif |
| |
| #ifdef KMP_DEBUG |
| static char *par_range_to_print = NULL; |
| |
| static void __kmp_stg_parse_par_range(char const *name, char const *value, |
| int *out_range, char *out_routine, |
| char *out_file, int *out_lb, |
| int *out_ub) { |
| size_t len = KMP_STRLEN(value) + 1; |
| par_range_to_print = (char *)KMP_INTERNAL_MALLOC(len + 1); |
| KMP_STRNCPY_S(par_range_to_print, len + 1, value, len + 1); |
| __kmp_par_range = +1; |
| __kmp_par_range_lb = 0; |
| __kmp_par_range_ub = INT_MAX; |
| for (;;) { |
| unsigned int len; |
| if (*value == '\0') { |
| break; |
| } |
| if (!__kmp_strcasecmp_with_sentinel("routine", value, '=')) { |
| value = strchr(value, '=') + 1; |
| len = __kmp_readstr_with_sentinel(out_routine, value, |
| KMP_PAR_RANGE_ROUTINE_LEN - 1, ','); |
| if (len == 0) { |
| goto par_range_error; |
| } |
| value = strchr(value, ','); |
| if (value != NULL) { |
| value++; |
| } |
| continue; |
| } |
| if (!__kmp_strcasecmp_with_sentinel("filename", value, '=')) { |
| value = strchr(value, '=') + 1; |
| len = __kmp_readstr_with_sentinel(out_file, value, |
| KMP_PAR_RANGE_FILENAME_LEN - 1, ','); |
| if (len == 0) { |
| goto par_range_error; |
| } |
| value = strchr(value, ','); |
| if (value != NULL) { |
| value++; |
| } |
| continue; |
| } |
| if ((!__kmp_strcasecmp_with_sentinel("range", value, '=')) || |
| (!__kmp_strcasecmp_with_sentinel("incl_range", value, '='))) { |
| value = strchr(value, '=') + 1; |
| if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) { |
| goto par_range_error; |
| } |
| *out_range = +1; |
| value = strchr(value, ','); |
| if (value != NULL) { |
| value++; |
| } |
| continue; |
| } |
| if (!__kmp_strcasecmp_with_sentinel("excl_range", value, '=')) { |
| value = strchr(value, '=') + 1; |
| if (KMP_SSCANF(value, "%d:%d", out_lb, out_ub) != 2) { |
| goto par_range_error; |
| } |
| *out_range = -1; |
| value = strchr(value, ','); |
| if (value != NULL) { |
| value++; |
| } |
| continue; |
| } |
| par_range_error: |
| KMP_WARNING(ParRangeSyntax, name); |
| __kmp_par_range = 0; |
| break; |
| } |
| } // __kmp_stg_parse_par_range |
| #endif |
| |
| int __kmp_initial_threads_capacity(int req_nproc) { |
| int nth = 32; |
| |
| /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ), |
| * __kmp_max_nth) */ |
| if (nth < (4 * req_nproc)) |
| nth = (4 * req_nproc); |
| if (nth < (4 * __kmp_xproc)) |
| nth = (4 * __kmp_xproc); |
| |
| if (nth > __kmp_max_nth) |
| nth = __kmp_max_nth; |
| |
| return nth; |
| } |
| |
| int __kmp_default_tp_capacity(int req_nproc, int max_nth, |
| int all_threads_specified) { |
| int nth = 128; |
| |
| if (all_threads_specified) |
| return max_nth; |
| /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ), |
| * __kmp_max_nth ) */ |
| if (nth < (4 * req_nproc)) |
| nth = (4 * req_nproc); |
| if (nth < (4 * __kmp_xproc)) |
| nth = (4 * __kmp_xproc); |
| |
| if (nth > __kmp_max_nth) |
| nth = __kmp_max_nth; |
| |
| return nth; |
| } |
| |
| // ----------------------------------------------------------------------------- |
| // Helper print functions. |
| |
| static void __kmp_stg_print_bool(kmp_str_buf_t *buffer, char const *name, |
| int value) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_BOOL; |
| } else { |
| __kmp_str_buf_print(buffer, " %s=%s\n", name, value ? "true" : "false"); |
| } |
| } // __kmp_stg_print_bool |
| |
| static void __kmp_stg_print_int(kmp_str_buf_t *buffer, char const *name, |
| int value) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_INT; |
| } else { |
| __kmp_str_buf_print(buffer, " %s=%d\n", name, value); |
| } |
| } // __kmp_stg_print_int |
| |
| #if USE_ITT_BUILD && USE_ITT_NOTIFY |
| static void __kmp_stg_print_uint64(kmp_str_buf_t *buffer, char const *name, |
| kmp_uint64 value) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_UINT64; |
| } else { |
| __kmp_str_buf_print(buffer, " %s=%" KMP_UINT64_SPEC "\n", name, value); |
| } |
| } // __kmp_stg_print_uint64 |
| #endif |
| |
| static void __kmp_stg_print_str(kmp_str_buf_t *buffer, char const *name, |
| char const *value) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_STR; |
| } else { |
| __kmp_str_buf_print(buffer, " %s=%s\n", name, value); |
| } |
| } // __kmp_stg_print_str |
| |
| static void __kmp_stg_print_size(kmp_str_buf_t *buffer, char const *name, |
| size_t value) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME_EX(name); |
| __kmp_str_buf_print_size(buffer, value); |
| __kmp_str_buf_print(buffer, "'\n"); |
| } else { |
| __kmp_str_buf_print(buffer, " %s=", name); |
| __kmp_str_buf_print_size(buffer, value); |
| __kmp_str_buf_print(buffer, "\n"); |
| return; |
| } |
| } // __kmp_stg_print_size |
| |
| // ============================================================================= |
| // Parse and print functions. |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS |
| |
| static void __kmp_stg_parse_device_thread_limit(char const *name, |
| char const *value, void *data) { |
| kmp_setting_t **rivals = (kmp_setting_t **)data; |
| int rc; |
| if (strcmp(name, "KMP_ALL_THREADS") == 0) { |
| KMP_INFORM(EnvVarDeprecated, name, "KMP_DEVICE_THREAD_LIMIT"); |
| } |
| rc = __kmp_stg_check_rivals(name, value, rivals); |
| if (rc) { |
| return; |
| } |
| if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) { |
| __kmp_max_nth = __kmp_xproc; |
| __kmp_allThreadsSpecified = 1; |
| } else { |
| __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_max_nth); |
| __kmp_allThreadsSpecified = 0; |
| } |
| K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth)); |
| |
| } // __kmp_stg_parse_device_thread_limit |
| |
| static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_max_nth); |
| } // __kmp_stg_print_device_thread_limit |
| |
| // ----------------------------------------------------------------------------- |
| // OMP_THREAD_LIMIT |
| static void __kmp_stg_parse_thread_limit(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_cg_max_nth); |
| K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth)); |
| |
| } // __kmp_stg_parse_thread_limit |
| |
| static void __kmp_stg_print_thread_limit(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_cg_max_nth); |
| } // __kmp_stg_print_thread_limit |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_TEAMS_THREAD_LIMIT |
| static void __kmp_stg_parse_teams_thread_limit(char const *name, |
| char const *value, void *data) { |
| __kmp_stg_parse_int(name, value, 1, __kmp_sys_max_nth, &__kmp_teams_max_nth); |
| } // __kmp_stg_teams_thread_limit |
| |
| static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_teams_max_nth); |
| } // __kmp_stg_print_teams_thread_limit |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_USE_YIELD |
| static void __kmp_stg_parse_use_yield(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, 0, 2, &__kmp_use_yield); |
| __kmp_use_yield_exp_set = 1; |
| } // __kmp_stg_parse_use_yield |
| |
| static void __kmp_stg_print_use_yield(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_use_yield); |
| } // __kmp_stg_print_use_yield |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_BLOCKTIME |
| |
| static void __kmp_stg_parse_blocktime(char const *name, char const *value, |
| void *data) { |
| __kmp_dflt_blocktime = __kmp_convert_to_milliseconds(value); |
| if (__kmp_dflt_blocktime < 0) { |
| __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME; |
| __kmp_msg(kmp_ms_warning, KMP_MSG(InvalidValue, name, value), |
| __kmp_msg_null); |
| KMP_INFORM(Using_int_Value, name, __kmp_dflt_blocktime); |
| __kmp_env_blocktime = FALSE; // Revert to default as if var not set. |
| } else { |
| if (__kmp_dflt_blocktime < KMP_MIN_BLOCKTIME) { |
| __kmp_dflt_blocktime = KMP_MIN_BLOCKTIME; |
| __kmp_msg(kmp_ms_warning, KMP_MSG(SmallValue, name, value), |
| __kmp_msg_null); |
| KMP_INFORM(MinValueUsing, name, __kmp_dflt_blocktime); |
| } else if (__kmp_dflt_blocktime > KMP_MAX_BLOCKTIME) { |
| __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME; |
| __kmp_msg(kmp_ms_warning, KMP_MSG(LargeValue, name, value), |
| __kmp_msg_null); |
| KMP_INFORM(MaxValueUsing, name, __kmp_dflt_blocktime); |
| } |
| __kmp_env_blocktime = TRUE; // KMP_BLOCKTIME was specified. |
| } |
| #if KMP_USE_MONITOR |
| // calculate number of monitor thread wakeup intervals corresponding to |
| // blocktime. |
| __kmp_monitor_wakeups = |
| KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups); |
| __kmp_bt_intervals = |
| KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime, __kmp_monitor_wakeups); |
| #endif |
| K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime)); |
| if (__kmp_env_blocktime) { |
| K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime)); |
| } |
| } // __kmp_stg_parse_blocktime |
| |
| static void __kmp_stg_print_blocktime(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_dflt_blocktime); |
| } // __kmp_stg_print_blocktime |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_DUPLICATE_LIB_OK |
| |
| static void __kmp_stg_parse_duplicate_lib_ok(char const *name, |
| char const *value, void *data) { |
| /* actually this variable is not supported, put here for compatibility with |
| earlier builds and for static/dynamic combination */ |
| __kmp_stg_parse_bool(name, value, &__kmp_duplicate_library_ok); |
| } // __kmp_stg_parse_duplicate_lib_ok |
| |
| static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_bool(buffer, name, __kmp_duplicate_library_ok); |
| } // __kmp_stg_print_duplicate_lib_ok |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_INHERIT_FP_CONTROL |
| |
| #if KMP_ARCH_X86 || KMP_ARCH_X86_64 |
| |
| static void __kmp_stg_parse_inherit_fp_control(char const *name, |
| char const *value, void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_inherit_fp_control); |
| } // __kmp_stg_parse_inherit_fp_control |
| |
| static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| #if KMP_DEBUG |
| __kmp_stg_print_bool(buffer, name, __kmp_inherit_fp_control); |
| #endif /* KMP_DEBUG */ |
| } // __kmp_stg_print_inherit_fp_control |
| |
| #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */ |
| |
| // Used for OMP_WAIT_POLICY |
| static char const *blocktime_str = NULL; |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_LIBRARY, OMP_WAIT_POLICY |
| |
| static void __kmp_stg_parse_wait_policy(char const *name, char const *value, |
| void *data) { |
| |
| kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data; |
| int rc; |
| |
| rc = __kmp_stg_check_rivals(name, value, wait->rivals); |
| if (rc) { |
| return; |
| } |
| |
| if (wait->omp) { |
| if (__kmp_str_match("ACTIVE", 1, value)) { |
| __kmp_library = library_turnaround; |
| if (blocktime_str == NULL) { |
| // KMP_BLOCKTIME not specified, so set default to "infinite". |
| __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME; |
| } |
| } else if (__kmp_str_match("PASSIVE", 1, value)) { |
| __kmp_library = library_throughput; |
| if (blocktime_str == NULL) { |
| // KMP_BLOCKTIME not specified, so set default to 0. |
| __kmp_dflt_blocktime = 0; |
| } |
| } else { |
| KMP_WARNING(StgInvalidValue, name, value); |
| } |
| } else { |
| if (__kmp_str_match("serial", 1, value)) { /* S */ |
| __kmp_library = library_serial; |
| } else if (__kmp_str_match("throughput", 2, value)) { /* TH */ |
| __kmp_library = library_throughput; |
| if (blocktime_str == NULL) { |
| // KMP_BLOCKTIME not specified, so set default to 0. |
| __kmp_dflt_blocktime = 0; |
| } |
| } else if (__kmp_str_match("turnaround", 2, value)) { /* TU */ |
| __kmp_library = library_turnaround; |
| } else if (__kmp_str_match("dedicated", 1, value)) { /* D */ |
| __kmp_library = library_turnaround; |
| } else if (__kmp_str_match("multiuser", 1, value)) { /* M */ |
| __kmp_library = library_throughput; |
| if (blocktime_str == NULL) { |
| // KMP_BLOCKTIME not specified, so set default to 0. |
| __kmp_dflt_blocktime = 0; |
| } |
| } else { |
| KMP_WARNING(StgInvalidValue, name, value); |
| } |
| } |
| } // __kmp_stg_parse_wait_policy |
| |
| static void __kmp_stg_print_wait_policy(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| |
| kmp_stg_wp_data_t *wait = (kmp_stg_wp_data_t *)data; |
| char const *value = NULL; |
| |
| if (wait->omp) { |
| switch (__kmp_library) { |
| case library_turnaround: { |
| value = "ACTIVE"; |
| } break; |
| case library_throughput: { |
| value = "PASSIVE"; |
| } break; |
| } |
| } else { |
| switch (__kmp_library) { |
| case library_serial: { |
| value = "serial"; |
| } break; |
| case library_turnaround: { |
| value = "turnaround"; |
| } break; |
| case library_throughput: { |
| value = "throughput"; |
| } break; |
| } |
| } |
| if (value != NULL) { |
| __kmp_stg_print_str(buffer, name, value); |
| } |
| |
| } // __kmp_stg_print_wait_policy |
| |
| #if KMP_USE_MONITOR |
| // ----------------------------------------------------------------------------- |
| // KMP_MONITOR_STACKSIZE |
| |
| static void __kmp_stg_parse_monitor_stacksize(char const *name, |
| char const *value, void *data) { |
| __kmp_stg_parse_size(name, value, __kmp_sys_min_stksize, KMP_MAX_STKSIZE, |
| NULL, &__kmp_monitor_stksize, 1); |
| } // __kmp_stg_parse_monitor_stacksize |
| |
| static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| if (__kmp_env_format) { |
| if (__kmp_monitor_stksize > 0) |
| KMP_STR_BUF_PRINT_NAME_EX(name); |
| else |
| KMP_STR_BUF_PRINT_NAME; |
| } else { |
| __kmp_str_buf_print(buffer, " %s", name); |
| } |
| if (__kmp_monitor_stksize > 0) { |
| __kmp_str_buf_print_size(buffer, __kmp_monitor_stksize); |
| } else { |
| __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); |
| } |
| if (__kmp_env_format && __kmp_monitor_stksize) { |
| __kmp_str_buf_print(buffer, "'\n"); |
| } |
| } // __kmp_stg_print_monitor_stacksize |
| #endif // KMP_USE_MONITOR |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_SETTINGS |
| |
| static void __kmp_stg_parse_settings(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_settings); |
| } // __kmp_stg_parse_settings |
| |
| static void __kmp_stg_print_settings(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_bool(buffer, name, __kmp_settings); |
| } // __kmp_stg_print_settings |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_STACKPAD |
| |
| static void __kmp_stg_parse_stackpad(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, // Env var name |
| value, // Env var value |
| KMP_MIN_STKPADDING, // Min value |
| KMP_MAX_STKPADDING, // Max value |
| &__kmp_stkpadding // Var to initialize |
| ); |
| } // __kmp_stg_parse_stackpad |
| |
| static void __kmp_stg_print_stackpad(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_stkpadding); |
| } // __kmp_stg_print_stackpad |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_STACKOFFSET |
| |
| static void __kmp_stg_parse_stackoffset(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_size(name, // Env var name |
| value, // Env var value |
| KMP_MIN_STKOFFSET, // Min value |
| KMP_MAX_STKOFFSET, // Max value |
| NULL, // |
| &__kmp_stkoffset, // Var to initialize |
| 1); |
| } // __kmp_stg_parse_stackoffset |
| |
| static void __kmp_stg_print_stackoffset(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_size(buffer, name, __kmp_stkoffset); |
| } // __kmp_stg_print_stackoffset |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE |
| |
| static void __kmp_stg_parse_stacksize(char const *name, char const *value, |
| void *data) { |
| |
| kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data; |
| int rc; |
| |
| rc = __kmp_stg_check_rivals(name, value, stacksize->rivals); |
| if (rc) { |
| return; |
| } |
| __kmp_stg_parse_size(name, // Env var name |
| value, // Env var value |
| __kmp_sys_min_stksize, // Min value |
| KMP_MAX_STKSIZE, // Max value |
| &__kmp_env_stksize, // |
| &__kmp_stksize, // Var to initialize |
| stacksize->factor); |
| |
| } // __kmp_stg_parse_stacksize |
| |
| // This function is called for printing both KMP_STACKSIZE (factor is 1) and |
| // OMP_STACKSIZE (factor is 1024). Currently it is not possible to print |
| // OMP_STACKSIZE value in bytes. We can consider adding this possibility by a |
| // customer request in future. |
| static void __kmp_stg_print_stacksize(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| kmp_stg_ss_data_t *stacksize = (kmp_stg_ss_data_t *)data; |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME_EX(name); |
| __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024) |
| ? __kmp_stksize / stacksize->factor |
| : __kmp_stksize); |
| __kmp_str_buf_print(buffer, "'\n"); |
| } else { |
| __kmp_str_buf_print(buffer, " %s=", name); |
| __kmp_str_buf_print_size(buffer, (__kmp_stksize % 1024) |
| ? __kmp_stksize / stacksize->factor |
| : __kmp_stksize); |
| __kmp_str_buf_print(buffer, "\n"); |
| } |
| } // __kmp_stg_print_stacksize |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_VERSION |
| |
| static void __kmp_stg_parse_version(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_version); |
| } // __kmp_stg_parse_version |
| |
| static void __kmp_stg_print_version(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_bool(buffer, name, __kmp_version); |
| } // __kmp_stg_print_version |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_WARNINGS |
| |
| static void __kmp_stg_parse_warnings(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_generate_warnings); |
| if (__kmp_generate_warnings != kmp_warnings_off) { |
| // AC: only 0/1 values documented, so reset to explicit to distinguish from |
| // default setting |
| __kmp_generate_warnings = kmp_warnings_explicit; |
| } |
| } // __kmp_stg_parse_warnings |
| |
| static void __kmp_stg_print_warnings(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| // AC: TODO: change to print_int? (needs documentation change) |
| __kmp_stg_print_bool(buffer, name, __kmp_generate_warnings); |
| } // __kmp_stg_print_warnings |
| |
| // ----------------------------------------------------------------------------- |
| // OMP_NESTED, OMP_NUM_THREADS |
| |
| static void __kmp_stg_parse_nested(char const *name, char const *value, |
| void *data) { |
| int nested; |
| KMP_INFORM(EnvVarDeprecated, name, "OMP_MAX_ACTIVE_LEVELS"); |
| __kmp_stg_parse_bool(name, value, &nested); |
| if (nested) { |
| if (!__kmp_dflt_max_active_levels_set) |
| __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; |
| } else { // nesting explicitly turned off |
| __kmp_dflt_max_active_levels = 1; |
| __kmp_dflt_max_active_levels_set = true; |
| } |
| } // __kmp_stg_parse_nested |
| |
| static void __kmp_stg_print_nested(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME; |
| } else { |
| __kmp_str_buf_print(buffer, " %s", name); |
| } |
| __kmp_str_buf_print(buffer, ": deprecated; max-active-levels-var=%d\n", |
| __kmp_dflt_max_active_levels); |
| } // __kmp_stg_print_nested |
| |
| static void __kmp_parse_nested_num_threads(const char *var, const char *env, |
| kmp_nested_nthreads_t *nth_array) { |
| const char *next = env; |
| const char *scan = next; |
| |
| int total = 0; // Count elements that were set. It'll be used as an array size |
| int prev_comma = FALSE; // For correct processing sequential commas |
| |
| // Count the number of values in the env. var string |
| for (;;) { |
| SKIP_WS(next); |
| |
| if (*next == '\0') { |
| break; |
| } |
| // Next character is not an integer or not a comma => end of list |
| if (((*next < '0') || (*next > '9')) && (*next != ',')) { |
| KMP_WARNING(NthSyntaxError, var, env); |
| return; |
| } |
| // The next character is ',' |
| if (*next == ',') { |
| // ',' is the fisrt character |
| if (total == 0 || prev_comma) { |
| total++; |
| } |
| prev_comma = TRUE; |
| next++; // skip ',' |
| SKIP_WS(next); |
| } |
| // Next character is a digit |
| if (*next >= '0' && *next <= '9') { |
| prev_comma = FALSE; |
| SKIP_DIGITS(next); |
| total++; |
| const char *tmp = next; |
| SKIP_WS(tmp); |
| if ((*next == ' ' || *next == '\t') && (*tmp >= '0' && *tmp <= '9')) { |
| KMP_WARNING(NthSpacesNotAllowed, var, env); |
| return; |
| } |
| } |
| } |
| if (!__kmp_dflt_max_active_levels_set && total > 1) |
| __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; |
| KMP_DEBUG_ASSERT(total > 0); |
| if (total <= 0) { |
| KMP_WARNING(NthSyntaxError, var, env); |
| return; |
| } |
| |
| // Check if the nested nthreads array exists |
| if (!nth_array->nth) { |
| // Allocate an array of double size |
| nth_array->nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total * 2); |
| if (nth_array->nth == NULL) { |
| KMP_FATAL(MemoryAllocFailed); |
| } |
| nth_array->size = total * 2; |
| } else { |
| if (nth_array->size < total) { |
| // Increase the array size |
| do { |
| nth_array->size *= 2; |
| } while (nth_array->size < total); |
| |
| nth_array->nth = (int *)KMP_INTERNAL_REALLOC( |
| nth_array->nth, sizeof(int) * nth_array->size); |
| if (nth_array->nth == NULL) { |
| KMP_FATAL(MemoryAllocFailed); |
| } |
| } |
| } |
| nth_array->used = total; |
| int i = 0; |
| |
| prev_comma = FALSE; |
| total = 0; |
| // Save values in the array |
| for (;;) { |
| SKIP_WS(scan); |
| if (*scan == '\0') { |
| break; |
| } |
| // The next character is ',' |
| if (*scan == ',') { |
| // ',' in the beginning of the list |
| if (total == 0) { |
| // The value is supposed to be equal to __kmp_avail_proc but it is |
| // unknown at the moment. |
| // So let's put a placeholder (#threads = 0) to correct it later. |
| nth_array->nth[i++] = 0; |
| total++; |
| } else if (prev_comma) { |
| // Num threads is inherited from the previous level |
| nth_array->nth[i] = nth_array->nth[i - 1]; |
| i++; |
| total++; |
| } |
| prev_comma = TRUE; |
| scan++; // skip ',' |
| SKIP_WS(scan); |
| } |
| // Next character is a digit |
| if (*scan >= '0' && *scan <= '9') { |
| int num; |
| const char *buf = scan; |
| char const *msg = NULL; |
| prev_comma = FALSE; |
| SKIP_DIGITS(scan); |
| total++; |
| |
| num = __kmp_str_to_int(buf, *scan); |
| if (num < KMP_MIN_NTH) { |
| msg = KMP_I18N_STR(ValueTooSmall); |
| num = KMP_MIN_NTH; |
| } else if (num > __kmp_sys_max_nth) { |
| msg = KMP_I18N_STR(ValueTooLarge); |
| num = __kmp_sys_max_nth; |
| } |
| if (msg != NULL) { |
| // Message is not empty. Print warning. |
| KMP_WARNING(ParseSizeIntWarn, var, env, msg); |
| KMP_INFORM(Using_int_Value, var, num); |
| } |
| nth_array->nth[i++] = num; |
| } |
| } |
| } |
| |
| static void __kmp_stg_parse_num_threads(char const *name, char const *value, |
| void *data) { |
| // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers! |
| if (!__kmp_strcasecmp_with_sentinel("all", value, 0)) { |
| // The array of 1 element |
| __kmp_nested_nth.nth = (int *)KMP_INTERNAL_MALLOC(sizeof(int)); |
| __kmp_nested_nth.size = __kmp_nested_nth.used = 1; |
| __kmp_nested_nth.nth[0] = __kmp_dflt_team_nth = __kmp_dflt_team_nth_ub = |
| __kmp_xproc; |
| } else { |
| __kmp_parse_nested_num_threads(name, value, &__kmp_nested_nth); |
| if (__kmp_nested_nth.nth) { |
| __kmp_dflt_team_nth = __kmp_nested_nth.nth[0]; |
| if (__kmp_dflt_team_nth_ub < __kmp_dflt_team_nth) { |
| __kmp_dflt_team_nth_ub = __kmp_dflt_team_nth; |
| } |
| } |
| } |
| K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth)); |
| } // __kmp_stg_parse_num_threads |
| |
| static void __kmp_stg_print_num_threads(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME; |
| } else { |
| __kmp_str_buf_print(buffer, " %s", name); |
| } |
| if (__kmp_nested_nth.used) { |
| kmp_str_buf_t buf; |
| __kmp_str_buf_init(&buf); |
| for (int i = 0; i < __kmp_nested_nth.used; i++) { |
| __kmp_str_buf_print(&buf, "%d", __kmp_nested_nth.nth[i]); |
| if (i < __kmp_nested_nth.used - 1) { |
| __kmp_str_buf_print(&buf, ","); |
| } |
| } |
| __kmp_str_buf_print(buffer, "='%s'\n", buf.str); |
| __kmp_str_buf_free(&buf); |
| } else { |
| __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); |
| } |
| } // __kmp_stg_print_num_threads |
| |
| // ----------------------------------------------------------------------------- |
| // OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS, |
| |
| static void __kmp_stg_parse_tasking(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, 0, (int)tskm_max, |
| (int *)&__kmp_tasking_mode); |
| } // __kmp_stg_parse_tasking |
| |
| static void __kmp_stg_print_tasking(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_tasking_mode); |
| } // __kmp_stg_print_tasking |
| |
| static void __kmp_stg_parse_task_stealing(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, 0, 1, |
| (int *)&__kmp_task_stealing_constraint); |
| } // __kmp_stg_parse_task_stealing |
| |
| static void __kmp_stg_print_task_stealing(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_task_stealing_constraint); |
| } // __kmp_stg_print_task_stealing |
| |
| static void __kmp_stg_parse_max_active_levels(char const *name, |
| char const *value, void *data) { |
| kmp_uint64 tmp_dflt = 0; |
| char const *msg = NULL; |
| if (!__kmp_dflt_max_active_levels_set) { |
| // Don't overwrite __kmp_dflt_max_active_levels if we get an invalid setting |
| __kmp_str_to_uint(value, &tmp_dflt, &msg); |
| if (msg != NULL) { // invalid setting; print warning and ignore |
| KMP_WARNING(ParseSizeIntWarn, name, value, msg); |
| } else if (tmp_dflt > KMP_MAX_ACTIVE_LEVELS_LIMIT) { |
| // invalid setting; print warning and ignore |
| msg = KMP_I18N_STR(ValueTooLarge); |
| KMP_WARNING(ParseSizeIntWarn, name, value, msg); |
| } else { // valid setting |
| __kmp_dflt_max_active_levels = tmp_dflt; |
| __kmp_dflt_max_active_levels_set = true; |
| } |
| } |
| } // __kmp_stg_parse_max_active_levels |
| |
| static void __kmp_stg_print_max_active_levels(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_dflt_max_active_levels); |
| } // __kmp_stg_print_max_active_levels |
| |
| // ----------------------------------------------------------------------------- |
| // OpenMP 4.0: OMP_DEFAULT_DEVICE |
| static void __kmp_stg_parse_default_device(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, 0, KMP_MAX_DEFAULT_DEVICE_LIMIT, |
| &__kmp_default_device); |
| } // __kmp_stg_parse_default_device |
| |
| static void __kmp_stg_print_default_device(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_default_device); |
| } // __kmp_stg_print_default_device |
| |
| // ----------------------------------------------------------------------------- |
| // OpenMP 5.0: OMP_TARGET_OFFLOAD |
| static void __kmp_stg_parse_target_offload(char const *name, char const *value, |
| void *data) { |
| const char *next = value; |
| const char *scan = next; |
| |
| __kmp_target_offload = tgt_default; |
| SKIP_WS(next); |
| if (*next == '\0') |
| return; |
| scan = next; |
| if (!__kmp_strcasecmp_with_sentinel("mandatory", scan, 0)) { |
| __kmp_target_offload = tgt_mandatory; |
| } else if (!__kmp_strcasecmp_with_sentinel("disabled", scan, 0)) { |
| __kmp_target_offload = tgt_disabled; |
| } else if (!__kmp_strcasecmp_with_sentinel("default", scan, 0)) { |
| __kmp_target_offload = tgt_default; |
| } else { |
| KMP_WARNING(SyntaxErrorUsing, name, "DEFAULT"); |
| } |
| |
| } // __kmp_stg_parse_target_offload |
| |
| static void __kmp_stg_print_target_offload(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| const char *value = NULL; |
| if (__kmp_target_offload == tgt_default) |
| value = "DEFAULT"; |
| else if (__kmp_target_offload == tgt_mandatory) |
| value = "MANDATORY"; |
| else if (__kmp_target_offload == tgt_disabled) |
| value = "DISABLED"; |
| KMP_DEBUG_ASSERT(value); |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME; |
| } else { |
| __kmp_str_buf_print(buffer, " %s", name); |
| } |
| __kmp_str_buf_print(buffer, "=%s\n", value); |
| } // __kmp_stg_print_target_offload |
| |
| // ----------------------------------------------------------------------------- |
| // OpenMP 4.5: OMP_MAX_TASK_PRIORITY |
| static void __kmp_stg_parse_max_task_priority(char const *name, |
| char const *value, void *data) { |
| __kmp_stg_parse_int(name, value, 0, KMP_MAX_TASK_PRIORITY_LIMIT, |
| &__kmp_max_task_priority); |
| } // __kmp_stg_parse_max_task_priority |
| |
| static void __kmp_stg_print_max_task_priority(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_max_task_priority); |
| } // __kmp_stg_print_max_task_priority |
| |
| // KMP_TASKLOOP_MIN_TASKS |
| // taskloop threashold to switch from recursive to linear tasks creation |
| static void __kmp_stg_parse_taskloop_min_tasks(char const *name, |
| char const *value, void *data) { |
| int tmp; |
| __kmp_stg_parse_int(name, value, 0, INT_MAX, &tmp); |
| __kmp_taskloop_min_tasks = tmp; |
| } // __kmp_stg_parse_taskloop_min_tasks |
| |
| static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_taskloop_min_tasks); |
| } // __kmp_stg_print_taskloop_min_tasks |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_DISP_NUM_BUFFERS |
| static void __kmp_stg_parse_disp_buffers(char const *name, char const *value, |
| void *data) { |
| if (TCR_4(__kmp_init_serial)) { |
| KMP_WARNING(EnvSerialWarn, name); |
| return; |
| } // read value before serial initialization only |
| __kmp_stg_parse_int(name, value, 1, KMP_MAX_NTH, &__kmp_dispatch_num_buffers); |
| } // __kmp_stg_parse_disp_buffers |
| |
| static void __kmp_stg_print_disp_buffers(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_dispatch_num_buffers); |
| } // __kmp_stg_print_disp_buffers |
| |
| #if KMP_NESTED_HOT_TEAMS |
| // ----------------------------------------------------------------------------- |
| // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE |
| |
| static void __kmp_stg_parse_hot_teams_level(char const *name, char const *value, |
| void *data) { |
| if (TCR_4(__kmp_init_parallel)) { |
| KMP_WARNING(EnvParallelWarn, name); |
| return; |
| } // read value before first parallel only |
| __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT, |
| &__kmp_hot_teams_max_level); |
| } // __kmp_stg_parse_hot_teams_level |
| |
| static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_hot_teams_max_level); |
| } // __kmp_stg_print_hot_teams_level |
| |
| static void __kmp_stg_parse_hot_teams_mode(char const *name, char const *value, |
| void *data) { |
| if (TCR_4(__kmp_init_parallel)) { |
| KMP_WARNING(EnvParallelWarn, name); |
| return; |
| } // read value before first parallel only |
| __kmp_stg_parse_int(name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT, |
| &__kmp_hot_teams_mode); |
| } // __kmp_stg_parse_hot_teams_mode |
| |
| static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_hot_teams_mode); |
| } // __kmp_stg_print_hot_teams_mode |
| |
| #endif // KMP_NESTED_HOT_TEAMS |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_HANDLE_SIGNALS |
| |
| #if KMP_HANDLE_SIGNALS |
| |
| static void __kmp_stg_parse_handle_signals(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_handle_signals); |
| } // __kmp_stg_parse_handle_signals |
| |
| static void __kmp_stg_print_handle_signals(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_bool(buffer, name, __kmp_handle_signals); |
| } // __kmp_stg_print_handle_signals |
| |
| #endif // KMP_HANDLE_SIGNALS |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG |
| |
| #ifdef KMP_DEBUG |
| |
| #define KMP_STG_X_DEBUG(x) \ |
| static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \ |
| void *data) { \ |
| __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug); \ |
| } /* __kmp_stg_parse_x_debug */ \ |
| static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer, \ |
| char const *name, void *data) { \ |
| __kmp_stg_print_int(buffer, name, kmp_##x##_debug); \ |
| } /* __kmp_stg_print_x_debug */ |
| |
| KMP_STG_X_DEBUG(a) |
| KMP_STG_X_DEBUG(b) |
| KMP_STG_X_DEBUG(c) |
| KMP_STG_X_DEBUG(d) |
| KMP_STG_X_DEBUG(e) |
| KMP_STG_X_DEBUG(f) |
| |
| #undef KMP_STG_X_DEBUG |
| |
| static void __kmp_stg_parse_debug(char const *name, char const *value, |
| void *data) { |
| int debug = 0; |
| __kmp_stg_parse_int(name, value, 0, INT_MAX, &debug); |
| if (kmp_a_debug < debug) { |
| kmp_a_debug = debug; |
| } |
| if (kmp_b_debug < debug) { |
| kmp_b_debug = debug; |
| } |
| if (kmp_c_debug < debug) { |
| kmp_c_debug = debug; |
| } |
| if (kmp_d_debug < debug) { |
| kmp_d_debug = debug; |
| } |
| if (kmp_e_debug < debug) { |
| kmp_e_debug = debug; |
| } |
| if (kmp_f_debug < debug) { |
| kmp_f_debug = debug; |
| } |
| } // __kmp_stg_parse_debug |
| |
| static void __kmp_stg_parse_debug_buf(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_debug_buf); |
| // !!! TODO: Move buffer initialization of of this file! It may works |
| // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or |
| // KMP_DEBUG_BUF_CHARS. |
| if (__kmp_debug_buf) { |
| int i; |
| int elements = __kmp_debug_buf_lines * __kmp_debug_buf_chars; |
| |
| /* allocate and initialize all entries in debug buffer to empty */ |
| __kmp_debug_buffer = (char *)__kmp_page_allocate(elements * sizeof(char)); |
| for (i = 0; i < elements; i += __kmp_debug_buf_chars) |
| __kmp_debug_buffer[i] = '\0'; |
| |
| __kmp_debug_count = 0; |
| } |
| K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf)); |
| } // __kmp_stg_parse_debug_buf |
| |
| static void __kmp_stg_print_debug_buf(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_bool(buffer, name, __kmp_debug_buf); |
| } // __kmp_stg_print_debug_buf |
| |
| static void __kmp_stg_parse_debug_buf_atomic(char const *name, |
| char const *value, void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_debug_buf_atomic); |
| } // __kmp_stg_parse_debug_buf_atomic |
| |
| static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_bool(buffer, name, __kmp_debug_buf_atomic); |
| } // __kmp_stg_print_debug_buf_atomic |
| |
| static void __kmp_stg_parse_debug_buf_chars(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_CHARS_MIN, INT_MAX, |
| &__kmp_debug_buf_chars); |
| } // __kmp_stg_debug_parse_buf_chars |
| |
| static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_debug_buf_chars); |
| } // __kmp_stg_print_debug_buf_chars |
| |
| static void __kmp_stg_parse_debug_buf_lines(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, KMP_DEBUG_BUF_LINES_MIN, INT_MAX, |
| &__kmp_debug_buf_lines); |
| } // __kmp_stg_parse_debug_buf_lines |
| |
| static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_debug_buf_lines); |
| } // __kmp_stg_print_debug_buf_lines |
| |
| static void __kmp_stg_parse_diag(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_diag); |
| } // __kmp_stg_parse_diag |
| |
| static void __kmp_stg_print_diag(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_int(buffer, name, kmp_diag); |
| } // __kmp_stg_print_diag |
| |
| #endif // KMP_DEBUG |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_ALIGN_ALLOC |
| |
| static void __kmp_stg_parse_align_alloc(char const *name, char const *value, |
| void *data) { |
| __kmp_stg_parse_size(name, value, CACHE_LINE, INT_MAX, NULL, |
| &__kmp_align_alloc, 1); |
| } // __kmp_stg_parse_align_alloc |
| |
| static void __kmp_stg_print_align_alloc(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_size(buffer, name, __kmp_align_alloc); |
| } // __kmp_stg_print_align_alloc |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER |
| |
| // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from |
| // parse and print functions, pass required info through data argument. |
| |
| static void __kmp_stg_parse_barrier_branch_bit(char const *name, |
| char const *value, void *data) { |
| const char *var; |
| |
| /* ---------- Barrier branch bit control ------------ */ |
| for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { |
| var = __kmp_barrier_branch_bit_env_name[i]; |
| if ((strcmp(var, name) == 0) && (value != 0)) { |
| char *comma; |
| |
| comma = CCAST(char *, strchr(value, ',')); |
| __kmp_barrier_gather_branch_bits[i] = |
| (kmp_uint32)__kmp_str_to_int(value, ','); |
| /* is there a specified release parameter? */ |
| if (comma == NULL) { |
| __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt; |
| } else { |
| __kmp_barrier_release_branch_bits[i] = |
| (kmp_uint32)__kmp_str_to_int(comma + 1, 0); |
| |
| if (__kmp_barrier_release_branch_bits[i] > KMP_MAX_BRANCH_BITS) { |
| __kmp_msg(kmp_ms_warning, |
| KMP_MSG(BarrReleaseValueInvalid, name, comma + 1), |
| __kmp_msg_null); |
| __kmp_barrier_release_branch_bits[i] = __kmp_barrier_release_bb_dflt; |
| } |
| } |
| if (__kmp_barrier_gather_branch_bits[i] > KMP_MAX_BRANCH_BITS) { |
| KMP_WARNING(BarrGatherValueInvalid, name, value); |
| KMP_INFORM(Using_uint_Value, name, __kmp_barrier_gather_bb_dflt); |
| __kmp_barrier_gather_branch_bits[i] = __kmp_barrier_gather_bb_dflt; |
| } |
| } |
| K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[i], |
| __kmp_barrier_gather_branch_bits[i], |
| __kmp_barrier_release_branch_bits[i])) |
| } |
| } // __kmp_stg_parse_barrier_branch_bit |
| |
| static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| const char *var; |
| for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { |
| var = __kmp_barrier_branch_bit_env_name[i]; |
| if (strcmp(var, name) == 0) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name[i]); |
| } else { |
| __kmp_str_buf_print(buffer, " %s='", |
| __kmp_barrier_branch_bit_env_name[i]); |
| } |
| __kmp_str_buf_print(buffer, "%d,%d'\n", |
| __kmp_barrier_gather_branch_bits[i], |
| __kmp_barrier_release_branch_bits[i]); |
| } |
| } |
| } // __kmp_stg_print_barrier_branch_bit |
| |
| // ---------------------------------------------------------------------------- |
| // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN, |
| // KMP_REDUCTION_BARRIER_PATTERN |
| |
| // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and |
| // print functions, pass required data to functions through data argument. |
| |
| static void __kmp_stg_parse_barrier_pattern(char const *name, char const *value, |
| void *data) { |
| const char *var; |
| /* ---------- Barrier method control ------------ */ |
| |
| for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { |
| var = __kmp_barrier_pattern_env_name[i]; |
| |
| if ((strcmp(var, name) == 0) && (value != 0)) { |
| int j; |
| char *comma = CCAST(char *, strchr(value, ',')); |
| |
| /* handle first parameter: gather pattern */ |
| for (j = bp_linear_bar; j < bp_last_bar; j++) { |
| if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name[j], value, 1, |
| ',')) { |
| __kmp_barrier_gather_pattern[i] = (kmp_bar_pat_e)j; |
| break; |
| } |
| } |
| if (j == bp_last_bar) { |
| KMP_WARNING(BarrGatherValueInvalid, name, value); |
| KMP_INFORM(Using_str_Value, name, |
| __kmp_barrier_pattern_name[bp_linear_bar]); |
| } |
| |
| /* handle second parameter: release pattern */ |
| if (comma != NULL) { |
| for (j = bp_linear_bar; j < bp_last_bar; j++) { |
| if (__kmp_str_match(__kmp_barrier_pattern_name[j], 1, comma + 1)) { |
| __kmp_barrier_release_pattern[i] = (kmp_bar_pat_e)j; |
| break; |
| } |
| } |
| if (j == bp_last_bar) { |
| __kmp_msg(kmp_ms_warning, |
| KMP_MSG(BarrReleaseValueInvalid, name, comma + 1), |
| __kmp_msg_null); |
| KMP_INFORM(Using_str_Value, name, |
| __kmp_barrier_pattern_name[bp_linear_bar]); |
| } |
| } |
| } |
| } |
| } // __kmp_stg_parse_barrier_pattern |
| |
| static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| const char *var; |
| for (int i = bs_plain_barrier; i < bs_last_barrier; i++) { |
| var = __kmp_barrier_pattern_env_name[i]; |
| if (strcmp(var, name) == 0) { |
| int j = __kmp_barrier_gather_pattern[i]; |
| int k = __kmp_barrier_release_pattern[i]; |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name[i]); |
| } else { |
| __kmp_str_buf_print(buffer, " %s='", |
| __kmp_barrier_pattern_env_name[i]); |
| } |
| __kmp_str_buf_print(buffer, "%s,%s'\n", __kmp_barrier_pattern_name[j], |
| __kmp_barrier_pattern_name[k]); |
| } |
| } |
| } // __kmp_stg_print_barrier_pattern |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_ABORT_DELAY |
| |
| static void __kmp_stg_parse_abort_delay(char const *name, char const *value, |
| void *data) { |
| // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is |
| // milliseconds. |
| int delay = __kmp_abort_delay / 1000; |
| __kmp_stg_parse_int(name, value, 0, INT_MAX / 1000, &delay); |
| __kmp_abort_delay = delay * 1000; |
| } // __kmp_stg_parse_abort_delay |
| |
| static void __kmp_stg_print_abort_delay(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_abort_delay); |
| } // __kmp_stg_print_abort_delay |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_CPUINFO_FILE |
| |
| static void __kmp_stg_parse_cpuinfo_file(char const *name, char const *value, |
| void *data) { |
| #if KMP_AFFINITY_SUPPORTED |
| __kmp_stg_parse_str(name, value, &__kmp_cpuinfo_file); |
| K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file)); |
| #endif |
| } //__kmp_stg_parse_cpuinfo_file |
| |
| static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| #if KMP_AFFINITY_SUPPORTED |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME; |
| } else { |
| __kmp_str_buf_print(buffer, " %s", name); |
| } |
| if (__kmp_cpuinfo_file) { |
| __kmp_str_buf_print(buffer, "='%s'\n", __kmp_cpuinfo_file); |
| } else { |
| __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); |
| } |
| #endif |
| } //__kmp_stg_print_cpuinfo_file |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION |
| |
| static void __kmp_stg_parse_force_reduction(char const *name, char const *value, |
| void *data) { |
| kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data; |
| int rc; |
| |
| rc = __kmp_stg_check_rivals(name, value, reduction->rivals); |
| if (rc) { |
| return; |
| } |
| if (reduction->force) { |
| if (value != 0) { |
| if (__kmp_str_match("critical", 0, value)) |
| __kmp_force_reduction_method = critical_reduce_block; |
| else if (__kmp_str_match("atomic", 0, value)) |
| __kmp_force_reduction_method = atomic_reduce_block; |
| else if (__kmp_str_match("tree", 0, value)) |
| __kmp_force_reduction_method = tree_reduce_block; |
| else { |
| KMP_FATAL(UnknownForceReduction, name, value); |
| } |
| } |
| } else { |
| __kmp_stg_parse_bool(name, value, &__kmp_determ_red); |
| if (__kmp_determ_red) { |
| __kmp_force_reduction_method = tree_reduce_block; |
| } else { |
| __kmp_force_reduction_method = reduction_method_not_defined; |
| } |
| } |
| K_DIAG(1, ("__kmp_force_reduction_method == %d\n", |
| __kmp_force_reduction_method)); |
| } // __kmp_stg_parse_force_reduction |
| |
| static void __kmp_stg_print_force_reduction(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| |
| kmp_stg_fr_data_t *reduction = (kmp_stg_fr_data_t *)data; |
| if (reduction->force) { |
| if (__kmp_force_reduction_method == critical_reduce_block) { |
| __kmp_stg_print_str(buffer, name, "critical"); |
| } else if (__kmp_force_reduction_method == atomic_reduce_block) { |
| __kmp_stg_print_str(buffer, name, "atomic"); |
| } else if (__kmp_force_reduction_method == tree_reduce_block) { |
| __kmp_stg_print_str(buffer, name, "tree"); |
| } else { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME; |
| } else { |
| __kmp_str_buf_print(buffer, " %s", name); |
| } |
| __kmp_str_buf_print(buffer, ": %s\n", KMP_I18N_STR(NotDefined)); |
| } |
| } else { |
| __kmp_stg_print_bool(buffer, name, __kmp_determ_red); |
| } |
| |
| } // __kmp_stg_print_force_reduction |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_STORAGE_MAP |
| |
| static void __kmp_stg_parse_storage_map(char const *name, char const *value, |
| void *data) { |
| if (__kmp_str_match("verbose", 1, value)) { |
| __kmp_storage_map = TRUE; |
| __kmp_storage_map_verbose = TRUE; |
| __kmp_storage_map_verbose_specified = TRUE; |
| |
| } else { |
| __kmp_storage_map_verbose = FALSE; |
| __kmp_stg_parse_bool(name, value, &__kmp_storage_map); // !!! |
| } |
| } // __kmp_stg_parse_storage_map |
| |
| static void __kmp_stg_print_storage_map(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| if (__kmp_storage_map_verbose || __kmp_storage_map_verbose_specified) { |
| __kmp_stg_print_str(buffer, name, "verbose"); |
| } else { |
| __kmp_stg_print_bool(buffer, name, __kmp_storage_map); |
| } |
| } // __kmp_stg_print_storage_map |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_ALL_THREADPRIVATE |
| |
| static void __kmp_stg_parse_all_threadprivate(char const *name, |
| char const *value, void *data) { |
| __kmp_stg_parse_int(name, value, |
| __kmp_allThreadsSpecified ? __kmp_max_nth : 1, |
| __kmp_max_nth, &__kmp_tp_capacity); |
| } // __kmp_stg_parse_all_threadprivate |
| |
| static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t *buffer, |
| char const *name, void *data) { |
| __kmp_stg_print_int(buffer, name, __kmp_tp_capacity); |
| } |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_FOREIGN_THREADS_THREADPRIVATE |
| |
| static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name, |
| char const *value, |
| void *data) { |
| __kmp_stg_parse_bool(name, value, &__kmp_foreign_tp); |
| } // __kmp_stg_parse_foreign_threads_threadprivate |
| |
| static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t *buffer, |
| char const *name, |
| void *data) { |
| __kmp_stg_print_bool(buffer, name, __kmp_foreign_tp); |
| } // __kmp_stg_print_foreign_threads_threadprivate |
| |
| // ----------------------------------------------------------------------------- |
| // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD |
| |
| #if KMP_AFFINITY_SUPPORTED |
| // Parse the proc id list. Return TRUE if successful, FALSE otherwise. |
| static int __kmp_parse_affinity_proc_id_list(const char *var, const char *env, |
| const char **nextEnv, |
| char **proclist) { |
| const char *scan = env; |
| const char *next = scan; |
| int empty = TRUE; |
| |
| *proclist = NULL; |
| |
| for (;;) { |
| int start, end, stride; |
| |
| SKIP_WS(scan); |
| next = scan; |
| if (*next == '\0') { |
| break; |
| } |
| |
| if (*next == '{') { |
| int num; |
| next++; // skip '{' |
| SKIP_WS(next); |
| scan = next; |
| |
| // Read the first integer in the set. |
| if ((*next < '0') || (*next > '9')) { |
| KMP_WARNING(AffSyntaxError, var); |
| return FALSE; |
| } |
| SKIP_DIGITS(next); |
| num = __kmp_str_to_int(scan, *next); |
| KMP_ASSERT(num >= 0); |
| |
| for (;;) { |
| // Check for end of set. |
| SKIP_WS(next); |
| if (*next == '}') { |
| next++; // skip '}' |
| break; |
| } |
| |
| // Skip optional comma. |
| if (*next == ',') { |
| next++; |
| } |
| SKIP_WS(next); |
| |
| // Read the next integer in the set. |
| scan = next; |
| if ((*next < '0') || (*next > '9')) { |
| KMP_WARNING(AffSyntaxError, var); |
| return FALSE; |
| } |
| |
| SKIP_DIGITS(next); |
| num = __kmp_str_to_int(scan, *next); |
| KMP_ASSERT(num >= 0); |
| } |
| empty = FALSE; |
| |
| SKIP_WS(next); |
| if (*next == ',') { |
| next++; |
| } |
| scan = next; |
| continue; |
| } |
| |
| // Next character is not an integer => end of list |
| if ((*next < '0') || (*next > '9')) { |
| if (empty) { |
| KMP_WARNING(AffSyntaxError, var); |
| return FALSE; |
| } |
| break; |
| } |
| |
| // Read the first integer. |
| SKIP_DIGITS(next); |
| start = __kmp_str_to_int(scan, *next); |
| KMP_ASSERT(start >= 0); |
| SKIP_WS(next); |
| |
| // If this isn't a range, then go on. |
| if (*next != '-') { |
| empty = FALSE; |
| |
| // Skip optional comma. |
| if (*next == ',') { |
| next++; |
| } |
| scan = next; |
| continue; |
| } |
| |
| // This is a range. Skip over the '-' and read in the 2nd int. |
| next++; // skip '-' |
| SKIP_WS(next); |
| scan = next; |
| if ((*next < '0') || (*next > '9')) { |
| KMP_WARNING(AffSyntaxError, var); |
| return FALSE; |
| } |
| SKIP_DIGITS(next); |
| end = __kmp_str_to_int(scan, *next); |
| KMP_ASSERT(end >= 0); |
| |
| // Check for a stride parameter |
| stride = 1; |
| SKIP_WS(next); |
| if (*next == ':') { |
| // A stride is specified. Skip over the ':" and read the 3rd int. |
| int sign = +1; |
| next++; // skip ':' |
| SKIP_WS(next); |
| scan = next; |
| if (*next == '-') { |
| sign = -1; |
| next++; |
| SKIP_WS(next); |
| scan = next; |
| } |
| if ((*next < '0') || (*next > '9')) { |
| KMP_WARNING(AffSyntaxError, var); |
| return FALSE; |
| } |
| SKIP_DIGITS(next); |
| stride = __kmp_str_to_int(scan, *next); |
| KMP_ASSERT(stride >= 0); |
| stride *= sign; |
| } |
| |
| // Do some range checks. |
| if (stride == 0) { |
| KMP_WARNING(AffZeroStride, var); |
| return FALSE; |
| } |
| if (stride > 0) { |
| if (start > end) { |
| KMP_WARNING(AffStartGreaterEnd, var, start, end); |
| return FALSE; |
| } |
| } else { |
| if (start < end) { |
| KMP_WARNING(AffStrideLessZero, var, start, end); |
| return FALSE; |
| } |
| } |
| if ((end - start) / stride > 65536) { |
| KMP_WARNING(AffRangeTooBig, var, end, start, stride); |
| return FALSE; |
| } |
| |
| empty = FALSE; |
| |
| // Skip optional comma. |
| SKIP_WS(next); |
| if (*next == ',') { |
| next++; |
| } |
| scan = next; |
| } |
| |
| *nextEnv = next; |
| |
| { |
| int len = next - env; |
| char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char)); |
| KMP_MEMCPY_S(retlist, (len + 1) * sizeof(char), env, len * sizeof(char)); |
| retlist[len] = '\0'; |
| *proclist = retlist; |
| } |
| return TRUE; |
| } |
| |
| // If KMP_AFFINITY is specified without a type, then |
| // __kmp_affinity_notype should point to its setting. |
| static kmp_setting_t *__kmp_affinity_notype = NULL; |
| |
| static void __kmp_parse_affinity_env(char const *name, char const *value, |
| enum affinity_type *out_type, |
| char **out_proclist, int *out_verbose, |
| int *out_warn, int *out_respect, |
| enum affinity_gran *out_gran, |
| int *out_gran_levels, int *out_dups, |
| int *out_compact, int *out_offset) { |
| char *buffer = NULL; // Copy of env var value. |
| char *buf = NULL; // Buffer for strtok_r() function. |
| char *next = NULL; // end of token / start of next. |
| const char *start; // start of current token (for err msgs) |
| int count = 0; // Counter of parsed integer numbers. |
| int number[2]; // Parsed numbers. |
| |
| // Guards. |
| int type = 0; |
| int proclist = 0; |
| int verbose = 0; |
| int warnings = 0; |
| int respect = 0; |
| int gran = 0; |
| int dups = 0; |
| |
| KMP_ASSERT(value != NULL); |
| |
| if (TCR_4(__kmp_init_middle)) { |
| KMP_WARNING(EnvMiddleWarn, name); |
| __kmp_env_toPrint(name, 0); |
| return; |
| } |
| __kmp_env_toPrint(name, 1); |
| |
| buffer = |
| __kmp_str_format("%s", value); // Copy env var to keep original intact. |
| buf = buffer; |
| SKIP_WS(buf); |
| |
| // Helper macros. |
| |
| // If we see a parse error, emit a warning and scan to the next ",". |
| // |
| // FIXME - there's got to be a better way to print an error |
| // message, hopefully without overwritting peices of buf. |
| #define EMIT_WARN(skip, errlist) \ |
| { \ |
| char ch; \ |
| if (skip) { \ |
| SKIP_TO(next, ','); \ |
| } \ |
| ch = *next; \ |
| *next = '\0'; \ |
| KMP_WARNING errlist; \ |
| *next = ch; \ |
| if (skip) { \ |
| if (ch == ',') \ |
| next++; \ |
| } \ |
| buf = next; \ |
| } |
| |
| #define _set_param(_guard, _var, _val) \ |
| { \ |
| if (_guard == 0) { \ |
| _var = _val; \ |
| } else { \ |
| EMIT_WARN(FALSE, (AffParamDefined, name, start)); \ |
| } \ |
| ++_guard; \ |
| } |
| |
| #define set_type(val) _set_param(type, *out_type, val) |
| #define set_verbose(val) _set_param(verbose, *out_verbose, val) |
| #define set_warnings(val) _set_param(warnings, *out_warn, val) |
| #define set_respect(val) _set_param(respect, *out_respect, val) |
| #define set_dups(val) _set_param(dups, *out_dups, val) |
| #define set_proclist(val) _set_param(proclist, *out_proclist, val) |
| |
| #define set_gran(val, levels) \ |
| { \ |
| if (gran == 0) { \ |
| *out_gran = val; \ |
| *out_gran_levels = levels; \ |
| } else { \ |
| EMIT_WARN(FALSE, (AffParamDefined, name, start)); \ |
| } \ |
| ++gran; \ |
| } |
| |
| KMP_DEBUG_ASSERT((__kmp_nested_proc_bind.bind_types != NULL) && |
| (__kmp_nested_proc_bind.used > 0)); |
| |
| while (*buf != '\0') { |
| start = next = buf; |
| |
| if (__kmp_match_str("none", buf, CCAST(const char **, &next))) { |
| set_type(affinity_none); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; |
| buf = next; |
| } else if (__kmp_match_str("scatter", buf, CCAST(const char **, &next))) { |
| set_type(affinity_scatter); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| buf = next; |
| } else if (__kmp_match_str("compact", buf, CCAST(const char **, &next))) { |
| set_type(affinity_compact); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| buf = next; |
| } else if (__kmp_match_str("logical", buf, CCAST(const char **, &next))) { |
| set_type(affinity_logical); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| buf = next; |
| } else if (__kmp_match_str("physical", buf, CCAST(const char **, &next))) { |
| set_type(affinity_physical); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| buf = next; |
| } else if (__kmp_match_str("explicit", buf, CCAST(const char **, &next))) { |
| set_type(affinity_explicit); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| buf = next; |
| } else if (__kmp_match_str("balanced", buf, CCAST(const char **, &next))) { |
| set_type(affinity_balanced); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| buf = next; |
| } else if (__kmp_match_str("disabled", buf, CCAST(const char **, &next))) { |
| set_type(affinity_disabled); |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_false; |
| buf = next; |
| } else if (__kmp_match_str("verbose", buf, CCAST(const char **, &next))) { |
| set_verbose(TRUE); |
| buf = next; |
| } else if (__kmp_match_str("noverbose", buf, CCAST(const char **, &next))) { |
| set_verbose(FALSE); |
| buf = next; |
| } else if (__kmp_match_str("warnings", buf, CCAST(const char **, &next))) { |
| set_warnings(TRUE); |
| buf = next; |
| } else if (__kmp_match_str("nowarnings", buf, |
| CCAST(const char **, &next))) { |
| set_warnings(FALSE); |
| buf = next; |
| } else if (__kmp_match_str("respect", buf, CCAST(const char **, &next))) { |
| set_respect(TRUE); |
| buf = next; |
| } else if (__kmp_match_str("norespect", buf, CCAST(const char **, &next))) { |
| set_respect(FALSE); |
| buf = next; |
| } else if (__kmp_match_str("duplicates", buf, |
| CCAST(const char **, &next)) || |
| __kmp_match_str("dups", buf, CCAST(const char **, &next))) { |
| set_dups(TRUE); |
| buf = next; |
| } else if (__kmp_match_str("noduplicates", buf, |
| CCAST(const char **, &next)) || |
| __kmp_match_str("nodups", buf, CCAST(const char **, &next))) { |
| set_dups(FALSE); |
| buf = next; |
| } else if (__kmp_match_str("granularity", buf, |
| CCAST(const char **, &next)) || |
| __kmp_match_str("gran", buf, CCAST(const char **, &next))) { |
| SKIP_WS(next); |
| if (*next != '=') { |
| EMIT_WARN(TRUE, (AffInvalidParam, name, start)); |
| continue; |
| } |
| next++; // skip '=' |
| SKIP_WS(next); |
| |
| buf = next; |
| if (__kmp_match_str("fine", buf, CCAST(const char **, &next))) { |
| set_gran(affinity_gran_fine, -1); |
| buf = next; |
| } else if (__kmp_match_str("thread", buf, CCAST(const char **, &next))) { |
| set_gran(affinity_gran_thread, -1); |
| buf = next; |
| } else if (__kmp_match_str("core", buf, CCAST(const char **, &next))) { |
| set_gran(affinity_gran_core, -1); |
| buf = next; |
| #if KMP_USE_HWLOC |
| } else if (__kmp_match_str("tile", buf, CCAST(const char **, &next))) { |
| set_gran(affinity_gran_tile, -1); |
| buf = next; |
| #endif |
| } else if (__kmp_match_str("package", buf, CCAST(const char **, &next))) { |
| set_gran(affinity_gran_package, -1); |
| buf = next; |
| } else if (__kmp_match_str("node", buf, CCAST(const char **, &next))) { |
| set_gran(affinity_gran_node, -1); |
| buf = next; |
| #if KMP_GROUP_AFFINITY |
| } else if (__kmp_match_str("group", buf, CCAST(const char **, &next))) { |
| set_gran(affinity_gran_group, -1); |
| buf = next; |
| #endif /* KMP_GROUP AFFINITY */ |
| } else if ((*buf >= '0') && (*buf <= '9')) { |
| int n; |
| next = buf; |
| SKIP_DIGITS(next); |
| n = __kmp_str_to_int(buf, *next); |
| KMP_ASSERT(n >= 0); |
| buf = next; |
| set_gran(affinity_gran_default, n); |
| } else { |
| EMIT_WARN(TRUE, (AffInvalidParam, name, start)); |
| continue; |
| } |
| } else if (__kmp_match_str("proclist", buf, CCAST(const char **, &next))) { |
| char *temp_proclist; |
| |
| SKIP_WS(next); |
| if (*next != '=') { |
| EMIT_WARN(TRUE, (AffInvalidParam, name, start)); |
| continue; |
| } |
| next++; // skip '=' |
| SKIP_WS(next); |
| if (*next != '[') { |
| EMIT_WARN(TRUE, (AffInvalidParam, name, start)); |
| continue; |
| } |
| next++; // skip '[' |
| buf = next; |
| if (!__kmp_parse_affinity_proc_id_list( |
| name, buf, CCAST(const char **, &next), &temp_proclist)) { |
| // warning already emitted. |
| SKIP_TO(next, ']'); |
| if (*next == ']') |
| next++; |
| SKIP_TO(next, ','); |
| if (*next == ',') |
| next++; |
| buf = next; |
| continue; |
| } |
| if (*next != ']') { |
| EMIT_WARN(TRUE, (AffInvalidParam, name, start)); |
| continue; |
| } |
| next++; // skip ']' |
| set_proclist(temp_proclist); |
| } else if ((*buf >= '0') && (*buf <= '9')) { |
| // Parse integer numbers -- permute and offset. |
| int n; |
| next = buf; |
| SKIP_DIGITS(next); |
| n = __kmp_str_to_int(buf, *next); |
| KMP_ASSERT(n >= 0); |
| buf = next; |
| if (count < 2) { |
| number[count] = n; |
| } else { |
| KMP_WARNING(AffManyParams, name, start); |
| } |
| ++count; |
| } else { |
| EMIT_WARN(TRUE, (AffInvalidParam, name, start)); |
| continue; |
| } |
| |
| SKIP_WS(next); |
| if (*next == ',') { |
| next++; |
| SKIP_WS(next); |
| } else if (*next != '\0') { |
| const char *temp = next; |
| EMIT_WARN(TRUE, (ParseExtraCharsWarn, name, temp)); |
| continue; |
| } |
| buf = next; |
| } // while |
| |
| #undef EMIT_WARN |
| #undef _set_param |
| #undef set_type |
| #undef set_verbose |
| #undef set_warnings |
| #undef set_respect |
| #undef set_granularity |
| |
| __kmp_str_free(&buffer); |
| |
| if (proclist) { |
| if (!type) { |
| KMP_WARNING(AffProcListNoType, name); |
| *out_type = affinity_explicit; |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| } else if (*out_type != affinity_explicit) { |
| KMP_WARNING(AffProcListNotExplicit, name); |
| KMP_ASSERT(*out_proclist != NULL); |
| KMP_INTERNAL_FREE(*out_proclist); |
| *out_proclist = NULL; |
| } |
| } |
| switch (*out_type) { |
| case affinity_logical: |
| case affinity_physical: { |
| if (count > 0) { |
| *out_offset = number[0]; |
| } |
| if (count > 1) { |
| KMP_WARNING(AffManyParamsForLogic, name, number[1]); |
| } |
| } break; |
| case affinity_balanced: { |
| if (count > 0) { |
| *out_compact = number[0]; |
| } |
| if (count > 1) { |
| *out_offset = number[1]; |
| } |
| |
| if (__kmp_affinity_gran == affinity_gran_default) { |
| #if KMP_MIC_SUPPORTED |
| if (__kmp_mic_type != non_mic) { |
| if (__kmp_affinity_verbose || __kmp_affinity_warnings) { |
| KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "fine"); |
| } |
| __kmp_affinity_gran = affinity_gran_fine; |
| } else |
| #endif |
| { |
| if (__kmp_affinity_verbose || __kmp_affinity_warnings) { |
| KMP_WARNING(AffGranUsing, "KMP_AFFINITY", "core"); |
| } |
| __kmp_affinity_gran = affinity_gran_core; |
| } |
| } |
| } break; |
| case affinity_scatter: |
| case affinity_compact: { |
| if (count > 0) { |
| *out_compact = number[0]; |
| } |
| if (count > 1) { |
| *out_offset = number[1]; |
| } |
| } break; |
| case affinity_explicit: { |
| if (*out_proclist == NULL) { |
| KMP_WARNING(AffNoProcList, name); |
| __kmp_affinity_type = affinity_none; |
| } |
| if (count > 0) { |
| KMP_WARNING(AffNoParam, name, "explicit"); |
| } |
| } break; |
| case affinity_none: { |
| if (count > 0) { |
| KMP_WARNING(AffNoParam, name, "none"); |
| } |
| } break; |
| case affinity_disabled: { |
| if (count > 0) { |
| KMP_WARNING(AffNoParam, name, "disabled"); |
| } |
| } break; |
| case affinity_default: { |
| if (count > 0) { |
| KMP_WARNING(AffNoParam, name, "default"); |
| } |
| } break; |
| default: { KMP_ASSERT(0); } |
| } |
| } // __kmp_parse_affinity_env |
| |
| static void __kmp_stg_parse_affinity(char const *name, char const *value, |
| void *data) { |
| kmp_setting_t **rivals = (kmp_setting_t **)data; |
| int rc; |
| |
| rc = __kmp_stg_check_rivals(name, value, rivals); |
| if (rc) { |
| return; |
| } |
| |
| __kmp_parse_affinity_env(name, value, &__kmp_affinity_type, |
| &__kmp_affinity_proclist, &__kmp_affinity_verbose, |
| &__kmp_affinity_warnings, |
| &__kmp_affinity_respect_mask, &__kmp_affinity_gran, |
| &__kmp_affinity_gran_levels, &__kmp_affinity_dups, |
| &__kmp_affinity_compact, &__kmp_affinity_offset); |
| |
| } // __kmp_stg_parse_affinity |
| |
| static void __kmp_stg_print_affinity(kmp_str_buf_t *buffer, char const *name, |
| void *data) { |
| if (__kmp_env_format) { |
| KMP_STR_BUF_PRINT_NAME_EX(name); |
| } else { |
| __kmp_str_buf_print(buffer, " %s='", name); |
| } |
| if (__kmp_affinity_verbose) { |
| __kmp_str_buf_print(buffer, "%s,", "verbose"); |
| } else { |
| __kmp_str_buf_print(buffer, "%s,", "noverbose"); |
| } |
| if (__kmp_affinity_warnings) { |
| __kmp_str_buf_print(buffer, "%s,", "warnings"); |
| } else { |
| __kmp_str_buf_print(buffer, "%s,", "nowarnings"); |
| } |
| if (KMP_AFFINITY_CAPABLE()) { |
| if (__kmp_affinity_respect_mask) { |
| __kmp_str_buf_print(buffer, "%s,", "respect"); |
| } else { |
| __kmp_str_buf_print(buffer, "%s,", "norespect"); |
| } |
| switch (__kmp_affinity_gran) { |
| case affinity_gran_default: |
| __kmp_str_buf_print(buffer, "%s", "granularity=default,"); |
| break; |
| case affinity_gran_fine: |
| __kmp_str_buf_print(buffer, "%s", "granularity=fine,"); |
| break; |
| case affinity_gran_thread: |
| __kmp_str_buf_print(buffer, "%s", "granularity=thread,"); |
| break; |
| case affinity_gran_core: |
| __kmp_str_buf_print(buffer, "%s", "granularity=core,"); |
| break; |
| case affinity_gran_package: |
| __kmp_str_buf_print(buffer, "%s", "granularity=package,"); |
| break; |
| case affinity_gran_node: |
| __kmp_str_buf_print(buffer, "%s", "granularity=node,"); |
| break; |
| #if KMP_GROUP_AFFINITY |
| case affinity_gran_group: |
| __kmp_str_buf_print(buffer, "%s", "granularity=group,"); |
| break; |
| #endif /* KMP_GROUP_AFFINITY */ |
| } |
| } |
| if (!KMP_AFFINITY_CAPABLE()) { |
| __kmp_str_buf_print(buffer, "%s", "disabled"); |
| } else |
| switch (__kmp_affinity_type) { |
| case affinity_none: |
| __kmp_str_buf_print(buffer, "%s", "none"); |
| break; |
| case affinity_physical: |
| __kmp_str_buf_print(buffer, "%s,%d", "physical", __kmp_affinity_offset); |
| break; |
| case affinity_logical: |
| __kmp_str_buf_print(buffer, "%s,%d", "logical", __kmp_affinity_offset); |
| break; |
| case affinity_compact: |
| __kmp_str_buf_print(buffer, "%s,%d,%d", "compact", __kmp_affinity_compact, |
| __kmp_affinity_offset); |
| break; |
| case affinity_scatter: |
| __kmp_str_buf_print(buffer, "%s,%d,%d", "scatter", __kmp_affinity_compact, |
| __kmp_affinity_offset); |
| break; |
| case affinity_explicit: |
| __kmp_str_buf_print(buffer, "%s=[%s],%s", "proclist", |
| __kmp_affinity_proclist, "explicit"); |
| break; |
| case affinity_balanced: |
| __kmp_str_buf_print(buffer, "%s,%d,%d", "balanced", |
| __kmp_affinity_compact, __kmp_affinity_offset); |
| break; |
| case affinity_disabled: |
| __kmp_str_buf_print(buffer, "%s", "disabled"); |
| break; |
| case affinity_default: |
| __kmp_str_buf_print(buffer, "%s", "default"); |
| break; |
| default: |
| __kmp_str_buf_print(buffer, "%s", "<unknown>"); |
| break; |
| } |
| __kmp_str_buf_print(buffer, "'\n"); |
| } //__kmp_stg_print_affinity |
| |
| #ifdef KMP_GOMP_COMPAT |
| |
| static void __kmp_stg_parse_gomp_cpu_affinity(char const *name, |
| char const *value, void *data) { |
| const char *next = NULL; |
| char *temp_proclist; |
| kmp_setting_t **rivals = (kmp_setting_t **)data; |
| int rc; |
| |
| rc = __kmp_stg_check_rivals(name, value, rivals); |
| if (rc) { |
| return; |
| } |
| |
| if (TCR_4(__kmp_init_middle)) { |
| KMP_WARNING(EnvMiddleWarn, name); |
| __kmp_env_toPrint(name, 0); |
| return; |
| } |
| |
| __kmp_env_toPrint(name, 1); |
| |
| if (__kmp_parse_affinity_proc_id_list(name, value, &next, &temp_proclist)) { |
| SKIP_WS(next); |
| if (*next == '\0') { |
| // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=... |
| __kmp_affinity_proclist = temp_proclist; |
| __kmp_affinity_type = affinity_explicit; |
| __kmp_affinity_gran = affinity_gran_fine; |
| __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel; |
| } else { |
| KMP_WARNING(AffSyntaxError, name); |
| if (temp_proclist != NULL) { |
| KMP_INTERNAL_FREE((void *)temp_proclist); |
| } |
| } |
| } else { |
| |