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