2 * kmp_settings.cpp -- Initialize environment variables
5 //===----------------------------------------------------------------------===//
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11 //===----------------------------------------------------------------------===//
14 #include "kmp_affinity.h"
15 #include "kmp_atomic.h"
16 #if KMP_USE_HIER_SCHED
17 #include "kmp_dispatch_hier.h"
19 #include "kmp_environment.h"
24 #include "kmp_settings.h"
26 #include "kmp_wrapper_getpid.h"
27 #include <ctype.h> // toupper()
29 #include "ompd-specific.h"
32 static int __kmp_env_toPrint(char const *name
, int flag
);
34 bool __kmp_env_format
= 0; // 0 - old format; 1 - new format
36 // -----------------------------------------------------------------------------
37 // Helper string functions. Subject to move to kmp_str.
39 #ifdef USE_LOAD_BALANCE
40 static double __kmp_convert_to_double(char const *s
) {
43 if (KMP_SSCANF(s
, "%lf", &result
) < 1) {
52 static unsigned int __kmp_readstr_with_sentinel(char *dest
, char const *src
,
53 size_t len
, char sentinel
) {
55 for (i
= 0; i
< len
; i
++) {
56 if ((*src
== '\0') || (*src
== sentinel
)) {
66 static int __kmp_match_with_sentinel(char const *a
, char const *b
, size_t len
,
74 while (*a
&& *b
&& *b
!= sentinel
) {
75 char ca
= *a
, cb
= *b
;
77 if (ca
>= 'a' && ca
<= 'z')
79 if (cb
>= 'a' && cb
<= 'z')
91 // token is the token to check for.
92 // buf is the string being parsed.
93 // *end returns the char after the end of the token.
94 // it is not modified unless a match occurs.
98 // if (__kmp_match_str("token", buf, *end) {
105 // if (__kmp_match_str("token", buf, *end) {
106 // char *save = **end;
108 // <use any of the __kmp*_with_sentinel() functions>
113 static int __kmp_match_str(char const *token
, char const *buf
,
116 KMP_ASSERT(token
!= NULL
);
117 KMP_ASSERT(buf
!= NULL
);
118 KMP_ASSERT(end
!= NULL
);
120 while (*token
&& *buf
) {
121 char ct
= *token
, cb
= *buf
;
123 if (ct
>= 'a' && ct
<= 'z')
125 if (cb
>= 'a' && cb
<= 'z')
140 static size_t __kmp_round4k(size_t size
) {
141 size_t _4k
= 4 * 1024;
142 if (size
& (_4k
- 1)) {
144 if (size
<= KMP_SIZE_T_MAX
- _4k
) {
145 size
+= _4k
; // Round up if there is no overflow.
152 static int __kmp_strcasecmp_with_sentinel(char const *a
, char const *b
,
158 while (*a
&& *b
&& *b
!= sentinel
) {
159 char ca
= *a
, cb
= *b
;
161 if (ca
>= 'a' && ca
<= 'z')
163 if (cb
>= 'a' && cb
<= 'z')
166 return (int)(unsigned char)*a
- (int)(unsigned char)*b
;
170 return *a
? (*b
&& *b
!= sentinel
)
171 ? (int)(unsigned char)*a
- (int)(unsigned char)*b
173 : (*b
&& *b
!= sentinel
) ? -1
177 // =============================================================================
178 // Table structures and helper functions.
180 typedef struct __kmp_setting kmp_setting_t
;
181 typedef struct __kmp_stg_ss_data kmp_stg_ss_data_t
;
182 typedef struct __kmp_stg_wp_data kmp_stg_wp_data_t
;
183 typedef struct __kmp_stg_fr_data kmp_stg_fr_data_t
;
185 typedef void (*kmp_stg_parse_func_t
)(char const *name
, char const *value
,
187 typedef void (*kmp_stg_print_func_t
)(kmp_str_buf_t
*buffer
, char const *name
,
190 struct __kmp_setting
{
191 char const *name
; // Name of setting (environment variable).
192 kmp_stg_parse_func_t parse
; // Parser function.
193 kmp_stg_print_func_t print
; // Print function.
194 void *data
; // Data passed to parser and printer.
195 int set
; // Variable set during this "session"
196 // (__kmp_env_initialize() or kmp_set_defaults() call).
197 int defined
; // Variable set in any "session".
198 }; // struct __kmp_setting
200 struct __kmp_stg_ss_data
{
201 size_t factor
; // Default factor: 1 for KMP_STACKSIZE, 1024 for others.
202 kmp_setting_t
**rivals
; // Array of pointers to rivals (including itself).
203 }; // struct __kmp_stg_ss_data
205 struct __kmp_stg_wp_data
{
206 int omp
; // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY.
207 kmp_setting_t
**rivals
; // Array of pointers to rivals (including itself).
208 }; // struct __kmp_stg_wp_data
210 struct __kmp_stg_fr_data
{
211 int force
; // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION.
212 kmp_setting_t
**rivals
; // Array of pointers to rivals (including itself).
213 }; // struct __kmp_stg_fr_data
215 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
216 char const *name
, // Name of variable.
217 char const *value
, // Value of the variable.
218 kmp_setting_t
**rivals
// List of rival settings (must include current one).
221 // Helper struct that trims heading/trailing white spaces
222 struct kmp_trimmed_str_t
{
224 kmp_trimmed_str_t(const char *str
) {
225 __kmp_str_buf_init(&buf
);
226 size_t len
= KMP_STRLEN(str
);
229 const char *begin
= str
;
230 const char *end
= str
+ KMP_STRLEN(str
) - 1;
232 while (begin
< end
&& *end
== ' ')
234 __kmp_str_buf_cat(&buf
, begin
, end
- begin
+ 1);
236 ~kmp_trimmed_str_t() { __kmp_str_buf_free(&buf
); }
237 const char *get() { return buf
.str
; }
240 // -----------------------------------------------------------------------------
241 // Helper parse functions.
243 static void __kmp_stg_parse_bool(char const *name
, char const *value
,
245 if (__kmp_str_match_true(value
)) {
247 } else if (__kmp_str_match_false(value
)) {
250 __kmp_msg(kmp_ms_warning
, KMP_MSG(BadBoolValue
, name
, value
),
251 KMP_HNT(ValidBoolValues
), __kmp_msg_null
);
253 } // __kmp_stg_parse_bool
255 // placed here in order to use __kmp_round4k static function
256 void __kmp_check_stksize(size_t *val
) {
257 // if system stack size is too big then limit the size for worker threads
258 if (*val
> KMP_DEFAULT_STKSIZE
* 16) // just a heuristics...
259 *val
= KMP_DEFAULT_STKSIZE
* 16;
260 if (*val
< __kmp_sys_min_stksize
)
261 *val
= __kmp_sys_min_stksize
;
262 if (*val
> KMP_MAX_STKSIZE
)
263 *val
= KMP_MAX_STKSIZE
; // dead code currently, but may work in future
265 *val
= __kmp_round4k(*val
);
266 #endif // KMP_OS_DARWIN
269 static void __kmp_stg_parse_size(char const *name
, char const *value
,
270 size_t size_min
, size_t size_max
,
271 int *is_specified
, size_t *out
,
273 char const *msg
= NULL
;
275 size_min
= __kmp_round4k(size_min
);
276 size_max
= __kmp_round4k(size_max
);
277 #endif // KMP_OS_DARWIN
279 if (is_specified
!= NULL
) {
282 __kmp_str_to_size(value
, out
, factor
, &msg
);
284 if (*out
> size_max
) {
286 msg
= KMP_I18N_STR(ValueTooLarge
);
287 } else if (*out
< size_min
) {
289 msg
= KMP_I18N_STR(ValueTooSmall
);
292 size_t round4k
= __kmp_round4k(*out
);
293 if (*out
!= round4k
) {
295 msg
= KMP_I18N_STR(NotMultiple4K
);
300 // If integer overflow occurred, * out == KMP_SIZE_T_MAX. Cut it to
301 // size_max silently.
302 if (*out
< size_min
) {
304 } else if (*out
> size_max
) {
309 // Message is not empty. Print warning.
311 __kmp_str_buf_init(&buf
);
312 __kmp_str_buf_print_size(&buf
, *out
);
313 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
314 KMP_INFORM(Using_str_Value
, name
, buf
.str
);
315 __kmp_str_buf_free(&buf
);
318 } // __kmp_stg_parse_size
320 static void __kmp_stg_parse_str(char const *name
, char const *value
,
323 *out
= __kmp_str_format("%s", value
);
324 } // __kmp_stg_parse_str
326 static void __kmp_stg_parse_int(
328 *name
, // I: Name of environment variable (used in warning messages).
329 char const *value
, // I: Value of environment variable to parse.
330 int min
, // I: Minimum allowed value.
331 int max
, // I: Maximum allowed value.
332 int *out
// O: Output (parsed) value.
334 char const *msg
= NULL
;
335 kmp_uint64 uint
= *out
;
336 __kmp_str_to_uint(value
, &uint
, &msg
);
338 if (uint
< (unsigned int)min
) {
339 msg
= KMP_I18N_STR(ValueTooSmall
);
341 } else if (uint
> (unsigned int)max
) {
342 msg
= KMP_I18N_STR(ValueTooLarge
);
346 // If overflow occurred msg contains error message and uint is very big. Cut
347 // tmp it to INT_MAX.
348 if (uint
< (unsigned int)min
) {
350 } else if (uint
> (unsigned int)max
) {
355 // Message is not empty. Print warning.
357 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
358 __kmp_str_buf_init(&buf
);
359 __kmp_str_buf_print(&buf
, "%" KMP_UINT64_SPEC
"", uint
);
360 KMP_INFORM(Using_uint64_Value
, name
, buf
.str
);
361 __kmp_str_buf_free(&buf
);
363 __kmp_type_convert(uint
, out
);
364 } // __kmp_stg_parse_int
366 #if KMP_DEBUG_ADAPTIVE_LOCKS
367 static void __kmp_stg_parse_file(char const *name
, char const *value
,
368 const char *suffix
, char **out
) {
373 t
= (char *)strrchr(value
, '.');
374 hasSuffix
= t
&& __kmp_str_eqf(t
, suffix
);
375 t
= __kmp_str_format("%s%s", value
, hasSuffix
? "" : suffix
);
376 __kmp_expand_file_name(buffer
, sizeof(buffer
), t
);
378 *out
= __kmp_str_format("%s", buffer
);
379 } // __kmp_stg_parse_file
383 static char *par_range_to_print
= NULL
;
385 static void __kmp_stg_parse_par_range(char const *name
, char const *value
,
386 int *out_range
, char *out_routine
,
387 char *out_file
, int *out_lb
,
389 const char *par_range_value
;
390 size_t len
= KMP_STRLEN(value
) + 1;
391 par_range_to_print
= (char *)KMP_INTERNAL_MALLOC(len
+ 1);
392 KMP_STRNCPY_S(par_range_to_print
, len
+ 1, value
, len
+ 1);
393 __kmp_par_range
= +1;
394 __kmp_par_range_lb
= 0;
395 __kmp_par_range_ub
= INT_MAX
;
398 if (!value
|| *value
== '\0') {
401 if (!__kmp_strcasecmp_with_sentinel("routine", value
, '=')) {
402 par_range_value
= strchr(value
, '=') + 1;
403 if (!par_range_value
)
404 goto par_range_error
;
405 value
= par_range_value
;
406 len
= __kmp_readstr_with_sentinel(out_routine
, value
,
407 KMP_PAR_RANGE_ROUTINE_LEN
- 1, ',');
409 goto par_range_error
;
411 value
= strchr(value
, ',');
417 if (!__kmp_strcasecmp_with_sentinel("filename", value
, '=')) {
418 par_range_value
= strchr(value
, '=') + 1;
419 if (!par_range_value
)
420 goto par_range_error
;
421 value
= par_range_value
;
422 len
= __kmp_readstr_with_sentinel(out_file
, value
,
423 KMP_PAR_RANGE_FILENAME_LEN
- 1, ',');
425 goto par_range_error
;
427 value
= strchr(value
, ',');
433 if ((!__kmp_strcasecmp_with_sentinel("range", value
, '=')) ||
434 (!__kmp_strcasecmp_with_sentinel("incl_range", value
, '='))) {
435 par_range_value
= strchr(value
, '=') + 1;
436 if (!par_range_value
)
437 goto par_range_error
;
438 value
= par_range_value
;
439 if (KMP_SSCANF(value
, "%d:%d", out_lb
, out_ub
) != 2) {
440 goto par_range_error
;
443 value
= strchr(value
, ',');
449 if (!__kmp_strcasecmp_with_sentinel("excl_range", value
, '=')) {
450 par_range_value
= strchr(value
, '=') + 1;
451 if (!par_range_value
)
452 goto par_range_error
;
453 value
= par_range_value
;
454 if (KMP_SSCANF(value
, "%d:%d", out_lb
, out_ub
) != 2) {
455 goto par_range_error
;
458 value
= strchr(value
, ',');
465 KMP_WARNING(ParRangeSyntax
, name
);
469 } // __kmp_stg_parse_par_range
472 int __kmp_initial_threads_capacity(int req_nproc
) {
475 /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
477 if (nth
< (4 * req_nproc
))
478 nth
= (4 * req_nproc
);
479 if (nth
< (4 * __kmp_xproc
))
480 nth
= (4 * __kmp_xproc
);
482 // If hidden helper task is enabled, we initialize the thread capacity with
483 // extra __kmp_hidden_helper_threads_num.
484 if (__kmp_enable_hidden_helper
) {
485 nth
+= __kmp_hidden_helper_threads_num
;
488 if (nth
> __kmp_max_nth
)
494 int __kmp_default_tp_capacity(int req_nproc
, int max_nth
,
495 int all_threads_specified
) {
498 if (all_threads_specified
)
500 /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ),
502 if (nth
< (4 * req_nproc
))
503 nth
= (4 * req_nproc
);
504 if (nth
< (4 * __kmp_xproc
))
505 nth
= (4 * __kmp_xproc
);
507 if (nth
> __kmp_max_nth
)
513 // -----------------------------------------------------------------------------
514 // Helper print functions.
516 static void __kmp_stg_print_bool(kmp_str_buf_t
*buffer
, char const *name
,
518 if (__kmp_env_format
) {
519 KMP_STR_BUF_PRINT_BOOL
;
521 __kmp_str_buf_print(buffer
, " %s=%s\n", name
, value
? "true" : "false");
523 } // __kmp_stg_print_bool
525 static void __kmp_stg_print_int(kmp_str_buf_t
*buffer
, char const *name
,
527 if (__kmp_env_format
) {
528 KMP_STR_BUF_PRINT_INT
;
530 __kmp_str_buf_print(buffer
, " %s=%d\n", name
, value
);
532 } // __kmp_stg_print_int
534 static void __kmp_stg_print_uint64(kmp_str_buf_t
*buffer
, char const *name
,
536 if (__kmp_env_format
) {
537 KMP_STR_BUF_PRINT_UINT64
;
539 __kmp_str_buf_print(buffer
, " %s=%" KMP_UINT64_SPEC
"\n", name
, value
);
541 } // __kmp_stg_print_uint64
543 static void __kmp_stg_print_str(kmp_str_buf_t
*buffer
, char const *name
,
545 if (__kmp_env_format
) {
546 KMP_STR_BUF_PRINT_STR
;
548 __kmp_str_buf_print(buffer
, " %s=%s\n", name
, value
);
550 } // __kmp_stg_print_str
552 static void __kmp_stg_print_size(kmp_str_buf_t
*buffer
, char const *name
,
554 if (__kmp_env_format
) {
555 KMP_STR_BUF_PRINT_NAME_EX(name
);
556 __kmp_str_buf_print_size(buffer
, value
);
557 __kmp_str_buf_print(buffer
, "'\n");
559 __kmp_str_buf_print(buffer
, " %s=", name
);
560 __kmp_str_buf_print_size(buffer
, value
);
561 __kmp_str_buf_print(buffer
, "\n");
564 } // __kmp_stg_print_size
566 // =============================================================================
567 // Parse and print functions.
569 // -----------------------------------------------------------------------------
570 // KMP_DEVICE_THREAD_LIMIT, KMP_ALL_THREADS
572 static void __kmp_stg_parse_device_thread_limit(char const *name
,
573 char const *value
, void *data
) {
574 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
576 if (strcmp(name
, "KMP_ALL_THREADS") == 0) {
577 KMP_INFORM(EnvVarDeprecated
, name
, "KMP_DEVICE_THREAD_LIMIT");
579 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
583 if (!__kmp_strcasecmp_with_sentinel("all", value
, 0)) {
584 __kmp_max_nth
= __kmp_xproc
;
585 __kmp_allThreadsSpecified
= 1;
587 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_max_nth
);
588 __kmp_allThreadsSpecified
= 0;
590 K_DIAG(1, ("__kmp_max_nth == %d\n", __kmp_max_nth
));
592 } // __kmp_stg_parse_device_thread_limit
594 static void __kmp_stg_print_device_thread_limit(kmp_str_buf_t
*buffer
,
595 char const *name
, void *data
) {
596 __kmp_stg_print_int(buffer
, name
, __kmp_max_nth
);
597 } // __kmp_stg_print_device_thread_limit
599 // -----------------------------------------------------------------------------
601 static void __kmp_stg_parse_thread_limit(char const *name
, char const *value
,
603 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_cg_max_nth
);
604 K_DIAG(1, ("__kmp_cg_max_nth == %d\n", __kmp_cg_max_nth
));
606 } // __kmp_stg_parse_thread_limit
608 static void __kmp_stg_print_thread_limit(kmp_str_buf_t
*buffer
,
609 char const *name
, void *data
) {
610 __kmp_stg_print_int(buffer
, name
, __kmp_cg_max_nth
);
611 } // __kmp_stg_print_thread_limit
613 // -----------------------------------------------------------------------------
615 static void __kmp_stg_parse_nteams(char const *name
, char const *value
,
617 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_nteams
);
618 K_DIAG(1, ("__kmp_nteams == %d\n", __kmp_nteams
));
619 } // __kmp_stg_parse_nteams
621 static void __kmp_stg_print_nteams(kmp_str_buf_t
*buffer
, char const *name
,
623 __kmp_stg_print_int(buffer
, name
, __kmp_nteams
);
624 } // __kmp_stg_print_nteams
626 // -----------------------------------------------------------------------------
627 // OMP_TEAMS_THREAD_LIMIT
628 static void __kmp_stg_parse_teams_th_limit(char const *name
, char const *value
,
630 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
,
631 &__kmp_teams_thread_limit
);
632 K_DIAG(1, ("__kmp_teams_thread_limit == %d\n", __kmp_teams_thread_limit
));
633 } // __kmp_stg_parse_teams_th_limit
635 static void __kmp_stg_print_teams_th_limit(kmp_str_buf_t
*buffer
,
636 char const *name
, void *data
) {
637 __kmp_stg_print_int(buffer
, name
, __kmp_teams_thread_limit
);
638 } // __kmp_stg_print_teams_th_limit
640 // -----------------------------------------------------------------------------
641 // KMP_TEAMS_THREAD_LIMIT
642 static void __kmp_stg_parse_teams_thread_limit(char const *name
,
643 char const *value
, void *data
) {
644 __kmp_stg_parse_int(name
, value
, 1, __kmp_sys_max_nth
, &__kmp_teams_max_nth
);
645 } // __kmp_stg_teams_thread_limit
647 static void __kmp_stg_print_teams_thread_limit(kmp_str_buf_t
*buffer
,
648 char const *name
, void *data
) {
649 __kmp_stg_print_int(buffer
, name
, __kmp_teams_max_nth
);
650 } // __kmp_stg_print_teams_thread_limit
652 // -----------------------------------------------------------------------------
654 static void __kmp_stg_parse_use_yield(char const *name
, char const *value
,
656 __kmp_stg_parse_int(name
, value
, 0, 2, &__kmp_use_yield
);
657 __kmp_use_yield_exp_set
= 1;
658 } // __kmp_stg_parse_use_yield
660 static void __kmp_stg_print_use_yield(kmp_str_buf_t
*buffer
, char const *name
,
662 __kmp_stg_print_int(buffer
, name
, __kmp_use_yield
);
663 } // __kmp_stg_print_use_yield
665 // -----------------------------------------------------------------------------
668 static void __kmp_stg_parse_blocktime(char const *name
, char const *value
,
670 const char *buf
= value
;
672 const int ms_mult
= 1000;
676 // Read integer blocktime value
678 if ((*buf
>= '0') && (*buf
<= '9')) {
681 num
= __kmp_basic_str_to_int(buf
);
682 KMP_ASSERT(num
>= 0);
689 // Read units: note that __kmp_dflt_blocktime units is now us
691 if (*buf
== '\0' || __kmp_match_str("ms", buf
, &next
)) {
692 // units are in ms; convert
693 __kmp_dflt_blocktime
= ms_mult
* num
;
694 __kmp_blocktime_units
= 'm';
695 multiplier
= ms_mult
;
696 } else if (__kmp_match_str("us", buf
, &next
)) {
698 __kmp_dflt_blocktime
= num
;
699 __kmp_blocktime_units
= 'u';
700 } else if (__kmp_match_str("infinite", buf
, &next
) ||
701 __kmp_match_str("infinity", buf
, &next
)) {
703 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
704 __kmp_blocktime_units
= 'm';
705 multiplier
= ms_mult
;
707 KMP_WARNING(StgInvalidValue
, name
, value
);
708 // default units are in ms
709 __kmp_dflt_blocktime
= ms_mult
* num
;
710 __kmp_blocktime_units
= 'm';
711 multiplier
= ms_mult
;
714 if (num
< 0 && __kmp_dflt_blocktime
< 0) { // num out of range
715 __kmp_dflt_blocktime
= KMP_DEFAULT_BLOCKTIME
; // now in us
716 __kmp_msg(kmp_ms_warning
, KMP_MSG(InvalidValue
, name
, value
),
718 // Inform in appropriate units
719 KMP_INFORM(Using_int_Value
, name
, __kmp_dflt_blocktime
/ multiplier
);
720 __kmp_env_blocktime
= FALSE
; // Revert to default as if var not set.
721 } else if (num
> 0 && __kmp_dflt_blocktime
< 0) { // overflow
722 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
723 __kmp_msg(kmp_ms_warning
, KMP_MSG(LargeValue
, name
, value
), __kmp_msg_null
);
724 KMP_INFORM(MaxValueUsing
, name
, __kmp_dflt_blocktime
/ multiplier
);
725 __kmp_env_blocktime
= TRUE
; // KMP_BLOCKTIME was specified.
727 if (__kmp_dflt_blocktime
< KMP_MIN_BLOCKTIME
) {
728 __kmp_dflt_blocktime
= KMP_MIN_BLOCKTIME
;
729 __kmp_msg(kmp_ms_warning
, KMP_MSG(SmallValue
, name
, value
),
731 KMP_INFORM(MinValueUsing
, name
, __kmp_dflt_blocktime
/ multiplier
);
732 } else if (__kmp_dflt_blocktime
> KMP_MAX_BLOCKTIME
) {
733 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
734 __kmp_msg(kmp_ms_warning
, KMP_MSG(LargeValue
, name
, value
),
736 KMP_INFORM(MaxValueUsing
, name
, __kmp_dflt_blocktime
/ multiplier
);
738 __kmp_env_blocktime
= TRUE
; // KMP_BLOCKTIME was specified.
741 // calculate number of monitor thread wakeup intervals corresponding to
743 __kmp_monitor_wakeups
=
744 KMP_WAKEUPS_FROM_BLOCKTIME(__kmp_dflt_blocktime
, __kmp_monitor_wakeups
);
746 KMP_INTERVALS_FROM_BLOCKTIME(__kmp_dflt_blocktime
, __kmp_monitor_wakeups
);
748 K_DIAG(1, ("__kmp_env_blocktime == %d\n", __kmp_env_blocktime
));
749 if (__kmp_env_blocktime
) {
750 K_DIAG(1, ("__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime
));
752 } // __kmp_stg_parse_blocktime
754 static void __kmp_stg_print_blocktime(kmp_str_buf_t
*buffer
, char const *name
,
756 int num
= __kmp_dflt_blocktime
;
757 if (__kmp_blocktime_units
== 'm') {
760 if (__kmp_env_format
) {
761 KMP_STR_BUF_PRINT_NAME_EX(name
);
763 __kmp_str_buf_print(buffer
, " %s=", name
);
765 __kmp_str_buf_print(buffer
, "%d", num
);
766 __kmp_str_buf_print(buffer
, "%cs\n", __kmp_blocktime_units
);
767 } // __kmp_stg_print_blocktime
769 // -----------------------------------------------------------------------------
770 // KMP_DUPLICATE_LIB_OK
772 static void __kmp_stg_parse_duplicate_lib_ok(char const *name
,
773 char const *value
, void *data
) {
774 /* actually this variable is not supported, put here for compatibility with
775 earlier builds and for static/dynamic combination */
776 __kmp_stg_parse_bool(name
, value
, &__kmp_duplicate_library_ok
);
777 } // __kmp_stg_parse_duplicate_lib_ok
779 static void __kmp_stg_print_duplicate_lib_ok(kmp_str_buf_t
*buffer
,
780 char const *name
, void *data
) {
781 __kmp_stg_print_bool(buffer
, name
, __kmp_duplicate_library_ok
);
782 } // __kmp_stg_print_duplicate_lib_ok
784 // -----------------------------------------------------------------------------
785 // KMP_INHERIT_FP_CONTROL
787 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
789 static void __kmp_stg_parse_inherit_fp_control(char const *name
,
790 char const *value
, void *data
) {
791 __kmp_stg_parse_bool(name
, value
, &__kmp_inherit_fp_control
);
792 } // __kmp_stg_parse_inherit_fp_control
794 static void __kmp_stg_print_inherit_fp_control(kmp_str_buf_t
*buffer
,
795 char const *name
, void *data
) {
797 __kmp_stg_print_bool(buffer
, name
, __kmp_inherit_fp_control
);
798 #endif /* KMP_DEBUG */
799 } // __kmp_stg_print_inherit_fp_control
801 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
803 // Used for OMP_WAIT_POLICY
804 static char const *blocktime_str
= NULL
;
806 // -----------------------------------------------------------------------------
807 // KMP_LIBRARY, OMP_WAIT_POLICY
809 static void __kmp_stg_parse_wait_policy(char const *name
, char const *value
,
812 kmp_stg_wp_data_t
*wait
= (kmp_stg_wp_data_t
*)data
;
815 rc
= __kmp_stg_check_rivals(name
, value
, wait
->rivals
);
821 if (__kmp_str_match("ACTIVE", 1, value
)) {
822 __kmp_library
= library_turnaround
;
823 if (blocktime_str
== NULL
) {
824 // KMP_BLOCKTIME not specified, so set default to "infinite".
825 __kmp_dflt_blocktime
= KMP_MAX_BLOCKTIME
;
827 } else if (__kmp_str_match("PASSIVE", 1, value
)) {
828 __kmp_library
= library_throughput
;
829 __kmp_wpolicy_passive
= true; /* allow sleep while active tasking */
830 if (blocktime_str
== NULL
) {
831 // KMP_BLOCKTIME not specified, so set default to 0.
832 __kmp_dflt_blocktime
= 0;
835 KMP_WARNING(StgInvalidValue
, name
, value
);
838 if (__kmp_str_match("serial", 1, value
)) { /* S */
839 __kmp_library
= library_serial
;
840 } else if (__kmp_str_match("throughput", 2, value
)) { /* TH */
841 __kmp_library
= library_throughput
;
842 if (blocktime_str
== NULL
) {
843 // KMP_BLOCKTIME not specified, so set default to 0.
844 __kmp_dflt_blocktime
= 0;
846 } else if (__kmp_str_match("turnaround", 2, value
)) { /* TU */
847 __kmp_library
= library_turnaround
;
848 } else if (__kmp_str_match("dedicated", 1, value
)) { /* D */
849 __kmp_library
= library_turnaround
;
850 } else if (__kmp_str_match("multiuser", 1, value
)) { /* M */
851 __kmp_library
= library_throughput
;
852 if (blocktime_str
== NULL
) {
853 // KMP_BLOCKTIME not specified, so set default to 0.
854 __kmp_dflt_blocktime
= 0;
857 KMP_WARNING(StgInvalidValue
, name
, value
);
860 } // __kmp_stg_parse_wait_policy
862 static void __kmp_stg_print_wait_policy(kmp_str_buf_t
*buffer
, char const *name
,
865 kmp_stg_wp_data_t
*wait
= (kmp_stg_wp_data_t
*)data
;
866 char const *value
= NULL
;
869 switch (__kmp_library
) {
870 case library_turnaround
: {
873 case library_throughput
: {
878 switch (__kmp_library
) {
879 case library_serial
: {
882 case library_turnaround
: {
883 value
= "turnaround";
885 case library_throughput
: {
886 value
= "throughput";
891 __kmp_stg_print_str(buffer
, name
, value
);
894 } // __kmp_stg_print_wait_policy
897 // -----------------------------------------------------------------------------
898 // KMP_MONITOR_STACKSIZE
900 static void __kmp_stg_parse_monitor_stacksize(char const *name
,
901 char const *value
, void *data
) {
902 __kmp_stg_parse_size(name
, value
, __kmp_sys_min_stksize
, KMP_MAX_STKSIZE
,
903 NULL
, &__kmp_monitor_stksize
, 1);
904 } // __kmp_stg_parse_monitor_stacksize
906 static void __kmp_stg_print_monitor_stacksize(kmp_str_buf_t
*buffer
,
907 char const *name
, void *data
) {
908 if (__kmp_env_format
) {
909 if (__kmp_monitor_stksize
> 0)
910 KMP_STR_BUF_PRINT_NAME_EX(name
);
912 KMP_STR_BUF_PRINT_NAME
;
914 __kmp_str_buf_print(buffer
, " %s", name
);
916 if (__kmp_monitor_stksize
> 0) {
917 __kmp_str_buf_print_size(buffer
, __kmp_monitor_stksize
);
919 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
921 if (__kmp_env_format
&& __kmp_monitor_stksize
) {
922 __kmp_str_buf_print(buffer
, "'\n");
924 } // __kmp_stg_print_monitor_stacksize
925 #endif // KMP_USE_MONITOR
927 // -----------------------------------------------------------------------------
930 static void __kmp_stg_parse_settings(char const *name
, char const *value
,
932 __kmp_stg_parse_bool(name
, value
, &__kmp_settings
);
933 } // __kmp_stg_parse_settings
935 static void __kmp_stg_print_settings(kmp_str_buf_t
*buffer
, char const *name
,
937 __kmp_stg_print_bool(buffer
, name
, __kmp_settings
);
938 } // __kmp_stg_print_settings
940 // -----------------------------------------------------------------------------
943 static void __kmp_stg_parse_stackpad(char const *name
, char const *value
,
945 __kmp_stg_parse_int(name
, // Env var name
946 value
, // Env var value
947 KMP_MIN_STKPADDING
, // Min value
948 KMP_MAX_STKPADDING
, // Max value
949 &__kmp_stkpadding
// Var to initialize
951 } // __kmp_stg_parse_stackpad
953 static void __kmp_stg_print_stackpad(kmp_str_buf_t
*buffer
, char const *name
,
955 __kmp_stg_print_int(buffer
, name
, __kmp_stkpadding
);
956 } // __kmp_stg_print_stackpad
958 // -----------------------------------------------------------------------------
961 static void __kmp_stg_parse_stackoffset(char const *name
, char const *value
,
963 __kmp_stg_parse_size(name
, // Env var name
964 value
, // Env var value
965 KMP_MIN_STKOFFSET
, // Min value
966 KMP_MAX_STKOFFSET
, // Max value
968 &__kmp_stkoffset
, // Var to initialize
970 } // __kmp_stg_parse_stackoffset
972 static void __kmp_stg_print_stackoffset(kmp_str_buf_t
*buffer
, char const *name
,
974 __kmp_stg_print_size(buffer
, name
, __kmp_stkoffset
);
975 } // __kmp_stg_print_stackoffset
977 // -----------------------------------------------------------------------------
978 // KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE
980 static void __kmp_stg_parse_stacksize(char const *name
, char const *value
,
983 kmp_stg_ss_data_t
*stacksize
= (kmp_stg_ss_data_t
*)data
;
986 rc
= __kmp_stg_check_rivals(name
, value
, stacksize
->rivals
);
990 __kmp_stg_parse_size(name
, // Env var name
991 value
, // Env var value
992 __kmp_sys_min_stksize
, // Min value
993 KMP_MAX_STKSIZE
, // Max value
994 &__kmp_env_stksize
, //
995 &__kmp_stksize
, // Var to initialize
998 } // __kmp_stg_parse_stacksize
1000 // This function is called for printing both KMP_STACKSIZE (factor is 1) and
1001 // OMP_STACKSIZE (factor is 1024). Currently it is not possible to print
1002 // OMP_STACKSIZE value in bytes. We can consider adding this possibility by a
1003 // customer request in future.
1004 static void __kmp_stg_print_stacksize(kmp_str_buf_t
*buffer
, char const *name
,
1006 kmp_stg_ss_data_t
*stacksize
= (kmp_stg_ss_data_t
*)data
;
1007 if (__kmp_env_format
) {
1008 KMP_STR_BUF_PRINT_NAME_EX(name
);
1009 __kmp_str_buf_print_size(buffer
, (__kmp_stksize
% 1024)
1010 ? __kmp_stksize
/ stacksize
->factor
1012 __kmp_str_buf_print(buffer
, "'\n");
1014 __kmp_str_buf_print(buffer
, " %s=", name
);
1015 __kmp_str_buf_print_size(buffer
, (__kmp_stksize
% 1024)
1016 ? __kmp_stksize
/ stacksize
->factor
1018 __kmp_str_buf_print(buffer
, "\n");
1020 } // __kmp_stg_print_stacksize
1022 // -----------------------------------------------------------------------------
1025 static void __kmp_stg_parse_version(char const *name
, char const *value
,
1027 __kmp_stg_parse_bool(name
, value
, &__kmp_version
);
1028 } // __kmp_stg_parse_version
1030 static void __kmp_stg_print_version(kmp_str_buf_t
*buffer
, char const *name
,
1032 __kmp_stg_print_bool(buffer
, name
, __kmp_version
);
1033 } // __kmp_stg_print_version
1035 // -----------------------------------------------------------------------------
1038 static void __kmp_stg_parse_warnings(char const *name
, char const *value
,
1040 __kmp_stg_parse_bool(name
, value
, &__kmp_generate_warnings
);
1041 if (__kmp_generate_warnings
!= kmp_warnings_off
) {
1042 // AC: only 0/1 values documented, so reset to explicit to distinguish from
1044 __kmp_generate_warnings
= kmp_warnings_explicit
;
1046 } // __kmp_stg_parse_warnings
1048 static void __kmp_stg_print_warnings(kmp_str_buf_t
*buffer
, char const *name
,
1050 // AC: TODO: change to print_int? (needs documentation change)
1051 __kmp_stg_print_bool(buffer
, name
, __kmp_generate_warnings
);
1052 } // __kmp_stg_print_warnings
1054 // -----------------------------------------------------------------------------
1057 static void __kmp_stg_parse_nesting_mode(char const *name
, char const *value
,
1059 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_nesting_mode
);
1060 #if KMP_AFFINITY_SUPPORTED && KMP_USE_HWLOC
1061 if (__kmp_nesting_mode
> 0)
1062 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
1064 } // __kmp_stg_parse_nesting_mode
1066 static void __kmp_stg_print_nesting_mode(kmp_str_buf_t
*buffer
,
1067 char const *name
, void *data
) {
1068 if (__kmp_env_format
) {
1069 KMP_STR_BUF_PRINT_NAME
;
1071 __kmp_str_buf_print(buffer
, " %s", name
);
1073 __kmp_str_buf_print(buffer
, "=%d\n", __kmp_nesting_mode
);
1074 } // __kmp_stg_print_nesting_mode
1076 // -----------------------------------------------------------------------------
1077 // OMP_NESTED, OMP_NUM_THREADS
1079 static void __kmp_stg_parse_nested(char const *name
, char const *value
,
1082 KMP_INFORM(EnvVarDeprecated
, name
, "OMP_MAX_ACTIVE_LEVELS");
1083 __kmp_stg_parse_bool(name
, value
, &nested
);
1085 if (!__kmp_dflt_max_active_levels_set
)
1086 __kmp_dflt_max_active_levels
= KMP_MAX_ACTIVE_LEVELS_LIMIT
;
1087 } else { // nesting explicitly turned off
1088 __kmp_dflt_max_active_levels
= 1;
1089 __kmp_dflt_max_active_levels_set
= true;
1091 } // __kmp_stg_parse_nested
1093 static void __kmp_stg_print_nested(kmp_str_buf_t
*buffer
, char const *name
,
1095 if (__kmp_env_format
) {
1096 KMP_STR_BUF_PRINT_NAME
;
1098 __kmp_str_buf_print(buffer
, " %s", name
);
1100 __kmp_str_buf_print(buffer
, ": deprecated; max-active-levels-var=%d\n",
1101 __kmp_dflt_max_active_levels
);
1102 } // __kmp_stg_print_nested
1104 static void __kmp_parse_nested_num_threads(const char *var
, const char *env
,
1105 kmp_nested_nthreads_t
*nth_array
) {
1106 const char *next
= env
;
1107 const char *scan
= next
;
1109 int total
= 0; // Count elements that were set. It'll be used as an array size
1110 int prev_comma
= FALSE
; // For correct processing sequential commas
1112 // Count the number of values in the env. var string
1116 if (*next
== '\0') {
1119 // Next character is not an integer or not a comma => end of list
1120 if (((*next
< '0') || (*next
> '9')) && (*next
!= ',')) {
1121 KMP_WARNING(NthSyntaxError
, var
, env
);
1124 // The next character is ','
1126 // ',' is the first character
1127 if (total
== 0 || prev_comma
) {
1134 // Next character is a digit
1135 if (*next
>= '0' && *next
<= '9') {
1139 const char *tmp
= next
;
1141 if ((*next
== ' ' || *next
== '\t') && (*tmp
>= '0' && *tmp
<= '9')) {
1142 KMP_WARNING(NthSpacesNotAllowed
, var
, env
);
1147 if (!__kmp_dflt_max_active_levels_set
&& total
> 1)
1148 __kmp_dflt_max_active_levels
= KMP_MAX_ACTIVE_LEVELS_LIMIT
;
1149 KMP_DEBUG_ASSERT(total
> 0);
1151 KMP_WARNING(NthSyntaxError
, var
, env
);
1155 // Check if the nested nthreads array exists
1156 if (!nth_array
->nth
) {
1157 // Allocate an array of double size
1158 nth_array
->nth
= (int *)KMP_INTERNAL_MALLOC(sizeof(int) * total
* 2);
1159 if (nth_array
->nth
== NULL
) {
1160 KMP_FATAL(MemoryAllocFailed
);
1162 nth_array
->size
= total
* 2;
1164 if (nth_array
->size
< total
) {
1165 // Increase the array size
1167 nth_array
->size
*= 2;
1168 } while (nth_array
->size
< total
);
1170 nth_array
->nth
= (int *)KMP_INTERNAL_REALLOC(
1171 nth_array
->nth
, sizeof(int) * nth_array
->size
);
1172 if (nth_array
->nth
== NULL
) {
1173 KMP_FATAL(MemoryAllocFailed
);
1177 nth_array
->used
= total
;
1182 // Save values in the array
1185 if (*scan
== '\0') {
1188 // The next character is ','
1190 // ',' in the beginning of the list
1192 // The value is supposed to be equal to __kmp_avail_proc but it is
1193 // unknown at the moment.
1194 // So let's put a placeholder (#threads = 0) to correct it later.
1195 nth_array
->nth
[i
++] = 0;
1197 } else if (prev_comma
) {
1198 // Num threads is inherited from the previous level
1199 nth_array
->nth
[i
] = nth_array
->nth
[i
- 1];
1207 // Next character is a digit
1208 if (*scan
>= '0' && *scan
<= '9') {
1210 const char *buf
= scan
;
1211 char const *msg
= NULL
;
1216 num
= __kmp_str_to_int(buf
, *scan
);
1217 if (num
< KMP_MIN_NTH
) {
1218 msg
= KMP_I18N_STR(ValueTooSmall
);
1220 } else if (num
> __kmp_sys_max_nth
) {
1221 msg
= KMP_I18N_STR(ValueTooLarge
);
1222 num
= __kmp_sys_max_nth
;
1225 // Message is not empty. Print warning.
1226 KMP_WARNING(ParseSizeIntWarn
, var
, env
, msg
);
1227 KMP_INFORM(Using_int_Value
, var
, num
);
1229 nth_array
->nth
[i
++] = num
;
1234 static void __kmp_stg_parse_num_threads(char const *name
, char const *value
,
1236 // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers!
1237 if (!__kmp_strcasecmp_with_sentinel("all", value
, 0)) {
1238 // The array of 1 element
1239 __kmp_nested_nth
.nth
= (int *)KMP_INTERNAL_MALLOC(sizeof(int));
1240 __kmp_nested_nth
.size
= __kmp_nested_nth
.used
= 1;
1241 __kmp_nested_nth
.nth
[0] = __kmp_dflt_team_nth
= __kmp_dflt_team_nth_ub
=
1244 __kmp_parse_nested_num_threads(name
, value
, &__kmp_nested_nth
);
1245 if (__kmp_nested_nth
.nth
) {
1246 __kmp_dflt_team_nth
= __kmp_nested_nth
.nth
[0];
1247 if (__kmp_dflt_team_nth_ub
< __kmp_dflt_team_nth
) {
1248 __kmp_dflt_team_nth_ub
= __kmp_dflt_team_nth
;
1252 K_DIAG(1, ("__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth
));
1253 } // __kmp_stg_parse_num_threads
1256 static void __kmp_stg_parse_max_tdgs(char const *name
, char const *value
,
1258 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_max_tdgs
);
1259 } // __kmp_stg_parse_max_tdgs
1261 static void __kmp_std_print_max_tdgs(kmp_str_buf_t
*buffer
, char const *name
,
1263 __kmp_stg_print_int(buffer
, name
, __kmp_max_tdgs
);
1264 } // __kmp_std_print_max_tdgs
1266 static void __kmp_stg_parse_tdg_dot(char const *name
, char const *value
,
1268 __kmp_stg_parse_bool(name
, value
, &__kmp_tdg_dot
);
1269 } // __kmp_stg_parse_tdg_dot
1271 static void __kmp_stg_print_tdg_dot(kmp_str_buf_t
*buffer
, char const *name
,
1273 __kmp_stg_print_bool(buffer
, name
, __kmp_tdg_dot
);
1274 } // __kmp_stg_print_tdg_dot
1277 static void __kmp_stg_parse_num_hidden_helper_threads(char const *name
,
1280 __kmp_stg_parse_int(name
, value
, 0, 16, &__kmp_hidden_helper_threads_num
);
1281 // If the number of hidden helper threads is zero, we disable hidden helper
1283 if (__kmp_hidden_helper_threads_num
== 0) {
1284 __kmp_enable_hidden_helper
= FALSE
;
1286 // Since the main thread of hidden helper team does not participate
1287 // in tasks execution let's increment the number of threads by one
1288 // so that requested number of threads do actual job.
1289 __kmp_hidden_helper_threads_num
++;
1291 } // __kmp_stg_parse_num_hidden_helper_threads
1293 static void __kmp_stg_print_num_hidden_helper_threads(kmp_str_buf_t
*buffer
,
1296 if (__kmp_hidden_helper_threads_num
== 0) {
1297 __kmp_stg_print_int(buffer
, name
, __kmp_hidden_helper_threads_num
);
1299 KMP_DEBUG_ASSERT(__kmp_hidden_helper_threads_num
> 1);
1300 // Let's exclude the main thread of hidden helper team and print
1301 // number of worker threads those do actual job.
1302 __kmp_stg_print_int(buffer
, name
, __kmp_hidden_helper_threads_num
- 1);
1304 } // __kmp_stg_print_num_hidden_helper_threads
1306 static void __kmp_stg_parse_use_hidden_helper(char const *name
,
1307 char const *value
, void *data
) {
1308 __kmp_stg_parse_bool(name
, value
, &__kmp_enable_hidden_helper
);
1310 __kmp_enable_hidden_helper
= FALSE
;
1312 ("__kmp_stg_parse_use_hidden_helper: Disable hidden helper task on "
1313 "non-Linux platform although it is enabled by user explicitly.\n"));
1315 } // __kmp_stg_parse_use_hidden_helper
1317 static void __kmp_stg_print_use_hidden_helper(kmp_str_buf_t
*buffer
,
1318 char const *name
, void *data
) {
1319 __kmp_stg_print_bool(buffer
, name
, __kmp_enable_hidden_helper
);
1320 } // __kmp_stg_print_use_hidden_helper
1322 static void __kmp_stg_print_num_threads(kmp_str_buf_t
*buffer
, char const *name
,
1324 if (__kmp_env_format
) {
1325 KMP_STR_BUF_PRINT_NAME
;
1327 __kmp_str_buf_print(buffer
, " %s", name
);
1329 if (__kmp_nested_nth
.used
) {
1331 __kmp_str_buf_init(&buf
);
1332 for (int i
= 0; i
< __kmp_nested_nth
.used
; i
++) {
1333 __kmp_str_buf_print(&buf
, "%d", __kmp_nested_nth
.nth
[i
]);
1334 if (i
< __kmp_nested_nth
.used
- 1) {
1335 __kmp_str_buf_print(&buf
, ",");
1338 __kmp_str_buf_print(buffer
, "='%s'\n", buf
.str
);
1339 __kmp_str_buf_free(&buf
);
1341 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
1343 } // __kmp_stg_print_num_threads
1345 // -----------------------------------------------------------------------------
1346 // OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS,
1348 static void __kmp_stg_parse_tasking(char const *name
, char const *value
,
1350 __kmp_stg_parse_int(name
, value
, 0, (int)tskm_max
,
1351 (int *)&__kmp_tasking_mode
);
1352 } // __kmp_stg_parse_tasking
1354 static void __kmp_stg_print_tasking(kmp_str_buf_t
*buffer
, char const *name
,
1356 __kmp_stg_print_int(buffer
, name
, __kmp_tasking_mode
);
1357 } // __kmp_stg_print_tasking
1359 static void __kmp_stg_parse_task_stealing(char const *name
, char const *value
,
1361 __kmp_stg_parse_int(name
, value
, 0, 1,
1362 (int *)&__kmp_task_stealing_constraint
);
1363 } // __kmp_stg_parse_task_stealing
1365 static void __kmp_stg_print_task_stealing(kmp_str_buf_t
*buffer
,
1366 char const *name
, void *data
) {
1367 __kmp_stg_print_int(buffer
, name
, __kmp_task_stealing_constraint
);
1368 } // __kmp_stg_print_task_stealing
1370 static void __kmp_stg_parse_max_active_levels(char const *name
,
1371 char const *value
, void *data
) {
1372 kmp_uint64 tmp_dflt
= 0;
1373 char const *msg
= NULL
;
1374 if (!__kmp_dflt_max_active_levels_set
) {
1375 // Don't overwrite __kmp_dflt_max_active_levels if we get an invalid setting
1376 __kmp_str_to_uint(value
, &tmp_dflt
, &msg
);
1377 if (msg
!= NULL
) { // invalid setting; print warning and ignore
1378 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
1379 } else if (tmp_dflt
> KMP_MAX_ACTIVE_LEVELS_LIMIT
) {
1380 // invalid setting; print warning and ignore
1381 msg
= KMP_I18N_STR(ValueTooLarge
);
1382 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
1383 } else { // valid setting
1384 __kmp_type_convert(tmp_dflt
, &(__kmp_dflt_max_active_levels
));
1385 __kmp_dflt_max_active_levels_set
= true;
1388 } // __kmp_stg_parse_max_active_levels
1390 static void __kmp_stg_print_max_active_levels(kmp_str_buf_t
*buffer
,
1391 char const *name
, void *data
) {
1392 __kmp_stg_print_int(buffer
, name
, __kmp_dflt_max_active_levels
);
1393 } // __kmp_stg_print_max_active_levels
1395 // -----------------------------------------------------------------------------
1396 // OpenMP 4.0: OMP_DEFAULT_DEVICE
1397 static void __kmp_stg_parse_default_device(char const *name
, char const *value
,
1399 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_DEFAULT_DEVICE_LIMIT
,
1400 &__kmp_default_device
);
1401 } // __kmp_stg_parse_default_device
1403 static void __kmp_stg_print_default_device(kmp_str_buf_t
*buffer
,
1404 char const *name
, void *data
) {
1405 __kmp_stg_print_int(buffer
, name
, __kmp_default_device
);
1406 } // __kmp_stg_print_default_device
1408 // -----------------------------------------------------------------------------
1409 // OpenMP 5.0: OMP_TARGET_OFFLOAD
1410 static void __kmp_stg_parse_target_offload(char const *name
, char const *value
,
1412 kmp_trimmed_str_t
value_str(value
);
1413 const char *scan
= value_str
.get();
1414 __kmp_target_offload
= tgt_default
;
1419 if (!__kmp_strcasecmp_with_sentinel("mandatory", scan
, 0)) {
1420 __kmp_target_offload
= tgt_mandatory
;
1421 } else if (!__kmp_strcasecmp_with_sentinel("disabled", scan
, 0)) {
1422 __kmp_target_offload
= tgt_disabled
;
1423 } else if (!__kmp_strcasecmp_with_sentinel("default", scan
, 0)) {
1424 __kmp_target_offload
= tgt_default
;
1426 KMP_WARNING(SyntaxErrorUsing
, name
, "DEFAULT");
1428 } // __kmp_stg_parse_target_offload
1430 static void __kmp_stg_print_target_offload(kmp_str_buf_t
*buffer
,
1431 char const *name
, void *data
) {
1432 const char *value
= NULL
;
1433 if (__kmp_target_offload
== tgt_default
)
1435 else if (__kmp_target_offload
== tgt_mandatory
)
1436 value
= "MANDATORY";
1437 else if (__kmp_target_offload
== tgt_disabled
)
1439 KMP_DEBUG_ASSERT(value
);
1440 if (__kmp_env_format
) {
1441 KMP_STR_BUF_PRINT_NAME
;
1443 __kmp_str_buf_print(buffer
, " %s", name
);
1445 __kmp_str_buf_print(buffer
, "=%s\n", value
);
1446 } // __kmp_stg_print_target_offload
1448 // -----------------------------------------------------------------------------
1449 // OpenMP 4.5: OMP_MAX_TASK_PRIORITY
1450 static void __kmp_stg_parse_max_task_priority(char const *name
,
1451 char const *value
, void *data
) {
1452 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_TASK_PRIORITY_LIMIT
,
1453 &__kmp_max_task_priority
);
1454 } // __kmp_stg_parse_max_task_priority
1456 static void __kmp_stg_print_max_task_priority(kmp_str_buf_t
*buffer
,
1457 char const *name
, void *data
) {
1458 __kmp_stg_print_int(buffer
, name
, __kmp_max_task_priority
);
1459 } // __kmp_stg_print_max_task_priority
1461 // KMP_TASKLOOP_MIN_TASKS
1462 // taskloop threshold to switch from recursive to linear tasks creation
1463 static void __kmp_stg_parse_taskloop_min_tasks(char const *name
,
1464 char const *value
, void *data
) {
1466 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &tmp
);
1467 __kmp_taskloop_min_tasks
= tmp
;
1468 } // __kmp_stg_parse_taskloop_min_tasks
1470 static void __kmp_stg_print_taskloop_min_tasks(kmp_str_buf_t
*buffer
,
1471 char const *name
, void *data
) {
1472 __kmp_stg_print_uint64(buffer
, name
, __kmp_taskloop_min_tasks
);
1473 } // __kmp_stg_print_taskloop_min_tasks
1475 // -----------------------------------------------------------------------------
1476 // KMP_DISP_NUM_BUFFERS
1477 static void __kmp_stg_parse_disp_buffers(char const *name
, char const *value
,
1479 if (TCR_4(__kmp_init_serial
)) {
1480 KMP_WARNING(EnvSerialWarn
, name
);
1482 } // read value before serial initialization only
1483 __kmp_stg_parse_int(name
, value
, KMP_MIN_DISP_NUM_BUFF
, KMP_MAX_DISP_NUM_BUFF
,
1484 &__kmp_dispatch_num_buffers
);
1485 } // __kmp_stg_parse_disp_buffers
1487 static void __kmp_stg_print_disp_buffers(kmp_str_buf_t
*buffer
,
1488 char const *name
, void *data
) {
1489 __kmp_stg_print_int(buffer
, name
, __kmp_dispatch_num_buffers
);
1490 } // __kmp_stg_print_disp_buffers
1492 #if KMP_NESTED_HOT_TEAMS
1493 // -----------------------------------------------------------------------------
1494 // KMP_HOT_TEAMS_MAX_LEVEL, KMP_HOT_TEAMS_MODE
1496 static void __kmp_stg_parse_hot_teams_level(char const *name
, char const *value
,
1498 if (TCR_4(__kmp_init_parallel
)) {
1499 KMP_WARNING(EnvParallelWarn
, name
);
1501 } // read value before first parallel only
1502 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT
,
1503 &__kmp_hot_teams_max_level
);
1504 } // __kmp_stg_parse_hot_teams_level
1506 static void __kmp_stg_print_hot_teams_level(kmp_str_buf_t
*buffer
,
1507 char const *name
, void *data
) {
1508 __kmp_stg_print_int(buffer
, name
, __kmp_hot_teams_max_level
);
1509 } // __kmp_stg_print_hot_teams_level
1511 static void __kmp_stg_parse_hot_teams_mode(char const *name
, char const *value
,
1513 if (TCR_4(__kmp_init_parallel
)) {
1514 KMP_WARNING(EnvParallelWarn
, name
);
1516 } // read value before first parallel only
1517 __kmp_stg_parse_int(name
, value
, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT
,
1518 &__kmp_hot_teams_mode
);
1519 } // __kmp_stg_parse_hot_teams_mode
1521 static void __kmp_stg_print_hot_teams_mode(kmp_str_buf_t
*buffer
,
1522 char const *name
, void *data
) {
1523 __kmp_stg_print_int(buffer
, name
, __kmp_hot_teams_mode
);
1524 } // __kmp_stg_print_hot_teams_mode
1526 #endif // KMP_NESTED_HOT_TEAMS
1528 // -----------------------------------------------------------------------------
1529 // KMP_HANDLE_SIGNALS
1531 #if KMP_HANDLE_SIGNALS
1533 static void __kmp_stg_parse_handle_signals(char const *name
, char const *value
,
1535 __kmp_stg_parse_bool(name
, value
, &__kmp_handle_signals
);
1536 } // __kmp_stg_parse_handle_signals
1538 static void __kmp_stg_print_handle_signals(kmp_str_buf_t
*buffer
,
1539 char const *name
, void *data
) {
1540 __kmp_stg_print_bool(buffer
, name
, __kmp_handle_signals
);
1541 } // __kmp_stg_print_handle_signals
1543 #endif // KMP_HANDLE_SIGNALS
1545 // -----------------------------------------------------------------------------
1546 // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG
1550 #define KMP_STG_X_DEBUG(x) \
1551 static void __kmp_stg_parse_##x##_debug(char const *name, char const *value, \
1553 __kmp_stg_parse_int(name, value, 0, INT_MAX, &kmp_##x##_debug); \
1554 } /* __kmp_stg_parse_x_debug */ \
1555 static void __kmp_stg_print_##x##_debug(kmp_str_buf_t *buffer, \
1556 char const *name, void *data) { \
1557 __kmp_stg_print_int(buffer, name, kmp_##x##_debug); \
1558 } /* __kmp_stg_print_x_debug */
1567 #undef KMP_STG_X_DEBUG
1569 static void __kmp_stg_parse_debug(char const *name
, char const *value
,
1572 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &debug
);
1573 if (kmp_a_debug
< debug
) {
1574 kmp_a_debug
= debug
;
1576 if (kmp_b_debug
< debug
) {
1577 kmp_b_debug
= debug
;
1579 if (kmp_c_debug
< debug
) {
1580 kmp_c_debug
= debug
;
1582 if (kmp_d_debug
< debug
) {
1583 kmp_d_debug
= debug
;
1585 if (kmp_e_debug
< debug
) {
1586 kmp_e_debug
= debug
;
1588 if (kmp_f_debug
< debug
) {
1589 kmp_f_debug
= debug
;
1591 } // __kmp_stg_parse_debug
1593 static void __kmp_stg_parse_debug_buf(char const *name
, char const *value
,
1595 __kmp_stg_parse_bool(name
, value
, &__kmp_debug_buf
);
1596 // !!! TODO: Move buffer initialization of this file! It may works
1597 // incorrectly if KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or
1598 // KMP_DEBUG_BUF_CHARS.
1599 if (__kmp_debug_buf
) {
1601 int elements
= __kmp_debug_buf_lines
* __kmp_debug_buf_chars
;
1603 /* allocate and initialize all entries in debug buffer to empty */
1604 __kmp_debug_buffer
= (char *)__kmp_page_allocate(elements
* sizeof(char));
1605 for (i
= 0; i
< elements
; i
+= __kmp_debug_buf_chars
)
1606 __kmp_debug_buffer
[i
] = '\0';
1608 __kmp_debug_count
= 0;
1610 K_DIAG(1, ("__kmp_debug_buf = %d\n", __kmp_debug_buf
));
1611 } // __kmp_stg_parse_debug_buf
1613 static void __kmp_stg_print_debug_buf(kmp_str_buf_t
*buffer
, char const *name
,
1615 __kmp_stg_print_bool(buffer
, name
, __kmp_debug_buf
);
1616 } // __kmp_stg_print_debug_buf
1618 static void __kmp_stg_parse_debug_buf_atomic(char const *name
,
1619 char const *value
, void *data
) {
1620 __kmp_stg_parse_bool(name
, value
, &__kmp_debug_buf_atomic
);
1621 } // __kmp_stg_parse_debug_buf_atomic
1623 static void __kmp_stg_print_debug_buf_atomic(kmp_str_buf_t
*buffer
,
1624 char const *name
, void *data
) {
1625 __kmp_stg_print_bool(buffer
, name
, __kmp_debug_buf_atomic
);
1626 } // __kmp_stg_print_debug_buf_atomic
1628 static void __kmp_stg_parse_debug_buf_chars(char const *name
, char const *value
,
1630 __kmp_stg_parse_int(name
, value
, KMP_DEBUG_BUF_CHARS_MIN
, INT_MAX
,
1631 &__kmp_debug_buf_chars
);
1632 } // __kmp_stg_debug_parse_buf_chars
1634 static void __kmp_stg_print_debug_buf_chars(kmp_str_buf_t
*buffer
,
1635 char const *name
, void *data
) {
1636 __kmp_stg_print_int(buffer
, name
, __kmp_debug_buf_chars
);
1637 } // __kmp_stg_print_debug_buf_chars
1639 static void __kmp_stg_parse_debug_buf_lines(char const *name
, char const *value
,
1641 __kmp_stg_parse_int(name
, value
, KMP_DEBUG_BUF_LINES_MIN
, INT_MAX
,
1642 &__kmp_debug_buf_lines
);
1643 } // __kmp_stg_parse_debug_buf_lines
1645 static void __kmp_stg_print_debug_buf_lines(kmp_str_buf_t
*buffer
,
1646 char const *name
, void *data
) {
1647 __kmp_stg_print_int(buffer
, name
, __kmp_debug_buf_lines
);
1648 } // __kmp_stg_print_debug_buf_lines
1650 static void __kmp_stg_parse_diag(char const *name
, char const *value
,
1652 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &kmp_diag
);
1653 } // __kmp_stg_parse_diag
1655 static void __kmp_stg_print_diag(kmp_str_buf_t
*buffer
, char const *name
,
1657 __kmp_stg_print_int(buffer
, name
, kmp_diag
);
1658 } // __kmp_stg_print_diag
1662 // -----------------------------------------------------------------------------
1665 static void __kmp_stg_parse_align_alloc(char const *name
, char const *value
,
1667 __kmp_stg_parse_size(name
, value
, CACHE_LINE
, INT_MAX
, NULL
,
1668 &__kmp_align_alloc
, 1);
1669 } // __kmp_stg_parse_align_alloc
1671 static void __kmp_stg_print_align_alloc(kmp_str_buf_t
*buffer
, char const *name
,
1673 __kmp_stg_print_size(buffer
, name
, __kmp_align_alloc
);
1674 } // __kmp_stg_print_align_alloc
1676 // -----------------------------------------------------------------------------
1677 // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER
1679 // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from
1680 // parse and print functions, pass required info through data argument.
1682 static void __kmp_stg_parse_barrier_branch_bit(char const *name
,
1683 char const *value
, void *data
) {
1686 /* ---------- Barrier branch bit control ------------ */
1687 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1688 var
= __kmp_barrier_branch_bit_env_name
[i
];
1689 if ((strcmp(var
, name
) == 0) && (value
!= 0)) {
1692 comma
= CCAST(char *, strchr(value
, ','));
1693 __kmp_barrier_gather_branch_bits
[i
] =
1694 (kmp_uint32
)__kmp_str_to_int(value
, ',');
1695 /* is there a specified release parameter? */
1696 if (comma
== NULL
) {
1697 __kmp_barrier_release_branch_bits
[i
] = __kmp_barrier_release_bb_dflt
;
1699 __kmp_barrier_release_branch_bits
[i
] =
1700 (kmp_uint32
)__kmp_str_to_int(comma
+ 1, 0);
1702 if (__kmp_barrier_release_branch_bits
[i
] > KMP_MAX_BRANCH_BITS
) {
1703 __kmp_msg(kmp_ms_warning
,
1704 KMP_MSG(BarrReleaseValueInvalid
, name
, comma
+ 1),
1706 __kmp_barrier_release_branch_bits
[i
] = __kmp_barrier_release_bb_dflt
;
1709 if (__kmp_barrier_gather_branch_bits
[i
] > KMP_MAX_BRANCH_BITS
) {
1710 KMP_WARNING(BarrGatherValueInvalid
, name
, value
);
1711 KMP_INFORM(Using_uint_Value
, name
, __kmp_barrier_gather_bb_dflt
);
1712 __kmp_barrier_gather_branch_bits
[i
] = __kmp_barrier_gather_bb_dflt
;
1715 K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name
[i
],
1716 __kmp_barrier_gather_branch_bits
[i
],
1717 __kmp_barrier_release_branch_bits
[i
]))
1719 } // __kmp_stg_parse_barrier_branch_bit
1721 static void __kmp_stg_print_barrier_branch_bit(kmp_str_buf_t
*buffer
,
1722 char const *name
, void *data
) {
1724 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1725 var
= __kmp_barrier_branch_bit_env_name
[i
];
1726 if (strcmp(var
, name
) == 0) {
1727 if (__kmp_env_format
) {
1728 KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_branch_bit_env_name
[i
]);
1730 __kmp_str_buf_print(buffer
, " %s='",
1731 __kmp_barrier_branch_bit_env_name
[i
]);
1733 __kmp_str_buf_print(buffer
, "%d,%d'\n",
1734 __kmp_barrier_gather_branch_bits
[i
],
1735 __kmp_barrier_release_branch_bits
[i
]);
1738 } // __kmp_stg_print_barrier_branch_bit
1740 // ----------------------------------------------------------------------------
1741 // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN,
1742 // KMP_REDUCTION_BARRIER_PATTERN
1744 // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and
1745 // print functions, pass required data to functions through data argument.
1747 static void __kmp_stg_parse_barrier_pattern(char const *name
, char const *value
,
1750 /* ---------- Barrier method control ------------ */
1752 static int dist_req
= 0, non_dist_req
= 0;
1753 static bool warn
= 1;
1754 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1755 var
= __kmp_barrier_pattern_env_name
[i
];
1757 if ((strcmp(var
, name
) == 0) && (value
!= 0)) {
1759 char *comma
= CCAST(char *, strchr(value
, ','));
1761 /* handle first parameter: gather pattern */
1762 for (j
= bp_linear_bar
; j
< bp_last_bar
; j
++) {
1763 if (__kmp_match_with_sentinel(__kmp_barrier_pattern_name
[j
], value
, 1,
1765 if (j
== bp_dist_bar
) {
1770 __kmp_barrier_gather_pattern
[i
] = (kmp_bar_pat_e
)j
;
1774 if (j
== bp_last_bar
) {
1775 KMP_WARNING(BarrGatherValueInvalid
, name
, value
);
1776 KMP_INFORM(Using_str_Value
, name
,
1777 __kmp_barrier_pattern_name
[bp_linear_bar
]);
1780 /* handle second parameter: release pattern */
1781 if (comma
!= NULL
) {
1782 for (j
= bp_linear_bar
; j
< bp_last_bar
; j
++) {
1783 if (__kmp_str_match(__kmp_barrier_pattern_name
[j
], 1, comma
+ 1)) {
1784 if (j
== bp_dist_bar
) {
1789 __kmp_barrier_release_pattern
[i
] = (kmp_bar_pat_e
)j
;
1793 if (j
== bp_last_bar
) {
1794 __kmp_msg(kmp_ms_warning
,
1795 KMP_MSG(BarrReleaseValueInvalid
, name
, comma
+ 1),
1797 KMP_INFORM(Using_str_Value
, name
,
1798 __kmp_barrier_pattern_name
[bp_linear_bar
]);
1803 if (dist_req
!= 0) {
1804 // set all barriers to dist
1805 if ((non_dist_req
!= 0) && warn
) {
1806 KMP_INFORM(BarrierPatternOverride
, name
,
1807 __kmp_barrier_pattern_name
[bp_dist_bar
]);
1810 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1811 if (__kmp_barrier_release_pattern
[i
] != bp_dist_bar
)
1812 __kmp_barrier_release_pattern
[i
] = bp_dist_bar
;
1813 if (__kmp_barrier_gather_pattern
[i
] != bp_dist_bar
)
1814 __kmp_barrier_gather_pattern
[i
] = bp_dist_bar
;
1817 } // __kmp_stg_parse_barrier_pattern
1819 static void __kmp_stg_print_barrier_pattern(kmp_str_buf_t
*buffer
,
1820 char const *name
, void *data
) {
1822 for (int i
= bs_plain_barrier
; i
< bs_last_barrier
; i
++) {
1823 var
= __kmp_barrier_pattern_env_name
[i
];
1824 if (strcmp(var
, name
) == 0) {
1825 int j
= __kmp_barrier_gather_pattern
[i
];
1826 int k
= __kmp_barrier_release_pattern
[i
];
1827 if (__kmp_env_format
) {
1828 KMP_STR_BUF_PRINT_NAME_EX(__kmp_barrier_pattern_env_name
[i
]);
1830 __kmp_str_buf_print(buffer
, " %s='",
1831 __kmp_barrier_pattern_env_name
[i
]);
1833 KMP_DEBUG_ASSERT(j
< bp_last_bar
&& k
< bp_last_bar
);
1834 __kmp_str_buf_print(buffer
, "%s,%s'\n", __kmp_barrier_pattern_name
[j
],
1835 __kmp_barrier_pattern_name
[k
]);
1838 } // __kmp_stg_print_barrier_pattern
1840 // -----------------------------------------------------------------------------
1843 static void __kmp_stg_parse_abort_delay(char const *name
, char const *value
,
1845 // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is
1847 int delay
= __kmp_abort_delay
/ 1000;
1848 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
/ 1000, &delay
);
1849 __kmp_abort_delay
= delay
* 1000;
1850 } // __kmp_stg_parse_abort_delay
1852 static void __kmp_stg_print_abort_delay(kmp_str_buf_t
*buffer
, char const *name
,
1854 __kmp_stg_print_int(buffer
, name
, __kmp_abort_delay
);
1855 } // __kmp_stg_print_abort_delay
1857 // -----------------------------------------------------------------------------
1860 static void __kmp_stg_parse_cpuinfo_file(char const *name
, char const *value
,
1862 #if KMP_AFFINITY_SUPPORTED
1863 __kmp_stg_parse_str(name
, value
, &__kmp_cpuinfo_file
);
1864 K_DIAG(1, ("__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file
));
1866 } //__kmp_stg_parse_cpuinfo_file
1868 static void __kmp_stg_print_cpuinfo_file(kmp_str_buf_t
*buffer
,
1869 char const *name
, void *data
) {
1870 #if KMP_AFFINITY_SUPPORTED
1871 if (__kmp_env_format
) {
1872 KMP_STR_BUF_PRINT_NAME
;
1874 __kmp_str_buf_print(buffer
, " %s", name
);
1876 if (__kmp_cpuinfo_file
) {
1877 __kmp_str_buf_print(buffer
, "='%s'\n", __kmp_cpuinfo_file
);
1879 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
1882 } //__kmp_stg_print_cpuinfo_file
1884 // -----------------------------------------------------------------------------
1885 // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION
1887 static void __kmp_stg_parse_force_reduction(char const *name
, char const *value
,
1889 kmp_stg_fr_data_t
*reduction
= (kmp_stg_fr_data_t
*)data
;
1892 rc
= __kmp_stg_check_rivals(name
, value
, reduction
->rivals
);
1896 if (reduction
->force
) {
1898 if (__kmp_str_match("critical", 0, value
))
1899 __kmp_force_reduction_method
= critical_reduce_block
;
1900 else if (__kmp_str_match("atomic", 0, value
))
1901 __kmp_force_reduction_method
= atomic_reduce_block
;
1902 else if (__kmp_str_match("tree", 0, value
))
1903 __kmp_force_reduction_method
= tree_reduce_block
;
1905 KMP_FATAL(UnknownForceReduction
, name
, value
);
1909 __kmp_stg_parse_bool(name
, value
, &__kmp_determ_red
);
1910 if (__kmp_determ_red
) {
1911 __kmp_force_reduction_method
= tree_reduce_block
;
1913 __kmp_force_reduction_method
= reduction_method_not_defined
;
1916 K_DIAG(1, ("__kmp_force_reduction_method == %d\n",
1917 __kmp_force_reduction_method
));
1918 } // __kmp_stg_parse_force_reduction
1920 static void __kmp_stg_print_force_reduction(kmp_str_buf_t
*buffer
,
1921 char const *name
, void *data
) {
1923 kmp_stg_fr_data_t
*reduction
= (kmp_stg_fr_data_t
*)data
;
1924 if (reduction
->force
) {
1925 if (__kmp_force_reduction_method
== critical_reduce_block
) {
1926 __kmp_stg_print_str(buffer
, name
, "critical");
1927 } else if (__kmp_force_reduction_method
== atomic_reduce_block
) {
1928 __kmp_stg_print_str(buffer
, name
, "atomic");
1929 } else if (__kmp_force_reduction_method
== tree_reduce_block
) {
1930 __kmp_stg_print_str(buffer
, name
, "tree");
1932 if (__kmp_env_format
) {
1933 KMP_STR_BUF_PRINT_NAME
;
1935 __kmp_str_buf_print(buffer
, " %s", name
);
1937 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
1940 __kmp_stg_print_bool(buffer
, name
, __kmp_determ_red
);
1943 } // __kmp_stg_print_force_reduction
1945 // -----------------------------------------------------------------------------
1948 static void __kmp_stg_parse_storage_map(char const *name
, char const *value
,
1950 if (__kmp_str_match("verbose", 1, value
)) {
1951 __kmp_storage_map
= TRUE
;
1952 __kmp_storage_map_verbose
= TRUE
;
1953 __kmp_storage_map_verbose_specified
= TRUE
;
1956 __kmp_storage_map_verbose
= FALSE
;
1957 __kmp_stg_parse_bool(name
, value
, &__kmp_storage_map
); // !!!
1959 } // __kmp_stg_parse_storage_map
1961 static void __kmp_stg_print_storage_map(kmp_str_buf_t
*buffer
, char const *name
,
1963 if (__kmp_storage_map_verbose
|| __kmp_storage_map_verbose_specified
) {
1964 __kmp_stg_print_str(buffer
, name
, "verbose");
1966 __kmp_stg_print_bool(buffer
, name
, __kmp_storage_map
);
1968 } // __kmp_stg_print_storage_map
1970 // -----------------------------------------------------------------------------
1971 // KMP_ALL_THREADPRIVATE
1973 static void __kmp_stg_parse_all_threadprivate(char const *name
,
1974 char const *value
, void *data
) {
1975 __kmp_stg_parse_int(name
, value
,
1976 __kmp_allThreadsSpecified
? __kmp_max_nth
: 1,
1977 __kmp_max_nth
, &__kmp_tp_capacity
);
1978 } // __kmp_stg_parse_all_threadprivate
1980 static void __kmp_stg_print_all_threadprivate(kmp_str_buf_t
*buffer
,
1981 char const *name
, void *data
) {
1982 __kmp_stg_print_int(buffer
, name
, __kmp_tp_capacity
);
1985 // -----------------------------------------------------------------------------
1986 // KMP_FOREIGN_THREADS_THREADPRIVATE
1988 static void __kmp_stg_parse_foreign_threads_threadprivate(char const *name
,
1991 __kmp_stg_parse_bool(name
, value
, &__kmp_foreign_tp
);
1992 } // __kmp_stg_parse_foreign_threads_threadprivate
1994 static void __kmp_stg_print_foreign_threads_threadprivate(kmp_str_buf_t
*buffer
,
1997 __kmp_stg_print_bool(buffer
, name
, __kmp_foreign_tp
);
1998 } // __kmp_stg_print_foreign_threads_threadprivate
2000 // -----------------------------------------------------------------------------
2001 // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD
2003 static inline const char *
2004 __kmp_hw_get_core_type_keyword(kmp_hw_core_type_t type
) {
2006 case KMP_HW_CORE_TYPE_UNKNOWN
:
2008 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
2009 case KMP_HW_CORE_TYPE_ATOM
:
2010 return "intel_atom";
2011 case KMP_HW_CORE_TYPE_CORE
:
2012 return "intel_core";
2018 #if KMP_AFFINITY_SUPPORTED
2019 // Parse the proc id list. Return TRUE if successful, FALSE otherwise.
2020 static int __kmp_parse_affinity_proc_id_list(const char *var
, const char *env
,
2021 const char **nextEnv
,
2023 const char *scan
= env
;
2024 const char *next
= scan
;
2030 int start
, end
, stride
;
2034 if (*next
== '\0') {
2044 // Read the first integer in the set.
2045 if ((*next
< '0') || (*next
> '9')) {
2046 KMP_WARNING(AffSyntaxError
, var
);
2050 num
= __kmp_str_to_int(scan
, *next
);
2051 KMP_ASSERT(num
>= 0);
2054 // Check for end of set.
2061 // Skip optional comma.
2067 // Read the next integer in the set.
2069 if ((*next
< '0') || (*next
> '9')) {
2070 KMP_WARNING(AffSyntaxError
, var
);
2075 num
= __kmp_str_to_int(scan
, *next
);
2076 KMP_ASSERT(num
>= 0);
2088 // Next character is not an integer => end of list
2089 if ((*next
< '0') || (*next
> '9')) {
2091 KMP_WARNING(AffSyntaxError
, var
);
2097 // Read the first integer.
2099 start
= __kmp_str_to_int(scan
, *next
);
2100 KMP_ASSERT(start
>= 0);
2103 // If this isn't a range, then go on.
2107 // Skip optional comma.
2115 // This is a range. Skip over the '-' and read in the 2nd int.
2119 if ((*next
< '0') || (*next
> '9')) {
2120 KMP_WARNING(AffSyntaxError
, var
);
2124 end
= __kmp_str_to_int(scan
, *next
);
2125 KMP_ASSERT(end
>= 0);
2127 // Check for a stride parameter
2131 // A stride is specified. Skip over the ':" and read the 3rd int.
2142 if ((*next
< '0') || (*next
> '9')) {
2143 KMP_WARNING(AffSyntaxError
, var
);
2147 stride
= __kmp_str_to_int(scan
, *next
);
2148 KMP_ASSERT(stride
>= 0);
2152 // Do some range checks.
2154 KMP_WARNING(AffZeroStride
, var
);
2159 KMP_WARNING(AffStartGreaterEnd
, var
, start
, end
);
2164 KMP_WARNING(AffStrideLessZero
, var
, start
, end
);
2168 if ((end
- start
) / stride
> 65536) {
2169 KMP_WARNING(AffRangeTooBig
, var
, end
, start
, stride
);
2175 // Skip optional comma.
2186 ptrdiff_t len
= next
- env
;
2187 char *retlist
= (char *)__kmp_allocate((len
+ 1) * sizeof(char));
2188 KMP_MEMCPY_S(retlist
, (len
+ 1) * sizeof(char), env
, len
* sizeof(char));
2189 retlist
[len
] = '\0';
2190 *proclist
= retlist
;
2195 // If KMP_AFFINITY is specified without a type, then
2196 // __kmp_affinity_notype should point to its setting.
2197 static kmp_setting_t
*__kmp_affinity_notype
= NULL
;
2199 static void __kmp_parse_affinity_env(char const *name
, char const *value
,
2200 kmp_affinity_t
*out_affinity
) {
2201 char *buffer
= NULL
; // Copy of env var value.
2202 char *buf
= NULL
; // Buffer for strtok_r() function.
2203 char *next
= NULL
; // end of token / start of next.
2204 const char *start
; // start of current token (for err msgs)
2205 int count
= 0; // Counter of parsed integer numbers.
2206 int number
[2]; // Parsed numbers.
2219 KMP_ASSERT(value
!= NULL
);
2221 if (TCR_4(__kmp_init_middle
)) {
2222 KMP_WARNING(EnvMiddleWarn
, name
);
2223 __kmp_env_toPrint(name
, 0);
2226 __kmp_env_toPrint(name
, 1);
2229 __kmp_str_format("%s", value
); // Copy env var to keep original intact.
2235 // If we see a parse error, emit a warning and scan to the next ",".
2237 // FIXME - there's got to be a better way to print an error
2238 // message, hopefully without overwriting peices of buf.
2239 #define EMIT_WARN(skip, errlist) \
2243 SKIP_TO(next, ','); \
2247 KMP_WARNING errlist; \
2256 #define _set_param(_guard, _var, _val) \
2258 if (_guard == 0) { \
2261 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
2266 #define set_type(val) _set_param(type, out_affinity->type, val)
2267 #define set_verbose(val) _set_param(verbose, out_affinity->flags.verbose, val)
2268 #define set_warnings(val) \
2269 _set_param(warnings, out_affinity->flags.warnings, val)
2270 #define set_respect(val) _set_param(respect, out_affinity->flags.respect, val)
2271 #define set_dups(val) _set_param(dups, out_affinity->flags.dups, val)
2272 #define set_proclist(val) _set_param(proclist, out_affinity->proclist, val)
2273 #define set_reset(val) _set_param(reset, out_affinity->flags.reset, val)
2275 #define set_gran(val, levels) \
2278 out_affinity->gran = val; \
2279 out_affinity->gran_levels = levels; \
2281 EMIT_WARN(FALSE, (AffParamDefined, name, start)); \
2286 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind
.bind_types
!= NULL
) &&
2287 (__kmp_nested_proc_bind
.used
> 0));
2289 while (*buf
!= '\0') {
2292 if (__kmp_match_str("none", buf
, CCAST(const char **, &next
))) {
2293 set_type(affinity_none
);
2294 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
2296 } else if (__kmp_match_str("scatter", buf
, CCAST(const char **, &next
))) {
2297 set_type(affinity_scatter
);
2298 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2300 } else if (__kmp_match_str("compact", buf
, CCAST(const char **, &next
))) {
2301 set_type(affinity_compact
);
2302 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2304 } else if (__kmp_match_str("logical", buf
, CCAST(const char **, &next
))) {
2305 set_type(affinity_logical
);
2306 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2308 } else if (__kmp_match_str("physical", buf
, CCAST(const char **, &next
))) {
2309 set_type(affinity_physical
);
2310 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2312 } else if (__kmp_match_str("explicit", buf
, CCAST(const char **, &next
))) {
2313 set_type(affinity_explicit
);
2314 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2316 } else if (__kmp_match_str("balanced", buf
, CCAST(const char **, &next
))) {
2317 set_type(affinity_balanced
);
2318 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2320 } else if (__kmp_match_str("disabled", buf
, CCAST(const char **, &next
))) {
2321 set_type(affinity_disabled
);
2322 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
2324 } else if (__kmp_match_str("verbose", buf
, CCAST(const char **, &next
))) {
2327 } else if (__kmp_match_str("noverbose", buf
, CCAST(const char **, &next
))) {
2330 } else if (__kmp_match_str("warnings", buf
, CCAST(const char **, &next
))) {
2333 } else if (__kmp_match_str("nowarnings", buf
,
2334 CCAST(const char **, &next
))) {
2335 set_warnings(FALSE
);
2337 } else if (__kmp_match_str("respect", buf
, CCAST(const char **, &next
))) {
2340 } else if (__kmp_match_str("norespect", buf
, CCAST(const char **, &next
))) {
2343 } else if (__kmp_match_str("reset", buf
, CCAST(const char **, &next
))) {
2346 } else if (__kmp_match_str("noreset", buf
, CCAST(const char **, &next
))) {
2349 } else if (__kmp_match_str("duplicates", buf
,
2350 CCAST(const char **, &next
)) ||
2351 __kmp_match_str("dups", buf
, CCAST(const char **, &next
))) {
2354 } else if (__kmp_match_str("noduplicates", buf
,
2355 CCAST(const char **, &next
)) ||
2356 __kmp_match_str("nodups", buf
, CCAST(const char **, &next
))) {
2359 } else if (__kmp_match_str("granularity", buf
,
2360 CCAST(const char **, &next
)) ||
2361 __kmp_match_str("gran", buf
, CCAST(const char **, &next
))) {
2364 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2372 // Have to try core_type and core_efficiency matches first since "core"
2373 // will register as core granularity with "extra chars"
2374 if (__kmp_match_str("core_type", buf
, CCAST(const char **, &next
))) {
2375 set_gran(KMP_HW_CORE
, -1);
2376 out_affinity
->flags
.core_types_gran
= 1;
2379 } else if (__kmp_match_str("core_efficiency", buf
,
2380 CCAST(const char **, &next
)) ||
2381 __kmp_match_str("core_eff", buf
,
2382 CCAST(const char **, &next
))) {
2383 set_gran(KMP_HW_CORE
, -1);
2384 out_affinity
->flags
.core_effs_gran
= 1;
2389 // Try any hardware topology type for granularity
2390 KMP_FOREACH_HW_TYPE(type
) {
2391 const char *name
= __kmp_hw_get_keyword(type
);
2392 if (__kmp_match_str(name
, buf
, CCAST(const char **, &next
))) {
2401 // Support older names for different granularity layers
2402 if (__kmp_match_str("fine", buf
, CCAST(const char **, &next
))) {
2403 set_gran(KMP_HW_THREAD
, -1);
2406 } else if (__kmp_match_str("package", buf
,
2407 CCAST(const char **, &next
))) {
2408 set_gran(KMP_HW_SOCKET
, -1);
2411 } else if (__kmp_match_str("node", buf
, CCAST(const char **, &next
))) {
2412 set_gran(KMP_HW_NUMA
, -1);
2415 #if KMP_GROUP_AFFINITY
2416 } else if (__kmp_match_str("group", buf
, CCAST(const char **, &next
))) {
2417 set_gran(KMP_HW_PROC_GROUP
, -1);
2420 #endif /* KMP_GROUP AFFINITY */
2421 } else if ((*buf
>= '0') && (*buf
<= '9')) {
2425 n
= __kmp_str_to_int(buf
, *next
);
2428 set_gran(KMP_HW_UNKNOWN
, n
);
2431 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2435 } else if (__kmp_match_str("proclist", buf
, CCAST(const char **, &next
))) {
2436 char *temp_proclist
;
2440 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2446 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2451 if (!__kmp_parse_affinity_proc_id_list(
2452 name
, buf
, CCAST(const char **, &next
), &temp_proclist
)) {
2453 // warning already emitted.
2464 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2468 set_proclist(temp_proclist
);
2469 } else if ((*buf
>= '0') && (*buf
<= '9')) {
2470 // Parse integer numbers -- permute and offset.
2474 n
= __kmp_str_to_int(buf
, *next
);
2480 KMP_WARNING(AffManyParams
, name
, start
);
2484 EMIT_WARN(TRUE
, (AffInvalidParam
, name
, start
));
2492 } else if (*next
!= '\0') {
2493 const char *temp
= next
;
2494 EMIT_WARN(TRUE
, (ParseExtraCharsWarn
, name
, temp
));
2506 #undef set_granularity
2509 __kmp_str_free(&buffer
);
2513 KMP_WARNING(AffProcListNoType
, name
);
2514 out_affinity
->type
= affinity_explicit
;
2515 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2516 } else if (out_affinity
->type
!= affinity_explicit
) {
2517 KMP_WARNING(AffProcListNotExplicit
, name
);
2518 KMP_ASSERT(out_affinity
->proclist
!= NULL
);
2519 KMP_INTERNAL_FREE(out_affinity
->proclist
);
2520 out_affinity
->proclist
= NULL
;
2523 switch (out_affinity
->type
) {
2524 case affinity_logical
:
2525 case affinity_physical
: {
2527 out_affinity
->offset
= number
[0];
2530 KMP_WARNING(AffManyParamsForLogic
, name
, number
[1]);
2533 case affinity_balanced
: {
2535 out_affinity
->compact
= number
[0];
2538 out_affinity
->offset
= number
[1];
2541 if (__kmp_affinity
.gran
== KMP_HW_UNKNOWN
) {
2542 int verbose
= out_affinity
->flags
.verbose
;
2543 int warnings
= out_affinity
->flags
.warnings
;
2544 #if KMP_MIC_SUPPORTED
2545 if (__kmp_mic_type
!= non_mic
) {
2546 if (verbose
|| warnings
) {
2547 KMP_WARNING(AffGranUsing
, out_affinity
->env_var
, "fine");
2549 out_affinity
->gran
= KMP_HW_THREAD
;
2553 if (verbose
|| warnings
) {
2554 KMP_WARNING(AffGranUsing
, out_affinity
->env_var
, "core");
2556 out_affinity
->gran
= KMP_HW_CORE
;
2560 case affinity_scatter
:
2561 case affinity_compact
: {
2563 out_affinity
->compact
= number
[0];
2566 out_affinity
->offset
= number
[1];
2569 case affinity_explicit
: {
2570 if (out_affinity
->proclist
== NULL
) {
2571 KMP_WARNING(AffNoProcList
, name
);
2572 out_affinity
->type
= affinity_none
;
2575 KMP_WARNING(AffNoParam
, name
, "explicit");
2578 case affinity_none
: {
2580 KMP_WARNING(AffNoParam
, name
, "none");
2583 case affinity_disabled
: {
2585 KMP_WARNING(AffNoParam
, name
, "disabled");
2588 case affinity_default
: {
2590 KMP_WARNING(AffNoParam
, name
, "default");
2597 } // __kmp_parse_affinity_env
2599 static void __kmp_stg_parse_affinity(char const *name
, char const *value
,
2601 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
2604 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
2609 __kmp_parse_affinity_env(name
, value
, &__kmp_affinity
);
2611 } // __kmp_stg_parse_affinity
2612 static void __kmp_stg_parse_hh_affinity(char const *name
, char const *value
,
2614 __kmp_parse_affinity_env(name
, value
, &__kmp_hh_affinity
);
2615 // Warn about unused parts of hidden helper affinity settings if specified.
2616 if (__kmp_hh_affinity
.flags
.reset
) {
2617 KMP_WARNING(AffInvalidParam
, name
, "reset");
2619 if (__kmp_hh_affinity
.flags
.respect
!= affinity_respect_mask_default
) {
2620 KMP_WARNING(AffInvalidParam
, name
, "respect");
2624 static void __kmp_print_affinity_env(kmp_str_buf_t
*buffer
, char const *name
,
2625 const kmp_affinity_t
&affinity
) {
2626 bool is_hh_affinity
= (&affinity
== &__kmp_hh_affinity
);
2627 if (__kmp_env_format
) {
2628 KMP_STR_BUF_PRINT_NAME_EX(name
);
2630 __kmp_str_buf_print(buffer
, " %s='", name
);
2632 if (affinity
.flags
.verbose
) {
2633 __kmp_str_buf_print(buffer
, "%s,", "verbose");
2635 __kmp_str_buf_print(buffer
, "%s,", "noverbose");
2637 if (affinity
.flags
.warnings
) {
2638 __kmp_str_buf_print(buffer
, "%s,", "warnings");
2640 __kmp_str_buf_print(buffer
, "%s,", "nowarnings");
2642 if (KMP_AFFINITY_CAPABLE()) {
2643 // Hidden helper affinity does not affect global reset
2644 // or respect flags. That is still solely controlled by KMP_AFFINITY.
2645 if (!is_hh_affinity
) {
2646 if (affinity
.flags
.respect
) {
2647 __kmp_str_buf_print(buffer
, "%s,", "respect");
2649 __kmp_str_buf_print(buffer
, "%s,", "norespect");
2651 if (affinity
.flags
.reset
) {
2652 __kmp_str_buf_print(buffer
, "%s,", "reset");
2654 __kmp_str_buf_print(buffer
, "%s,", "noreset");
2657 __kmp_str_buf_print(buffer
, "granularity=");
2658 if (affinity
.flags
.core_types_gran
)
2659 __kmp_str_buf_print(buffer
, "core_type,");
2660 else if (affinity
.flags
.core_effs_gran
) {
2661 __kmp_str_buf_print(buffer
, "core_eff,");
2663 __kmp_str_buf_print(
2664 buffer
, "%s,", __kmp_hw_get_keyword(affinity
.gran
, /*plural=*/false));
2667 if (!KMP_AFFINITY_CAPABLE()) {
2668 __kmp_str_buf_print(buffer
, "%s", "disabled");
2670 int compact
= affinity
.compact
;
2671 int offset
= affinity
.offset
;
2672 switch (affinity
.type
) {
2674 __kmp_str_buf_print(buffer
, "%s", "none");
2676 case affinity_physical
:
2677 __kmp_str_buf_print(buffer
, "%s,%d", "physical", offset
);
2679 case affinity_logical
:
2680 __kmp_str_buf_print(buffer
, "%s,%d", "logical", offset
);
2682 case affinity_compact
:
2683 __kmp_str_buf_print(buffer
, "%s,%d,%d", "compact", compact
, offset
);
2685 case affinity_scatter
:
2686 __kmp_str_buf_print(buffer
, "%s,%d,%d", "scatter", compact
, offset
);
2688 case affinity_explicit
:
2689 __kmp_str_buf_print(buffer
, "%s=[%s],%s", "proclist", affinity
.proclist
,
2692 case affinity_balanced
:
2693 __kmp_str_buf_print(buffer
, "%s,%d,%d", "balanced", compact
, offset
);
2695 case affinity_disabled
:
2696 __kmp_str_buf_print(buffer
, "%s", "disabled");
2698 case affinity_default
:
2699 __kmp_str_buf_print(buffer
, "%s", "default");
2702 __kmp_str_buf_print(buffer
, "%s", "<unknown>");
2706 __kmp_str_buf_print(buffer
, "'\n");
2707 } //__kmp_stg_print_affinity
2709 static void __kmp_stg_print_affinity(kmp_str_buf_t
*buffer
, char const *name
,
2711 __kmp_print_affinity_env(buffer
, name
, __kmp_affinity
);
2713 static void __kmp_stg_print_hh_affinity(kmp_str_buf_t
*buffer
, char const *name
,
2715 __kmp_print_affinity_env(buffer
, name
, __kmp_hh_affinity
);
2718 #ifdef KMP_GOMP_COMPAT
2720 static void __kmp_stg_parse_gomp_cpu_affinity(char const *name
,
2721 char const *value
, void *data
) {
2722 const char *next
= NULL
;
2723 char *temp_proclist
;
2724 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
2727 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
2732 if (TCR_4(__kmp_init_middle
)) {
2733 KMP_WARNING(EnvMiddleWarn
, name
);
2734 __kmp_env_toPrint(name
, 0);
2738 __kmp_env_toPrint(name
, 1);
2740 if (__kmp_parse_affinity_proc_id_list(name
, value
, &next
, &temp_proclist
)) {
2742 if (*next
== '\0') {
2743 // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...
2744 __kmp_affinity
.proclist
= temp_proclist
;
2745 __kmp_affinity
.type
= affinity_explicit
;
2746 __kmp_affinity
.gran
= KMP_HW_THREAD
;
2747 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
2749 KMP_WARNING(AffSyntaxError
, name
);
2750 if (temp_proclist
!= NULL
) {
2751 KMP_INTERNAL_FREE((void *)temp_proclist
);
2755 // Warning already emitted
2756 __kmp_affinity
.type
= affinity_none
;
2757 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
2759 } // __kmp_stg_parse_gomp_cpu_affinity
2761 #endif /* KMP_GOMP_COMPAT */
2763 /*-----------------------------------------------------------------------------
2764 The OMP_PLACES proc id list parser. Here is the grammar:
2767 place_list := place , place_list
2769 place := place : num
2770 place := place : num : signed
2771 place := { subplacelist }
2772 place := ! place // (lowest priority)
2773 subplace_list := subplace
2774 subplace_list := subplace , subplace_list
2776 subplace := num : num
2777 subplace := num : num : signed
2781 -----------------------------------------------------------------------------*/
2783 // Return TRUE if successful parse, FALSE otherwise
2784 static int __kmp_parse_subplace_list(const char *var
, const char **scan
) {
2788 int start
, count
, stride
;
2791 // Read in the starting proc id
2794 if ((**scan
< '0') || (**scan
> '9')) {
2799 start
= __kmp_str_to_int(*scan
, *next
);
2800 KMP_ASSERT(start
>= 0);
2803 // valid follow sets are ',' ':' and '}'
2805 if (**scan
== '}') {
2808 if (**scan
== ',') {
2809 (*scan
)++; // skip ','
2812 if (**scan
!= ':') {
2815 (*scan
)++; // skip ':'
2817 // Read count parameter
2819 if ((**scan
< '0') || (**scan
> '9')) {
2824 count
= __kmp_str_to_int(*scan
, *next
);
2825 KMP_ASSERT(count
>= 0);
2828 // valid follow sets are ',' ':' and '}'
2830 if (**scan
== '}') {
2833 if (**scan
== ',') {
2834 (*scan
)++; // skip ','
2837 if (**scan
!= ':') {
2840 (*scan
)++; // skip ':'
2842 // Read stride parameter
2846 if (**scan
== '+') {
2847 (*scan
)++; // skip '+'
2850 if (**scan
== '-') {
2852 (*scan
)++; // skip '-'
2858 if ((**scan
< '0') || (**scan
> '9')) {
2863 stride
= __kmp_str_to_int(*scan
, *next
);
2864 KMP_ASSERT(stride
>= 0);
2868 // valid follow sets are ',' and '}'
2870 if (**scan
== '}') {
2873 if (**scan
== ',') {
2874 (*scan
)++; // skip ','
2882 // Return TRUE if successful parse, FALSE otherwise
2883 static int __kmp_parse_place(const char *var
, const char **scan
) {
2886 // valid follow sets are '{' '!' and num
2888 if (**scan
== '{') {
2889 (*scan
)++; // skip '{'
2890 if (!__kmp_parse_subplace_list(var
, scan
)) {
2893 if (**scan
!= '}') {
2896 (*scan
)++; // skip '}'
2897 } else if (**scan
== '!') {
2898 (*scan
)++; // skip '!'
2899 return __kmp_parse_place(var
, scan
); //'!' has lower precedence than ':'
2900 } else if ((**scan
>= '0') && (**scan
<= '9')) {
2903 int proc
= __kmp_str_to_int(*scan
, *next
);
2904 KMP_ASSERT(proc
>= 0);
2912 // Return TRUE if successful parse, FALSE otherwise
2913 static int __kmp_parse_place_list(const char *var
, const char *env
,
2914 char **place_list
) {
2915 const char *scan
= env
;
2916 const char *next
= scan
;
2921 if (!__kmp_parse_place(var
, &scan
)) {
2925 // valid follow sets are ',' ':' and EOL
2927 if (*scan
== '\0') {
2939 // Read count parameter
2941 if ((*scan
< '0') || (*scan
> '9')) {
2946 count
= __kmp_str_to_int(scan
, *next
);
2947 KMP_ASSERT(count
>= 0);
2950 // valid follow sets are ',' ':' and EOL
2952 if (*scan
== '\0') {
2964 // Read stride parameter
2980 if ((*scan
< '0') || (*scan
> '9')) {
2985 stride
= __kmp_str_to_int(scan
, *next
);
2986 KMP_ASSERT(stride
>= 0);
2990 // valid follow sets are ',' and EOL
2992 if (*scan
== '\0') {
3004 ptrdiff_t len
= scan
- env
;
3005 char *retlist
= (char *)__kmp_allocate((len
+ 1) * sizeof(char));
3006 KMP_MEMCPY_S(retlist
, (len
+ 1) * sizeof(char), env
, len
* sizeof(char));
3007 retlist
[len
] = '\0';
3008 *place_list
= retlist
;
3013 static inline void __kmp_places_set(enum affinity_type type
, kmp_hw_t kind
) {
3014 __kmp_affinity
.type
= type
;
3015 __kmp_affinity
.gran
= kind
;
3016 __kmp_affinity
.flags
.dups
= FALSE
;
3017 __kmp_affinity
.flags
.omp_places
= TRUE
;
3020 static void __kmp_places_syntax_error_fallback(char const *name
,
3022 const char *str
= __kmp_hw_get_catalog_string(kind
, /*plural=*/true);
3023 KMP_WARNING(SyntaxErrorUsing
, name
, str
);
3024 __kmp_places_set(affinity_compact
, kind
);
3025 if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
)
3026 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3029 static void __kmp_stg_parse_places(char const *name
, char const *value
,
3031 struct kmp_place_t
{
3037 const char *scan
= value
;
3038 const char *next
= scan
;
3039 kmp_place_t std_places
[] = {{"threads", KMP_HW_THREAD
},
3040 {"cores", KMP_HW_CORE
},
3041 {"numa_domains", KMP_HW_NUMA
},
3042 {"ll_caches", KMP_HW_LLC
},
3043 {"sockets", KMP_HW_SOCKET
}};
3044 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
3047 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
3053 for (size_t i
= 0; i
< sizeof(std_places
) / sizeof(std_places
[0]); ++i
) {
3054 const kmp_place_t
&place
= std_places
[i
];
3055 if (__kmp_match_str(place
.name
, scan
, &next
)) {
3057 __kmp_places_set(affinity_compact
, place
.type
);
3059 // Parse core attribute if it exists
3060 if (KMP_HW_MAX_NUM_CORE_TYPES
> 1) {
3063 if (place
.type
!= KMP_HW_CORE
) {
3064 __kmp_places_syntax_error_fallback(name
, place
.type
);
3069 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3070 if (__kmp_match_str("intel_core", scan
, &next
)) {
3071 __kmp_affinity
.core_attr_gran
.core_type
= KMP_HW_CORE_TYPE_CORE
;
3072 __kmp_affinity
.core_attr_gran
.valid
= 1;
3074 } else if (__kmp_match_str("intel_atom", scan
, &next
)) {
3075 __kmp_affinity
.core_attr_gran
.core_type
= KMP_HW_CORE_TYPE_ATOM
;
3076 __kmp_affinity
.core_attr_gran
.valid
= 1;
3080 if (__kmp_match_str("eff", scan
, &next
)) {
3082 if (!isdigit(*next
)) {
3083 __kmp_places_syntax_error_fallback(name
, place
.type
);
3088 eff
= __kmp_str_to_int(scan
, *next
);
3090 __kmp_places_syntax_error_fallback(name
, place
.type
);
3093 if (eff
>= KMP_HW_MAX_NUM_CORE_EFFS
)
3094 eff
= KMP_HW_MAX_NUM_CORE_EFFS
- 1;
3095 __kmp_affinity
.core_attr_gran
.core_eff
= eff
;
3096 __kmp_affinity
.core_attr_gran
.valid
= 1;
3099 if (!__kmp_affinity
.core_attr_gran
.valid
) {
3100 __kmp_places_syntax_error_fallback(name
, place
.type
);
3108 // Implementation choices for OMP_PLACES based on internal types
3110 KMP_FOREACH_HW_TYPE(type
) {
3111 const char *name
= __kmp_hw_get_keyword(type
, true);
3112 if (__kmp_match_str("unknowns", scan
, &next
))
3114 if (__kmp_match_str(name
, scan
, &next
)) {
3116 __kmp_places_set(affinity_compact
, type
);
3122 // Implementation choices for OMP_PLACES based on core attributes
3124 if (__kmp_match_str("core_types", scan
, &next
)) {
3126 if (*scan
!= '\0') {
3127 KMP_WARNING(ParseExtraCharsWarn
, name
, scan
);
3129 __kmp_places_set(affinity_compact
, KMP_HW_CORE
);
3130 __kmp_affinity
.flags
.core_types_gran
= 1;
3132 } else if (__kmp_match_str("core_effs", scan
, &next
) ||
3133 __kmp_match_str("core_efficiencies", scan
, &next
)) {
3135 if (*scan
!= '\0') {
3136 KMP_WARNING(ParseExtraCharsWarn
, name
, scan
);
3138 __kmp_places_set(affinity_compact
, KMP_HW_CORE
);
3139 __kmp_affinity
.flags
.core_effs_gran
= 1;
3143 // Explicit place list
3145 if (__kmp_affinity
.proclist
!= NULL
) {
3146 KMP_INTERNAL_FREE((void *)__kmp_affinity
.proclist
);
3147 __kmp_affinity
.proclist
= NULL
;
3149 if (__kmp_parse_place_list(name
, value
, &__kmp_affinity
.proclist
)) {
3150 __kmp_places_set(affinity_explicit
, KMP_HW_THREAD
);
3152 // Syntax error fallback
3153 __kmp_places_syntax_error_fallback(name
, KMP_HW_CORE
);
3155 if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
) {
3156 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3161 kmp_hw_t gran
= __kmp_affinity
.gran
;
3162 if (__kmp_affinity
.gran
!= KMP_HW_UNKNOWN
) {
3163 gran
= __kmp_affinity
.gran
;
3168 if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
) {
3169 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3173 if (*scan
== '\0') {
3177 // Parse option count parameter in parentheses
3179 __kmp_places_syntax_error_fallback(name
, gran
);
3187 count
= __kmp_str_to_int(scan
, *next
);
3188 KMP_ASSERT(count
>= 0);
3193 __kmp_places_syntax_error_fallback(name
, gran
);
3199 if (*scan
!= '\0') {
3200 KMP_WARNING(ParseExtraCharsWarn
, name
, scan
);
3202 __kmp_affinity_num_places
= count
;
3205 static void __kmp_stg_print_places(kmp_str_buf_t
*buffer
, char const *name
,
3207 enum affinity_type type
= __kmp_affinity
.type
;
3208 const char *proclist
= __kmp_affinity
.proclist
;
3209 kmp_hw_t gran
= __kmp_affinity
.gran
;
3211 if (__kmp_env_format
) {
3212 KMP_STR_BUF_PRINT_NAME
;
3214 __kmp_str_buf_print(buffer
, " %s", name
);
3216 if ((__kmp_nested_proc_bind
.used
== 0) ||
3217 (__kmp_nested_proc_bind
.bind_types
== NULL
) ||
3218 (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_false
)) {
3219 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3220 } else if (type
== affinity_explicit
) {
3221 if (proclist
!= NULL
) {
3222 __kmp_str_buf_print(buffer
, "='%s'\n", proclist
);
3224 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3226 } else if (type
== affinity_compact
) {
3228 if (__kmp_affinity
.num_masks
> 0) {
3229 num
= __kmp_affinity
.num_masks
;
3230 } else if (__kmp_affinity_num_places
> 0) {
3231 num
= __kmp_affinity_num_places
;
3235 if (gran
!= KMP_HW_UNKNOWN
) {
3236 // If core_types or core_effs, just print and return
3237 if (__kmp_affinity
.flags
.core_types_gran
) {
3238 __kmp_str_buf_print(buffer
, "='%s'\n", "core_types");
3241 if (__kmp_affinity
.flags
.core_effs_gran
) {
3242 __kmp_str_buf_print(buffer
, "='%s'\n", "core_effs");
3246 // threads, cores, sockets, cores:<attribute>, etc.
3247 const char *name
= __kmp_hw_get_keyword(gran
, true);
3248 __kmp_str_buf_print(buffer
, "='%s", name
);
3250 // Add core attributes if it exists
3251 if (__kmp_affinity
.core_attr_gran
.valid
) {
3252 kmp_hw_core_type_t ct
=
3253 (kmp_hw_core_type_t
)__kmp_affinity
.core_attr_gran
.core_type
;
3254 int eff
= __kmp_affinity
.core_attr_gran
.core_eff
;
3255 if (ct
!= KMP_HW_CORE_TYPE_UNKNOWN
) {
3256 const char *ct_name
= __kmp_hw_get_core_type_keyword(ct
);
3257 __kmp_str_buf_print(buffer
, ":%s", name
, ct_name
);
3258 } else if (eff
>= 0 && eff
< KMP_HW_MAX_NUM_CORE_EFFS
) {
3259 __kmp_str_buf_print(buffer
, ":eff%d", name
, eff
);
3263 // Add the '(#)' part if it exists
3265 __kmp_str_buf_print(buffer
, "(%d)", num
);
3266 __kmp_str_buf_print(buffer
, "'\n");
3268 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3271 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3275 static void __kmp_stg_parse_topology_method(char const *name
, char const *value
,
3277 if (__kmp_str_match("all", 1, value
)) {
3278 __kmp_affinity_top_method
= affinity_top_method_all
;
3281 else if (__kmp_str_match("hwloc", 1, value
)) {
3282 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
3285 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3286 else if (__kmp_str_match("cpuid_leaf31", 12, value
) ||
3287 __kmp_str_match("cpuid 1f", 8, value
) ||
3288 __kmp_str_match("cpuid 31", 8, value
) ||
3289 __kmp_str_match("cpuid1f", 7, value
) ||
3290 __kmp_str_match("cpuid31", 7, value
) ||
3291 __kmp_str_match("leaf 1f", 7, value
) ||
3292 __kmp_str_match("leaf 31", 7, value
) ||
3293 __kmp_str_match("leaf1f", 6, value
) ||
3294 __kmp_str_match("leaf31", 6, value
)) {
3295 __kmp_affinity_top_method
= affinity_top_method_x2apicid_1f
;
3296 } else if (__kmp_str_match("x2apic id", 9, value
) ||
3297 __kmp_str_match("x2apic_id", 9, value
) ||
3298 __kmp_str_match("x2apic-id", 9, value
) ||
3299 __kmp_str_match("x2apicid", 8, value
) ||
3300 __kmp_str_match("cpuid leaf 11", 13, value
) ||
3301 __kmp_str_match("cpuid_leaf_11", 13, value
) ||
3302 __kmp_str_match("cpuid-leaf-11", 13, value
) ||
3303 __kmp_str_match("cpuid leaf11", 12, value
) ||
3304 __kmp_str_match("cpuid_leaf11", 12, value
) ||
3305 __kmp_str_match("cpuid-leaf11", 12, value
) ||
3306 __kmp_str_match("cpuidleaf 11", 12, value
) ||
3307 __kmp_str_match("cpuidleaf_11", 12, value
) ||
3308 __kmp_str_match("cpuidleaf-11", 12, value
) ||
3309 __kmp_str_match("cpuidleaf11", 11, value
) ||
3310 __kmp_str_match("cpuid 11", 8, value
) ||
3311 __kmp_str_match("cpuid_11", 8, value
) ||
3312 __kmp_str_match("cpuid-11", 8, value
) ||
3313 __kmp_str_match("cpuid11", 7, value
) ||
3314 __kmp_str_match("leaf 11", 7, value
) ||
3315 __kmp_str_match("leaf_11", 7, value
) ||
3316 __kmp_str_match("leaf-11", 7, value
) ||
3317 __kmp_str_match("leaf11", 6, value
)) {
3318 __kmp_affinity_top_method
= affinity_top_method_x2apicid
;
3319 } else if (__kmp_str_match("apic id", 7, value
) ||
3320 __kmp_str_match("apic_id", 7, value
) ||
3321 __kmp_str_match("apic-id", 7, value
) ||
3322 __kmp_str_match("apicid", 6, value
) ||
3323 __kmp_str_match("cpuid leaf 4", 12, value
) ||
3324 __kmp_str_match("cpuid_leaf_4", 12, value
) ||
3325 __kmp_str_match("cpuid-leaf-4", 12, value
) ||
3326 __kmp_str_match("cpuid leaf4", 11, value
) ||
3327 __kmp_str_match("cpuid_leaf4", 11, value
) ||
3328 __kmp_str_match("cpuid-leaf4", 11, value
) ||
3329 __kmp_str_match("cpuidleaf 4", 11, value
) ||
3330 __kmp_str_match("cpuidleaf_4", 11, value
) ||
3331 __kmp_str_match("cpuidleaf-4", 11, value
) ||
3332 __kmp_str_match("cpuidleaf4", 10, value
) ||
3333 __kmp_str_match("cpuid 4", 7, value
) ||
3334 __kmp_str_match("cpuid_4", 7, value
) ||
3335 __kmp_str_match("cpuid-4", 7, value
) ||
3336 __kmp_str_match("cpuid4", 6, value
) ||
3337 __kmp_str_match("leaf 4", 6, value
) ||
3338 __kmp_str_match("leaf_4", 6, value
) ||
3339 __kmp_str_match("leaf-4", 6, value
) ||
3340 __kmp_str_match("leaf4", 5, value
)) {
3341 __kmp_affinity_top_method
= affinity_top_method_apicid
;
3343 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3344 else if (__kmp_str_match("/proc/cpuinfo", 2, value
) ||
3345 __kmp_str_match("cpuinfo", 5, value
)) {
3346 __kmp_affinity_top_method
= affinity_top_method_cpuinfo
;
3348 #if KMP_GROUP_AFFINITY
3349 else if (__kmp_str_match("group", 1, value
)) {
3350 KMP_WARNING(StgDeprecatedValue
, name
, value
, "all");
3351 __kmp_affinity_top_method
= affinity_top_method_group
;
3353 #endif /* KMP_GROUP_AFFINITY */
3354 else if (__kmp_str_match("flat", 1, value
)) {
3355 __kmp_affinity_top_method
= affinity_top_method_flat
;
3357 KMP_WARNING(StgInvalidValue
, name
, value
);
3359 } // __kmp_stg_parse_topology_method
3361 static void __kmp_stg_print_topology_method(kmp_str_buf_t
*buffer
,
3362 char const *name
, void *data
) {
3363 char const *value
= NULL
;
3365 switch (__kmp_affinity_top_method
) {
3366 case affinity_top_method_default
:
3370 case affinity_top_method_all
:
3374 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3375 case affinity_top_method_x2apicid_1f
:
3376 value
= "x2APIC id leaf 0x1f";
3379 case affinity_top_method_x2apicid
:
3380 value
= "x2APIC id leaf 0xb";
3383 case affinity_top_method_apicid
:
3386 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3389 case affinity_top_method_hwloc
:
3394 case affinity_top_method_cpuinfo
:
3398 #if KMP_GROUP_AFFINITY
3399 case affinity_top_method_group
:
3402 #endif /* KMP_GROUP_AFFINITY */
3404 case affinity_top_method_flat
:
3409 if (value
!= NULL
) {
3410 __kmp_stg_print_str(buffer
, name
, value
);
3412 } // __kmp_stg_print_topology_method
3414 // KMP_TEAMS_PROC_BIND
3415 struct kmp_proc_bind_info_t
{
3417 kmp_proc_bind_t proc_bind
;
3419 static kmp_proc_bind_info_t proc_bind_table
[] = {
3420 {"spread", proc_bind_spread
},
3421 {"true", proc_bind_spread
},
3422 {"close", proc_bind_close
},
3423 // teams-bind = false means "replicate the primary thread's affinity"
3424 {"false", proc_bind_primary
},
3425 {"primary", proc_bind_primary
}};
3426 static void __kmp_stg_parse_teams_proc_bind(char const *name
, char const *value
,
3431 for (size_t i
= 0; i
< sizeof(proc_bind_table
) / sizeof(proc_bind_table
[0]);
3433 if (__kmp_match_str(proc_bind_table
[i
].name
, value
, &end
)) {
3434 __kmp_teams_proc_bind
= proc_bind_table
[i
].proc_bind
;
3440 KMP_WARNING(StgInvalidValue
, name
, value
);
3443 static void __kmp_stg_print_teams_proc_bind(kmp_str_buf_t
*buffer
,
3444 char const *name
, void *data
) {
3445 const char *value
= KMP_I18N_STR(NotDefined
);
3446 for (size_t i
= 0; i
< sizeof(proc_bind_table
) / sizeof(proc_bind_table
[0]);
3448 if (__kmp_teams_proc_bind
== proc_bind_table
[i
].proc_bind
) {
3449 value
= proc_bind_table
[i
].name
;
3453 __kmp_stg_print_str(buffer
, name
, value
);
3455 #endif /* KMP_AFFINITY_SUPPORTED */
3457 // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
3458 // OMP_PLACES / place-partition-var is not.
3459 static void __kmp_stg_parse_proc_bind(char const *name
, char const *value
,
3461 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
3464 rc
= __kmp_stg_check_rivals(name
, value
, rivals
);
3469 // In OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
3470 KMP_DEBUG_ASSERT((__kmp_nested_proc_bind
.bind_types
!= NULL
) &&
3471 (__kmp_nested_proc_bind
.used
> 0));
3473 const char *buf
= value
;
3477 if ((*buf
>= '0') && (*buf
<= '9')) {
3480 num
= __kmp_str_to_int(buf
, *next
);
3481 KMP_ASSERT(num
>= 0);
3489 if (__kmp_match_str("disabled", buf
, &next
)) {
3492 #if KMP_AFFINITY_SUPPORTED
3493 __kmp_affinity
.type
= affinity_disabled
;
3494 #endif /* KMP_AFFINITY_SUPPORTED */
3495 __kmp_nested_proc_bind
.used
= 1;
3496 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
3497 } else if ((num
== (int)proc_bind_false
) ||
3498 __kmp_match_str("false", buf
, &next
)) {
3501 #if KMP_AFFINITY_SUPPORTED
3502 __kmp_affinity
.type
= affinity_none
;
3503 #endif /* KMP_AFFINITY_SUPPORTED */
3504 __kmp_nested_proc_bind
.used
= 1;
3505 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
3506 } else if ((num
== (int)proc_bind_true
) ||
3507 __kmp_match_str("true", buf
, &next
)) {
3510 __kmp_nested_proc_bind
.used
= 1;
3511 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_true
;
3513 // Count the number of values in the env var string
3516 for (scan
= buf
; *scan
!= '\0'; scan
++) {
3522 // Create / expand the nested proc_bind array as needed
3523 if (__kmp_nested_proc_bind
.size
< nelem
) {
3524 __kmp_nested_proc_bind
.bind_types
=
3525 (kmp_proc_bind_t
*)KMP_INTERNAL_REALLOC(
3526 __kmp_nested_proc_bind
.bind_types
,
3527 sizeof(kmp_proc_bind_t
) * nelem
);
3528 if (__kmp_nested_proc_bind
.bind_types
== NULL
) {
3529 KMP_FATAL(MemoryAllocFailed
);
3531 __kmp_nested_proc_bind
.size
= nelem
;
3533 __kmp_nested_proc_bind
.used
= nelem
;
3535 if (nelem
> 1 && !__kmp_dflt_max_active_levels_set
)
3536 __kmp_dflt_max_active_levels
= KMP_MAX_ACTIVE_LEVELS_LIMIT
;
3538 // Save values in the nested proc_bind array
3541 enum kmp_proc_bind_t bind
;
3543 if ((num
== (int)proc_bind_primary
) ||
3544 __kmp_match_str("master", buf
, &next
) ||
3545 __kmp_match_str("primary", buf
, &next
)) {
3548 bind
= proc_bind_primary
;
3549 } else if ((num
== (int)proc_bind_close
) ||
3550 __kmp_match_str("close", buf
, &next
)) {
3553 bind
= proc_bind_close
;
3554 } else if ((num
== (int)proc_bind_spread
) ||
3555 __kmp_match_str("spread", buf
, &next
)) {
3558 bind
= proc_bind_spread
;
3560 KMP_WARNING(StgInvalidValue
, name
, value
);
3561 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
3562 __kmp_nested_proc_bind
.used
= 1;
3566 __kmp_nested_proc_bind
.bind_types
[i
++] = bind
;
3570 KMP_DEBUG_ASSERT(*buf
== ',');
3574 // Read next value if it was specified as an integer
3575 if ((*buf
>= '0') && (*buf
<= '9')) {
3578 num
= __kmp_str_to_int(buf
, *next
);
3579 KMP_ASSERT(num
>= 0);
3589 KMP_WARNING(ParseExtraCharsWarn
, name
, buf
);
3593 static void __kmp_stg_print_proc_bind(kmp_str_buf_t
*buffer
, char const *name
,
3595 int nelem
= __kmp_nested_proc_bind
.used
;
3596 if (__kmp_env_format
) {
3597 KMP_STR_BUF_PRINT_NAME
;
3599 __kmp_str_buf_print(buffer
, " %s", name
);
3602 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
3605 __kmp_str_buf_print(buffer
, "='", name
);
3606 for (i
= 0; i
< nelem
; i
++) {
3607 switch (__kmp_nested_proc_bind
.bind_types
[i
]) {
3608 case proc_bind_false
:
3609 __kmp_str_buf_print(buffer
, "false");
3612 case proc_bind_true
:
3613 __kmp_str_buf_print(buffer
, "true");
3616 case proc_bind_primary
:
3617 __kmp_str_buf_print(buffer
, "primary");
3620 case proc_bind_close
:
3621 __kmp_str_buf_print(buffer
, "close");
3624 case proc_bind_spread
:
3625 __kmp_str_buf_print(buffer
, "spread");
3628 case proc_bind_intel
:
3629 __kmp_str_buf_print(buffer
, "intel");
3632 case proc_bind_default
:
3633 __kmp_str_buf_print(buffer
, "default");
3636 if (i
< nelem
- 1) {
3637 __kmp_str_buf_print(buffer
, ",");
3640 __kmp_str_buf_print(buffer
, "'\n");
3644 static void __kmp_stg_parse_display_affinity(char const *name
,
3645 char const *value
, void *data
) {
3646 __kmp_stg_parse_bool(name
, value
, &__kmp_display_affinity
);
3648 static void __kmp_stg_print_display_affinity(kmp_str_buf_t
*buffer
,
3649 char const *name
, void *data
) {
3650 __kmp_stg_print_bool(buffer
, name
, __kmp_display_affinity
);
3652 static void __kmp_stg_parse_affinity_format(char const *name
, char const *value
,
3654 size_t length
= KMP_STRLEN(value
);
3655 __kmp_strncpy_truncate(__kmp_affinity_format
, KMP_AFFINITY_FORMAT_SIZE
, value
,
3658 static void __kmp_stg_print_affinity_format(kmp_str_buf_t
*buffer
,
3659 char const *name
, void *data
) {
3660 if (__kmp_env_format
) {
3661 KMP_STR_BUF_PRINT_NAME_EX(name
);
3663 __kmp_str_buf_print(buffer
, " %s='", name
);
3665 __kmp_str_buf_print(buffer
, "%s'\n", __kmp_affinity_format
);
3668 /*-----------------------------------------------------------------------------
3669 OMP_ALLOCATOR sets default allocator. Here is the grammar:
3671 <allocator> |= <predef-allocator> | <predef-mem-space> |
3672 <predef-mem-space>:<traits>
3673 <traits> |= <trait>=<value> | <trait>=<value>,<traits>
3674 <predef-allocator> |= omp_default_mem_alloc | omp_large_cap_mem_alloc |
3675 omp_const_mem_alloc | omp_high_bw_mem_alloc |
3676 omp_low_lat_mem_alloc | omp_cgroup_mem_alloc |
3677 omp_pteam_mem_alloc | omp_thread_mem_alloc
3678 <predef-mem-space> |= omp_default_mem_space | omp_large_cap_mem_space |
3679 omp_const_mem_space | omp_high_bw_mem_space |
3680 omp_low_lat_mem_space
3681 <trait> |= sync_hint | alignment | access | pool_size | fallback |
3682 fb_data | pinned | partition
3683 <value> |= one of the allowed values of trait |
3684 non-negative integer | <predef-allocator>
3685 -----------------------------------------------------------------------------*/
3687 static void __kmp_stg_parse_allocator(char const *name
, char const *value
,
3689 const char *buf
= value
;
3690 const char *next
, *scan
, *start
;
3692 omp_allocator_handle_t al
;
3693 omp_memspace_handle_t ms
= omp_default_mem_space
;
3694 bool is_memspace
= false;
3695 int ntraits
= 0, count
= 0;
3699 const char *delim
= strchr(buf
, ':');
3700 const char *predef_mem_space
= strstr(buf
, "mem_space");
3702 bool is_memalloc
= (!predef_mem_space
&& !delim
) ? true : false;
3704 // Count the number of traits in the env var string
3707 for (scan
= buf
; *scan
!= '\0'; scan
++) {
3712 omp_alloctrait_t
*traits
=
3713 (omp_alloctrait_t
*)KMP_ALLOCA(ntraits
* sizeof(omp_alloctrait_t
));
3716 #define IS_POWER_OF_TWO(n) (((n) & ((n)-1)) == 0)
3718 #define GET_NEXT(sentinel) \
3721 if (*next == sentinel) \
3727 #define SKIP_PAIR(key) \
3729 char const str_delimiter[] = {',', 0}; \
3730 char *value = __kmp_str_token(CCAST(char *, scan), str_delimiter, \
3731 CCAST(char **, &next)); \
3732 KMP_WARNING(StgInvalidValue, key, value); \
3740 char const str_delimiter[] = {'=', 0}; \
3741 key = __kmp_str_token(CCAST(char *, start), str_delimiter, \
3742 CCAST(char **, &next)); \
3747 while (*next
!= '\0') {
3749 __kmp_match_str("fb_data", scan
, &next
)) { // allocator check
3752 // check HBW and LCAP first as the only non-default supported
3753 if (__kmp_match_str("omp_high_bw_mem_alloc", scan
, &next
)) {
3756 if (__kmp_memkind_available
) {
3757 __kmp_def_allocator
= omp_high_bw_mem_alloc
;
3760 KMP_WARNING(OmpNoAllocator
, "omp_high_bw_mem_alloc");
3763 traits
[count
].key
= omp_atk_fb_data
;
3764 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_high_bw_mem_alloc
);
3766 } else if (__kmp_match_str("omp_large_cap_mem_alloc", scan
, &next
)) {
3769 if (__kmp_memkind_available
) {
3770 __kmp_def_allocator
= omp_large_cap_mem_alloc
;
3773 KMP_WARNING(OmpNoAllocator
, "omp_large_cap_mem_alloc");
3776 traits
[count
].key
= omp_atk_fb_data
;
3777 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_large_cap_mem_alloc
);
3779 } else if (__kmp_match_str("omp_default_mem_alloc", scan
, &next
)) {
3780 // default requested
3783 traits
[count
].key
= omp_atk_fb_data
;
3784 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_default_mem_alloc
);
3786 } else if (__kmp_match_str("omp_const_mem_alloc", scan
, &next
)) {
3789 KMP_WARNING(OmpNoAllocator
, "omp_const_mem_alloc");
3791 traits
[count
].key
= omp_atk_fb_data
;
3792 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_const_mem_alloc
);
3794 } else if (__kmp_match_str("omp_low_lat_mem_alloc", scan
, &next
)) {
3797 KMP_WARNING(OmpNoAllocator
, "omp_low_lat_mem_alloc");
3799 traits
[count
].key
= omp_atk_fb_data
;
3800 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_low_lat_mem_alloc
);
3802 } else if (__kmp_match_str("omp_cgroup_mem_alloc", scan
, &next
)) {
3805 KMP_WARNING(OmpNoAllocator
, "omp_cgroup_mem_alloc");
3807 traits
[count
].key
= omp_atk_fb_data
;
3808 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_cgroup_mem_alloc
);
3810 } else if (__kmp_match_str("omp_pteam_mem_alloc", scan
, &next
)) {
3813 KMP_WARNING(OmpNoAllocator
, "omp_pteam_mem_alloc");
3815 traits
[count
].key
= omp_atk_fb_data
;
3816 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_pteam_mem_alloc
);
3818 } else if (__kmp_match_str("omp_thread_mem_alloc", scan
, &next
)) {
3821 KMP_WARNING(OmpNoAllocator
, "omp_thread_mem_alloc");
3823 traits
[count
].key
= omp_atk_fb_data
;
3824 traits
[count
].value
= RCAST(omp_uintptr_t
, omp_thread_mem_alloc
);
3834 __kmp_def_allocator
= omp_default_mem_alloc
;
3835 if (next
== buf
|| *next
!= '\0') {
3836 // either no match or extra symbols present after the matched token
3837 KMP_WARNING(StgInvalidValue
, name
, value
);
3842 if (count
== ntraits
)
3846 } else { // memspace
3848 if (__kmp_match_str("omp_default_mem_space", scan
, &next
)) {
3850 ms
= omp_default_mem_space
;
3851 } else if (__kmp_match_str("omp_large_cap_mem_space", scan
, &next
)) {
3853 ms
= omp_large_cap_mem_space
;
3854 } else if (__kmp_match_str("omp_const_mem_space", scan
, &next
)) {
3856 ms
= omp_const_mem_space
;
3857 } else if (__kmp_match_str("omp_high_bw_mem_space", scan
, &next
)) {
3859 ms
= omp_high_bw_mem_space
;
3860 } else if (__kmp_match_str("omp_low_lat_mem_space", scan
, &next
)) {
3862 ms
= omp_low_lat_mem_space
;
3864 __kmp_def_allocator
= omp_default_mem_alloc
;
3865 if (next
== buf
|| *next
!= '\0') {
3866 // either no match or extra symbols present after the matched token
3867 KMP_WARNING(StgInvalidValue
, name
, value
);
3873 if (delim
) { // traits
3876 if (__kmp_match_str("sync_hint", scan
, &next
)) {
3878 traits
[count
].key
= omp_atk_sync_hint
;
3879 if (__kmp_match_str("contended", scan
, &next
)) {
3880 traits
[count
].value
= omp_atv_contended
;
3881 } else if (__kmp_match_str("uncontended", scan
, &next
)) {
3882 traits
[count
].value
= omp_atv_uncontended
;
3883 } else if (__kmp_match_str("serialized", scan
, &next
)) {
3884 traits
[count
].value
= omp_atv_serialized
;
3885 } else if (__kmp_match_str("private", scan
, &next
)) {
3886 traits
[count
].value
= omp_atv_private
;
3892 } else if (__kmp_match_str("alignment", scan
, &next
)) {
3894 if (!isdigit(*next
)) {
3900 int n
= __kmp_str_to_int(scan
, ',');
3901 if (n
< 0 || !IS_POWER_OF_TWO(n
)) {
3906 traits
[count
].key
= omp_atk_alignment
;
3907 traits
[count
].value
= n
;
3908 } else if (__kmp_match_str("access", scan
, &next
)) {
3910 traits
[count
].key
= omp_atk_access
;
3911 if (__kmp_match_str("all", scan
, &next
)) {
3912 traits
[count
].value
= omp_atv_all
;
3913 } else if (__kmp_match_str("cgroup", scan
, &next
)) {
3914 traits
[count
].value
= omp_atv_cgroup
;
3915 } else if (__kmp_match_str("pteam", scan
, &next
)) {
3916 traits
[count
].value
= omp_atv_pteam
;
3917 } else if (__kmp_match_str("thread", scan
, &next
)) {
3918 traits
[count
].value
= omp_atv_thread
;
3924 } else if (__kmp_match_str("pool_size", scan
, &next
)) {
3926 if (!isdigit(*next
)) {
3932 int n
= __kmp_str_to_int(scan
, ',');
3938 traits
[count
].key
= omp_atk_pool_size
;
3939 traits
[count
].value
= n
;
3940 } else if (__kmp_match_str("fallback", scan
, &next
)) {
3942 traits
[count
].key
= omp_atk_fallback
;
3943 if (__kmp_match_str("default_mem_fb", scan
, &next
)) {
3944 traits
[count
].value
= omp_atv_default_mem_fb
;
3945 } else if (__kmp_match_str("null_fb", scan
, &next
)) {
3946 traits
[count
].value
= omp_atv_null_fb
;
3947 } else if (__kmp_match_str("abort_fb", scan
, &next
)) {
3948 traits
[count
].value
= omp_atv_abort_fb
;
3949 } else if (__kmp_match_str("allocator_fb", scan
, &next
)) {
3950 traits
[count
].value
= omp_atv_allocator_fb
;
3956 } else if (__kmp_match_str("pinned", scan
, &next
)) {
3958 traits
[count
].key
= omp_atk_pinned
;
3959 if (__kmp_str_match_true(next
)) {
3960 traits
[count
].value
= omp_atv_true
;
3961 } else if (__kmp_str_match_false(next
)) {
3962 traits
[count
].value
= omp_atv_false
;
3968 } else if (__kmp_match_str("partition", scan
, &next
)) {
3970 traits
[count
].key
= omp_atk_partition
;
3971 if (__kmp_match_str("environment", scan
, &next
)) {
3972 traits
[count
].value
= omp_atv_environment
;
3973 } else if (__kmp_match_str("nearest", scan
, &next
)) {
3974 traits
[count
].value
= omp_atv_nearest
;
3975 } else if (__kmp_match_str("blocked", scan
, &next
)) {
3976 traits
[count
].value
= omp_atv_blocked
;
3977 } else if (__kmp_match_str("interleaved", scan
, &next
)) {
3978 traits
[count
].value
= omp_atv_interleaved
;
3991 if (count
== ntraits
)
3997 al
= __kmpc_init_allocator(__kmp_get_gtid(), ms
, ntraits
, traits
);
3998 __kmp_def_allocator
= (al
== omp_null_allocator
) ? omp_default_mem_alloc
: al
;
4001 static void __kmp_stg_print_allocator(kmp_str_buf_t
*buffer
, char const *name
,
4003 if (__kmp_def_allocator
== omp_default_mem_alloc
) {
4004 __kmp_stg_print_str(buffer
, name
, "omp_default_mem_alloc");
4005 } else if (__kmp_def_allocator
== omp_high_bw_mem_alloc
) {
4006 __kmp_stg_print_str(buffer
, name
, "omp_high_bw_mem_alloc");
4007 } else if (__kmp_def_allocator
== omp_large_cap_mem_alloc
) {
4008 __kmp_stg_print_str(buffer
, name
, "omp_large_cap_mem_alloc");
4009 } else if (__kmp_def_allocator
== omp_const_mem_alloc
) {
4010 __kmp_stg_print_str(buffer
, name
, "omp_const_mem_alloc");
4011 } else if (__kmp_def_allocator
== omp_low_lat_mem_alloc
) {
4012 __kmp_stg_print_str(buffer
, name
, "omp_low_lat_mem_alloc");
4013 } else if (__kmp_def_allocator
== omp_cgroup_mem_alloc
) {
4014 __kmp_stg_print_str(buffer
, name
, "omp_cgroup_mem_alloc");
4015 } else if (__kmp_def_allocator
== omp_pteam_mem_alloc
) {
4016 __kmp_stg_print_str(buffer
, name
, "omp_pteam_mem_alloc");
4017 } else if (__kmp_def_allocator
== omp_thread_mem_alloc
) {
4018 __kmp_stg_print_str(buffer
, name
, "omp_thread_mem_alloc");
4022 // -----------------------------------------------------------------------------
4025 static void __kmp_stg_parse_omp_dynamic(char const *name
, char const *value
,
4027 __kmp_stg_parse_bool(name
, value
, &(__kmp_global
.g
.g_dynamic
));
4028 } // __kmp_stg_parse_omp_dynamic
4030 static void __kmp_stg_print_omp_dynamic(kmp_str_buf_t
*buffer
, char const *name
,
4032 __kmp_stg_print_bool(buffer
, name
, __kmp_global
.g
.g_dynamic
);
4033 } // __kmp_stg_print_omp_dynamic
4035 static void __kmp_stg_parse_kmp_dynamic_mode(char const *name
,
4036 char const *value
, void *data
) {
4037 if (TCR_4(__kmp_init_parallel
)) {
4038 KMP_WARNING(EnvParallelWarn
, name
);
4039 __kmp_env_toPrint(name
, 0);
4042 #ifdef USE_LOAD_BALANCE
4043 else if (__kmp_str_match("load balance", 2, value
) ||
4044 __kmp_str_match("load_balance", 2, value
) ||
4045 __kmp_str_match("load-balance", 2, value
) ||
4046 __kmp_str_match("loadbalance", 2, value
) ||
4047 __kmp_str_match("balance", 1, value
)) {
4048 __kmp_global
.g
.g_dynamic_mode
= dynamic_load_balance
;
4050 #endif /* USE_LOAD_BALANCE */
4051 else if (__kmp_str_match("thread limit", 1, value
) ||
4052 __kmp_str_match("thread_limit", 1, value
) ||
4053 __kmp_str_match("thread-limit", 1, value
) ||
4054 __kmp_str_match("threadlimit", 1, value
) ||
4055 __kmp_str_match("limit", 2, value
)) {
4056 __kmp_global
.g
.g_dynamic_mode
= dynamic_thread_limit
;
4057 } else if (__kmp_str_match("random", 1, value
)) {
4058 __kmp_global
.g
.g_dynamic_mode
= dynamic_random
;
4060 KMP_WARNING(StgInvalidValue
, name
, value
);
4062 } //__kmp_stg_parse_kmp_dynamic_mode
4064 static void __kmp_stg_print_kmp_dynamic_mode(kmp_str_buf_t
*buffer
,
4065 char const *name
, void *data
) {
4067 if (__kmp_global
.g
.g_dynamic_mode
== dynamic_default
) {
4068 __kmp_str_buf_print(buffer
, " %s: %s \n", name
, KMP_I18N_STR(NotDefined
));
4070 #ifdef USE_LOAD_BALANCE
4071 else if (__kmp_global
.g
.g_dynamic_mode
== dynamic_load_balance
) {
4072 __kmp_stg_print_str(buffer
, name
, "load balance");
4074 #endif /* USE_LOAD_BALANCE */
4075 else if (__kmp_global
.g
.g_dynamic_mode
== dynamic_thread_limit
) {
4076 __kmp_stg_print_str(buffer
, name
, "thread limit");
4077 } else if (__kmp_global
.g
.g_dynamic_mode
== dynamic_random
) {
4078 __kmp_stg_print_str(buffer
, name
, "random");
4082 #endif /* KMP_DEBUG */
4083 } // __kmp_stg_print_kmp_dynamic_mode
4085 #ifdef USE_LOAD_BALANCE
4087 // -----------------------------------------------------------------------------
4088 // KMP_LOAD_BALANCE_INTERVAL
4090 static void __kmp_stg_parse_ld_balance_interval(char const *name
,
4091 char const *value
, void *data
) {
4092 double interval
= __kmp_convert_to_double(value
);
4093 if (interval
>= 0) {
4094 __kmp_load_balance_interval
= interval
;
4096 KMP_WARNING(StgInvalidValue
, name
, value
);
4098 } // __kmp_stg_parse_load_balance_interval
4100 static void __kmp_stg_print_ld_balance_interval(kmp_str_buf_t
*buffer
,
4101 char const *name
, void *data
) {
4103 __kmp_str_buf_print(buffer
, " %s=%8.6f\n", name
,
4104 __kmp_load_balance_interval
);
4105 #endif /* KMP_DEBUG */
4106 } // __kmp_stg_print_load_balance_interval
4108 #endif /* USE_LOAD_BALANCE */
4110 // -----------------------------------------------------------------------------
4113 static void __kmp_stg_parse_init_at_fork(char const *name
, char const *value
,
4115 __kmp_stg_parse_bool(name
, value
, &__kmp_need_register_atfork
);
4116 if (__kmp_need_register_atfork
) {
4117 __kmp_need_register_atfork_specified
= TRUE
;
4119 } // __kmp_stg_parse_init_at_fork
4121 static void __kmp_stg_print_init_at_fork(kmp_str_buf_t
*buffer
,
4122 char const *name
, void *data
) {
4123 __kmp_stg_print_bool(buffer
, name
, __kmp_need_register_atfork_specified
);
4124 } // __kmp_stg_print_init_at_fork
4126 // -----------------------------------------------------------------------------
4129 static void __kmp_stg_parse_schedule(char const *name
, char const *value
,
4132 if (value
!= NULL
) {
4133 size_t length
= KMP_STRLEN(value
);
4134 if (length
> INT_MAX
) {
4135 KMP_WARNING(LongValue
, name
);
4137 const char *semicolon
;
4138 if (value
[length
- 1] == '"' || value
[length
- 1] == '\'')
4139 KMP_WARNING(UnbalancedQuotes
, name
);
4143 semicolon
= strchr(value
, ';');
4144 if (*value
&& semicolon
!= value
) {
4145 const char *comma
= strchr(value
, ',');
4152 if (!__kmp_strcasecmp_with_sentinel("static", value
, sentinel
)) {
4153 if (!__kmp_strcasecmp_with_sentinel("greedy", comma
, ';')) {
4154 __kmp_static
= kmp_sch_static_greedy
;
4156 } else if (!__kmp_strcasecmp_with_sentinel("balanced", comma
,
4158 __kmp_static
= kmp_sch_static_balanced
;
4161 } else if (!__kmp_strcasecmp_with_sentinel("guided", value
,
4163 if (!__kmp_strcasecmp_with_sentinel("iterative", comma
, ';')) {
4164 __kmp_guided
= kmp_sch_guided_iterative_chunked
;
4166 } else if (!__kmp_strcasecmp_with_sentinel("analytical", comma
,
4168 /* analytical not allowed for too many threads */
4169 __kmp_guided
= kmp_sch_guided_analytical_chunked
;
4173 KMP_WARNING(InvalidClause
, name
, value
);
4175 KMP_WARNING(EmptyClause
, name
);
4176 } while ((value
= semicolon
? semicolon
+ 1 : NULL
));
4180 } // __kmp_stg_parse__schedule
4182 static void __kmp_stg_print_schedule(kmp_str_buf_t
*buffer
, char const *name
,
4184 if (__kmp_env_format
) {
4185 KMP_STR_BUF_PRINT_NAME_EX(name
);
4187 __kmp_str_buf_print(buffer
, " %s='", name
);
4189 if (__kmp_static
== kmp_sch_static_greedy
) {
4190 __kmp_str_buf_print(buffer
, "%s", "static,greedy");
4191 } else if (__kmp_static
== kmp_sch_static_balanced
) {
4192 __kmp_str_buf_print(buffer
, "%s", "static,balanced");
4194 if (__kmp_guided
== kmp_sch_guided_iterative_chunked
) {
4195 __kmp_str_buf_print(buffer
, ";%s'\n", "guided,iterative");
4196 } else if (__kmp_guided
== kmp_sch_guided_analytical_chunked
) {
4197 __kmp_str_buf_print(buffer
, ";%s'\n", "guided,analytical");
4199 } // __kmp_stg_print_schedule
4201 // -----------------------------------------------------------------------------
4204 static inline void __kmp_omp_schedule_restore() {
4205 #if KMP_USE_HIER_SCHED
4206 __kmp_hier_scheds
.deallocate();
4209 __kmp_sched
= kmp_sch_default
;
4212 // if parse_hier = true:
4213 // Parse [HW,][modifier:]kind[,chunk]
4215 // Parse [modifier:]kind[,chunk]
4216 static const char *__kmp_parse_single_omp_schedule(const char *name
,
4218 bool parse_hier
= false) {
4219 /* get the specified scheduling style */
4220 const char *ptr
= value
;
4223 enum sched_type sched
= kmp_sch_default
;
4227 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4229 #if KMP_USE_HIER_SCHED
4230 kmp_hier_layer_e layer
= kmp_hier_layer_e::LAYER_THREAD
;
4232 if (*delim
== ',') {
4233 if (!__kmp_strcasecmp_with_sentinel("L1", ptr
, ',')) {
4234 layer
= kmp_hier_layer_e::LAYER_L1
;
4235 } else if (!__kmp_strcasecmp_with_sentinel("L2", ptr
, ',')) {
4236 layer
= kmp_hier_layer_e::LAYER_L2
;
4237 } else if (!__kmp_strcasecmp_with_sentinel("L3", ptr
, ',')) {
4238 layer
= kmp_hier_layer_e::LAYER_L3
;
4239 } else if (!__kmp_strcasecmp_with_sentinel("NUMA", ptr
, ',')) {
4240 layer
= kmp_hier_layer_e::LAYER_NUMA
;
4243 if (layer
!= kmp_hier_layer_e::LAYER_THREAD
&& *delim
!= ',') {
4244 // If there is no comma after the layer, then this schedule is invalid
4245 KMP_WARNING(StgInvalidValue
, name
, value
);
4246 __kmp_omp_schedule_restore();
4248 } else if (layer
!= kmp_hier_layer_e::LAYER_THREAD
) {
4250 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4254 #endif // KMP_USE_HIER_SCHED
4255 // Read in schedule modifier if specified
4256 enum sched_type sched_modifier
= (enum sched_type
)0;
4257 if (*delim
== ':') {
4258 if (!__kmp_strcasecmp_with_sentinel("monotonic", ptr
, *delim
)) {
4259 sched_modifier
= sched_type::kmp_sch_modifier_monotonic
;
4261 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4263 } else if (!__kmp_strcasecmp_with_sentinel("nonmonotonic", ptr
, *delim
)) {
4264 sched_modifier
= sched_type::kmp_sch_modifier_nonmonotonic
;
4266 while (*delim
!= ',' && *delim
!= ':' && *delim
!= '\0')
4268 } else if (!parse_hier
) {
4269 // If there is no proper schedule modifier, then this schedule is invalid
4270 KMP_WARNING(StgInvalidValue
, name
, value
);
4271 __kmp_omp_schedule_restore();
4275 // Read in schedule kind (required)
4276 if (!__kmp_strcasecmp_with_sentinel("dynamic", ptr
, *delim
))
4277 sched
= kmp_sch_dynamic_chunked
;
4278 else if (!__kmp_strcasecmp_with_sentinel("guided", ptr
, *delim
))
4279 sched
= kmp_sch_guided_chunked
;
4280 // AC: TODO: probably remove TRAPEZOIDAL (OMP 3.0 does not allow it)
4281 else if (!__kmp_strcasecmp_with_sentinel("auto", ptr
, *delim
))
4282 sched
= kmp_sch_auto
;
4283 else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", ptr
, *delim
))
4284 sched
= kmp_sch_trapezoidal
;
4285 else if (!__kmp_strcasecmp_with_sentinel("static", ptr
, *delim
))
4286 sched
= kmp_sch_static
;
4287 #if KMP_STATIC_STEAL_ENABLED
4288 else if (!__kmp_strcasecmp_with_sentinel("static_steal", ptr
, *delim
)) {
4289 // replace static_steal with dynamic to better cope with ordered loops
4290 sched
= kmp_sch_dynamic_chunked
;
4291 sched_modifier
= sched_type::kmp_sch_modifier_nonmonotonic
;
4295 // If there is no proper schedule kind, then this schedule is invalid
4296 KMP_WARNING(StgInvalidValue
, name
, value
);
4297 __kmp_omp_schedule_restore();
4301 // Read in schedule chunk size if specified
4302 if (*delim
== ',') {
4305 if (!isdigit(*ptr
)) {
4306 // If there is no chunk after comma, then this schedule is invalid
4307 KMP_WARNING(StgInvalidValue
, name
, value
);
4308 __kmp_omp_schedule_restore();
4312 // auto schedule should not specify chunk size
4313 if (sched
== kmp_sch_auto
) {
4314 __kmp_msg(kmp_ms_warning
, KMP_MSG(IgnoreChunk
, name
, delim
),
4317 if (sched
== kmp_sch_static
)
4318 sched
= kmp_sch_static_chunked
;
4319 chunk
= __kmp_str_to_int(delim
+ 1, *ptr
);
4321 chunk
= KMP_DEFAULT_CHUNK
;
4322 __kmp_msg(kmp_ms_warning
, KMP_MSG(InvalidChunk
, name
, delim
),
4324 KMP_INFORM(Using_int_Value
, name
, __kmp_chunk
);
4325 // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK
4326 // (to improve code coverage :)
4327 // The default chunk size is 1 according to standard, thus making
4328 // KMP_MIN_CHUNK not 1 we would introduce mess:
4329 // wrong chunk becomes 1, but it will be impossible to explicitly set
4330 // to 1 because it becomes KMP_MIN_CHUNK...
4331 // } else if ( chunk < KMP_MIN_CHUNK ) {
4332 // chunk = KMP_MIN_CHUNK;
4333 } else if (chunk
> KMP_MAX_CHUNK
) {
4334 chunk
= KMP_MAX_CHUNK
;
4335 __kmp_msg(kmp_ms_warning
, KMP_MSG(LargeChunk
, name
, delim
),
4337 KMP_INFORM(Using_int_Value
, name
, chunk
);
4344 SCHEDULE_SET_MODIFIERS(sched
, sched_modifier
);
4346 #if KMP_USE_HIER_SCHED
4347 if (layer
!= kmp_hier_layer_e::LAYER_THREAD
) {
4348 __kmp_hier_scheds
.append(sched
, chunk
, layer
);
4352 __kmp_chunk
= chunk
;
4353 __kmp_sched
= sched
;
4358 static void __kmp_stg_parse_omp_schedule(char const *name
, char const *value
,
4361 const char *ptr
= value
;
4364 length
= KMP_STRLEN(value
);
4366 if (value
[length
- 1] == '"' || value
[length
- 1] == '\'')
4367 KMP_WARNING(UnbalancedQuotes
, name
);
4368 /* get the specified scheduling style */
4369 #if KMP_USE_HIER_SCHED
4370 if (!__kmp_strcasecmp_with_sentinel("EXPERIMENTAL", ptr
, ' ')) {
4373 while ((ptr
= __kmp_parse_single_omp_schedule(name
, ptr
, true))) {
4374 while (*ptr
== ' ' || *ptr
== '\t' || *ptr
== ':')
4381 __kmp_parse_single_omp_schedule(name
, ptr
);
4383 KMP_WARNING(EmptyString
, name
);
4385 #if KMP_USE_HIER_SCHED
4386 __kmp_hier_scheds
.sort();
4388 K_DIAG(1, ("__kmp_static == %d\n", __kmp_static
))
4389 K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided
))
4390 K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched
))
4391 K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk
))
4392 } // __kmp_stg_parse_omp_schedule
4394 static void __kmp_stg_print_omp_schedule(kmp_str_buf_t
*buffer
,
4395 char const *name
, void *data
) {
4396 if (__kmp_env_format
) {
4397 KMP_STR_BUF_PRINT_NAME_EX(name
);
4399 __kmp_str_buf_print(buffer
, " %s='", name
);
4401 enum sched_type sched
= SCHEDULE_WITHOUT_MODIFIERS(__kmp_sched
);
4402 if (SCHEDULE_HAS_MONOTONIC(__kmp_sched
)) {
4403 __kmp_str_buf_print(buffer
, "monotonic:");
4404 } else if (SCHEDULE_HAS_NONMONOTONIC(__kmp_sched
)) {
4405 __kmp_str_buf_print(buffer
, "nonmonotonic:");
4409 case kmp_sch_dynamic_chunked
:
4410 __kmp_str_buf_print(buffer
, "%s,%d'\n", "dynamic", __kmp_chunk
);
4412 case kmp_sch_guided_iterative_chunked
:
4413 case kmp_sch_guided_analytical_chunked
:
4414 __kmp_str_buf_print(buffer
, "%s,%d'\n", "guided", __kmp_chunk
);
4416 case kmp_sch_trapezoidal
:
4417 __kmp_str_buf_print(buffer
, "%s,%d'\n", "trapezoidal", __kmp_chunk
);
4419 case kmp_sch_static
:
4420 case kmp_sch_static_chunked
:
4421 case kmp_sch_static_balanced
:
4422 case kmp_sch_static_greedy
:
4423 __kmp_str_buf_print(buffer
, "%s,%d'\n", "static", __kmp_chunk
);
4425 case kmp_sch_static_steal
:
4426 __kmp_str_buf_print(buffer
, "%s,%d'\n", "static_steal", __kmp_chunk
);
4429 __kmp_str_buf_print(buffer
, "%s,%d'\n", "auto", __kmp_chunk
);
4434 case kmp_sch_dynamic_chunked
:
4435 __kmp_str_buf_print(buffer
, "%s'\n", "dynamic");
4437 case kmp_sch_guided_iterative_chunked
:
4438 case kmp_sch_guided_analytical_chunked
:
4439 __kmp_str_buf_print(buffer
, "%s'\n", "guided");
4441 case kmp_sch_trapezoidal
:
4442 __kmp_str_buf_print(buffer
, "%s'\n", "trapezoidal");
4444 case kmp_sch_static
:
4445 case kmp_sch_static_chunked
:
4446 case kmp_sch_static_balanced
:
4447 case kmp_sch_static_greedy
:
4448 __kmp_str_buf_print(buffer
, "%s'\n", "static");
4450 case kmp_sch_static_steal
:
4451 __kmp_str_buf_print(buffer
, "%s'\n", "static_steal");
4454 __kmp_str_buf_print(buffer
, "%s'\n", "auto");
4458 } // __kmp_stg_print_omp_schedule
4460 #if KMP_USE_HIER_SCHED
4461 // -----------------------------------------------------------------------------
4462 // KMP_DISP_HAND_THREAD
4463 static void __kmp_stg_parse_kmp_hand_thread(char const *name
, char const *value
,
4465 __kmp_stg_parse_bool(name
, value
, &(__kmp_dispatch_hand_threading
));
4466 } // __kmp_stg_parse_kmp_hand_thread
4468 static void __kmp_stg_print_kmp_hand_thread(kmp_str_buf_t
*buffer
,
4469 char const *name
, void *data
) {
4470 __kmp_stg_print_bool(buffer
, name
, __kmp_dispatch_hand_threading
);
4471 } // __kmp_stg_print_kmp_hand_thread
4474 // -----------------------------------------------------------------------------
4475 // KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE
4476 static void __kmp_stg_parse_kmp_force_monotonic(char const *name
,
4477 char const *value
, void *data
) {
4478 __kmp_stg_parse_bool(name
, value
, &(__kmp_force_monotonic
));
4479 } // __kmp_stg_parse_kmp_force_monotonic
4481 static void __kmp_stg_print_kmp_force_monotonic(kmp_str_buf_t
*buffer
,
4482 char const *name
, void *data
) {
4483 __kmp_stg_print_bool(buffer
, name
, __kmp_force_monotonic
);
4484 } // __kmp_stg_print_kmp_force_monotonic
4486 // -----------------------------------------------------------------------------
4489 static void __kmp_stg_parse_atomic_mode(char const *name
, char const *value
,
4491 // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP
4492 // compatibility mode.
4495 #ifdef KMP_GOMP_COMPAT
4497 #endif /* KMP_GOMP_COMPAT */
4498 __kmp_stg_parse_int(name
, value
, 0, max
, &mode
);
4499 // TODO; parse_int is not very suitable for this case. In case of overflow it
4501 // 0 rather that max value.
4503 __kmp_atomic_mode
= mode
;
4505 } // __kmp_stg_parse_atomic_mode
4507 static void __kmp_stg_print_atomic_mode(kmp_str_buf_t
*buffer
, char const *name
,
4509 __kmp_stg_print_int(buffer
, name
, __kmp_atomic_mode
);
4510 } // __kmp_stg_print_atomic_mode
4512 // -----------------------------------------------------------------------------
4513 // KMP_CONSISTENCY_CHECK
4515 static void __kmp_stg_parse_consistency_check(char const *name
,
4516 char const *value
, void *data
) {
4517 if (!__kmp_strcasecmp_with_sentinel("all", value
, 0)) {
4518 // Note, this will not work from kmp_set_defaults because th_cons stack was
4520 // for existed thread(s) thus the first __kmp_push_<construct> will break
4522 // TODO: allocate th_cons if called from kmp_set_defaults.
4523 __kmp_env_consistency_check
= TRUE
;
4524 } else if (!__kmp_strcasecmp_with_sentinel("none", value
, 0)) {
4525 __kmp_env_consistency_check
= FALSE
;
4527 KMP_WARNING(StgInvalidValue
, name
, value
);
4529 } // __kmp_stg_parse_consistency_check
4531 static void __kmp_stg_print_consistency_check(kmp_str_buf_t
*buffer
,
4532 char const *name
, void *data
) {
4534 const char *value
= NULL
;
4536 if (__kmp_env_consistency_check
) {
4542 if (value
!= NULL
) {
4543 __kmp_stg_print_str(buffer
, name
, value
);
4545 #endif /* KMP_DEBUG */
4546 } // __kmp_stg_print_consistency_check
4549 // -----------------------------------------------------------------------------
4550 // KMP_ITT_PREPARE_DELAY
4554 static void __kmp_stg_parse_itt_prepare_delay(char const *name
,
4555 char const *value
, void *data
) {
4556 // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop
4559 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &delay
);
4560 __kmp_itt_prepare_delay
= delay
;
4561 } // __kmp_str_parse_itt_prepare_delay
4563 static void __kmp_stg_print_itt_prepare_delay(kmp_str_buf_t
*buffer
,
4564 char const *name
, void *data
) {
4565 __kmp_stg_print_uint64(buffer
, name
, __kmp_itt_prepare_delay
);
4567 } // __kmp_str_print_itt_prepare_delay
4569 #endif // USE_ITT_NOTIFY
4570 #endif /* USE_ITT_BUILD */
4572 // -----------------------------------------------------------------------------
4573 // KMP_MALLOC_POOL_INCR
4575 static void __kmp_stg_parse_malloc_pool_incr(char const *name
,
4576 char const *value
, void *data
) {
4577 __kmp_stg_parse_size(name
, value
, KMP_MIN_MALLOC_POOL_INCR
,
4578 KMP_MAX_MALLOC_POOL_INCR
, NULL
, &__kmp_malloc_pool_incr
,
4580 } // __kmp_stg_parse_malloc_pool_incr
4582 static void __kmp_stg_print_malloc_pool_incr(kmp_str_buf_t
*buffer
,
4583 char const *name
, void *data
) {
4584 __kmp_stg_print_size(buffer
, name
, __kmp_malloc_pool_incr
);
4586 } // _kmp_stg_print_malloc_pool_incr
4590 // -----------------------------------------------------------------------------
4593 static void __kmp_stg_parse_par_range_env(char const *name
, char const *value
,
4595 __kmp_stg_parse_par_range(name
, value
, &__kmp_par_range
,
4596 __kmp_par_range_routine
, __kmp_par_range_filename
,
4597 &__kmp_par_range_lb
, &__kmp_par_range_ub
);
4598 } // __kmp_stg_parse_par_range_env
4600 static void __kmp_stg_print_par_range_env(kmp_str_buf_t
*buffer
,
4601 char const *name
, void *data
) {
4602 if (__kmp_par_range
!= 0) {
4603 __kmp_stg_print_str(buffer
, name
, par_range_to_print
);
4605 } // __kmp_stg_print_par_range_env
4609 // -----------------------------------------------------------------------------
4612 static void __kmp_stg_parse_gtid_mode(char const *name
, char const *value
,
4615 // 0 -- do not change default
4617 // 2 -- use "keyed" TLS var, i.e.
4618 // pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
4619 // 3 -- __declspec(thread) TLS var in tdata section
4622 #ifdef KMP_TDATA_GTID
4624 #endif /* KMP_TDATA_GTID */
4625 __kmp_stg_parse_int(name
, value
, 0, max
, &mode
);
4626 // TODO; parse_int is not very suitable for this case. In case of overflow it
4627 // is better to use 0 rather that max value.
4629 __kmp_adjust_gtid_mode
= TRUE
;
4631 __kmp_gtid_mode
= mode
;
4632 __kmp_adjust_gtid_mode
= FALSE
;
4634 } // __kmp_str_parse_gtid_mode
4636 static void __kmp_stg_print_gtid_mode(kmp_str_buf_t
*buffer
, char const *name
,
4638 if (__kmp_adjust_gtid_mode
) {
4639 __kmp_stg_print_int(buffer
, name
, 0);
4641 __kmp_stg_print_int(buffer
, name
, __kmp_gtid_mode
);
4643 } // __kmp_stg_print_gtid_mode
4645 // -----------------------------------------------------------------------------
4646 // KMP_NUM_LOCKS_IN_BLOCK
4648 static void __kmp_stg_parse_lock_block(char const *name
, char const *value
,
4650 __kmp_stg_parse_int(name
, value
, 0, KMP_INT_MAX
, &__kmp_num_locks_in_block
);
4651 } // __kmp_str_parse_lock_block
4653 static void __kmp_stg_print_lock_block(kmp_str_buf_t
*buffer
, char const *name
,
4655 __kmp_stg_print_int(buffer
, name
, __kmp_num_locks_in_block
);
4656 } // __kmp_stg_print_lock_block
4658 // -----------------------------------------------------------------------------
4661 #if KMP_USE_DYNAMIC_LOCK
4662 #define KMP_STORE_LOCK_SEQ(a) (__kmp_user_lock_seq = lockseq_##a)
4664 #define KMP_STORE_LOCK_SEQ(a)
4667 static void __kmp_stg_parse_lock_kind(char const *name
, char const *value
,
4669 if (__kmp_init_user_locks
) {
4670 KMP_WARNING(EnvLockWarn
, name
);
4674 if (__kmp_str_match("tas", 2, value
) ||
4675 __kmp_str_match("test and set", 2, value
) ||
4676 __kmp_str_match("test_and_set", 2, value
) ||
4677 __kmp_str_match("test-and-set", 2, value
) ||
4678 __kmp_str_match("test andset", 2, value
) ||
4679 __kmp_str_match("test_andset", 2, value
) ||
4680 __kmp_str_match("test-andset", 2, value
) ||
4681 __kmp_str_match("testand set", 2, value
) ||
4682 __kmp_str_match("testand_set", 2, value
) ||
4683 __kmp_str_match("testand-set", 2, value
) ||
4684 __kmp_str_match("testandset", 2, value
)) {
4685 __kmp_user_lock_kind
= lk_tas
;
4686 KMP_STORE_LOCK_SEQ(tas
);
4689 else if (__kmp_str_match("futex", 1, value
)) {
4690 if (__kmp_futex_determine_capable()) {
4691 __kmp_user_lock_kind
= lk_futex
;
4692 KMP_STORE_LOCK_SEQ(futex
);
4694 KMP_WARNING(FutexNotSupported
, name
, value
);
4698 else if (__kmp_str_match("ticket", 2, value
)) {
4699 __kmp_user_lock_kind
= lk_ticket
;
4700 KMP_STORE_LOCK_SEQ(ticket
);
4701 } else if (__kmp_str_match("queuing", 1, value
) ||
4702 __kmp_str_match("queue", 1, value
)) {
4703 __kmp_user_lock_kind
= lk_queuing
;
4704 KMP_STORE_LOCK_SEQ(queuing
);
4705 } else if (__kmp_str_match("drdpa ticket", 1, value
) ||
4706 __kmp_str_match("drdpa_ticket", 1, value
) ||
4707 __kmp_str_match("drdpa-ticket", 1, value
) ||
4708 __kmp_str_match("drdpaticket", 1, value
) ||
4709 __kmp_str_match("drdpa", 1, value
)) {
4710 __kmp_user_lock_kind
= lk_drdpa
;
4711 KMP_STORE_LOCK_SEQ(drdpa
);
4713 #if KMP_USE_ADAPTIVE_LOCKS
4714 else if (__kmp_str_match("adaptive", 1, value
)) {
4715 if (__kmp_cpuinfo
.flags
.rtm
) { // ??? Is cpuinfo available here?
4716 __kmp_user_lock_kind
= lk_adaptive
;
4717 KMP_STORE_LOCK_SEQ(adaptive
);
4719 KMP_WARNING(AdaptiveNotSupported
, name
, value
);
4720 __kmp_user_lock_kind
= lk_queuing
;
4721 KMP_STORE_LOCK_SEQ(queuing
);
4724 #endif // KMP_USE_ADAPTIVE_LOCKS
4725 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4726 else if (__kmp_str_match("rtm_queuing", 1, value
)) {
4727 if (__kmp_cpuinfo
.flags
.rtm
) {
4728 __kmp_user_lock_kind
= lk_rtm_queuing
;
4729 KMP_STORE_LOCK_SEQ(rtm_queuing
);
4731 KMP_WARNING(AdaptiveNotSupported
, name
, value
);
4732 __kmp_user_lock_kind
= lk_queuing
;
4733 KMP_STORE_LOCK_SEQ(queuing
);
4735 } else if (__kmp_str_match("rtm_spin", 1, value
)) {
4736 if (__kmp_cpuinfo
.flags
.rtm
) {
4737 __kmp_user_lock_kind
= lk_rtm_spin
;
4738 KMP_STORE_LOCK_SEQ(rtm_spin
);
4740 KMP_WARNING(AdaptiveNotSupported
, name
, value
);
4741 __kmp_user_lock_kind
= lk_tas
;
4742 KMP_STORE_LOCK_SEQ(queuing
);
4744 } else if (__kmp_str_match("hle", 1, value
)) {
4745 __kmp_user_lock_kind
= lk_hle
;
4746 KMP_STORE_LOCK_SEQ(hle
);
4750 KMP_WARNING(StgInvalidValue
, name
, value
);
4754 static void __kmp_stg_print_lock_kind(kmp_str_buf_t
*buffer
, char const *name
,
4756 const char *value
= NULL
;
4758 switch (__kmp_user_lock_kind
) {
4773 #if KMP_USE_DYNAMIC_LOCK && KMP_USE_TSX
4774 case lk_rtm_queuing
:
4775 value
= "rtm_queuing";
4798 #if KMP_USE_ADAPTIVE_LOCKS
4805 if (value
!= NULL
) {
4806 __kmp_stg_print_str(buffer
, name
, value
);
4810 // -----------------------------------------------------------------------------
4811 // KMP_SPIN_BACKOFF_PARAMS
4813 // KMP_SPIN_BACKOFF_PARAMS=max_backoff[,min_tick] (max backoff size, min tick
4814 // for machine pause)
4815 static void __kmp_stg_parse_spin_backoff_params(const char *name
,
4816 const char *value
, void *data
) {
4817 const char *next
= value
;
4819 int total
= 0; // Count elements that were set. It'll be used as an array size
4820 int prev_comma
= FALSE
; // For correct processing sequential commas
4823 kmp_uint32 max_backoff
= __kmp_spin_backoff_params
.max_backoff
;
4824 kmp_uint32 min_tick
= __kmp_spin_backoff_params
.min_tick
;
4826 // Run only 3 iterations because it is enough to read two values or find a
4828 for (i
= 0; i
< 3; i
++) {
4831 if (*next
== '\0') {
4834 // Next character is not an integer or not a comma OR number of values > 2
4836 if (((*next
< '0' || *next
> '9') && *next
!= ',') || total
> 2) {
4837 KMP_WARNING(EnvSyntaxError
, name
, value
);
4840 // The next character is ','
4842 // ',' is the first character
4843 if (total
== 0 || prev_comma
) {
4850 // Next character is a digit
4851 if (*next
>= '0' && *next
<= '9') {
4853 const char *buf
= next
;
4854 char const *msg
= NULL
;
4859 const char *tmp
= next
;
4861 if ((*next
== ' ' || *next
== '\t') && (*tmp
>= '0' && *tmp
<= '9')) {
4862 KMP_WARNING(EnvSpacesNotAllowed
, name
, value
);
4866 num
= __kmp_str_to_int(buf
, *next
);
4867 if (num
<= 0) { // The number of retries should be > 0
4868 msg
= KMP_I18N_STR(ValueTooSmall
);
4870 } else if (num
> KMP_INT_MAX
) {
4871 msg
= KMP_I18N_STR(ValueTooLarge
);
4875 // Message is not empty. Print warning.
4876 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
4877 KMP_INFORM(Using_int_Value
, name
, num
);
4881 } else if (total
== 2) {
4886 KMP_DEBUG_ASSERT(total
> 0);
4888 KMP_WARNING(EnvSyntaxError
, name
, value
);
4891 __kmp_spin_backoff_params
.max_backoff
= max_backoff
;
4892 __kmp_spin_backoff_params
.min_tick
= min_tick
;
4895 static void __kmp_stg_print_spin_backoff_params(kmp_str_buf_t
*buffer
,
4896 char const *name
, void *data
) {
4897 if (__kmp_env_format
) {
4898 KMP_STR_BUF_PRINT_NAME_EX(name
);
4900 __kmp_str_buf_print(buffer
, " %s='", name
);
4902 __kmp_str_buf_print(buffer
, "%d,%d'\n", __kmp_spin_backoff_params
.max_backoff
,
4903 __kmp_spin_backoff_params
.min_tick
);
4906 #if KMP_USE_ADAPTIVE_LOCKS
4908 // -----------------------------------------------------------------------------
4909 // KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE
4911 // Parse out values for the tunable parameters from a string of the form
4912 // KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]
4913 static void __kmp_stg_parse_adaptive_lock_props(const char *name
,
4914 const char *value
, void *data
) {
4915 int max_retries
= 0;
4916 int max_badness
= 0;
4918 const char *next
= value
;
4920 int total
= 0; // Count elements that were set. It'll be used as an array size
4921 int prev_comma
= FALSE
; // For correct processing sequential commas
4924 // Save values in the structure __kmp_speculative_backoff_params
4925 // Run only 3 iterations because it is enough to read two values or find a
4927 for (i
= 0; i
< 3; i
++) {
4930 if (*next
== '\0') {
4933 // Next character is not an integer or not a comma OR number of values > 2
4935 if (((*next
< '0' || *next
> '9') && *next
!= ',') || total
> 2) {
4936 KMP_WARNING(EnvSyntaxError
, name
, value
);
4939 // The next character is ','
4941 // ',' is the first character
4942 if (total
== 0 || prev_comma
) {
4949 // Next character is a digit
4950 if (*next
>= '0' && *next
<= '9') {
4952 const char *buf
= next
;
4953 char const *msg
= NULL
;
4958 const char *tmp
= next
;
4960 if ((*next
== ' ' || *next
== '\t') && (*tmp
>= '0' && *tmp
<= '9')) {
4961 KMP_WARNING(EnvSpacesNotAllowed
, name
, value
);
4965 num
= __kmp_str_to_int(buf
, *next
);
4966 if (num
< 0) { // The number of retries should be >= 0
4967 msg
= KMP_I18N_STR(ValueTooSmall
);
4969 } else if (num
> KMP_INT_MAX
) {
4970 msg
= KMP_I18N_STR(ValueTooLarge
);
4974 // Message is not empty. Print warning.
4975 KMP_WARNING(ParseSizeIntWarn
, name
, value
, msg
);
4976 KMP_INFORM(Using_int_Value
, name
, num
);
4980 } else if (total
== 2) {
4985 KMP_DEBUG_ASSERT(total
> 0);
4987 KMP_WARNING(EnvSyntaxError
, name
, value
);
4990 __kmp_adaptive_backoff_params
.max_soft_retries
= max_retries
;
4991 __kmp_adaptive_backoff_params
.max_badness
= max_badness
;
4994 static void __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t
*buffer
,
4995 char const *name
, void *data
) {
4996 if (__kmp_env_format
) {
4997 KMP_STR_BUF_PRINT_NAME_EX(name
);
4999 __kmp_str_buf_print(buffer
, " %s='", name
);
5001 __kmp_str_buf_print(buffer
, "%d,%d'\n",
5002 __kmp_adaptive_backoff_params
.max_soft_retries
,
5003 __kmp_adaptive_backoff_params
.max_badness
);
5004 } // __kmp_stg_print_adaptive_lock_props
5006 #if KMP_DEBUG_ADAPTIVE_LOCKS
5008 static void __kmp_stg_parse_speculative_statsfile(char const *name
,
5011 __kmp_stg_parse_file(name
, value
, "",
5012 CCAST(char **, &__kmp_speculative_statsfile
));
5013 } // __kmp_stg_parse_speculative_statsfile
5015 static void __kmp_stg_print_speculative_statsfile(kmp_str_buf_t
*buffer
,
5018 if (__kmp_str_match("-", 0, __kmp_speculative_statsfile
)) {
5019 __kmp_stg_print_str(buffer
, name
, "stdout");
5021 __kmp_stg_print_str(buffer
, name
, __kmp_speculative_statsfile
);
5024 } // __kmp_stg_print_speculative_statsfile
5026 #endif // KMP_DEBUG_ADAPTIVE_LOCKS
5028 #endif // KMP_USE_ADAPTIVE_LOCKS
5030 // -----------------------------------------------------------------------------
5031 // KMP_HW_SUBSET (was KMP_PLACE_THREADS)
5032 // 2s16c,2t => 2S16C,2T => 2S16C \0 2T
5034 // Return KMP_HW_SUBSET preferred hardware type in case a token is ambiguously
5035 // short. The original KMP_HW_SUBSET environment variable had single letters:
5036 // s, c, t for sockets, cores, threads repsectively.
5037 static kmp_hw_t
__kmp_hw_subset_break_tie(const kmp_hw_t
*possible
,
5038 size_t num_possible
) {
5039 for (size_t i
= 0; i
< num_possible
; ++i
) {
5040 if (possible
[i
] == KMP_HW_THREAD
)
5041 return KMP_HW_THREAD
;
5042 else if (possible
[i
] == KMP_HW_CORE
)
5044 else if (possible
[i
] == KMP_HW_SOCKET
)
5045 return KMP_HW_SOCKET
;
5047 return KMP_HW_UNKNOWN
;
5050 // Return hardware type from string or HW_UNKNOWN if string cannot be parsed
5051 // This algorithm is very forgiving to the user in that, the instant it can
5052 // reduce the search space to one, it assumes that is the topology level the
5053 // user wanted, even if it is misspelled later in the token.
5054 static kmp_hw_t
__kmp_stg_parse_hw_subset_name(char const *token
) {
5055 size_t index
, num_possible
, token_length
;
5056 kmp_hw_t possible
[KMP_HW_LAST
];
5059 // Find the end of the hardware token string
5062 while (isalnum(*end
) || *end
== '_') {
5067 // Set the possibilities to all hardware types
5069 KMP_FOREACH_HW_TYPE(type
) { possible
[num_possible
++] = type
; }
5071 // Eliminate hardware types by comparing the front of the token
5072 // with hardware names
5073 // In most cases, the first letter in the token will indicate exactly
5074 // which hardware type is parsed, e.g., 'C' = Core
5076 while (num_possible
> 1 && index
< token_length
) {
5077 size_t n
= num_possible
;
5078 char token_char
= (char)toupper(token
[index
]);
5079 for (size_t i
= 0; i
< n
; ++i
) {
5081 kmp_hw_t type
= possible
[i
];
5082 s
= __kmp_hw_get_keyword(type
, false);
5083 if (index
< KMP_STRLEN(s
)) {
5084 char c
= (char)toupper(s
[index
]);
5085 // Mark hardware types for removal when the characters do not match
5086 if (c
!= token_char
) {
5087 possible
[i
] = KMP_HW_UNKNOWN
;
5092 // Remove hardware types that this token cannot be
5094 for (size_t i
= 0; i
< n
; ++i
) {
5095 if (possible
[i
] != KMP_HW_UNKNOWN
) {
5096 kmp_hw_t temp
= possible
[i
];
5097 possible
[i
] = possible
[start
];
5098 possible
[start
] = temp
;
5102 KMP_ASSERT(start
== num_possible
);
5106 // Attempt to break a tie if user has very short token
5107 // (e.g., is 'T' tile or thread?)
5108 if (num_possible
> 1)
5109 return __kmp_hw_subset_break_tie(possible
, num_possible
);
5110 if (num_possible
== 1)
5112 return KMP_HW_UNKNOWN
;
5115 // The longest observable sequence of items can only be HW_LAST length
5116 // The input string is usually short enough, let's use 512 limit for now
5117 #define MAX_T_LEVEL KMP_HW_LAST
5118 #define MAX_STR_LEN 512
5119 static void __kmp_stg_parse_hw_subset(char const *name
, char const *value
,
5121 // Value example: 1s,5c@3,2T
5122 // Which means "use 1 socket, 5 cores with offset 3, 2 threads per core"
5123 kmp_setting_t
**rivals
= (kmp_setting_t
**)data
;
5124 if (strcmp(name
, "KMP_PLACE_THREADS") == 0) {
5125 KMP_INFORM(EnvVarDeprecated
, name
, "KMP_HW_SUBSET");
5127 if (__kmp_stg_check_rivals(name
, value
, rivals
)) {
5131 char *components
[MAX_T_LEVEL
];
5132 char const *digits
= "0123456789";
5133 char input
[MAX_STR_LEN
];
5134 size_t len
= 0, mlen
= MAX_STR_LEN
;
5136 bool absolute
= false;
5137 // Canonicalize the string (remove spaces, unify delimiters, etc.)
5138 char *pos
= CCAST(char *, value
);
5139 while (*pos
&& mlen
) {
5140 if (*pos
!= ' ') { // skip spaces
5141 if (len
== 0 && *pos
== ':') {
5144 input
[len
] = (char)(toupper(*pos
));
5145 if (input
[len
] == 'X')
5146 input
[len
] = ','; // unify delimiters of levels
5147 if (input
[len
] == 'O' && strchr(digits
, *(pos
+ 1)))
5148 input
[len
] = '@'; // unify delimiters of offset
5155 if (len
== 0 || mlen
== 0) {
5156 goto err
; // contents is either empty or too long
5159 // Split by delimiter
5161 components
[level
++] = pos
;
5162 while ((pos
= strchr(pos
, ','))) {
5163 if (level
>= MAX_T_LEVEL
)
5164 goto err
; // too many components provided
5165 *pos
= '\0'; // modify input and avoid more copying
5166 components
[level
++] = ++pos
; // expect something after ","
5169 __kmp_hw_subset
= kmp_hw_subset_t::allocate();
5171 __kmp_hw_subset
->set_absolute();
5173 // Check each component
5174 for (int i
= 0; i
< level
; ++i
) {
5176 char *core_components
[MAX_T_LEVEL
];
5177 // Split possible core components by '&' delimiter
5178 pos
= components
[i
];
5179 core_components
[core_level
++] = pos
;
5180 while ((pos
= strchr(pos
, '&'))) {
5181 if (core_level
>= MAX_T_LEVEL
)
5182 goto err
; // too many different core types
5183 *pos
= '\0'; // modify input and avoid more copying
5184 core_components
[core_level
++] = ++pos
; // expect something after '&'
5187 for (int j
= 0; j
< core_level
; ++j
) {
5193 // components may begin with an optional count of the number of resources
5194 if (isdigit(*core_components
[j
])) {
5195 num
= atoi(core_components
[j
]);
5197 goto err
; // only positive integers are valid for count
5199 pos
= core_components
[j
] + strspn(core_components
[j
], digits
);
5200 } else if (*core_components
[j
] == '*') {
5201 num
= kmp_hw_subset_t::USE_ALL
;
5202 pos
= core_components
[j
] + 1;
5204 num
= kmp_hw_subset_t::USE_ALL
;
5205 pos
= core_components
[j
];
5208 offset_ptr
= strchr(core_components
[j
], '@');
5209 attr_ptr
= strchr(core_components
[j
], ':');
5212 offset
= atoi(offset_ptr
+ 1); // save offset
5213 *offset_ptr
= '\0'; // cut the offset from the component
5217 // save the attribute
5218 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
5219 if (__kmp_str_match("intel_core", -1, attr_ptr
+ 1)) {
5220 attr
.set_core_type(KMP_HW_CORE_TYPE_CORE
);
5221 } else if (__kmp_str_match("intel_atom", -1, attr_ptr
+ 1)) {
5222 attr
.set_core_type(KMP_HW_CORE_TYPE_ATOM
);
5225 if (__kmp_str_match("eff", 3, attr_ptr
+ 1)) {
5226 const char *number
= attr_ptr
+ 1;
5227 // skip the eff[iciency] token
5228 while (isalpha(*number
))
5230 if (!isdigit(*number
)) {
5233 int efficiency
= atoi(number
);
5234 attr
.set_core_eff(efficiency
);
5238 *attr_ptr
= '\0'; // cut the attribute from the component
5240 // detect the component type
5241 kmp_hw_t type
= __kmp_stg_parse_hw_subset_name(pos
);
5242 if (type
== KMP_HW_UNKNOWN
) {
5245 // Only the core type can have attributes
5246 if (attr
&& type
!= KMP_HW_CORE
)
5248 // Must allow core be specified more than once
5249 if (type
!= KMP_HW_CORE
&& __kmp_hw_subset
->specified(type
)) {
5252 __kmp_hw_subset
->push_back(num
, type
, offset
, attr
);
5257 KMP_WARNING(AffHWSubsetInvalid
, name
, value
);
5258 if (__kmp_hw_subset
) {
5259 kmp_hw_subset_t::deallocate(__kmp_hw_subset
);
5260 __kmp_hw_subset
= nullptr;
5265 static void __kmp_stg_print_hw_subset(kmp_str_buf_t
*buffer
, char const *name
,
5269 if (!__kmp_hw_subset
)
5271 __kmp_str_buf_init(&buf
);
5272 if (__kmp_env_format
)
5273 KMP_STR_BUF_PRINT_NAME_EX(name
);
5275 __kmp_str_buf_print(buffer
, " %s='", name
);
5277 depth
= __kmp_hw_subset
->get_depth();
5278 for (int i
= 0; i
< depth
; ++i
) {
5279 const auto &item
= __kmp_hw_subset
->at(i
);
5281 __kmp_str_buf_print(&buf
, "%c", ',');
5282 for (int j
= 0; j
< item
.num_attrs
; ++j
) {
5283 __kmp_str_buf_print(&buf
, "%s%d%s", (j
> 0 ? "&" : ""), item
.num
[j
],
5284 __kmp_hw_get_keyword(item
.type
));
5285 if (item
.attr
[j
].is_core_type_valid())
5286 __kmp_str_buf_print(
5288 __kmp_hw_get_core_type_keyword(item
.attr
[j
].get_core_type()));
5289 if (item
.attr
[j
].is_core_eff_valid())
5290 __kmp_str_buf_print(&buf
, ":eff%d", item
.attr
[j
].get_core_eff());
5292 __kmp_str_buf_print(&buf
, "@%d", item
.offset
[j
]);
5295 __kmp_str_buf_print(buffer
, "%s'\n", buf
.str
);
5296 __kmp_str_buf_free(&buf
);
5300 // -----------------------------------------------------------------------------
5301 // KMP_FORKJOIN_FRAMES
5303 static void __kmp_stg_parse_forkjoin_frames(char const *name
, char const *value
,
5305 __kmp_stg_parse_bool(name
, value
, &__kmp_forkjoin_frames
);
5306 } // __kmp_stg_parse_forkjoin_frames
5308 static void __kmp_stg_print_forkjoin_frames(kmp_str_buf_t
*buffer
,
5309 char const *name
, void *data
) {
5310 __kmp_stg_print_bool(buffer
, name
, __kmp_forkjoin_frames
);
5311 } // __kmp_stg_print_forkjoin_frames
5313 // -----------------------------------------------------------------------------
5314 // KMP_FORKJOIN_FRAMES_MODE
5316 static void __kmp_stg_parse_forkjoin_frames_mode(char const *name
,
5319 __kmp_stg_parse_int(name
, value
, 0, 3, &__kmp_forkjoin_frames_mode
);
5320 } // __kmp_stg_parse_forkjoin_frames
5322 static void __kmp_stg_print_forkjoin_frames_mode(kmp_str_buf_t
*buffer
,
5323 char const *name
, void *data
) {
5324 __kmp_stg_print_int(buffer
, name
, __kmp_forkjoin_frames_mode
);
5325 } // __kmp_stg_print_forkjoin_frames
5326 #endif /* USE_ITT_BUILD */
5328 // -----------------------------------------------------------------------------
5329 // KMP_ENABLE_TASK_THROTTLING
5331 static void __kmp_stg_parse_task_throttling(char const *name
, char const *value
,
5333 __kmp_stg_parse_bool(name
, value
, &__kmp_enable_task_throttling
);
5334 } // __kmp_stg_parse_task_throttling
5336 static void __kmp_stg_print_task_throttling(kmp_str_buf_t
*buffer
,
5337 char const *name
, void *data
) {
5338 __kmp_stg_print_bool(buffer
, name
, __kmp_enable_task_throttling
);
5339 } // __kmp_stg_print_task_throttling
5341 #if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5342 // -----------------------------------------------------------------------------
5343 // KMP_USER_LEVEL_MWAIT
5345 static void __kmp_stg_parse_user_level_mwait(char const *name
,
5346 char const *value
, void *data
) {
5347 __kmp_stg_parse_bool(name
, value
, &__kmp_user_level_mwait
);
5348 } // __kmp_stg_parse_user_level_mwait
5350 static void __kmp_stg_print_user_level_mwait(kmp_str_buf_t
*buffer
,
5351 char const *name
, void *data
) {
5352 __kmp_stg_print_bool(buffer
, name
, __kmp_user_level_mwait
);
5353 } // __kmp_stg_print_user_level_mwait
5355 // -----------------------------------------------------------------------------
5358 static void __kmp_stg_parse_mwait_hints(char const *name
, char const *value
,
5360 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_mwait_hints
);
5361 } // __kmp_stg_parse_mwait_hints
5363 static void __kmp_stg_print_mwait_hints(kmp_str_buf_t
*buffer
, char const *name
,
5365 __kmp_stg_print_int(buffer
, name
, __kmp_mwait_hints
);
5366 } // __kmp_stg_print_mwait_hints
5368 #endif // KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5371 // -----------------------------------------------------------------------------
5373 // 0 = don't use TPAUSE, 1 = use C0.1 state, 2 = use C0.2 state
5375 static void __kmp_stg_parse_tpause(char const *name
, char const *value
,
5377 __kmp_stg_parse_int(name
, value
, 0, INT_MAX
, &__kmp_tpause_state
);
5378 if (__kmp_tpause_state
!= 0) {
5379 // The actual hint passed to tpause is: 0 for C0.2 and 1 for C0.1
5380 if (__kmp_tpause_state
== 2) // use C0.2
5381 __kmp_tpause_hint
= 0; // default was set to 1 for C0.1
5383 } // __kmp_stg_parse_tpause
5385 static void __kmp_stg_print_tpause(kmp_str_buf_t
*buffer
, char const *name
,
5387 __kmp_stg_print_int(buffer
, name
, __kmp_tpause_state
);
5388 } // __kmp_stg_print_tpause
5389 #endif // KMP_HAVE_UMWAIT
5391 // -----------------------------------------------------------------------------
5394 static void __kmp_stg_parse_omp_display_env(char const *name
, char const *value
,
5396 if (__kmp_str_match("VERBOSE", 1, value
)) {
5397 __kmp_display_env_verbose
= TRUE
;
5399 __kmp_stg_parse_bool(name
, value
, &__kmp_display_env
);
5401 } // __kmp_stg_parse_omp_display_env
5403 static void __kmp_stg_print_omp_display_env(kmp_str_buf_t
*buffer
,
5404 char const *name
, void *data
) {
5405 if (__kmp_display_env_verbose
) {
5406 __kmp_stg_print_str(buffer
, name
, "VERBOSE");
5408 __kmp_stg_print_bool(buffer
, name
, __kmp_display_env
);
5410 } // __kmp_stg_print_omp_display_env
5412 static void __kmp_stg_parse_omp_cancellation(char const *name
,
5413 char const *value
, void *data
) {
5414 if (TCR_4(__kmp_init_parallel
)) {
5415 KMP_WARNING(EnvParallelWarn
, name
);
5417 } // read value before first parallel only
5418 __kmp_stg_parse_bool(name
, value
, &__kmp_omp_cancellation
);
5419 } // __kmp_stg_parse_omp_cancellation
5421 static void __kmp_stg_print_omp_cancellation(kmp_str_buf_t
*buffer
,
5422 char const *name
, void *data
) {
5423 __kmp_stg_print_bool(buffer
, name
, __kmp_omp_cancellation
);
5424 } // __kmp_stg_print_omp_cancellation
5429 static void __kmp_stg_parse_omp_tool(char const *name
, char const *value
,
5431 __kmp_stg_parse_bool(name
, value
, &__kmp_tool
);
5432 } // __kmp_stg_parse_omp_tool
5434 static void __kmp_stg_print_omp_tool(kmp_str_buf_t
*buffer
, char const *name
,
5436 if (__kmp_env_format
) {
5437 KMP_STR_BUF_PRINT_BOOL_EX(name
, __kmp_tool
, "enabled", "disabled");
5439 __kmp_str_buf_print(buffer
, " %s=%s\n", name
,
5440 __kmp_tool
? "enabled" : "disabled");
5442 } // __kmp_stg_print_omp_tool
5444 char *__kmp_tool_libraries
= NULL
;
5446 static void __kmp_stg_parse_omp_tool_libraries(char const *name
,
5447 char const *value
, void *data
) {
5448 __kmp_stg_parse_str(name
, value
, &__kmp_tool_libraries
);
5449 } // __kmp_stg_parse_omp_tool_libraries
5451 static void __kmp_stg_print_omp_tool_libraries(kmp_str_buf_t
*buffer
,
5452 char const *name
, void *data
) {
5453 if (__kmp_tool_libraries
)
5454 __kmp_stg_print_str(buffer
, name
, __kmp_tool_libraries
);
5456 if (__kmp_env_format
) {
5457 KMP_STR_BUF_PRINT_NAME
;
5459 __kmp_str_buf_print(buffer
, " %s", name
);
5461 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
5463 } // __kmp_stg_print_omp_tool_libraries
5465 char *__kmp_tool_verbose_init
= NULL
;
5467 static void __kmp_stg_parse_omp_tool_verbose_init(char const *name
,
5470 __kmp_stg_parse_str(name
, value
, &__kmp_tool_verbose_init
);
5471 } // __kmp_stg_parse_omp_tool_libraries
5473 static void __kmp_stg_print_omp_tool_verbose_init(kmp_str_buf_t
*buffer
,
5476 if (__kmp_tool_verbose_init
)
5477 __kmp_stg_print_str(buffer
, name
, __kmp_tool_verbose_init
);
5479 if (__kmp_env_format
) {
5480 KMP_STR_BUF_PRINT_NAME
;
5482 __kmp_str_buf_print(buffer
, " %s", name
);
5484 __kmp_str_buf_print(buffer
, ": %s\n", KMP_I18N_STR(NotDefined
));
5486 } // __kmp_stg_print_omp_tool_verbose_init
5492 static kmp_setting_t __kmp_stg_table
[] = {
5494 {"KMP_ALL_THREADS", __kmp_stg_parse_device_thread_limit
, NULL
, NULL
, 0, 0},
5495 {"KMP_BLOCKTIME", __kmp_stg_parse_blocktime
, __kmp_stg_print_blocktime
,
5497 {"KMP_USE_YIELD", __kmp_stg_parse_use_yield
, __kmp_stg_print_use_yield
,
5499 {"KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok
,
5500 __kmp_stg_print_duplicate_lib_ok
, NULL
, 0, 0},
5501 {"KMP_LIBRARY", __kmp_stg_parse_wait_policy
, __kmp_stg_print_wait_policy
,
5503 {"KMP_DEVICE_THREAD_LIMIT", __kmp_stg_parse_device_thread_limit
,
5504 __kmp_stg_print_device_thread_limit
, NULL
, 0, 0},
5506 {"KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize
,
5507 __kmp_stg_print_monitor_stacksize
, NULL
, 0, 0},
5509 {"KMP_SETTINGS", __kmp_stg_parse_settings
, __kmp_stg_print_settings
, NULL
,
5511 {"KMP_STACKOFFSET", __kmp_stg_parse_stackoffset
,
5512 __kmp_stg_print_stackoffset
, NULL
, 0, 0},
5513 {"KMP_STACKSIZE", __kmp_stg_parse_stacksize
, __kmp_stg_print_stacksize
,
5515 {"KMP_STACKPAD", __kmp_stg_parse_stackpad
, __kmp_stg_print_stackpad
, NULL
,
5517 {"KMP_VERSION", __kmp_stg_parse_version
, __kmp_stg_print_version
, NULL
, 0,
5519 {"KMP_WARNINGS", __kmp_stg_parse_warnings
, __kmp_stg_print_warnings
, NULL
,
5522 {"KMP_NESTING_MODE", __kmp_stg_parse_nesting_mode
,
5523 __kmp_stg_print_nesting_mode
, NULL
, 0, 0},
5524 {"OMP_NESTED", __kmp_stg_parse_nested
, __kmp_stg_print_nested
, NULL
, 0, 0},
5525 {"OMP_NUM_THREADS", __kmp_stg_parse_num_threads
,
5526 __kmp_stg_print_num_threads
, NULL
, 0, 0},
5527 {"OMP_STACKSIZE", __kmp_stg_parse_stacksize
, __kmp_stg_print_stacksize
,
5530 {"KMP_TASKING", __kmp_stg_parse_tasking
, __kmp_stg_print_tasking
, NULL
, 0,
5532 {"KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing
,
5533 __kmp_stg_print_task_stealing
, NULL
, 0, 0},
5534 {"OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels
,
5535 __kmp_stg_print_max_active_levels
, NULL
, 0, 0},
5536 {"OMP_DEFAULT_DEVICE", __kmp_stg_parse_default_device
,
5537 __kmp_stg_print_default_device
, NULL
, 0, 0},
5538 {"OMP_TARGET_OFFLOAD", __kmp_stg_parse_target_offload
,
5539 __kmp_stg_print_target_offload
, NULL
, 0, 0},
5540 {"OMP_MAX_TASK_PRIORITY", __kmp_stg_parse_max_task_priority
,
5541 __kmp_stg_print_max_task_priority
, NULL
, 0, 0},
5542 {"KMP_TASKLOOP_MIN_TASKS", __kmp_stg_parse_taskloop_min_tasks
,
5543 __kmp_stg_print_taskloop_min_tasks
, NULL
, 0, 0},
5544 {"OMP_THREAD_LIMIT", __kmp_stg_parse_thread_limit
,
5545 __kmp_stg_print_thread_limit
, NULL
, 0, 0},
5546 {"KMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_thread_limit
,
5547 __kmp_stg_print_teams_thread_limit
, NULL
, 0, 0},
5548 {"OMP_NUM_TEAMS", __kmp_stg_parse_nteams
, __kmp_stg_print_nteams
, NULL
, 0,
5550 {"OMP_TEAMS_THREAD_LIMIT", __kmp_stg_parse_teams_th_limit
,
5551 __kmp_stg_print_teams_th_limit
, NULL
, 0, 0},
5552 {"OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy
,
5553 __kmp_stg_print_wait_policy
, NULL
, 0, 0},
5554 {"KMP_DISP_NUM_BUFFERS", __kmp_stg_parse_disp_buffers
,
5555 __kmp_stg_print_disp_buffers
, NULL
, 0, 0},
5556 #if KMP_NESTED_HOT_TEAMS
5557 {"KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level
,
5558 __kmp_stg_print_hot_teams_level
, NULL
, 0, 0},
5559 {"KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode
,
5560 __kmp_stg_print_hot_teams_mode
, NULL
, 0, 0},
5561 #endif // KMP_NESTED_HOT_TEAMS
5563 #if KMP_HANDLE_SIGNALS
5564 {"KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals
,
5565 __kmp_stg_print_handle_signals
, NULL
, 0, 0},
5568 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
5569 {"KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control
,
5570 __kmp_stg_print_inherit_fp_control
, NULL
, 0, 0},
5571 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
5573 #ifdef KMP_GOMP_COMPAT
5574 {"GOMP_STACKSIZE", __kmp_stg_parse_stacksize
, NULL
, NULL
, 0, 0},
5578 {"KMP_A_DEBUG", __kmp_stg_parse_a_debug
, __kmp_stg_print_a_debug
, NULL
, 0,
5580 {"KMP_B_DEBUG", __kmp_stg_parse_b_debug
, __kmp_stg_print_b_debug
, NULL
, 0,
5582 {"KMP_C_DEBUG", __kmp_stg_parse_c_debug
, __kmp_stg_print_c_debug
, NULL
, 0,
5584 {"KMP_D_DEBUG", __kmp_stg_parse_d_debug
, __kmp_stg_print_d_debug
, NULL
, 0,
5586 {"KMP_E_DEBUG", __kmp_stg_parse_e_debug
, __kmp_stg_print_e_debug
, NULL
, 0,
5588 {"KMP_F_DEBUG", __kmp_stg_parse_f_debug
, __kmp_stg_print_f_debug
, NULL
, 0,
5590 {"KMP_DEBUG", __kmp_stg_parse_debug
, NULL
, /* no print */ NULL
, 0, 0},
5591 {"KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf
, __kmp_stg_print_debug_buf
,
5593 {"KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic
,
5594 __kmp_stg_print_debug_buf_atomic
, NULL
, 0, 0},
5595 {"KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars
,
5596 __kmp_stg_print_debug_buf_chars
, NULL
, 0, 0},
5597 {"KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines
,
5598 __kmp_stg_print_debug_buf_lines
, NULL
, 0, 0},
5599 {"KMP_DIAG", __kmp_stg_parse_diag
, __kmp_stg_print_diag
, NULL
, 0, 0},
5601 {"KMP_PAR_RANGE", __kmp_stg_parse_par_range_env
,
5602 __kmp_stg_print_par_range_env
, NULL
, 0, 0},
5605 {"KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc
,
5606 __kmp_stg_print_align_alloc
, NULL
, 0, 0},
5608 {"KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit
,
5609 __kmp_stg_print_barrier_branch_bit
, NULL
, 0, 0},
5610 {"KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern
,
5611 __kmp_stg_print_barrier_pattern
, NULL
, 0, 0},
5612 {"KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit
,
5613 __kmp_stg_print_barrier_branch_bit
, NULL
, 0, 0},
5614 {"KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern
,
5615 __kmp_stg_print_barrier_pattern
, NULL
, 0, 0},
5616 #if KMP_FAST_REDUCTION_BARRIER
5617 {"KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit
,
5618 __kmp_stg_print_barrier_branch_bit
, NULL
, 0, 0},
5619 {"KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern
,
5620 __kmp_stg_print_barrier_pattern
, NULL
, 0, 0},
5623 {"KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay
,
5624 __kmp_stg_print_abort_delay
, NULL
, 0, 0},
5625 {"KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file
,
5626 __kmp_stg_print_cpuinfo_file
, NULL
, 0, 0},
5627 {"KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction
,
5628 __kmp_stg_print_force_reduction
, NULL
, 0, 0},
5629 {"KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction
,
5630 __kmp_stg_print_force_reduction
, NULL
, 0, 0},
5631 {"KMP_STORAGE_MAP", __kmp_stg_parse_storage_map
,
5632 __kmp_stg_print_storage_map
, NULL
, 0, 0},
5633 {"KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate
,
5634 __kmp_stg_print_all_threadprivate
, NULL
, 0, 0},
5635 {"KMP_FOREIGN_THREADS_THREADPRIVATE",
5636 __kmp_stg_parse_foreign_threads_threadprivate
,
5637 __kmp_stg_print_foreign_threads_threadprivate
, NULL
, 0, 0},
5639 #if KMP_AFFINITY_SUPPORTED
5640 {"KMP_AFFINITY", __kmp_stg_parse_affinity
, __kmp_stg_print_affinity
, NULL
,
5642 {"KMP_HIDDEN_HELPER_AFFINITY", __kmp_stg_parse_hh_affinity
,
5643 __kmp_stg_print_hh_affinity
, NULL
, 0, 0},
5644 #ifdef KMP_GOMP_COMPAT
5645 {"GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity
, NULL
,
5646 /* no print */ NULL
, 0, 0},
5647 #endif /* KMP_GOMP_COMPAT */
5648 {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind
, __kmp_stg_print_proc_bind
,
5650 {"KMP_TEAMS_PROC_BIND", __kmp_stg_parse_teams_proc_bind
,
5651 __kmp_stg_print_teams_proc_bind
, NULL
, 0, 0},
5652 {"OMP_PLACES", __kmp_stg_parse_places
, __kmp_stg_print_places
, NULL
, 0, 0},
5653 {"KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method
,
5654 __kmp_stg_print_topology_method
, NULL
, 0, 0},
5658 // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
5659 // OMP_PROC_BIND and proc-bind-var are supported, however.
5660 {"OMP_PROC_BIND", __kmp_stg_parse_proc_bind
, __kmp_stg_print_proc_bind
,
5663 #endif // KMP_AFFINITY_SUPPORTED
5664 {"OMP_DISPLAY_AFFINITY", __kmp_stg_parse_display_affinity
,
5665 __kmp_stg_print_display_affinity
, NULL
, 0, 0},
5666 {"OMP_AFFINITY_FORMAT", __kmp_stg_parse_affinity_format
,
5667 __kmp_stg_print_affinity_format
, NULL
, 0, 0},
5668 {"KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork
,
5669 __kmp_stg_print_init_at_fork
, NULL
, 0, 0},
5670 {"KMP_SCHEDULE", __kmp_stg_parse_schedule
, __kmp_stg_print_schedule
, NULL
,
5672 {"OMP_SCHEDULE", __kmp_stg_parse_omp_schedule
, __kmp_stg_print_omp_schedule
,
5674 #if KMP_USE_HIER_SCHED
5675 {"KMP_DISP_HAND_THREAD", __kmp_stg_parse_kmp_hand_thread
,
5676 __kmp_stg_print_kmp_hand_thread
, NULL
, 0, 0},
5678 {"KMP_FORCE_MONOTONIC_DYNAMIC_SCHEDULE",
5679 __kmp_stg_parse_kmp_force_monotonic
, __kmp_stg_print_kmp_force_monotonic
,
5681 {"KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode
,
5682 __kmp_stg_print_atomic_mode
, NULL
, 0, 0},
5683 {"KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check
,
5684 __kmp_stg_print_consistency_check
, NULL
, 0, 0},
5686 #if USE_ITT_BUILD && USE_ITT_NOTIFY
5687 {"KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay
,
5688 __kmp_stg_print_itt_prepare_delay
, NULL
, 0, 0},
5689 #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
5690 {"KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr
,
5691 __kmp_stg_print_malloc_pool_incr
, NULL
, 0, 0},
5692 {"KMP_GTID_MODE", __kmp_stg_parse_gtid_mode
, __kmp_stg_print_gtid_mode
,
5694 {"OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic
, __kmp_stg_print_omp_dynamic
,
5696 {"KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode
,
5697 __kmp_stg_print_kmp_dynamic_mode
, NULL
, 0, 0},
5699 #ifdef USE_LOAD_BALANCE
5700 {"KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval
,
5701 __kmp_stg_print_ld_balance_interval
, NULL
, 0, 0},
5704 {"KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block
,
5705 __kmp_stg_print_lock_block
, NULL
, 0, 0},
5706 {"KMP_LOCK_KIND", __kmp_stg_parse_lock_kind
, __kmp_stg_print_lock_kind
,
5708 {"KMP_SPIN_BACKOFF_PARAMS", __kmp_stg_parse_spin_backoff_params
,
5709 __kmp_stg_print_spin_backoff_params
, NULL
, 0, 0},
5710 #if KMP_USE_ADAPTIVE_LOCKS
5711 {"KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props
,
5712 __kmp_stg_print_adaptive_lock_props
, NULL
, 0, 0},
5713 #if KMP_DEBUG_ADAPTIVE_LOCKS
5714 {"KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile
,
5715 __kmp_stg_print_speculative_statsfile
, NULL
, 0, 0},
5717 #endif // KMP_USE_ADAPTIVE_LOCKS
5718 {"KMP_PLACE_THREADS", __kmp_stg_parse_hw_subset
, __kmp_stg_print_hw_subset
,
5720 {"KMP_HW_SUBSET", __kmp_stg_parse_hw_subset
, __kmp_stg_print_hw_subset
,
5723 {"KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames
,
5724 __kmp_stg_print_forkjoin_frames
, NULL
, 0, 0},
5725 {"KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode
,
5726 __kmp_stg_print_forkjoin_frames_mode
, NULL
, 0, 0},
5728 {"KMP_ENABLE_TASK_THROTTLING", __kmp_stg_parse_task_throttling
,
5729 __kmp_stg_print_task_throttling
, NULL
, 0, 0},
5731 {"OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env
,
5732 __kmp_stg_print_omp_display_env
, NULL
, 0, 0},
5733 {"OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation
,
5734 __kmp_stg_print_omp_cancellation
, NULL
, 0, 0},
5735 {"OMP_ALLOCATOR", __kmp_stg_parse_allocator
, __kmp_stg_print_allocator
,
5737 {"LIBOMP_USE_HIDDEN_HELPER_TASK", __kmp_stg_parse_use_hidden_helper
,
5738 __kmp_stg_print_use_hidden_helper
, NULL
, 0, 0},
5739 {"LIBOMP_NUM_HIDDEN_HELPER_THREADS",
5740 __kmp_stg_parse_num_hidden_helper_threads
,
5741 __kmp_stg_print_num_hidden_helper_threads
, NULL
, 0, 0},
5743 {"KMP_MAX_TDGS", __kmp_stg_parse_max_tdgs
, __kmp_std_print_max_tdgs
, NULL
,
5745 {"KMP_TDG_DOT", __kmp_stg_parse_tdg_dot
, __kmp_stg_print_tdg_dot
, NULL
, 0, 0},
5749 {"OMP_TOOL", __kmp_stg_parse_omp_tool
, __kmp_stg_print_omp_tool
, NULL
, 0,
5751 {"OMP_TOOL_LIBRARIES", __kmp_stg_parse_omp_tool_libraries
,
5752 __kmp_stg_print_omp_tool_libraries
, NULL
, 0, 0},
5753 {"OMP_TOOL_VERBOSE_INIT", __kmp_stg_parse_omp_tool_verbose_init
,
5754 __kmp_stg_print_omp_tool_verbose_init
, NULL
, 0, 0},
5757 #if KMP_HAVE_MWAIT || KMP_HAVE_UMWAIT
5758 {"KMP_USER_LEVEL_MWAIT", __kmp_stg_parse_user_level_mwait
,
5759 __kmp_stg_print_user_level_mwait
, NULL
, 0, 0},
5760 {"KMP_MWAIT_HINTS", __kmp_stg_parse_mwait_hints
,
5761 __kmp_stg_print_mwait_hints
, NULL
, 0, 0},
5765 {"KMP_TPAUSE", __kmp_stg_parse_tpause
, __kmp_stg_print_tpause
, NULL
, 0, 0},
5767 {"", NULL
, NULL
, NULL
, 0, 0}}; // settings
5769 static int const __kmp_stg_count
=
5770 sizeof(__kmp_stg_table
) / sizeof(kmp_setting_t
);
5772 static inline kmp_setting_t
*__kmp_stg_find(char const *name
) {
5776 for (i
= 0; i
< __kmp_stg_count
; ++i
) {
5777 if (strcmp(__kmp_stg_table
[i
].name
, name
) == 0) {
5778 return &__kmp_stg_table
[i
];
5786 static int __kmp_stg_cmp(void const *_a
, void const *_b
) {
5787 const kmp_setting_t
*a
= RCAST(const kmp_setting_t
*, _a
);
5788 const kmp_setting_t
*b
= RCAST(const kmp_setting_t
*, _b
);
5790 // Process KMP_AFFINITY last.
5791 // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
5792 if (strcmp(a
->name
, "KMP_AFFINITY") == 0) {
5793 if (strcmp(b
->name
, "KMP_AFFINITY") == 0) {
5797 } else if (strcmp(b
->name
, "KMP_AFFINITY") == 0) {
5800 return strcmp(a
->name
, b
->name
);
5803 static void __kmp_stg_init(void) {
5805 static int initialized
= 0;
5810 qsort(__kmp_stg_table
, __kmp_stg_count
- 1, sizeof(kmp_setting_t
),
5813 { // Initialize *_STACKSIZE data.
5814 kmp_setting_t
*kmp_stacksize
=
5815 __kmp_stg_find("KMP_STACKSIZE"); // 1st priority.
5816 #ifdef KMP_GOMP_COMPAT
5817 kmp_setting_t
*gomp_stacksize
=
5818 __kmp_stg_find("GOMP_STACKSIZE"); // 2nd priority.
5820 kmp_setting_t
*omp_stacksize
=
5821 __kmp_stg_find("OMP_STACKSIZE"); // 3rd priority.
5823 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5824 // !!! Compiler does not understand rivals is used and optimizes out
5826 // !!! rivals[ i ++ ] = ...;
5827 static kmp_setting_t
*volatile rivals
[4];
5828 static kmp_stg_ss_data_t kmp_data
= {1, CCAST(kmp_setting_t
**, rivals
)};
5829 #ifdef KMP_GOMP_COMPAT
5830 static kmp_stg_ss_data_t gomp_data
= {1024,
5831 CCAST(kmp_setting_t
**, rivals
)};
5833 static kmp_stg_ss_data_t omp_data
= {1024,
5834 CCAST(kmp_setting_t
**, rivals
)};
5837 rivals
[i
++] = kmp_stacksize
;
5838 #ifdef KMP_GOMP_COMPAT
5839 if (gomp_stacksize
!= NULL
) {
5840 rivals
[i
++] = gomp_stacksize
;
5843 rivals
[i
++] = omp_stacksize
;
5846 kmp_stacksize
->data
= &kmp_data
;
5847 #ifdef KMP_GOMP_COMPAT
5848 if (gomp_stacksize
!= NULL
) {
5849 gomp_stacksize
->data
= &gomp_data
;
5852 omp_stacksize
->data
= &omp_data
;
5855 { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
5856 kmp_setting_t
*kmp_library
=
5857 __kmp_stg_find("KMP_LIBRARY"); // 1st priority.
5858 kmp_setting_t
*omp_wait_policy
=
5859 __kmp_stg_find("OMP_WAIT_POLICY"); // 2nd priority.
5861 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5862 static kmp_setting_t
*volatile rivals
[3];
5863 static kmp_stg_wp_data_t kmp_data
= {0, CCAST(kmp_setting_t
**, rivals
)};
5864 static kmp_stg_wp_data_t omp_data
= {1, CCAST(kmp_setting_t
**, rivals
)};
5867 rivals
[i
++] = kmp_library
;
5868 if (omp_wait_policy
!= NULL
) {
5869 rivals
[i
++] = omp_wait_policy
;
5873 kmp_library
->data
= &kmp_data
;
5874 if (omp_wait_policy
!= NULL
) {
5875 omp_wait_policy
->data
= &omp_data
;
5879 { // Initialize KMP_DEVICE_THREAD_LIMIT and KMP_ALL_THREADS
5880 kmp_setting_t
*kmp_device_thread_limit
=
5881 __kmp_stg_find("KMP_DEVICE_THREAD_LIMIT"); // 1st priority.
5882 kmp_setting_t
*kmp_all_threads
=
5883 __kmp_stg_find("KMP_ALL_THREADS"); // 2nd priority.
5885 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5886 static kmp_setting_t
*volatile rivals
[3];
5889 rivals
[i
++] = kmp_device_thread_limit
;
5890 rivals
[i
++] = kmp_all_threads
;
5893 kmp_device_thread_limit
->data
= CCAST(kmp_setting_t
**, rivals
);
5894 kmp_all_threads
->data
= CCAST(kmp_setting_t
**, rivals
);
5897 { // Initialize KMP_HW_SUBSET and KMP_PLACE_THREADS
5899 kmp_setting_t
*kmp_hw_subset
= __kmp_stg_find("KMP_HW_SUBSET");
5901 kmp_setting_t
*kmp_place_threads
= __kmp_stg_find("KMP_PLACE_THREADS");
5903 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5904 static kmp_setting_t
*volatile rivals
[3];
5907 rivals
[i
++] = kmp_hw_subset
;
5908 rivals
[i
++] = kmp_place_threads
;
5911 kmp_hw_subset
->data
= CCAST(kmp_setting_t
**, rivals
);
5912 kmp_place_threads
->data
= CCAST(kmp_setting_t
**, rivals
);
5915 #if KMP_AFFINITY_SUPPORTED
5916 { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
5917 kmp_setting_t
*kmp_affinity
=
5918 __kmp_stg_find("KMP_AFFINITY"); // 1st priority.
5919 KMP_DEBUG_ASSERT(kmp_affinity
!= NULL
);
5921 #ifdef KMP_GOMP_COMPAT
5922 kmp_setting_t
*gomp_cpu_affinity
=
5923 __kmp_stg_find("GOMP_CPU_AFFINITY"); // 2nd priority.
5924 KMP_DEBUG_ASSERT(gomp_cpu_affinity
!= NULL
);
5927 kmp_setting_t
*omp_proc_bind
=
5928 __kmp_stg_find("OMP_PROC_BIND"); // 3rd priority.
5929 KMP_DEBUG_ASSERT(omp_proc_bind
!= NULL
);
5931 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5932 static kmp_setting_t
*volatile rivals
[4];
5935 rivals
[i
++] = kmp_affinity
;
5937 #ifdef KMP_GOMP_COMPAT
5938 rivals
[i
++] = gomp_cpu_affinity
;
5939 gomp_cpu_affinity
->data
= CCAST(kmp_setting_t
**, rivals
);
5942 rivals
[i
++] = omp_proc_bind
;
5943 omp_proc_bind
->data
= CCAST(kmp_setting_t
**, rivals
);
5946 static kmp_setting_t
*volatile places_rivals
[4];
5949 kmp_setting_t
*omp_places
= __kmp_stg_find("OMP_PLACES"); // 3rd priority.
5950 KMP_DEBUG_ASSERT(omp_places
!= NULL
);
5952 places_rivals
[i
++] = kmp_affinity
;
5953 #ifdef KMP_GOMP_COMPAT
5954 places_rivals
[i
++] = gomp_cpu_affinity
;
5956 places_rivals
[i
++] = omp_places
;
5957 omp_places
->data
= CCAST(kmp_setting_t
**, places_rivals
);
5958 places_rivals
[i
++] = NULL
;
5961 // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
5962 // OMP_PLACES not supported yet.
5963 #endif // KMP_AFFINITY_SUPPORTED
5965 { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
5966 kmp_setting_t
*kmp_force_red
=
5967 __kmp_stg_find("KMP_FORCE_REDUCTION"); // 1st priority.
5968 kmp_setting_t
*kmp_determ_red
=
5969 __kmp_stg_find("KMP_DETERMINISTIC_REDUCTION"); // 2nd priority.
5971 // !!! volatile keyword is Intel(R) C Compiler bug CQ49908 workaround.
5972 static kmp_setting_t
*volatile rivals
[3];
5973 static kmp_stg_fr_data_t force_data
= {1,
5974 CCAST(kmp_setting_t
**, rivals
)};
5975 static kmp_stg_fr_data_t determ_data
= {0,
5976 CCAST(kmp_setting_t
**, rivals
)};
5979 rivals
[i
++] = kmp_force_red
;
5980 if (kmp_determ_red
!= NULL
) {
5981 rivals
[i
++] = kmp_determ_red
;
5985 kmp_force_red
->data
= &force_data
;
5986 if (kmp_determ_red
!= NULL
) {
5987 kmp_determ_red
->data
= &determ_data
;
5996 for (i
= 0; i
< __kmp_stg_count
; ++i
) {
5997 __kmp_stg_table
[i
].set
= 0;
6002 static void __kmp_stg_parse(char const *name
, char const *value
) {
6003 // On Windows* OS there are some nameless variables like "C:=C:\" (yeah,
6004 // really nameless, they are presented in environment block as
6005 // "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
6010 if (value
!= NULL
) {
6011 kmp_setting_t
*setting
= __kmp_stg_find(name
);
6012 if (setting
!= NULL
) {
6013 setting
->parse(name
, value
, setting
->data
);
6014 setting
->defined
= 1;
6018 } // __kmp_stg_parse
6020 static int __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
6021 char const *name
, // Name of variable.
6022 char const *value
, // Value of the variable.
6023 kmp_setting_t
**rivals
// List of rival settings (must include current one).
6026 if (rivals
== NULL
) {
6030 // Loop thru higher priority settings (listed before current).
6032 for (; strcmp(rivals
[i
]->name
, name
) != 0; i
++) {
6033 KMP_DEBUG_ASSERT(rivals
[i
] != NULL
);
6035 #if KMP_AFFINITY_SUPPORTED
6036 if (rivals
[i
] == __kmp_affinity_notype
) {
6037 // If KMP_AFFINITY is specified without a type name,
6038 // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
6043 if (rivals
[i
]->set
) {
6044 KMP_WARNING(StgIgnored
, name
, rivals
[i
]->name
);
6049 ++i
; // Skip current setting.
6052 } // __kmp_stg_check_rivals
6054 static int __kmp_env_toPrint(char const *name
, int flag
) {
6056 kmp_setting_t
*setting
= __kmp_stg_find(name
);
6057 if (setting
!= NULL
) {
6058 rc
= setting
->defined
;
6060 setting
->defined
= flag
;
6066 #if defined(KMP_DEBUG) && KMP_AFFINITY_SUPPORTED
6067 static void __kmp_print_affinity_settings(const kmp_affinity_t
*affinity
) {
6068 K_DIAG(1, ("%s:\n", affinity
->env_var
));
6069 K_DIAG(1, (" type : %d\n", affinity
->type
));
6070 K_DIAG(1, (" compact : %d\n", affinity
->compact
));
6071 K_DIAG(1, (" offset : %d\n", affinity
->offset
));
6072 K_DIAG(1, (" verbose : %u\n", affinity
->flags
.verbose
));
6073 K_DIAG(1, (" warnings : %u\n", affinity
->flags
.warnings
));
6074 K_DIAG(1, (" respect : %u\n", affinity
->flags
.respect
));
6075 K_DIAG(1, (" reset : %u\n", affinity
->flags
.reset
));
6076 K_DIAG(1, (" dups : %u\n", affinity
->flags
.dups
));
6077 K_DIAG(1, (" gran : %d\n", (int)affinity
->gran
));
6078 KMP_DEBUG_ASSERT(affinity
->type
!= affinity_default
);
6082 static void __kmp_aux_env_initialize(kmp_env_blk_t
*block
) {
6086 /* OMP_NUM_THREADS */
6087 value
= __kmp_env_blk_var(block
, "OMP_NUM_THREADS");
6089 ompc_set_num_threads(__kmp_dflt_team_nth
);
6093 value
= __kmp_env_blk_var(block
, "KMP_BLOCKTIME");
6098 gtid
= __kmp_entry_gtid();
6099 tid
= __kmp_tid_from_gtid(gtid
);
6100 thread
= __kmp_thread_from_gtid(gtid
);
6101 __kmp_aux_set_blocktime(__kmp_dflt_blocktime
, thread
, tid
);
6105 value
= __kmp_env_blk_var(block
, "OMP_NESTED");
6107 ompc_set_nested(__kmp_dflt_max_active_levels
> 1);
6111 value
= __kmp_env_blk_var(block
, "OMP_DYNAMIC");
6113 ompc_set_dynamic(__kmp_global
.g
.g_dynamic
);
6117 void __kmp_env_initialize(char const *string
) {
6119 kmp_env_blk_t block
;
6125 if (string
== NULL
) {
6126 // __kmp_max_nth = __kmp_sys_max_nth;
6127 __kmp_threads_capacity
=
6128 __kmp_initial_threads_capacity(__kmp_dflt_team_nth_ub
);
6130 __kmp_env_blk_init(&block
, string
);
6132 // update the set flag on all entries that have an env var
6133 for (i
= 0; i
< block
.count
; ++i
) {
6134 if ((block
.vars
[i
].name
== NULL
) || (*block
.vars
[i
].name
== '\0')) {
6137 if (block
.vars
[i
].value
== NULL
) {
6140 kmp_setting_t
*setting
= __kmp_stg_find(block
.vars
[i
].name
);
6141 if (setting
!= NULL
) {
6146 // We need to know if blocktime was set when processing OMP_WAIT_POLICY
6147 blocktime_str
= __kmp_env_blk_var(&block
, "KMP_BLOCKTIME");
6149 // Special case. If we parse environment, not a string, process KMP_WARNINGS
6151 if (string
== NULL
) {
6152 char const *name
= "KMP_WARNINGS";
6153 char const *value
= __kmp_env_blk_var(&block
, name
);
6154 __kmp_stg_parse(name
, value
);
6157 #if KMP_AFFINITY_SUPPORTED
6158 // Special case. KMP_AFFINITY is not a rival to other affinity env vars
6159 // if no affinity type is specified. We want to allow
6160 // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when
6161 // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
6162 // affinity mechanism.
6163 __kmp_affinity_notype
= NULL
;
6164 char const *aff_str
= __kmp_env_blk_var(&block
, "KMP_AFFINITY");
6165 if (aff_str
!= NULL
) {
6166 // Check if the KMP_AFFINITY type is specified in the string.
6167 // We just search the string for "compact", "scatter", etc.
6168 // without really parsing the string. The syntax of the
6169 // KMP_AFFINITY env var is such that none of the affinity
6170 // type names can appear anywhere other that the type
6171 // specifier, even as substrings.
6173 // I can't find a case-insensitive version of strstr on Windows* OS.
6174 // Use the case-sensitive version for now.
6179 #define FIND strcasestr
6182 if ((FIND(aff_str
, "none") == NULL
) &&
6183 (FIND(aff_str
, "physical") == NULL
) &&
6184 (FIND(aff_str
, "logical") == NULL
) &&
6185 (FIND(aff_str
, "compact") == NULL
) &&
6186 (FIND(aff_str
, "scatter") == NULL
) &&
6187 (FIND(aff_str
, "explicit") == NULL
) &&
6188 (FIND(aff_str
, "balanced") == NULL
) &&
6189 (FIND(aff_str
, "disabled") == NULL
)) {
6190 __kmp_affinity_notype
= __kmp_stg_find("KMP_AFFINITY");
6192 // A new affinity type is specified.
6193 // Reset the affinity flags to their default values,
6194 // in case this is called from kmp_set_defaults().
6195 __kmp_affinity
.type
= affinity_default
;
6196 __kmp_affinity
.gran
= KMP_HW_UNKNOWN
;
6197 __kmp_affinity_top_method
= affinity_top_method_default
;
6198 __kmp_affinity
.flags
.respect
= affinity_respect_mask_default
;
6202 // Also reset the affinity flags if OMP_PROC_BIND is specified.
6203 aff_str
= __kmp_env_blk_var(&block
, "OMP_PROC_BIND");
6204 if (aff_str
!= NULL
) {
6205 __kmp_affinity
.type
= affinity_default
;
6206 __kmp_affinity
.gran
= KMP_HW_UNKNOWN
;
6207 __kmp_affinity_top_method
= affinity_top_method_default
;
6208 __kmp_affinity
.flags
.respect
= affinity_respect_mask_default
;
6212 #endif /* KMP_AFFINITY_SUPPORTED */
6214 // Set up the nested proc bind type vector.
6215 if (__kmp_nested_proc_bind
.bind_types
== NULL
) {
6216 __kmp_nested_proc_bind
.bind_types
=
6217 (kmp_proc_bind_t
*)KMP_INTERNAL_MALLOC(sizeof(kmp_proc_bind_t
));
6218 if (__kmp_nested_proc_bind
.bind_types
== NULL
) {
6219 KMP_FATAL(MemoryAllocFailed
);
6221 __kmp_nested_proc_bind
.size
= 1;
6222 __kmp_nested_proc_bind
.used
= 1;
6223 #if KMP_AFFINITY_SUPPORTED
6224 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_default
;
6226 // default proc bind is false if affinity not supported
6227 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
6231 // Set up the affinity format ICV
6232 // Grab the default affinity format string from the message catalog
6234 __kmp_msg_format(kmp_i18n_msg_AffFormatDefault
, "%P", "%i", "%n", "%A");
6235 KMP_DEBUG_ASSERT(KMP_STRLEN(m
.str
) < KMP_AFFINITY_FORMAT_SIZE
);
6237 if (__kmp_affinity_format
== NULL
) {
6238 __kmp_affinity_format
=
6239 (char *)KMP_INTERNAL_MALLOC(sizeof(char) * KMP_AFFINITY_FORMAT_SIZE
);
6241 KMP_STRCPY_S(__kmp_affinity_format
, KMP_AFFINITY_FORMAT_SIZE
, m
.str
);
6242 __kmp_str_free(&m
.str
);
6244 // Now process all of the settings.
6245 for (i
= 0; i
< block
.count
; ++i
) {
6246 __kmp_stg_parse(block
.vars
[i
].name
, block
.vars
[i
].value
);
6249 // If user locks have been allocated yet, don't reset the lock vptr table.
6250 if (!__kmp_init_user_locks
) {
6251 if (__kmp_user_lock_kind
== lk_default
) {
6252 __kmp_user_lock_kind
= lk_queuing
;
6254 #if KMP_USE_DYNAMIC_LOCK
6255 __kmp_init_dynamic_user_locks();
6257 __kmp_set_user_lock_vptrs(__kmp_user_lock_kind
);
6260 KMP_DEBUG_ASSERT(string
!= NULL
); // kmp_set_defaults() was called
6261 KMP_DEBUG_ASSERT(__kmp_user_lock_kind
!= lk_default
);
6262 // Binds lock functions again to follow the transition between different
6263 // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
6264 // as we do not allow lock kind changes after making a call to any
6265 // user lock functions (true).
6266 #if KMP_USE_DYNAMIC_LOCK
6267 __kmp_init_dynamic_user_locks();
6269 __kmp_set_user_lock_vptrs(__kmp_user_lock_kind
);
6273 #if KMP_AFFINITY_SUPPORTED
6275 if (!TCR_4(__kmp_init_middle
)) {
6277 // Force using hwloc when either tiles or numa nodes requested within
6278 // KMP_HW_SUBSET or granularity setting and no other topology method
6280 if (__kmp_hw_subset
&&
6281 __kmp_affinity_top_method
== affinity_top_method_default
)
6282 if (__kmp_hw_subset
->specified(KMP_HW_NUMA
) ||
6283 __kmp_hw_subset
->specified(KMP_HW_TILE
) ||
6284 __kmp_affinity
.gran
== KMP_HW_TILE
||
6285 __kmp_affinity
.gran
== KMP_HW_NUMA
)
6286 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
6287 // Force using hwloc when tiles or numa nodes requested for OMP_PLACES
6288 if (__kmp_affinity
.gran
== KMP_HW_NUMA
||
6289 __kmp_affinity
.gran
== KMP_HW_TILE
)
6290 __kmp_affinity_top_method
= affinity_top_method_hwloc
;
6292 // Determine if the machine/OS is actually capable of supporting
6294 const char *var
= "KMP_AFFINITY";
6295 KMPAffinity::pick_api();
6297 // If Hwloc topology discovery was requested but affinity was also disabled,
6298 // then tell user that Hwloc request is being ignored and use default
6299 // topology discovery method.
6300 if (__kmp_affinity_top_method
== affinity_top_method_hwloc
&&
6301 __kmp_affinity_dispatch
->get_api_type() != KMPAffinity::HWLOC
) {
6302 KMP_WARNING(AffIgnoringHwloc
, var
);
6303 __kmp_affinity_top_method
= affinity_top_method_all
;
6306 if (__kmp_affinity
.type
== affinity_disabled
) {
6307 KMP_AFFINITY_DISABLE();
6308 } else if (!KMP_AFFINITY_CAPABLE()) {
6309 __kmp_affinity_dispatch
->determine_capable(var
);
6310 if (!KMP_AFFINITY_CAPABLE()) {
6311 if (__kmp_affinity
.flags
.verbose
||
6312 (__kmp_affinity
.flags
.warnings
&&
6313 (__kmp_affinity
.type
!= affinity_default
) &&
6314 (__kmp_affinity
.type
!= affinity_none
) &&
6315 (__kmp_affinity
.type
!= affinity_disabled
))) {
6316 KMP_WARNING(AffNotSupported
, var
);
6318 __kmp_affinity
.type
= affinity_disabled
;
6319 __kmp_affinity
.flags
.respect
= FALSE
;
6320 __kmp_affinity
.gran
= KMP_HW_THREAD
;
6324 if (__kmp_affinity
.type
== affinity_disabled
) {
6325 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
6326 } else if (__kmp_nested_proc_bind
.bind_types
[0] == proc_bind_true
) {
6327 // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
6328 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_spread
;
6331 if (KMP_AFFINITY_CAPABLE()) {
6333 #if KMP_GROUP_AFFINITY
6334 // This checks to see if the initial affinity mask is equal
6335 // to a single windows processor group. If it is, then we do
6336 // not respect the initial affinity mask and instead, use the
6338 bool exactly_one_group
= false;
6339 if (__kmp_num_proc_groups
> 1) {
6341 bool within_one_group
;
6342 // Get the initial affinity mask and determine if it is
6343 // contained within a single group.
6344 kmp_affin_mask_t
*init_mask
;
6345 KMP_CPU_ALLOC(init_mask
);
6346 __kmp_get_system_affinity(init_mask
, TRUE
);
6347 group
= __kmp_get_proc_group(init_mask
);
6348 within_one_group
= (group
>= 0);
6349 // If the initial affinity is within a single group,
6350 // then determine if it is equal to that single group.
6351 if (within_one_group
) {
6352 DWORD num_bits_in_group
= __kmp_GetActiveProcessorCount(group
);
6353 DWORD num_bits_in_mask
= 0;
6354 for (int bit
= init_mask
->begin(); bit
!= init_mask
->end();
6355 bit
= init_mask
->next(bit
))
6357 exactly_one_group
= (num_bits_in_group
== num_bits_in_mask
);
6359 KMP_CPU_FREE(init_mask
);
6362 // Handle the Win 64 group affinity stuff if there are multiple
6363 // processor groups, or if the user requested it, and OMP 4.0
6364 // affinity is not in effect.
6365 if (__kmp_num_proc_groups
> 1 &&
6366 __kmp_affinity
.type
== affinity_default
&&
6367 __kmp_nested_proc_bind
.bind_types
[0] == proc_bind_default
) {
6368 // Do not respect the initial processor affinity mask if it is assigned
6369 // exactly one Windows Processor Group since this is interpreted as the
6370 // default OS assignment. Not respecting the mask allows the runtime to
6371 // use all the logical processors in all groups.
6372 if (__kmp_affinity
.flags
.respect
== affinity_respect_mask_default
&&
6373 exactly_one_group
) {
6374 __kmp_affinity
.flags
.respect
= FALSE
;
6376 // Use compact affinity with anticipation of pinning to at least the
6377 // group granularity since threads can only be bound to one group.
6378 if (__kmp_affinity
.type
== affinity_default
) {
6379 __kmp_affinity
.type
= affinity_compact
;
6380 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
6382 if (__kmp_hh_affinity
.type
== affinity_default
)
6383 __kmp_hh_affinity
.type
= affinity_compact
;
6384 if (__kmp_affinity_top_method
== affinity_top_method_default
)
6385 __kmp_affinity_top_method
= affinity_top_method_all
;
6386 if (__kmp_affinity
.gran
== KMP_HW_UNKNOWN
)
6387 __kmp_affinity
.gran
= KMP_HW_PROC_GROUP
;
6388 if (__kmp_hh_affinity
.gran
== KMP_HW_UNKNOWN
)
6389 __kmp_hh_affinity
.gran
= KMP_HW_PROC_GROUP
;
6392 #endif /* KMP_GROUP_AFFINITY */
6395 if (__kmp_affinity
.flags
.respect
== affinity_respect_mask_default
) {
6396 #if KMP_GROUP_AFFINITY
6397 if (__kmp_num_proc_groups
> 1 && exactly_one_group
) {
6398 __kmp_affinity
.flags
.respect
= FALSE
;
6400 #endif /* KMP_GROUP_AFFINITY */
6402 __kmp_affinity
.flags
.respect
= TRUE
;
6405 if ((__kmp_nested_proc_bind
.bind_types
[0] != proc_bind_intel
) &&
6406 (__kmp_nested_proc_bind
.bind_types
[0] != proc_bind_default
)) {
6407 if (__kmp_affinity
.type
== affinity_default
) {
6408 __kmp_affinity
.type
= affinity_compact
;
6409 __kmp_affinity
.flags
.dups
= FALSE
;
6411 } else if (__kmp_affinity
.type
== affinity_default
) {
6412 #if KMP_MIC_SUPPORTED
6413 if (__kmp_mic_type
!= non_mic
) {
6414 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_intel
;
6418 __kmp_nested_proc_bind
.bind_types
[0] = proc_bind_false
;
6420 #if KMP_MIC_SUPPORTED
6421 if (__kmp_mic_type
!= non_mic
) {
6422 __kmp_affinity
.type
= affinity_scatter
;
6426 __kmp_affinity
.type
= affinity_none
;
6429 if (__kmp_hh_affinity
.type
== affinity_default
)
6430 __kmp_hh_affinity
.type
= affinity_none
;
6431 if ((__kmp_affinity
.gran
== KMP_HW_UNKNOWN
) &&
6432 (__kmp_affinity
.gran_levels
< 0)) {
6433 #if KMP_MIC_SUPPORTED
6434 if (__kmp_mic_type
!= non_mic
) {
6435 __kmp_affinity
.gran
= KMP_HW_THREAD
;
6439 __kmp_affinity
.gran
= KMP_HW_CORE
;
6442 if ((__kmp_hh_affinity
.gran
== KMP_HW_UNKNOWN
) &&
6443 (__kmp_hh_affinity
.gran_levels
< 0)) {
6444 #if KMP_MIC_SUPPORTED
6445 if (__kmp_mic_type
!= non_mic
) {
6446 __kmp_hh_affinity
.gran
= KMP_HW_THREAD
;
6450 __kmp_hh_affinity
.gran
= KMP_HW_CORE
;
6453 if (__kmp_affinity_top_method
== affinity_top_method_default
) {
6454 __kmp_affinity_top_method
= affinity_top_method_all
;
6458 // If affinity is disabled, then still need to assign topology method
6459 // to attempt machine detection and affinity types
6460 if (__kmp_affinity_top_method
== affinity_top_method_default
)
6461 __kmp_affinity_top_method
= affinity_top_method_all
;
6462 if (__kmp_affinity
.type
== affinity_default
)
6463 __kmp_affinity
.type
= affinity_disabled
;
6464 if (__kmp_hh_affinity
.type
== affinity_default
)
6465 __kmp_hh_affinity
.type
= affinity_disabled
;
6469 for (const kmp_affinity_t
*affinity
: __kmp_affinities
)
6470 __kmp_print_affinity_settings(affinity
);
6471 KMP_DEBUG_ASSERT(__kmp_nested_proc_bind
.bind_types
[0] != proc_bind_default
);
6472 K_DIAG(1, ("__kmp_nested_proc_bind.bind_types[0] == %d\n",
6473 __kmp_nested_proc_bind
.bind_types
[0]));
6477 #endif /* KMP_AFFINITY_SUPPORTED */
6479 // Post-initialization step: some env. vars need their value's further
6481 if (string
!= NULL
) { // kmp_set_defaults() was called
6482 __kmp_aux_env_initialize(&block
);
6485 __kmp_env_blk_free(&block
);
6489 } // __kmp_env_initialize
6491 void __kmp_env_print() {
6493 kmp_env_blk_t block
;
6495 kmp_str_buf_t buffer
;
6498 __kmp_str_buf_init(&buffer
);
6500 __kmp_env_blk_init(&block
, NULL
);
6501 __kmp_env_blk_sort(&block
);
6503 // Print real environment values.
6504 __kmp_str_buf_print(&buffer
, "\n%s\n\n", KMP_I18N_STR(UserSettings
));
6505 for (i
= 0; i
< block
.count
; ++i
) {
6506 char const *name
= block
.vars
[i
].name
;
6507 char const *value
= block
.vars
[i
].value
;
6508 if ((KMP_STRLEN(name
) > 4 && strncmp(name
, "KMP_", 4) == 0) ||
6509 strncmp(name
, "OMP_", 4) == 0
6510 #ifdef KMP_GOMP_COMPAT
6511 || strncmp(name
, "GOMP_", 5) == 0
6512 #endif // KMP_GOMP_COMPAT
6514 __kmp_str_buf_print(&buffer
, " %s=%s\n", name
, value
);
6517 __kmp_str_buf_print(&buffer
, "\n");
6519 // Print internal (effective) settings.
6520 __kmp_str_buf_print(&buffer
, "%s\n\n", KMP_I18N_STR(EffectiveSettings
));
6521 for (int i
= 0; i
< __kmp_stg_count
; ++i
) {
6522 if (__kmp_stg_table
[i
].print
!= NULL
) {
6523 __kmp_stg_table
[i
].print(&buffer
, __kmp_stg_table
[i
].name
,
6524 __kmp_stg_table
[i
].data
);
6528 __kmp_printf("%s", buffer
.str
);
6530 __kmp_env_blk_free(&block
);
6531 __kmp_str_buf_free(&buffer
);
6535 } // __kmp_env_print
6537 void __kmp_env_print_2() {
6538 __kmp_display_env_impl(__kmp_display_env
, __kmp_display_env_verbose
);
6539 } // __kmp_env_print_2
6541 void __kmp_display_env_impl(int display_env
, int display_env_verbose
) {
6542 kmp_env_blk_t block
;
6543 kmp_str_buf_t buffer
;
6545 __kmp_env_format
= 1;
6548 __kmp_str_buf_init(&buffer
);
6550 __kmp_env_blk_init(&block
, NULL
);
6551 __kmp_env_blk_sort(&block
);
6553 __kmp_str_buf_print(&buffer
, "\n%s\n", KMP_I18N_STR(DisplayEnvBegin
));
6554 __kmp_str_buf_print(&buffer
, " _OPENMP='%d'\n", __kmp_openmp_version
);
6556 for (int i
= 0; i
< __kmp_stg_count
; ++i
) {
6557 if (__kmp_stg_table
[i
].print
!= NULL
&&
6558 ((display_env
&& strncmp(__kmp_stg_table
[i
].name
, "OMP_", 4) == 0) ||
6559 display_env_verbose
)) {
6560 __kmp_stg_table
[i
].print(&buffer
, __kmp_stg_table
[i
].name
,
6561 __kmp_stg_table
[i
].data
);
6565 __kmp_str_buf_print(&buffer
, "%s\n", KMP_I18N_STR(DisplayEnvEnd
));
6566 __kmp_str_buf_print(&buffer
, "\n");
6568 __kmp_printf("%s", buffer
.str
);
6570 __kmp_env_blk_free(&block
);
6571 __kmp_str_buf_free(&buffer
);
6577 // Dump environment variables for OMPD
6578 void __kmp_env_dump() {
6580 kmp_env_blk_t block
;
6581 kmp_str_buf_t buffer
, env
, notdefined
;
6584 __kmp_str_buf_init(&buffer
);
6585 __kmp_str_buf_init(&env
);
6586 __kmp_str_buf_init(¬defined
);
6588 __kmp_env_blk_init(&block
, NULL
);
6589 __kmp_env_blk_sort(&block
);
6591 __kmp_str_buf_print(¬defined
, ": %s", KMP_I18N_STR(NotDefined
));
6593 for (int i
= 0; i
< __kmp_stg_count
; ++i
) {
6594 if (__kmp_stg_table
[i
].print
== NULL
)
6596 __kmp_str_buf_clear(&env
);
6597 __kmp_stg_table
[i
].print(&env
, __kmp_stg_table
[i
].name
,
6598 __kmp_stg_table
[i
].data
);
6599 if (env
.used
< 4) // valid definition must have indents (3) and a new line
6601 if (strstr(env
.str
, notdefined
.str
))
6602 // normalize the string
6603 __kmp_str_buf_print(&buffer
, "%s=undefined\n", __kmp_stg_table
[i
].name
);
6605 __kmp_str_buf_cat(&buffer
, env
.str
+ 3, env
.used
- 3);
6608 ompd_env_block
= (char *)__kmp_allocate(buffer
.used
+ 1);
6609 KMP_MEMCPY(ompd_env_block
, buffer
.str
, buffer
.used
+ 1);
6610 ompd_env_block_size
= (ompd_size_t
)KMP_STRLEN(ompd_env_block
);
6612 __kmp_env_blk_free(&block
);
6613 __kmp_str_buf_free(&buffer
);
6614 __kmp_str_buf_free(&env
);
6615 __kmp_str_buf_free(¬defined
);
6617 #endif // OMPD_SUPPORT