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