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