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