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_mic_type != non_mic ) {
2930  __kmp_affinity_gran = affinity_gran_fine;
2931  } else {
2932  __kmp_affinity_gran = affinity_gran_core;
2933  }
2934  }
2935  else {
2936  __kmp_affinity_type = affinity_none;
2937  }
2938 } // __kmp_parse_proc_bind
2939 
2940 # endif /* if (! OMP_40_ENABLED) */
2941 
2942 
2943 static void
2944 __kmp_stg_parse_topology_method( char const * name, char const * value,
2945  void * data ) {
2946  if ( __kmp_str_match( "all", 1, value ) ) {
2947  __kmp_affinity_top_method = affinity_top_method_all;
2948  }
2949 # if KMP_ARCH_X86 || KMP_ARCH_X86_64
2950  else if ( __kmp_str_match( "x2apic id", 9, value )
2951  || __kmp_str_match( "x2apic_id", 9, value )
2952  || __kmp_str_match( "x2apic-id", 9, value )
2953  || __kmp_str_match( "x2apicid", 8, value )
2954  || __kmp_str_match( "cpuid leaf 11", 13, value )
2955  || __kmp_str_match( "cpuid_leaf_11", 13, value )
2956  || __kmp_str_match( "cpuid-leaf-11", 13, value )
2957  || __kmp_str_match( "cpuid leaf11", 12, value )
2958  || __kmp_str_match( "cpuid_leaf11", 12, value )
2959  || __kmp_str_match( "cpuid-leaf11", 12, value )
2960  || __kmp_str_match( "cpuidleaf 11", 12, value )
2961  || __kmp_str_match( "cpuidleaf_11", 12, value )
2962  || __kmp_str_match( "cpuidleaf-11", 12, value )
2963  || __kmp_str_match( "cpuidleaf11", 11, value )
2964  || __kmp_str_match( "cpuid 11", 8, value )
2965  || __kmp_str_match( "cpuid_11", 8, value )
2966  || __kmp_str_match( "cpuid-11", 8, value )
2967  || __kmp_str_match( "cpuid11", 7, value )
2968  || __kmp_str_match( "leaf 11", 7, value )
2969  || __kmp_str_match( "leaf_11", 7, value )
2970  || __kmp_str_match( "leaf-11", 7, value )
2971  || __kmp_str_match( "leaf11", 6, value ) ) {
2972  __kmp_affinity_top_method = affinity_top_method_x2apicid;
2973  }
2974  else if ( __kmp_str_match( "apic id", 7, value )
2975  || __kmp_str_match( "apic_id", 7, value )
2976  || __kmp_str_match( "apic-id", 7, value )
2977  || __kmp_str_match( "apicid", 6, value )
2978  || __kmp_str_match( "cpuid leaf 4", 12, value )
2979  || __kmp_str_match( "cpuid_leaf_4", 12, value )
2980  || __kmp_str_match( "cpuid-leaf-4", 12, value )
2981  || __kmp_str_match( "cpuid leaf4", 11, value )
2982  || __kmp_str_match( "cpuid_leaf4", 11, value )
2983  || __kmp_str_match( "cpuid-leaf4", 11, value )
2984  || __kmp_str_match( "cpuidleaf 4", 11, value )
2985  || __kmp_str_match( "cpuidleaf_4", 11, value )
2986  || __kmp_str_match( "cpuidleaf-4", 11, value )
2987  || __kmp_str_match( "cpuidleaf4", 10, value )
2988  || __kmp_str_match( "cpuid 4", 7, value )
2989  || __kmp_str_match( "cpuid_4", 7, value )
2990  || __kmp_str_match( "cpuid-4", 7, value )
2991  || __kmp_str_match( "cpuid4", 6, value )
2992  || __kmp_str_match( "leaf 4", 6, value )
2993  || __kmp_str_match( "leaf_4", 6, value )
2994  || __kmp_str_match( "leaf-4", 6, value )
2995  || __kmp_str_match( "leaf4", 5, value ) ) {
2996  __kmp_affinity_top_method = affinity_top_method_apicid;
2997  }
2998 # endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
2999  else if ( __kmp_str_match( "/proc/cpuinfo", 2, value )
3000  || __kmp_str_match( "cpuinfo", 5, value )) {
3001  __kmp_affinity_top_method = affinity_top_method_cpuinfo;
3002  }
3003 # if KMP_GROUP_AFFINITY
3004  else if ( __kmp_str_match( "group", 1, value ) ) {
3005  __kmp_affinity_top_method = affinity_top_method_group;
3006  }
3007 # endif /* KMP_GROUP_AFFINITY */
3008  else if ( __kmp_str_match( "flat", 1, value ) ) {
3009  __kmp_affinity_top_method = affinity_top_method_flat;
3010  }
3011  else {
3012  KMP_WARNING( StgInvalidValue, name, value );
3013  }
3014 } // __kmp_stg_parse_topology_method
3015 
3016 static void
3017 __kmp_stg_print_topology_method( kmp_str_buf_t * buffer, char const * name,
3018  void * data ) {
3019 # if KMP_DEBUG
3020  char const * value = NULL;
3021 
3022  switch ( __kmp_affinity_top_method ) {
3023  case affinity_top_method_default:
3024  value = "default";
3025  break;
3026 
3027  case affinity_top_method_all:
3028  value = "all";
3029  break;
3030 
3031 # if KMP_ARCH_X86 || KMP_ARCH_X86_64
3032  case affinity_top_method_x2apicid:
3033  value = "x2APIC id";
3034  break;
3035 
3036  case affinity_top_method_apicid:
3037  value = "APIC id";
3038  break;
3039 # endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
3040 
3041  case affinity_top_method_cpuinfo:
3042  value = "cpuinfo";
3043  break;
3044 
3045 # if KMP_GROUP_AFFINITY
3046  case affinity_top_method_group:
3047  value = "group";
3048  break;
3049 # endif /* KMP_GROUP_AFFINITY */
3050 
3051  case affinity_top_method_flat:
3052  value = "flat";
3053  break;
3054  }
3055 
3056  if ( value != NULL ) {
3057  __kmp_stg_print_str( buffer, name, value );
3058  }
3059 # endif /* KMP_DEBUG */
3060 } // __kmp_stg_print_topology_method
3061 
3062 #endif /* KMP_AFFINITY_SUPPORTED */
3063 
3064 
3065 #if OMP_40_ENABLED
3066 
3067 //
3068 // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
3069 // OMP_PLACES / place-partition-var is not.
3070 //
3071 static void
3072 __kmp_stg_parse_proc_bind( char const * name, char const * value, void * data )
3073 {
3074  kmp_setting_t **rivals = (kmp_setting_t **) data;
3075  int rc;
3076 
3077  rc = __kmp_stg_check_rivals( name, value, rivals );
3078  if ( rc ) {
3079  return;
3080  }
3081 
3082  //
3083  // in OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
3084  //
3085  KMP_DEBUG_ASSERT( (__kmp_nested_proc_bind.bind_types != NULL)
3086  && ( __kmp_nested_proc_bind.used > 0 ) );
3087 
3088  const char *buf = value;
3089  const char *next;
3090  int num;
3091  SKIP_WS( buf );
3092  if ( (*buf >= '0') && (*buf <= '9') ) {
3093  next = buf;
3094  SKIP_DIGITS( next );
3095  num = __kmp_str_to_int( buf, *next );
3096  KMP_ASSERT( num >= 0 );
3097  buf = next;
3098  SKIP_WS( buf );
3099  }
3100  else {
3101  num = -1;
3102  }
3103 
3104  next = buf;
3105  if ( __kmp_match_str( "disabled", buf, &next ) ) {
3106  buf = next;
3107  SKIP_WS( buf );
3108 # if KMP_AFFINITY_SUPPORTED
3109  __kmp_affinity_type = affinity_disabled;
3110 # endif /* KMP_AFFINITY_SUPPORTED */
3111  __kmp_nested_proc_bind.used = 1;
3112  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3113  }
3114  else if ( ( num == (int)proc_bind_false )
3115  || __kmp_match_str( "false", buf, &next ) ) {
3116  buf = next;
3117  SKIP_WS( buf );
3118 # if KMP_AFFINITY_SUPPORTED
3119  __kmp_affinity_type = affinity_none;
3120 # endif /* KMP_AFFINITY_SUPPORTED */
3121  __kmp_nested_proc_bind.used = 1;
3122  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3123  }
3124  else if ( ( num == (int)proc_bind_true )
3125  || __kmp_match_str( "true", buf, &next ) ) {
3126  buf = next;
3127  SKIP_WS( buf );
3128  __kmp_nested_proc_bind.used = 1;
3129  __kmp_nested_proc_bind.bind_types[0] = proc_bind_true;
3130  }
3131  else {
3132  //
3133  // Count the number of values in the env var string
3134  //
3135  const char *scan;
3136  int nelem = 1;
3137  for ( scan = buf; *scan != '\0'; scan++ ) {
3138  if ( *scan == ',' ) {
3139  nelem++;
3140  }
3141  }
3142 
3143  //
3144  // Create / expand the nested proc_bind array as needed
3145  //
3146  if ( __kmp_nested_proc_bind.size < nelem ) {
3147  __kmp_nested_proc_bind.bind_types = (kmp_proc_bind_t *)
3148  KMP_INTERNAL_REALLOC( __kmp_nested_proc_bind.bind_types,
3149  sizeof(kmp_proc_bind_t) * nelem );
3150  if ( __kmp_nested_proc_bind.bind_types == NULL ) {
3151  KMP_FATAL( MemoryAllocFailed );
3152  }
3153  __kmp_nested_proc_bind.size = nelem;
3154  }
3155  __kmp_nested_proc_bind.used = nelem;
3156 
3157  //
3158  // Save values in the nested proc_bind array
3159  //
3160  int i = 0;
3161  for (;;) {
3162  enum kmp_proc_bind_t bind;
3163 
3164  if ( ( num == (int)proc_bind_master )
3165  || __kmp_match_str( "master", buf, &next ) ) {
3166  buf = next;
3167  SKIP_WS( buf );
3168  bind = proc_bind_master;
3169  }
3170  else if ( ( num == (int)proc_bind_close )
3171  || __kmp_match_str( "close", buf, &next ) ) {
3172  buf = next;
3173  SKIP_WS( buf );
3174  bind = proc_bind_close;
3175  }
3176  else if ( ( num == (int)proc_bind_spread )
3177  || __kmp_match_str( "spread", buf, &next ) ) {
3178  buf = next;
3179  SKIP_WS( buf );
3180  bind = proc_bind_spread;
3181  }
3182  else {
3183  KMP_WARNING( StgInvalidValue, name, value );
3184  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
3185  __kmp_nested_proc_bind.used = 1;
3186  return;
3187  }
3188 
3189  __kmp_nested_proc_bind.bind_types[i++] = bind;
3190  if ( i >= nelem ) {
3191  break;
3192  }
3193  KMP_DEBUG_ASSERT( *buf == ',' );
3194  buf++;
3195  SKIP_WS( buf );
3196 
3197  //
3198  // Read next value if it was specified as an integer
3199  //
3200  if ( (*buf >= '0') && (*buf <= '9') ) {
3201  next = buf;
3202  SKIP_DIGITS( next );
3203  num = __kmp_str_to_int( buf, *next );
3204  KMP_ASSERT( num >= 0 );
3205  buf = next;
3206  SKIP_WS( buf );
3207  }
3208  else {
3209  num = -1;
3210  }
3211  }
3212  SKIP_WS( buf );
3213  }
3214  if ( *buf != '\0' ) {
3215  KMP_WARNING( ParseExtraCharsWarn, name, buf );
3216  }
3217 }
3218 
3219 
3220 static void
3221 __kmp_stg_print_proc_bind( kmp_str_buf_t * buffer, char const * name,
3222  void * data )
3223 {
3224  int nelem = __kmp_nested_proc_bind.used;
3225  if( __kmp_env_format ) {
3226  KMP_STR_BUF_PRINT_NAME;
3227  } else {
3228  __kmp_str_buf_print( buffer, " %s", name );
3229  }
3230  if ( nelem == 0 ) {
3231  __kmp_str_buf_print( buffer, ": %s\n", KMP_I18N_STR( NotDefined ) );
3232  }
3233  else {
3234  int i;
3235  __kmp_str_buf_print( buffer, "='", name );
3236  for ( i = 0; i < nelem; i++ ) {
3237  switch ( __kmp_nested_proc_bind.bind_types[i] ) {
3238  case proc_bind_false:
3239  __kmp_str_buf_print( buffer, "false" );
3240  break;
3241 
3242  case proc_bind_true:
3243  __kmp_str_buf_print( buffer, "true" );
3244  break;
3245 
3246  case proc_bind_master:
3247  __kmp_str_buf_print( buffer, "master" );
3248  break;
3249 
3250  case proc_bind_close:
3251  __kmp_str_buf_print( buffer, "close" );
3252  break;
3253 
3254  case proc_bind_spread:
3255  __kmp_str_buf_print( buffer, "spread" );
3256  break;
3257 
3258  case proc_bind_intel:
3259  __kmp_str_buf_print( buffer, "intel" );
3260  break;
3261 
3262  case proc_bind_default:
3263  __kmp_str_buf_print( buffer, "default" );
3264  break;
3265  }
3266  if ( i < nelem - 1 ) {
3267  __kmp_str_buf_print( buffer, "," );
3268  }
3269  }
3270  __kmp_str_buf_print( buffer, "'\n" );
3271  }
3272 }
3273 
3274 #endif /* OMP_40_ENABLED */
3275 
3276 
3277 // -------------------------------------------------------------------------------------------------
3278 // OMP_DYNAMIC
3279 // -------------------------------------------------------------------------------------------------
3280 
3281 static void
3282 __kmp_stg_parse_omp_dynamic( char const * name, char const * value, void * data )
3283 {
3284  __kmp_stg_parse_bool( name, value, & (__kmp_global.g.g_dynamic) );
3285 } // __kmp_stg_parse_omp_dynamic
3286 
3287 static void
3288 __kmp_stg_print_omp_dynamic( kmp_str_buf_t * buffer, char const * name, void * data )
3289 {
3290  __kmp_stg_print_bool( buffer, name, __kmp_global.g.g_dynamic );
3291 } // __kmp_stg_print_omp_dynamic
3292 
3293 static void
3294 __kmp_stg_parse_kmp_dynamic_mode( char const * name, char const * value, void * data )
3295 {
3296  if ( TCR_4(__kmp_init_parallel) ) {
3297  KMP_WARNING( EnvParallelWarn, name );
3298  __kmp_env_toPrint( name, 0 );
3299  return;
3300  }
3301 #ifdef USE_LOAD_BALANCE
3302  else if ( __kmp_str_match( "load balance", 2, value )
3303  || __kmp_str_match( "load_balance", 2, value )
3304  || __kmp_str_match( "load-balance", 2, value )
3305  || __kmp_str_match( "loadbalance", 2, value )
3306  || __kmp_str_match( "balance", 1, value ) ) {
3307  __kmp_global.g.g_dynamic_mode = dynamic_load_balance;
3308  }
3309 #endif /* USE_LOAD_BALANCE */
3310  else if ( __kmp_str_match( "thread limit", 1, value )
3311  || __kmp_str_match( "thread_limit", 1, value )
3312  || __kmp_str_match( "thread-limit", 1, value )
3313  || __kmp_str_match( "threadlimit", 1, value )
3314  || __kmp_str_match( "limit", 2, value ) ) {
3315  __kmp_global.g.g_dynamic_mode = dynamic_thread_limit;
3316  }
3317  else if ( __kmp_str_match( "random", 1, value ) ) {
3318  __kmp_global.g.g_dynamic_mode = dynamic_random;
3319  }
3320  else {
3321  KMP_WARNING( StgInvalidValue, name, value );
3322  }
3323 } //__kmp_stg_parse_kmp_dynamic_mode
3324 
3325 static void
3326 __kmp_stg_print_kmp_dynamic_mode( kmp_str_buf_t * buffer, char const * name, void * data )
3327 {
3328 #if KMP_DEBUG
3329  if ( __kmp_global.g.g_dynamic_mode == dynamic_default ) {
3330  __kmp_str_buf_print( buffer, " %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
3331  }
3332 # ifdef USE_LOAD_BALANCE
3333  else if ( __kmp_global.g.g_dynamic_mode == dynamic_load_balance ) {
3334  __kmp_stg_print_str( buffer, name, "load balance" );
3335  }
3336 # endif /* USE_LOAD_BALANCE */
3337  else if ( __kmp_global.g.g_dynamic_mode == dynamic_thread_limit ) {
3338  __kmp_stg_print_str( buffer, name, "thread limit" );
3339  }
3340  else if ( __kmp_global.g.g_dynamic_mode == dynamic_random ) {
3341  __kmp_stg_print_str( buffer, name, "random" );
3342  }
3343  else {
3344  KMP_ASSERT(0);
3345  }
3346 #endif /* KMP_DEBUG */
3347 } // __kmp_stg_print_kmp_dynamic_mode
3348 
3349 
3350 #ifdef USE_LOAD_BALANCE
3351 
3352 // -------------------------------------------------------------------------------------------------
3353 // KMP_LOAD_BALANCE_INTERVAL
3354 // -------------------------------------------------------------------------------------------------
3355 
3356 static void
3357 __kmp_stg_parse_ld_balance_interval( char const * name, char const * value, void * data )
3358 {
3359  double interval = __kmp_convert_to_double( value );
3360  if ( interval >= 0 ) {
3361  __kmp_load_balance_interval = interval;
3362  } else {
3363  KMP_WARNING( StgInvalidValue, name, value );
3364  }; // if
3365 } // __kmp_stg_parse_load_balance_interval
3366 
3367 static void
3368 __kmp_stg_print_ld_balance_interval( kmp_str_buf_t * buffer, char const * name, void * data ) {
3369 #if KMP_DEBUG
3370  __kmp_str_buf_print( buffer, " %s=%8.6f\n", name, __kmp_load_balance_interval );
3371 #endif /* KMP_DEBUG */
3372 } // __kmp_stg_print_load_balance_interval
3373 
3374 #endif /* USE_LOAD_BALANCE */
3375 
3376 
3377 
3378 // -------------------------------------------------------------------------------------------------
3379 // KMP_INIT_AT_FORK
3380 // -------------------------------------------------------------------------------------------------
3381 
3382 static void
3383 __kmp_stg_parse_init_at_fork( char const * name, char const * value, void * data ) {
3384  __kmp_stg_parse_bool( name, value, & __kmp_need_register_atfork );
3385  if ( __kmp_need_register_atfork ) {
3386  __kmp_need_register_atfork_specified = TRUE;
3387  };
3388 } // __kmp_stg_parse_init_at_fork
3389 
3390 static void
3391 __kmp_stg_print_init_at_fork( kmp_str_buf_t * buffer, char const * name, void * data ) {
3392  __kmp_stg_print_bool( buffer, name, __kmp_need_register_atfork_specified );
3393 } // __kmp_stg_print_init_at_fork
3394 
3395 // -------------------------------------------------------------------------------------------------
3396 // KMP_SCHEDULE
3397 // -------------------------------------------------------------------------------------------------
3398 
3399 static void
3400 __kmp_stg_parse_schedule( char const * name, char const * value, void * data ) {
3401 
3402  if ( value != NULL ) {
3403  size_t length = KMP_STRLEN( value );
3404  if ( length > INT_MAX ) {
3405  KMP_WARNING( LongValue, name );
3406  } else {
3407  char *semicolon;
3408  if( value[ length - 1 ] == '"' || value[ length -1 ] == '\'' )
3409  KMP_WARNING( UnbalancedQuotes, name );
3410  do {
3411  char sentinel;
3412 
3413  semicolon = (char *) strchr( value, ';' );
3414  if( *value && semicolon != value ) {
3415  char *comma = (char *) strchr( value, ',' );
3416 
3417  if ( comma ) {
3418  ++comma;
3419  sentinel = ',';
3420  } else
3421  sentinel = ';';
3422  if ( !__kmp_strcasecmp_with_sentinel( "static", value, sentinel ) ) {
3423  if( !__kmp_strcasecmp_with_sentinel( "greedy", comma, ';' ) ) {
3424  __kmp_static = kmp_sch_static_greedy;
3425  continue;
3426  } else if( !__kmp_strcasecmp_with_sentinel( "balanced", comma, ';' ) ) {
3427  __kmp_static = kmp_sch_static_balanced;
3428  continue;
3429  }
3430  } else if ( !__kmp_strcasecmp_with_sentinel( "guided", value, sentinel ) ) {
3431  if ( !__kmp_strcasecmp_with_sentinel( "iterative", comma, ';' ) ) {
3432  __kmp_guided = kmp_sch_guided_iterative_chunked;
3433  continue;
3434  } else if ( !__kmp_strcasecmp_with_sentinel( "analytical", comma, ';' ) ) {
3435  /* analytical not allowed for too many threads */
3436  __kmp_guided = kmp_sch_guided_analytical_chunked;
3437  continue;
3438  }
3439  }
3440  KMP_WARNING( InvalidClause, name, value );
3441  } else
3442  KMP_WARNING( EmptyClause, name );
3443  } while ( (value = semicolon ? semicolon + 1 : NULL) );
3444  }
3445  }; // if
3446 
3447 } // __kmp_stg_parse__schedule
3448 
3449 static void
3450 __kmp_stg_print_schedule( kmp_str_buf_t * buffer, char const * name, void * data ) {
3451  if( __kmp_env_format ) {
3452  KMP_STR_BUF_PRINT_NAME_EX(name);
3453  } else {
3454  __kmp_str_buf_print( buffer, " %s='", name );
3455  }
3456  if ( __kmp_static == kmp_sch_static_greedy ) {
3457  __kmp_str_buf_print( buffer, "%s", "static,greedy");
3458  } else if ( __kmp_static == kmp_sch_static_balanced ) {
3459  __kmp_str_buf_print ( buffer, "%s", "static,balanced");
3460  }
3461  if ( __kmp_guided == kmp_sch_guided_iterative_chunked ) {
3462  __kmp_str_buf_print( buffer, ";%s'\n", "guided,iterative");
3463  } else if ( __kmp_guided == kmp_sch_guided_analytical_chunked ) {
3464  __kmp_str_buf_print( buffer, ";%s'\n", "guided,analytical");
3465  }
3466 } // __kmp_stg_print_schedule
3467 
3468 // -------------------------------------------------------------------------------------------------
3469 // OMP_SCHEDULE
3470 // -------------------------------------------------------------------------------------------------
3471 
3472 static void
3473 __kmp_stg_parse_omp_schedule( char const * name, char const * value, void * data )
3474 {
3475  size_t length;
3476  if( value ) {
3477  length = KMP_STRLEN( value );
3478  if( length ) {
3479  char *comma = (char *) strchr( value, ',' );
3480  if( value[ length - 1 ] == '"' || value[ length -1 ] == '\'')
3481  KMP_WARNING( UnbalancedQuotes, name );
3482  /* get the specified scheduling style */
3483  if (!__kmp_strcasecmp_with_sentinel("dynamic", value, ',')) /* DYNAMIC */
3484  __kmp_sched = kmp_sch_dynamic_chunked;
3485  else if (!__kmp_strcasecmp_with_sentinel("guided", value, ',')) /* GUIDED */
3486  __kmp_sched = kmp_sch_guided_chunked;
3487 // AC: TODO: add AUTO schedule, and pprobably remove TRAPEZOIDAL (OMP 3.0 does not allow it)
3488  else if (!__kmp_strcasecmp_with_sentinel("auto", value, ',')) { /* AUTO */
3489  __kmp_sched = kmp_sch_auto;
3490  if( comma ) {
3491  __kmp_msg( kmp_ms_warning, KMP_MSG( IgnoreChunk, name, comma ), __kmp_msg_null );
3492  comma = NULL;
3493  }
3494  }
3495  else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", value, ',')) /* TRAPEZOIDAL */
3496  __kmp_sched = kmp_sch_trapezoidal;
3497  else if (!__kmp_strcasecmp_with_sentinel("static", value, ',')) /* STATIC */
3498  __kmp_sched = kmp_sch_static;
3499 #ifdef KMP_STATIC_STEAL_ENABLED
3500  else if (KMP_ARCH_X86_64 &&
3501  !__kmp_strcasecmp_with_sentinel("static_steal", value, ','))
3502  __kmp_sched = kmp_sch_static_steal;
3503 #endif
3504  else {
3505  KMP_WARNING( StgInvalidValue, name, value );
3506  value = NULL; /* skip processing of comma */
3507  }
3508  if( value && comma ) {
3509  __kmp_env_chunk = TRUE;
3510 
3511  if(__kmp_sched == kmp_sch_static)
3512  __kmp_sched = kmp_sch_static_chunked;
3513  ++comma;
3514  __kmp_chunk = __kmp_str_to_int( comma, 0 );
3515  if ( __kmp_chunk < 1 ) {
3516  __kmp_chunk = KMP_DEFAULT_CHUNK;
3517  __kmp_msg( kmp_ms_warning, KMP_MSG( InvalidChunk, name, comma ), __kmp_msg_null );
3518  KMP_INFORM( Using_int_Value, name, __kmp_chunk );
3519 // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK (to improve code coverage :)
3520 // The default chunk size is 1 according to standard, thus making KMP_MIN_CHUNK not 1 we would introduce mess:
3521 // wrong chunk becomes 1, but it will be impossible to explicitely set 1, because it becomes KMP_MIN_CHUNK...
3522 // } else if ( __kmp_chunk < KMP_MIN_CHUNK ) {
3523 // __kmp_chunk = KMP_MIN_CHUNK;
3524  } else if ( __kmp_chunk > KMP_MAX_CHUNK ) {
3525  __kmp_chunk = KMP_MAX_CHUNK;
3526  __kmp_msg( kmp_ms_warning, KMP_MSG( LargeChunk, name, comma ), __kmp_msg_null );
3527  KMP_INFORM( Using_int_Value, name, __kmp_chunk );
3528  }
3529  } else
3530  __kmp_env_chunk = FALSE;
3531  } else
3532  KMP_WARNING( EmptyString, name );
3533  }
3534  K_DIAG(1, ("__kmp_static == %d\n", __kmp_static))
3535  K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided))
3536  K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched))
3537  K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk))
3538 } // __kmp_stg_parse_omp_schedule
3539 
3540 static void
3541 __kmp_stg_print_omp_schedule( kmp_str_buf_t * buffer, char const * name, void * data ) {
3542  if( __kmp_env_format ) {
3543  KMP_STR_BUF_PRINT_NAME_EX(name);
3544  } else {
3545  __kmp_str_buf_print( buffer, " %s='", name );
3546  }
3547  if ( __kmp_chunk ) {
3548  switch ( __kmp_sched ) {
3549  case kmp_sch_dynamic_chunked:
3550  __kmp_str_buf_print( buffer, "%s,%d'\n", "dynamic", __kmp_chunk);
3551  break;
3552  case kmp_sch_guided_iterative_chunked:
3553  case kmp_sch_guided_analytical_chunked:
3554  __kmp_str_buf_print( buffer, "%s,%d'\n", "guided", __kmp_chunk);
3555  break;
3556  case kmp_sch_trapezoidal:
3557  __kmp_str_buf_print( buffer, "%s,%d'\n", "trapezoidal", __kmp_chunk);
3558  break;
3559  case kmp_sch_static:
3560  case kmp_sch_static_chunked:
3561  case kmp_sch_static_balanced:
3562  case kmp_sch_static_greedy:
3563  __kmp_str_buf_print( buffer, "%s,%d'\n", "static", __kmp_chunk);
3564  break;
3565  case kmp_sch_static_steal:
3566  __kmp_str_buf_print( buffer, "%s,%d'\n", "static_steal", __kmp_chunk);
3567  break;
3568  case kmp_sch_auto:
3569  __kmp_str_buf_print( buffer, "%s,%d'\n", "auto", __kmp_chunk);
3570  break;
3571  }
3572  } else {
3573  switch ( __kmp_sched ) {
3574  case kmp_sch_dynamic_chunked:
3575  __kmp_str_buf_print( buffer, "%s'\n", "dynamic");
3576  break;
3577  case kmp_sch_guided_iterative_chunked:
3578  case kmp_sch_guided_analytical_chunked:
3579  __kmp_str_buf_print( buffer, "%s'\n", "guided");
3580  break;
3581  case kmp_sch_trapezoidal:
3582  __kmp_str_buf_print( buffer, "%s'\n", "trapezoidal");
3583  break;
3584  case kmp_sch_static:
3585  case kmp_sch_static_chunked:
3586  case kmp_sch_static_balanced:
3587  case kmp_sch_static_greedy:
3588  __kmp_str_buf_print( buffer, "%s'\n", "static");
3589  break;
3590  case kmp_sch_static_steal:
3591  __kmp_str_buf_print( buffer, "%s'\n", "static_steal");
3592  break;
3593  case kmp_sch_auto:
3594  __kmp_str_buf_print( buffer, "%s'\n", "auto");
3595  break;
3596  }
3597  }
3598 } // __kmp_stg_print_omp_schedule
3599 
3600 // -------------------------------------------------------------------------------------------------
3601 // KMP_ATOMIC_MODE
3602 // -------------------------------------------------------------------------------------------------
3603 
3604 static void
3605 __kmp_stg_parse_atomic_mode( char const * name, char const * value, void * data ) {
3606  // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP compatibility mode.
3607  int mode = 0;
3608  int max = 1;
3609  #ifdef KMP_GOMP_COMPAT
3610  max = 2;
3611  #endif /* KMP_GOMP_COMPAT */
3612  __kmp_stg_parse_int( name, value, 0, max, & mode );
3613  // TODO; parse_int is not very suitable for this case. In case of overflow it is better to use
3614  // 0 rather that max value.
3615  if ( mode > 0 ) {
3616  __kmp_atomic_mode = mode;
3617  }; // if
3618 } // __kmp_stg_parse_atomic_mode
3619 
3620 static void
3621 __kmp_stg_print_atomic_mode( kmp_str_buf_t * buffer, char const * name, void * data ) {
3622  __kmp_stg_print_int( buffer, name, __kmp_atomic_mode );
3623 } // __kmp_stg_print_atomic_mode
3624 
3625 
3626 // -------------------------------------------------------------------------------------------------
3627 // KMP_CONSISTENCY_CHECK
3628 // -------------------------------------------------------------------------------------------------
3629 
3630 static void
3631 __kmp_stg_parse_consistency_check( char const * name, char const * value, void * data ) {
3632  if ( ! __kmp_strcasecmp_with_sentinel( "all", value, 0 ) ) {
3633  // Note, this will not work from kmp_set_defaults because th_cons stack was not allocated
3634  // for existed thread(s) thus the first __kmp_push_<construct> will break with assertion.
3635  // TODO: allocate th_cons if called from kmp_set_defaults.
3636  __kmp_env_consistency_check = TRUE;
3637  } else if ( ! __kmp_strcasecmp_with_sentinel( "none", value, 0 ) ) {
3638  __kmp_env_consistency_check = FALSE;
3639  } else {
3640  KMP_WARNING( StgInvalidValue, name, value );
3641  }; // if
3642 } // __kmp_stg_parse_consistency_check
3643 
3644 static void
3645 __kmp_stg_print_consistency_check( kmp_str_buf_t * buffer, char const * name, void * data ) {
3646 #if KMP_DEBUG
3647  const char *value = NULL;
3648 
3649  if ( __kmp_env_consistency_check ) {
3650  value = "all";
3651  } else {
3652  value = "none";
3653  }
3654 
3655  if ( value != NULL ) {
3656  __kmp_stg_print_str( buffer, name, value );
3657  }
3658 #endif /* KMP_DEBUG */
3659 } // __kmp_stg_print_consistency_check
3660 
3661 
3662 #if USE_ITT_BUILD
3663 // -------------------------------------------------------------------------------------------------
3664 // KMP_ITT_PREPARE_DELAY
3665 // -------------------------------------------------------------------------------------------------
3666 
3667 #if USE_ITT_NOTIFY
3668 
3669 static void
3670 __kmp_stg_parse_itt_prepare_delay( char const * name, char const * value, void * data )
3671 {
3672  // Experimental code: KMP_ITT_PREPARE_DELAY specifies numbert of loop iterations.
3673  int delay = 0;
3674  __kmp_stg_parse_int( name, value, 0, INT_MAX, & delay );
3675  __kmp_itt_prepare_delay = delay;
3676 } // __kmp_str_parse_itt_prepare_delay
3677 
3678 static void
3679 __kmp_stg_print_itt_prepare_delay( kmp_str_buf_t * buffer, char const * name, void * data ) {
3680  __kmp_stg_print_uint64( buffer, name, __kmp_itt_prepare_delay );
3681 
3682 } // __kmp_str_print_itt_prepare_delay
3683 
3684 #endif // USE_ITT_NOTIFY
3685 #endif /* USE_ITT_BUILD */
3686 
3687 // -------------------------------------------------------------------------------------------------
3688 // KMP_MALLOC_POOL_INCR
3689 // -------------------------------------------------------------------------------------------------
3690 
3691 static void
3692 __kmp_stg_parse_malloc_pool_incr( char const * name, char const * value, void * data ) {
3693  __kmp_stg_parse_size(
3694  name,
3695  value,
3696  KMP_MIN_MALLOC_POOL_INCR,
3697  KMP_MAX_MALLOC_POOL_INCR,
3698  NULL,
3699  & __kmp_malloc_pool_incr,
3700  1
3701  );
3702 } // __kmp_stg_parse_malloc_pool_incr
3703 
3704 static void
3705 __kmp_stg_print_malloc_pool_incr( kmp_str_buf_t * buffer, char const * name, void * data ) {
3706  __kmp_stg_print_size( buffer, name, __kmp_malloc_pool_incr );
3707 
3708 } // _kmp_stg_print_malloc_pool_incr
3709 
3710 
3711 #ifdef KMP_DEBUG
3712 
3713 // -------------------------------------------------------------------------------------------------
3714 // KMP_PAR_RANGE
3715 // -------------------------------------------------------------------------------------------------
3716 
3717 static void
3718 __kmp_stg_parse_par_range_env( char const * name, char const * value, void * data ) {
3719  __kmp_stg_parse_par_range(
3720  name,
3721  value,
3722  & __kmp_par_range,
3723  __kmp_par_range_routine,
3724  __kmp_par_range_filename,
3725  & __kmp_par_range_lb,
3726  & __kmp_par_range_ub
3727  );
3728 } // __kmp_stg_parse_par_range_env
3729 
3730 static void
3731 __kmp_stg_print_par_range_env( kmp_str_buf_t * buffer, char const * name, void * data ) {
3732  if (__kmp_par_range != 0) {
3733  __kmp_stg_print_str( buffer, name, par_range_to_print );
3734  }
3735 } // __kmp_stg_print_par_range_env
3736 
3737 // -------------------------------------------------------------------------------------------------
3738 // KMP_YIELD_CYCLE, KMP_YIELD_ON, KMP_YIELD_OFF
3739 // -------------------------------------------------------------------------------------------------
3740 
3741 static void
3742 __kmp_stg_parse_yield_cycle( char const * name, char const * value, void * data ) {
3743  int flag = __kmp_yield_cycle;
3744  __kmp_stg_parse_bool( name, value, & flag );
3745  __kmp_yield_cycle = flag;
3746 } // __kmp_stg_parse_yield_cycle
3747 
3748 static void
3749 __kmp_stg_print_yield_cycle( kmp_str_buf_t * buffer, char const * name, void * data ) {
3750  __kmp_stg_print_bool( buffer, name, __kmp_yield_cycle );
3751 } // __kmp_stg_print_yield_cycle
3752 
3753 static void
3754 __kmp_stg_parse_yield_on( char const * name, char const * value, void * data ) {
3755  __kmp_stg_parse_int( name, value, 2, INT_MAX, & __kmp_yield_on_count );
3756 } // __kmp_stg_parse_yield_on
3757 
3758 static void
3759 __kmp_stg_print_yield_on( kmp_str_buf_t * buffer, char const * name, void * data ) {
3760  __kmp_stg_print_int( buffer, name, __kmp_yield_on_count );
3761 } // __kmp_stg_print_yield_on
3762 
3763 static void
3764 __kmp_stg_parse_yield_off( char const * name, char const * value, void * data ) {
3765  __kmp_stg_parse_int( name, value, 2, INT_MAX, & __kmp_yield_off_count );
3766 } // __kmp_stg_parse_yield_off
3767 
3768 static void
3769 __kmp_stg_print_yield_off( kmp_str_buf_t * buffer, char const * name, void * data ) {
3770  __kmp_stg_print_int( buffer, name, __kmp_yield_off_count );
3771 } // __kmp_stg_print_yield_off
3772 
3773 #endif
3774 
3775 // -------------------------------------------------------------------------------------------------
3776 // KMP_INIT_WAIT, KMP_NEXT_WAIT
3777 // -------------------------------------------------------------------------------------------------
3778 
3779 static void
3780 __kmp_stg_parse_init_wait( char const * name, char const * value, void * data ) {
3781  int wait;
3782  KMP_ASSERT( ( __kmp_init_wait & 1 ) == 0 );
3783  wait = __kmp_init_wait / 2;
3784  __kmp_stg_parse_int( name, value, KMP_MIN_INIT_WAIT, KMP_MAX_INIT_WAIT, & wait );
3785  __kmp_init_wait = wait * 2;
3786  KMP_ASSERT( ( __kmp_init_wait & 1 ) == 0 );
3787  __kmp_yield_init = __kmp_init_wait;
3788 } // __kmp_stg_parse_init_wait
3789 
3790 static void
3791 __kmp_stg_print_init_wait( kmp_str_buf_t * buffer, char const * name, void * data ) {
3792  __kmp_stg_print_int( buffer, name, __kmp_init_wait );
3793 } // __kmp_stg_print_init_wait
3794 
3795 static void
3796 __kmp_stg_parse_next_wait( char const * name, char const * value, void * data ) {
3797  int wait;
3798  KMP_ASSERT( ( __kmp_next_wait & 1 ) == 0 );
3799  wait = __kmp_next_wait / 2;
3800  __kmp_stg_parse_int( name, value, KMP_MIN_NEXT_WAIT, KMP_MAX_NEXT_WAIT, & wait );
3801  __kmp_next_wait = wait * 2;
3802  KMP_ASSERT( ( __kmp_next_wait & 1 ) == 0 );
3803  __kmp_yield_next = __kmp_next_wait;
3804 } // __kmp_stg_parse_next_wait
3805 
3806 static void
3807 __kmp_stg_print_next_wait( kmp_str_buf_t * buffer, char const * name, void * data ) {
3808  __kmp_stg_print_int( buffer, name, __kmp_next_wait );
3809 } //__kmp_stg_print_next_wait
3810 
3811 
3812 // -------------------------------------------------------------------------------------------------
3813 // KMP_GTID_MODE
3814 // -------------------------------------------------------------------------------------------------
3815 
3816 static void
3817 __kmp_stg_parse_gtid_mode( char const * name, char const * value, void * data ) {
3818  //
3819  // Modes:
3820  // 0 -- do not change default
3821  // 1 -- sp search
3822  // 2 -- use "keyed" TLS var, i.e.
3823  // pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
3824  // 3 -- __declspec(thread) TLS var in tdata section
3825  //
3826  int mode = 0;
3827  int max = 2;
3828  #ifdef KMP_TDATA_GTID
3829  max = 3;
3830  #endif /* KMP_TDATA_GTID */
3831  __kmp_stg_parse_int( name, value, 0, max, & mode );
3832  // TODO; parse_int is not very suitable for this case. In case of overflow it is better to use
3833  // 0 rather that max value.
3834  if ( mode == 0 ) {
3835  __kmp_adjust_gtid_mode = TRUE;
3836  }
3837  else {
3838  __kmp_gtid_mode = mode;
3839  __kmp_adjust_gtid_mode = FALSE;
3840  }; // if
3841 } // __kmp_str_parse_gtid_mode
3842 
3843 static void
3844 __kmp_stg_print_gtid_mode( kmp_str_buf_t * buffer, char const * name, void * data ) {
3845  if ( __kmp_adjust_gtid_mode ) {
3846  __kmp_stg_print_int( buffer, name, 0 );
3847  }
3848  else {
3849  __kmp_stg_print_int( buffer, name, __kmp_gtid_mode );
3850  }
3851 } // __kmp_stg_print_gtid_mode
3852 
3853 
3854 // -------------------------------------------------------------------------------------------------
3855 // KMP_NUM_LOCKS_IN_BLOCK
3856 // -------------------------------------------------------------------------------------------------
3857 
3858 static void
3859 __kmp_stg_parse_lock_block( char const * name, char const * value, void * data ) {
3860  __kmp_stg_parse_int( name, value, 0, KMP_INT_MAX, & __kmp_num_locks_in_block );
3861 } // __kmp_str_parse_lock_block
3862 
3863 static void
3864 __kmp_stg_print_lock_block( kmp_str_buf_t * buffer, char const * name, void * data ) {
3865  __kmp_stg_print_int( buffer, name, __kmp_num_locks_in_block );
3866 } // __kmp_stg_print_lock_block
3867 
3868 // -------------------------------------------------------------------------------------------------
3869 // KMP_LOCK_KIND
3870 // -------------------------------------------------------------------------------------------------
3871 
3872 static void
3873 __kmp_stg_parse_lock_kind( char const * name, char const * value, void * data ) {
3874  if ( __kmp_init_user_locks ) {
3875  KMP_WARNING( EnvLockWarn, name );
3876  return;
3877  }
3878 
3879  if ( __kmp_str_match( "tas", 2, value )
3880  || __kmp_str_match( "test and set", 2, value )
3881  || __kmp_str_match( "test_and_set", 2, value )
3882  || __kmp_str_match( "test-and-set", 2, value )
3883  || __kmp_str_match( "test andset", 2, value )
3884  || __kmp_str_match( "test_andset", 2, value )
3885  || __kmp_str_match( "test-andset", 2, value )
3886  || __kmp_str_match( "testand set", 2, value )
3887  || __kmp_str_match( "testand_set", 2, value )
3888  || __kmp_str_match( "testand-set", 2, value )
3889  || __kmp_str_match( "testandset", 2, value ) ) {
3890  __kmp_user_lock_kind = lk_tas;
3891  DYNA_STORE_LOCK_SEQ(tas);
3892  }
3893 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64 || KMP_ARCH_ARM)
3894  else if ( __kmp_str_match( "futex", 1, value ) ) {
3895  if ( __kmp_futex_determine_capable() ) {
3896  __kmp_user_lock_kind = lk_futex;
3897  DYNA_STORE_LOCK_SEQ(futex);
3898  }
3899  else {
3900  KMP_WARNING( FutexNotSupported, name, value );
3901  }
3902  }
3903 #endif
3904  else if ( __kmp_str_match( "ticket", 2, value ) ) {
3905  __kmp_user_lock_kind = lk_ticket;
3906  DYNA_STORE_LOCK_SEQ(ticket);
3907  }
3908  else if ( __kmp_str_match( "queuing", 1, value )
3909  || __kmp_str_match( "queue", 1, value ) ) {
3910  __kmp_user_lock_kind = lk_queuing;
3911  DYNA_STORE_LOCK_SEQ(queuing);
3912  }
3913  else if ( __kmp_str_match( "drdpa ticket", 1, value )
3914  || __kmp_str_match( "drdpa_ticket", 1, value )
3915  || __kmp_str_match( "drdpa-ticket", 1, value )
3916  || __kmp_str_match( "drdpaticket", 1, value )
3917  || __kmp_str_match( "drdpa", 1, value ) ) {
3918  __kmp_user_lock_kind = lk_drdpa;
3919  DYNA_STORE_LOCK_SEQ(drdpa);
3920  }
3921 #if KMP_USE_ADAPTIVE_LOCKS
3922  else if ( __kmp_str_match( "adaptive", 1, value ) ) {
3923  if( __kmp_cpuinfo.rtm ) { // ??? Is cpuinfo available here?
3924  __kmp_user_lock_kind = lk_adaptive;
3925  DYNA_STORE_LOCK_SEQ(adaptive);
3926  } else {
3927  KMP_WARNING( AdaptiveNotSupported, name, value );
3928  __kmp_user_lock_kind = lk_queuing;
3929  DYNA_STORE_LOCK_SEQ(queuing);
3930  }
3931  }
3932 #endif // KMP_USE_ADAPTIVE_LOCKS
3933 #if KMP_USE_DYNAMIC_LOCK
3934  else if ( __kmp_str_match("hle", 1, value) ) {
3935  DYNA_STORE_LOCK_SEQ(hle);
3936  }
3937 #endif
3938  else {
3939  KMP_WARNING( StgInvalidValue, name, value );
3940  }
3941 }
3942 
3943 static void
3944 __kmp_stg_print_lock_kind( kmp_str_buf_t * buffer, char const * name, void * data ) {
3945  const char *value = NULL;
3946 
3947  switch ( __kmp_user_lock_kind ) {
3948  case lk_default:
3949  value = "default";
3950  break;
3951 
3952  case lk_tas:
3953  value = "tas";
3954  break;
3955 
3956 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
3957  case lk_futex:
3958  value = "futex";
3959  break;
3960 #endif
3961 
3962  case lk_ticket:
3963  value = "ticket";
3964  break;
3965 
3966  case lk_queuing:
3967  value = "queuing";
3968  break;
3969 
3970  case lk_drdpa:
3971  value = "drdpa";
3972  break;
3973 #if KMP_USE_ADAPTIVE_LOCKS
3974  case lk_adaptive:
3975  value = "adaptive";
3976  break;
3977 #endif
3978  }
3979 
3980  if ( value != NULL ) {
3981  __kmp_stg_print_str( buffer, name, value );
3982  }
3983 }
3984 
3985 #if KMP_USE_ADAPTIVE_LOCKS
3986 
3987 // -------------------------------------------------------------------------------------------------
3988 // KMP_ADAPTIVE_LOCK_PROPS, KMP_SPECULATIVE_STATSFILE
3989 // -------------------------------------------------------------------------------------------------
3990 
3991 // Parse out values for the tunable parameters from a string of the form
3992 // KMP_ADAPTIVE_LOCK_PROPS=max_soft_retries[,max_badness]
3993 static void
3994 __kmp_stg_parse_adaptive_lock_props( const char *name, const char *value, void *data )
3995 {
3996  int max_retries = 0;
3997  int max_badness = 0;
3998 
3999  const char *next = value;
4000 
4001  int total = 0; // Count elements that were set. It'll be used as an array size
4002  int prev_comma = FALSE; // For correct processing sequential commas
4003  int i;
4004 
4005  // Save values in the structure __kmp_speculative_backoff_params
4006  // Run only 3 iterations because it is enough to read two values or find a syntax error
4007  for ( i = 0; i < 3 ; i++) {
4008  SKIP_WS( next );
4009 
4010  if ( *next == '\0' ) {
4011  break;
4012  }
4013  // Next character is not an integer or not a comma OR number of values > 2 => end of list
4014  if ( ( ( *next < '0' || *next > '9' ) && *next !=',' ) || total > 2 ) {
4015  KMP_WARNING( EnvSyntaxError, name, value );
4016  return;
4017  }
4018  // The next character is ','
4019  if ( *next == ',' ) {
4020  // ',' is the fisrt character
4021  if ( total == 0 || prev_comma ) {
4022  total++;
4023  }
4024  prev_comma = TRUE;
4025  next++; //skip ','
4026  SKIP_WS( next );
4027  }
4028  // Next character is a digit
4029  if ( *next >= '0' && *next <= '9' ) {
4030  int num;
4031  const char *buf = next;
4032  char const * msg = NULL;
4033  prev_comma = FALSE;
4034  SKIP_DIGITS( next );
4035  total++;
4036 
4037  const char *tmp = next;
4038  SKIP_WS( tmp );
4039  if ( ( *next == ' ' || *next == '\t' ) && ( *tmp >= '0' && *tmp <= '9' ) ) {
4040  KMP_WARNING( EnvSpacesNotAllowed, name, value );
4041  return;
4042  }
4043 
4044  num = __kmp_str_to_int( buf, *next );
4045  if ( num < 1 ) { // The number of retries should be > 0
4046  msg = KMP_I18N_STR( ValueTooSmall );
4047  num = 1;
4048  } else if ( num > KMP_INT_MAX ) {
4049  msg = KMP_I18N_STR( ValueTooLarge );
4050  num = KMP_INT_MAX;
4051  }
4052  if ( msg != NULL ) {
4053  // Message is not empty. Print warning.
4054  KMP_WARNING( ParseSizeIntWarn, name, value, msg );
4055  KMP_INFORM( Using_int_Value, name, num );
4056  }
4057  if( total == 1 ) {
4058  max_retries = num;
4059  } else if( total == 2 ) {
4060  max_badness = num;
4061  }
4062  }
4063  }
4064  KMP_DEBUG_ASSERT( total > 0 );
4065  if( total <= 0 ) {
4066  KMP_WARNING( EnvSyntaxError, name, value );
4067  return;
4068  }
4069  if( max_retries != 0 ) {
4070  __kmp_adaptive_backoff_params.max_soft_retries = max_retries;
4071  }
4072  if( max_badness != 0 ) {
4073  __kmp_adaptive_backoff_params.max_badness = max_badness;
4074  }
4075 }
4076 
4077 
4078 static void
4079 __kmp_stg_print_adaptive_lock_props(kmp_str_buf_t * buffer, char const * name, void * data )
4080 {
4081  if( __kmp_env_format ) {
4082  KMP_STR_BUF_PRINT_NAME_EX(name);
4083  } else {
4084  __kmp_str_buf_print( buffer, " %s='", name );
4085  }
4086  __kmp_str_buf_print( buffer, "%d,%d'\n", __kmp_adaptive_backoff_params.max_soft_retries,
4087  __kmp_adaptive_backoff_params.max_badness );
4088 } // __kmp_stg_print_adaptive_lock_props
4089 
4090 #if KMP_DEBUG_ADAPTIVE_LOCKS
4091 
4092 static void
4093 __kmp_stg_parse_speculative_statsfile( char const * name, char const * value, void * data ) {
4094  __kmp_stg_parse_file( name, value, "", & __kmp_speculative_statsfile );
4095 } // __kmp_stg_parse_speculative_statsfile
4096 
4097 static void
4098 __kmp_stg_print_speculative_statsfile( kmp_str_buf_t * buffer, char const * name, void * data ) {
4099  if ( __kmp_str_match( "-", 0, __kmp_speculative_statsfile ) ) {
4100  __kmp_stg_print_str( buffer, name, "stdout" );
4101  } else {
4102  __kmp_stg_print_str( buffer, name, __kmp_speculative_statsfile );
4103  }
4104 
4105 } // __kmp_stg_print_speculative_statsfile
4106 
4107 #endif // KMP_DEBUG_ADAPTIVE_LOCKS
4108 
4109 #endif // KMP_USE_ADAPTIVE_LOCKS
4110 
4111 // -------------------------------------------------------------------------------------------------
4112 // KMP_PLACE_THREADS
4113 // -------------------------------------------------------------------------------------------------
4114 
4115 static void
4116 __kmp_stg_parse_place_threads( char const * name, char const * value, void * data ) {
4117  // Value example: 5Cx2Tx15O
4118  // Which means "use 5 cores with offset 15, 2 threads per core"
4119 
4120  int num;
4121  int prev_delim = 0;
4122  const char *next = value;
4123  const char *prev;
4124 
4125  SKIP_WS( next );
4126  if ( *next == '\0' ) {
4127  return; // leave default values
4128  }
4129 
4130  // Get num_cores first
4131  if ( *next >= '0' && *next <= '9' ) {
4132  prev = next;
4133  SKIP_DIGITS( next );
4134  num = __kmp_str_to_int( prev, *next );
4135  SKIP_WS( next );
4136  if ( *next == 'C' || *next == 'c' ) {
4137  __kmp_place_num_cores = num;
4138  next++;
4139  } else if ( *next == ',' || *next == 'x' ) {
4140  __kmp_place_num_cores = num;
4141  prev_delim = 1;
4142  next++;
4143  } else if ( *next == 'T' || *next == 't' ) {
4144  __kmp_place_num_threads_per_core = num;
4145  return; // we ignore offset value in case all cores are used
4146  } else if ( *next == '\0' ) {
4147  __kmp_place_num_cores = num;
4148  return; // the only value provided
4149  } else {
4150  KMP_WARNING( AffThrPlaceInvalid, name, value );
4151  return;
4152  }
4153  } else if ( *next == ',' || *next == 'x' ) {
4154  // First character is delimiter, skip it, leave num_cores default value
4155  prev_delim = 2;
4156  next++;
4157  } else {
4158  KMP_WARNING( AffThrPlaceInvalid, name, value );
4159  return;
4160  }
4161  SKIP_WS( next );
4162  if ( *next == '\0' ) {
4163  return; // " n " - something like this
4164  }
4165  if ( ( *next == ',' || *next == 'x' ) && !prev_delim ) {
4166  prev_delim = 1;
4167  next++; // skip delimiter after num_core value
4168  SKIP_WS( next );
4169  }
4170 
4171  // Get threads_per_core next
4172  if ( *next >= '0' && *next <= '9' ) {
4173  prev_delim = 0;
4174  prev = next;
4175  SKIP_DIGITS( next );
4176  num = __kmp_str_to_int( prev, *next );
4177  SKIP_WS( next );
4178  if ( *next == 'T' || *next == 't' ) {
4179  __kmp_place_num_threads_per_core = num;
4180  next++;
4181  } else if ( *next == ',' || *next == 'x' ) {
4182  __kmp_place_num_threads_per_core = num;
4183  prev_delim = 1;
4184  next++;
4185  } else if ( *next == 'O' || *next == 'o' ) {
4186  __kmp_place_core_offset = num;
4187  return; // threads_per_core remains default
4188  } else if ( *next == '\0' ) {
4189  __kmp_place_num_threads_per_core = num;
4190  return;
4191  } else {
4192  KMP_WARNING( AffThrPlaceInvalid, name, value );
4193  return;
4194  }
4195  } else if ( *next == ',' || *next == 'x' ) {
4196  if ( prev_delim == 2 ) {
4197  return; // no sense in the only offset value, thus skip the rest
4198  }
4199  KMP_DEBUG_ASSERT( prev_delim == 1 );
4200  next++; // no value for threads_per_core provided
4201  } else {
4202  KMP_WARNING( AffThrPlaceInvalid, name, value );
4203  return;
4204  }
4205  SKIP_WS( next );
4206  if ( *next == '\0' ) {
4207  return; // " nC,mT " - something like this
4208  }
4209  if ( ( *next == ',' || *next == 'x' ) && !prev_delim ) {
4210  prev_delim = 1;
4211  next++; // skip delimiter after threads_per_core value
4212  SKIP_WS( next );
4213  }
4214 
4215  // Get core offset last if any,
4216  // don't bother checking syntax after all data obtained
4217  if ( *next >= '0' && *next <= '9' ) {
4218  prev = next;
4219  SKIP_DIGITS( next );
4220  num = __kmp_str_to_int( prev, *next );
4221  __kmp_place_core_offset = num;
4222  }
4223 }
4224 
4225 static void
4226 __kmp_stg_print_place_threads( kmp_str_buf_t * buffer, char const * name, void * data ) {
4227  if ( __kmp_place_num_cores + __kmp_place_num_threads_per_core ) {
4228  kmp_str_buf_t buf;
4229  __kmp_str_buf_init( &buf );
4230  if( __kmp_env_format ) {
4231  KMP_STR_BUF_PRINT_NAME_EX(name);
4232  } else {
4233  __kmp_str_buf_print( buffer, " %s='", name );
4234  }
4235  __kmp_str_buf_print( &buf, "%dC", __kmp_place_num_cores );
4236  __kmp_str_buf_print( &buf, "x%dT", __kmp_place_num_threads_per_core );
4237  if ( __kmp_place_core_offset ) {
4238  __kmp_str_buf_print( &buf, ",%dO", __kmp_place_core_offset );
4239  }
4240  __kmp_str_buf_print(buffer, "%s'\n", buf.str );
4241  __kmp_str_buf_free(&buf);
4242 /*
4243  } else {
4244  __kmp_str_buf_print( buffer, " %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
4245 */
4246  }
4247 }
4248 
4249 #if USE_ITT_BUILD
4250 // -------------------------------------------------------------------------------------------------
4251 // KMP_FORKJOIN_FRAMES
4252 // -------------------------------------------------------------------------------------------------
4253 
4254 static void
4255 __kmp_stg_parse_forkjoin_frames( char const * name, char const * value, void * data ) {
4256  __kmp_stg_parse_bool( name, value, & __kmp_forkjoin_frames );
4257 } // __kmp_stg_parse_forkjoin_frames
4258 
4259 static void
4260 __kmp_stg_print_forkjoin_frames( kmp_str_buf_t * buffer, char const * name, void * data ) {
4261  __kmp_stg_print_bool( buffer, name, __kmp_forkjoin_frames );
4262 } // __kmp_stg_print_forkjoin_frames
4263 
4264 // -------------------------------------------------------------------------------------------------
4265 // KMP_FORKJOIN_FRAMES_MODE
4266 // -------------------------------------------------------------------------------------------------
4267 
4268 static void
4269 __kmp_stg_parse_forkjoin_frames_mode( char const * name, char const * value, void * data ) {
4270  __kmp_stg_parse_int( name, value, 0, 3, & __kmp_forkjoin_frames_mode );
4271 } // __kmp_stg_parse_forkjoin_frames
4272 
4273 static void
4274 __kmp_stg_print_forkjoin_frames_mode( kmp_str_buf_t * buffer, char const * name, void * data ) {
4275  __kmp_stg_print_int( buffer, name, __kmp_forkjoin_frames_mode );
4276 } // __kmp_stg_print_forkjoin_frames
4277 #endif /* USE_ITT_BUILD */
4278 
4279 // -------------------------------------------------------------------------------------------------
4280 // OMP_DISPLAY_ENV
4281 // -------------------------------------------------------------------------------------------------
4282 
4283 #if OMP_40_ENABLED
4284 
4285 static void
4286 __kmp_stg_parse_omp_display_env( char const * name, char const * value, void * data )
4287 {
4288  if ( __kmp_str_match( "VERBOSE", 1, value ) )
4289  {
4290  __kmp_display_env_verbose = TRUE;
4291  } else {
4292  __kmp_stg_parse_bool( name, value, & __kmp_display_env );
4293  }
4294 
4295 } // __kmp_stg_parse_omp_display_env
4296 
4297 static void
4298 __kmp_stg_print_omp_display_env( kmp_str_buf_t * buffer, char const * name, void * data )
4299 {
4300  if ( __kmp_display_env_verbose )
4301  {
4302  __kmp_stg_print_str( buffer, name, "VERBOSE" );
4303  } else {
4304  __kmp_stg_print_bool( buffer, name, __kmp_display_env );
4305  }
4306 } // __kmp_stg_print_omp_display_env
4307 
4308 static void
4309 __kmp_stg_parse_omp_cancellation( char const * name, char const * value, void * data ) {
4310  if ( TCR_4(__kmp_init_parallel) ) {
4311  KMP_WARNING( EnvParallelWarn, name );
4312  return;
4313  } // read value before first parallel only
4314  __kmp_stg_parse_bool( name, value, & __kmp_omp_cancellation );
4315 } // __kmp_stg_parse_omp_cancellation
4316 
4317 static void
4318 __kmp_stg_print_omp_cancellation( kmp_str_buf_t * buffer, char const * name, void * data ) {
4319  __kmp_stg_print_bool( buffer, name, __kmp_omp_cancellation );
4320 } // __kmp_stg_print_omp_cancellation
4321 
4322 #endif
4323 
4324 // -------------------------------------------------------------------------------------------------
4325 // Table.
4326 // -------------------------------------------------------------------------------------------------
4327 
4328 
4329 static kmp_setting_t __kmp_stg_table[] = {
4330 
4331  { "KMP_ALL_THREADS", __kmp_stg_parse_all_threads, __kmp_stg_print_all_threads, NULL, 0, 0 },
4332  { "KMP_BLOCKTIME", __kmp_stg_parse_blocktime, __kmp_stg_print_blocktime, NULL, 0, 0 },
4333  { "KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok, __kmp_stg_print_duplicate_lib_ok, NULL, 0, 0 },
4334  { "KMP_LIBRARY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy, NULL, 0, 0 },
4335  { "KMP_MAX_THREADS", __kmp_stg_parse_all_threads, NULL, NULL, 0, 0 }, // For backward compatibility
4336  { "KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize, __kmp_stg_print_monitor_stacksize, NULL, 0, 0 },
4337  { "KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL, 0, 0 },
4338  { "KMP_STACKOFFSET", __kmp_stg_parse_stackoffset, __kmp_stg_print_stackoffset, NULL, 0, 0 },
4339  { "KMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize, NULL, 0, 0 },
4340  { "KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL, 0, 0 },
4341  { "KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0, 0 },
4342  { "KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL, 0, 0 },
4343 
4344  { "OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0 },
4345  { "OMP_NUM_THREADS", __kmp_stg_parse_num_threads, __kmp_stg_print_num_threads, NULL, 0, 0 },
4346  { "OMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize, NULL, 0, 0 },
4347 
4348  { "KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0, 0 },
4349  { "KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing, __kmp_stg_print_task_stealing, NULL, 0, 0 },
4350  { "OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels, __kmp_stg_print_max_active_levels, NULL, 0, 0 },
4351  { "OMP_THREAD_LIMIT", __kmp_stg_parse_all_threads, __kmp_stg_print_all_threads, NULL, 0, 0 },
4352  { "OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy, NULL, 0, 0 },
4353 #if KMP_NESTED_HOT_TEAMS
4354  { "KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level, __kmp_stg_print_hot_teams_level, NULL, 0, 0 },
4355  { "KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode, __kmp_stg_print_hot_teams_mode, NULL, 0, 0 },
4356 #endif // KMP_NESTED_HOT_TEAMS
4357 
4358 #if KMP_HANDLE_SIGNALS
4359  { "KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals, __kmp_stg_print_handle_signals, NULL, 0, 0 },
4360 #endif
4361 
4362 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
4363  { "KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control, __kmp_stg_print_inherit_fp_control, NULL, 0, 0 },
4364 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
4365 
4366 #ifdef KMP_GOMP_COMPAT
4367  { "GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0 },
4368 #endif
4369 
4370 #ifdef KMP_DEBUG
4371  { "KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0, 0 },
4372  { "KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0, 0 },
4373  { "KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0, 0 },
4374  { "KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0, 0 },
4375  { "KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0, 0 },
4376  { "KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0, 0 },
4377  { "KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0 },
4378  { "KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf, NULL, 0, 0 },
4379  { "KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic, __kmp_stg_print_debug_buf_atomic, NULL, 0, 0 },
4380  { "KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars, __kmp_stg_print_debug_buf_chars, NULL, 0, 0 },
4381  { "KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines, __kmp_stg_print_debug_buf_lines, NULL, 0, 0 },
4382  { "KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0 },
4383 
4384  { "KMP_PAR_RANGE", __kmp_stg_parse_par_range_env, __kmp_stg_print_par_range_env, NULL, 0, 0 },
4385  { "KMP_YIELD_CYCLE", __kmp_stg_parse_yield_cycle, __kmp_stg_print_yield_cycle, NULL, 0, 0 },
4386  { "KMP_YIELD_ON", __kmp_stg_parse_yield_on, __kmp_stg_print_yield_on, NULL, 0, 0 },
4387  { "KMP_YIELD_OFF", __kmp_stg_parse_yield_off, __kmp_stg_print_yield_off, NULL, 0, 0 },
4388 #endif // KMP_DEBUG
4389 
4390  { "KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc, __kmp_stg_print_align_alloc, NULL, 0, 0 },
4391 
4392  { "KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
4393  { "KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, __kmp_stg_print_barrier_pattern, NULL, 0, 0 },
4394  { "KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
4395  { "KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, __kmp_stg_print_barrier_pattern, NULL, 0, 0 },
4396 #if KMP_FAST_REDUCTION_BARRIER
4397  { "KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
4398  { "KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, __kmp_stg_print_barrier_pattern, NULL, 0, 0 },
4399 #endif
4400 
4401  { "KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay, __kmp_stg_print_abort_delay, NULL, 0, 0 },
4402  { "KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file, __kmp_stg_print_cpuinfo_file, NULL, 0, 0 },
4403  { "KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction, __kmp_stg_print_force_reduction, NULL, 0, 0 },
4404  { "KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction, __kmp_stg_print_force_reduction, NULL, 0, 0 },
4405  { "KMP_STORAGE_MAP", __kmp_stg_parse_storage_map, __kmp_stg_print_storage_map, NULL, 0, 0 },
4406  { "KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate, __kmp_stg_print_all_threadprivate, NULL, 0, 0 },
4407  { "KMP_FOREIGN_THREADS_THREADPRIVATE", __kmp_stg_parse_foreign_threads_threadprivate, __kmp_stg_print_foreign_threads_threadprivate, NULL, 0, 0 },
4408 
4409 #if KMP_AFFINITY_SUPPORTED
4410  { "KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL, 0, 0 },
4411 # ifdef KMP_GOMP_COMPAT
4412  { "GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL, /* no print */ NULL, 0, 0 },
4413 # endif /* KMP_GOMP_COMPAT */
4414 # if OMP_40_ENABLED
4415  { "OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind, NULL, 0, 0 },
4416  { "OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0 },
4417 # else
4418  { "OMP_PROC_BIND", __kmp_stg_parse_proc_bind, NULL, /* no print */ NULL, 0, 0 },
4419 # endif /* OMP_40_ENABLED */
4420 
4421  { "KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method, __kmp_stg_print_topology_method, NULL, 0, 0 },
4422 
4423 #else
4424 
4425  //
4426  // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
4427  // OMP_PROC_BIND and proc-bind-var are supported, however.
4428  //
4429 # if OMP_40_ENABLED
4430  { "OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind, NULL, 0, 0 },
4431 # endif
4432 
4433 #endif // KMP_AFFINITY_SUPPORTED
4434 
4435  { "KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork, __kmp_stg_print_init_at_fork, NULL, 0, 0 },
4436  { "KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL, 0, 0 },
4437  { "OMP_SCHEDULE", __kmp_stg_parse_omp_schedule, __kmp_stg_print_omp_schedule, NULL, 0, 0 },
4438  { "KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode, __kmp_stg_print_atomic_mode, NULL, 0, 0 },
4439  { "KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check, __kmp_stg_print_consistency_check, NULL, 0, 0 },
4440 
4441 #if USE_ITT_BUILD && USE_ITT_NOTIFY
4442  { "KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay, __kmp_stg_print_itt_prepare_delay, NULL, 0, 0 },
4443 #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
4444  { "KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr, __kmp_stg_print_malloc_pool_incr, NULL, 0, 0 },
4445  { "KMP_INIT_WAIT", __kmp_stg_parse_init_wait, __kmp_stg_print_init_wait, NULL, 0, 0 },
4446  { "KMP_NEXT_WAIT", __kmp_stg_parse_next_wait, __kmp_stg_print_next_wait, NULL, 0, 0 },
4447  { "KMP_GTID_MODE", __kmp_stg_parse_gtid_mode, __kmp_stg_print_gtid_mode, NULL, 0, 0 },
4448  { "OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic, __kmp_stg_print_omp_dynamic, NULL, 0, 0 },
4449  { "KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode, __kmp_stg_print_kmp_dynamic_mode, NULL, 0, 0 },
4450 
4451 #ifdef USE_LOAD_BALANCE
4452  { "KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval,__kmp_stg_print_ld_balance_interval,NULL, 0, 0 },
4453 #endif
4454 
4455 
4456 
4457  { "KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block, __kmp_stg_print_lock_block, NULL, 0, 0 },
4458  { "KMP_LOCK_KIND", __kmp_stg_parse_lock_kind, __kmp_stg_print_lock_kind, NULL, 0, 0 },
4459 #if KMP_USE_ADAPTIVE_LOCKS
4460  { "KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props,__kmp_stg_print_adaptive_lock_props, NULL, 0, 0 },
4461 #if KMP_DEBUG_ADAPTIVE_LOCKS
4462  { "KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile,__kmp_stg_print_speculative_statsfile, NULL, 0, 0 },
4463 #endif
4464 #endif // KMP_USE_ADAPTIVE_LOCKS
4465  { "KMP_PLACE_THREADS", __kmp_stg_parse_place_threads, __kmp_stg_print_place_threads, NULL, 0, 0 },
4466 #if USE_ITT_BUILD
4467  { "KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames, __kmp_stg_print_forkjoin_frames, NULL, 0, 0 },
4468  { "KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode,__kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0 },
4469 #endif
4470 
4471 # if OMP_40_ENABLED
4472  { "OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env, __kmp_stg_print_omp_display_env, NULL, 0, 0 },
4473  { "OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation, __kmp_stg_print_omp_cancellation, NULL, 0, 0 },
4474 #endif
4475  { "", NULL, NULL, NULL, 0, 0 }
4476 }; // settings
4477 
4478 static int const __kmp_stg_count = sizeof( __kmp_stg_table ) / sizeof( kmp_setting_t );
4479 
4480 static inline
4481 kmp_setting_t *
4482 __kmp_stg_find( char const * name ) {
4483 
4484  int i;
4485  if ( name != NULL ) {
4486  for ( i = 0; i < __kmp_stg_count; ++ i ) {
4487  if ( strcmp( __kmp_stg_table[ i ].name, name ) == 0 ) {
4488  return & __kmp_stg_table[ i ];
4489  }; // if
4490  }; // for
4491  }; // if
4492  return NULL;
4493 
4494 } // __kmp_stg_find
4495 
4496 
4497 static int
4498 __kmp_stg_cmp( void const * _a, void const * _b ) {
4499  kmp_setting_t * a = (kmp_setting_t *) _a;
4500  kmp_setting_t * b = (kmp_setting_t *) _b;
4501 
4502  //
4503  // Process KMP_AFFINITY last.
4504  // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
4505  //
4506  if ( strcmp( a->name, "KMP_AFFINITY" ) == 0 ) {
4507  if ( strcmp( b->name, "KMP_AFFINITY" ) == 0 ) {
4508  return 0;
4509  }
4510  return 1;
4511  }
4512  else if ( strcmp( b->name, "KMP_AFFINITY" ) == 0 ) {
4513  return -1;
4514  }
4515  return strcmp( a->name, b->name );
4516 } // __kmp_stg_cmp
4517 
4518 
4519 static void
4520 __kmp_stg_init( void
4521 ) {
4522 
4523  static int initialized = 0;
4524 
4525  if ( ! initialized ) {
4526 
4527  // Sort table.
4528  qsort( __kmp_stg_table, __kmp_stg_count - 1, sizeof( kmp_setting_t ), __kmp_stg_cmp );
4529 
4530  { // Initialize *_STACKSIZE data.
4531 
4532  kmp_setting_t * kmp_stacksize = __kmp_stg_find( "KMP_STACKSIZE" ); // 1st priority.
4533 #ifdef KMP_GOMP_COMPAT
4534  kmp_setting_t * gomp_stacksize = __kmp_stg_find( "GOMP_STACKSIZE" ); // 2nd priority.
4535 #endif
4536  kmp_setting_t * omp_stacksize = __kmp_stg_find( "OMP_STACKSIZE" ); // 3rd priority.
4537 
4538  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4539  // !!! Compiler does not understand rivals is used and optimizes out assignments
4540  // !!! rivals[ i ++ ] = ...;
4541  static kmp_setting_t * volatile rivals[ 4 ];
4542  static kmp_stg_ss_data_t kmp_data = { 1, (kmp_setting_t **)rivals };
4543 #ifdef KMP_GOMP_COMPAT
4544  static kmp_stg_ss_data_t gomp_data = { 1024, (kmp_setting_t **)rivals };
4545 #endif
4546  static kmp_stg_ss_data_t omp_data = { 1024, (kmp_setting_t **)rivals };
4547  int i = 0;
4548 
4549  rivals[ i ++ ] = kmp_stacksize;
4550 #ifdef KMP_GOMP_COMPAT
4551  if ( gomp_stacksize != NULL ) {
4552  rivals[ i ++ ] = gomp_stacksize;
4553  }; // if
4554 #endif
4555  rivals[ i ++ ] = omp_stacksize;
4556  rivals[ i ++ ] = NULL;
4557 
4558  kmp_stacksize->data = & kmp_data;
4559 #ifdef KMP_GOMP_COMPAT
4560  if ( gomp_stacksize != NULL ) {
4561  gomp_stacksize->data = & gomp_data;
4562  }; // if
4563 #endif
4564  omp_stacksize->data = & omp_data;
4565 
4566  }
4567 
4568  { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
4569 
4570  kmp_setting_t * kmp_library = __kmp_stg_find( "KMP_LIBRARY" ); // 1st priority.
4571  kmp_setting_t * omp_wait_policy = __kmp_stg_find( "OMP_WAIT_POLICY" ); // 2nd priority.
4572 
4573  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4574  static kmp_setting_t * volatile rivals[ 3 ];
4575  static kmp_stg_wp_data_t kmp_data = { 0, (kmp_setting_t **)rivals };
4576  static kmp_stg_wp_data_t omp_data = { 1, (kmp_setting_t **)rivals };
4577  int i = 0;
4578 
4579  rivals[ i ++ ] = kmp_library;
4580  if ( omp_wait_policy != NULL ) {
4581  rivals[ i ++ ] = omp_wait_policy;
4582  }; // if
4583  rivals[ i ++ ] = NULL;
4584 
4585  kmp_library->data = & kmp_data;
4586  if ( omp_wait_policy != NULL ) {
4587  omp_wait_policy->data = & omp_data;
4588  }; // if
4589 
4590  }
4591 
4592  { // Initialize KMP_ALL_THREADS, KMP_MAX_THREADS, and OMP_THREAD_LIMIT data.
4593 
4594  kmp_setting_t * kmp_all_threads = __kmp_stg_find( "KMP_ALL_THREADS" ); // 1st priority.
4595  kmp_setting_t * kmp_max_threads = __kmp_stg_find( "KMP_MAX_THREADS" ); // 2nd priority.
4596  kmp_setting_t * omp_thread_limit = __kmp_stg_find( "OMP_THREAD_LIMIT" ); // 3rd priority.
4597 
4598  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4599  static kmp_setting_t * volatile rivals[ 4 ];
4600  int i = 0;
4601 
4602  rivals[ i ++ ] = kmp_all_threads;
4603  rivals[ i ++ ] = kmp_max_threads;
4604  if ( omp_thread_limit != NULL ) {
4605  rivals[ i ++ ] = omp_thread_limit;
4606  }; // if
4607  rivals[ i ++ ] = NULL;
4608 
4609  kmp_all_threads->data = (void*)& rivals;
4610  kmp_max_threads->data = (void*)& rivals;
4611  if ( omp_thread_limit != NULL ) {
4612  omp_thread_limit->data = (void*)& rivals;
4613  }; // if
4614 
4615  }
4616 
4617 #if KMP_AFFINITY_SUPPORTED
4618  { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
4619 
4620  kmp_setting_t * kmp_affinity = __kmp_stg_find( "KMP_AFFINITY" ); // 1st priority.
4621  KMP_DEBUG_ASSERT( kmp_affinity != NULL );
4622 
4623 # ifdef KMP_GOMP_COMPAT
4624  kmp_setting_t * gomp_cpu_affinity = __kmp_stg_find( "GOMP_CPU_AFFINITY" ); // 2nd priority.
4625  KMP_DEBUG_ASSERT( gomp_cpu_affinity != NULL );
4626 # endif
4627 
4628  kmp_setting_t * omp_proc_bind = __kmp_stg_find( "OMP_PROC_BIND" ); // 3rd priority.
4629  KMP_DEBUG_ASSERT( omp_proc_bind != NULL );
4630 
4631  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4632  static kmp_setting_t * volatile rivals[ 4 ];
4633  int i = 0;
4634 
4635  rivals[ i ++ ] = kmp_affinity;
4636 
4637 # ifdef KMP_GOMP_COMPAT
4638  rivals[ i ++ ] = gomp_cpu_affinity;
4639  gomp_cpu_affinity->data = (void*)& rivals;
4640 # endif
4641 
4642  rivals[ i ++ ] = omp_proc_bind;
4643  omp_proc_bind->data = (void*)& rivals;
4644  rivals[ i ++ ] = NULL;
4645 
4646 # if OMP_40_ENABLED
4647  static kmp_setting_t * volatile places_rivals[ 4 ];
4648  i = 0;
4649 
4650  kmp_setting_t * omp_places = __kmp_stg_find( "OMP_PLACES" ); // 3rd priority.
4651  KMP_DEBUG_ASSERT( omp_places != NULL );
4652 
4653  places_rivals[ i ++ ] = kmp_affinity;
4654 # ifdef KMP_GOMP_COMPAT
4655  places_rivals[ i ++ ] = gomp_cpu_affinity;
4656 # endif
4657  places_rivals[ i ++ ] = omp_places;
4658  omp_places->data = (void*)& places_rivals;
4659  places_rivals[ i ++ ] = NULL;
4660 # endif
4661  }
4662 #else
4663  // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
4664  // OMP_PLACES not supported yet.
4665 #endif // KMP_AFFINITY_SUPPORTED
4666 
4667  { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
4668 
4669  kmp_setting_t * kmp_force_red = __kmp_stg_find( "KMP_FORCE_REDUCTION" ); // 1st priority.
4670  kmp_setting_t * kmp_determ_red = __kmp_stg_find( "KMP_DETERMINISTIC_REDUCTION" ); // 2nd priority.
4671 
4672  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4673  static kmp_setting_t * volatile rivals[ 3 ];
4674  static kmp_stg_fr_data_t force_data = { 1, (kmp_setting_t **)rivals };
4675  static kmp_stg_fr_data_t determ_data = { 0, (kmp_setting_t **)rivals };
4676  int i = 0;
4677 
4678  rivals[ i ++ ] = kmp_force_red;
4679  if ( kmp_determ_red != NULL ) {
4680  rivals[ i ++ ] = kmp_determ_red;
4681  }; // if
4682  rivals[ i ++ ] = NULL;
4683 
4684  kmp_force_red->data = & force_data;
4685  if ( kmp_determ_red != NULL ) {
4686  kmp_determ_red->data = & determ_data;
4687  }; // if
4688  }
4689 
4690  initialized = 1;
4691 
4692  }; // if
4693 
4694  // Reset flags.
4695  int i;
4696  for ( i = 0; i < __kmp_stg_count; ++ i ) {
4697  __kmp_stg_table[ i ].set = 0;
4698  }; // for
4699 
4700 } // __kmp_stg_init
4701 
4702 
4703 static void
4704 __kmp_stg_parse(
4705  char const * name,
4706  char const * value
4707 ) {
4708 
4709  // On Windows* OS there are some nameless variables like "C:=C:\" (yeah, really nameless, they are
4710  // presented in environment block as "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
4711  if ( name[ 0 ] == 0 ) {
4712  return;
4713  }; // if
4714 
4715  if ( value != NULL ) {
4716  kmp_setting_t * setting = __kmp_stg_find( name );
4717  if ( setting != NULL ) {
4718  setting->parse( name, value, setting->data );
4719  setting->defined = 1;
4720  }; // if
4721  }; // if
4722 
4723 } // __kmp_stg_parse
4724 
4725 
4726 static int
4727 __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
4728  char const * name, // Name of variable.
4729  char const * value, // Value of the variable.
4730  kmp_setting_t * * rivals // List of rival settings (the list must include current one).
4731 ) {
4732 
4733  if ( rivals == NULL ) {
4734  return 0;
4735  }
4736 
4737  // Loop thru higher priority settings (listed before current).
4738  int i = 0;
4739  for ( ; strcmp( rivals[ i ]->name, name ) != 0; i++ ) {
4740  KMP_DEBUG_ASSERT( rivals[ i ] != NULL );
4741 
4742 #if KMP_AFFINITY_SUPPORTED
4743  if ( rivals[ i ] == __kmp_affinity_notype ) {
4744  //
4745  // If KMP_AFFINITY is specified without a type name,
4746  // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
4747  //
4748  continue;
4749  }
4750 #endif
4751 
4752  if ( rivals[ i ]->set ) {
4753  KMP_WARNING( StgIgnored, name, rivals[ i ]->name );
4754  return 1;
4755  }; // if
4756  }; // while
4757 
4758  ++ i; // Skip current setting.
4759  return 0;
4760 
4761 }; // __kmp_stg_check_rivals
4762 
4763 
4764 static int
4765 __kmp_env_toPrint( char const * name, int flag ) {
4766  int rc = 0;
4767  kmp_setting_t * setting = __kmp_stg_find( name );
4768  if ( setting != NULL ) {
4769  rc = setting->defined;
4770  if ( flag >= 0 ) {
4771  setting->defined = flag;
4772  }; // if
4773  }; // if
4774  return rc;
4775 }
4776 
4777 
4778 static void
4779 __kmp_aux_env_initialize( kmp_env_blk_t* block ) {
4780 
4781  char const * value;
4782 
4783  /* OMP_NUM_THREADS */
4784  value = __kmp_env_blk_var( block, "OMP_NUM_THREADS" );
4785  if ( value ) {
4786  ompc_set_num_threads( __kmp_dflt_team_nth );
4787  }
4788 
4789  /* KMP_BLOCKTIME */
4790  value = __kmp_env_blk_var( block, "KMP_BLOCKTIME" );
4791  if ( value ) {
4792  kmpc_set_blocktime( __kmp_dflt_blocktime );
4793  }
4794 
4795  /* OMP_NESTED */
4796  value = __kmp_env_blk_var( block, "OMP_NESTED" );
4797  if ( value ) {
4798  ompc_set_nested( __kmp_dflt_nested );
4799  }
4800 
4801  /* OMP_DYNAMIC */
4802  value = __kmp_env_blk_var( block, "OMP_DYNAMIC" );
4803  if ( value ) {
4804  ompc_set_dynamic( __kmp_global.g.g_dynamic );
4805  }
4806 
4807 }
4808 
4809 void
4810 __kmp_env_initialize( char const * string ) {
4811 
4812  kmp_env_blk_t block;
4813  int i;
4814 
4815  __kmp_stg_init();
4816 
4817  // Hack!!!
4818  if ( string == NULL ) {
4819  // __kmp_max_nth = __kmp_sys_max_nth;
4820  __kmp_threads_capacity = __kmp_initial_threads_capacity( __kmp_dflt_team_nth_ub );
4821  }; // if
4822  __kmp_env_blk_init( & block, string );
4823 
4824  //
4825  // update the set flag on all entries that have an env var
4826  //
4827  for ( i = 0; i < block.count; ++ i ) {
4828  if (( block.vars[ i ].name == NULL )
4829  || ( *block.vars[ i ].name == '\0')) {
4830  continue;
4831  }
4832  if ( block.vars[ i ].value == NULL ) {
4833  continue;
4834  }
4835  kmp_setting_t * setting = __kmp_stg_find( block.vars[ i ].name );
4836  if ( setting != NULL ) {
4837  setting->set = 1;
4838  }
4839  }; // for i
4840 
4841  // Special case. If we parse environment, not a string, process KMP_WARNINGS first.
4842  if ( string == NULL ) {
4843  char const * name = "KMP_WARNINGS";
4844  char const * value = __kmp_env_blk_var( & block, name );
4845  __kmp_stg_parse( name, value );
4846  }; // if
4847 
4848 #if KMP_AFFINITY_SUPPORTED
4849  //
4850  // Special case. KMP_AFFINITY is not a rival to other affinity env vars
4851  // if no affinity type is specified. We want to allow
4852  // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when
4853  // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
4854  // affinity mechanism.
4855  //
4856  __kmp_affinity_notype = NULL;
4857  char const *aff_str = __kmp_env_blk_var( & block, "KMP_AFFINITY" );
4858  if ( aff_str != NULL ) {
4859  //
4860  // Check if the KMP_AFFINITY type is specified in the string.
4861  // We just search the string for "compact", "scatter", etc.
4862  // without really parsing the string. The syntax of the
4863  // KMP_AFFINITY env var is such that none of the affinity
4864  // type names can appear anywhere other that the type
4865  // specifier, even as substrings.
4866  //
4867  // I can't find a case-insensitive version of strstr on Windows* OS.
4868  // Use the case-sensitive version for now.
4869  //
4870 
4871 # if KMP_OS_WINDOWS
4872 # define FIND strstr
4873 # else
4874 # define FIND strcasestr
4875 # endif
4876 
4877  if ( ( FIND( aff_str, "none" ) == NULL )
4878  && ( FIND( aff_str, "physical" ) == NULL )
4879  && ( FIND( aff_str, "logical" ) == NULL )
4880  && ( FIND( aff_str, "compact" ) == NULL )
4881  && ( FIND( aff_str, "scatter" ) == NULL )
4882  && ( FIND( aff_str, "explicit" ) == NULL )
4883  && ( FIND( aff_str, "balanced" ) == NULL )
4884  && ( FIND( aff_str, "disabled" ) == NULL ) ) {
4885  __kmp_affinity_notype = __kmp_stg_find( "KMP_AFFINITY" );
4886  }
4887  else {
4888  //
4889  // A new affinity type is specified.
4890  // Reset the affinity flags to their default values,
4891  // in case this is called from kmp_set_defaults().
4892  //
4893  __kmp_affinity_type = affinity_default;
4894  __kmp_affinity_gran = affinity_gran_default;
4895  __kmp_affinity_top_method = affinity_top_method_default;
4896  __kmp_affinity_respect_mask = affinity_respect_mask_default;
4897  }
4898 # undef FIND
4899 
4900 #if OMP_40_ENABLED
4901  //
4902  // Also reset the affinity flags if OMP_PROC_BIND is specified.
4903  //
4904  aff_str = __kmp_env_blk_var( & block, "OMP_PROC_BIND" );
4905  if ( aff_str != NULL ) {
4906  __kmp_affinity_type = affinity_default;
4907  __kmp_affinity_gran = affinity_gran_default;
4908  __kmp_affinity_top_method = affinity_top_method_default;
4909  __kmp_affinity_respect_mask = affinity_respect_mask_default;
4910  }
4911 #endif /* OMP_40_ENABLED */
4912  }
4913 
4914 #endif /* KMP_AFFINITY_SUPPORTED */
4915 
4916 #if OMP_40_ENABLED
4917  //
4918  // Set up the nested proc bind type vector.
4919  //
4920  if ( __kmp_nested_proc_bind.bind_types == NULL ) {
4921  __kmp_nested_proc_bind.bind_types = (kmp_proc_bind_t *)
4922  KMP_INTERNAL_MALLOC( sizeof(kmp_proc_bind_t) );
4923  if ( __kmp_nested_proc_bind.bind_types == NULL ) {
4924  KMP_FATAL( MemoryAllocFailed );
4925  }
4926  __kmp_nested_proc_bind.size = 1;
4927  __kmp_nested_proc_bind.used = 1;
4928 # if KMP_AFFINITY_SUPPORTED
4929  __kmp_nested_proc_bind.bind_types[0] = proc_bind_default;
4930 # else
4931  // default proc bind is false if affinity not supported
4932  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
4933 # endif
4934 
4935  }
4936 #endif /* OMP_40_ENABLED */
4937 
4938  //
4939  // Now process all of the settings.
4940  //
4941  for ( i = 0; i < block.count; ++ i ) {
4942  __kmp_stg_parse( block.vars[ i ].name, block.vars[ i ].value );
4943  }; // for i
4944 
4945  //
4946  // If user locks have been allocated yet, don't reset the lock vptr table.
4947  //
4948  if ( ! __kmp_init_user_locks ) {
4949  if ( __kmp_user_lock_kind == lk_default ) {
4950  __kmp_user_lock_kind = lk_queuing;
4951  }
4952 #if KMP_USE_DYNAMIC_LOCK
4953  __kmp_init_dynamic_user_locks();
4954 #else
4955  __kmp_set_user_lock_vptrs( __kmp_user_lock_kind );
4956 #endif
4957  }
4958  else {
4959  KMP_DEBUG_ASSERT( string != NULL); // kmp_set_defaults() was called
4960  KMP_DEBUG_ASSERT( __kmp_user_lock_kind != lk_default );
4961  // Binds lock functions again to follow the transition between different
4962  // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
4963  // as we do not allow lock kind changes after making a call to any
4964  // user lock functions (true).
4965 #if KMP_USE_DYNAMIC_LOCK
4966  __kmp_init_dynamic_user_locks();
4967 #else
4968  __kmp_set_user_lock_vptrs( __kmp_user_lock_kind );
4969 #endif
4970  }
4971 
4972 #if KMP_AFFINITY_SUPPORTED
4973 
4974  if ( ! TCR_4(__kmp_init_middle) ) {
4975  //
4976  // Determine if the machine/OS is actually capable of supporting
4977  // affinity.
4978  //
4979  const char *var = "KMP_AFFINITY";
4980  if ( __kmp_affinity_type == affinity_disabled ) {
4981  KMP_AFFINITY_DISABLE();
4982  }
4983  else if ( ! KMP_AFFINITY_CAPABLE() ) {
4984  __kmp_affinity_determine_capable( var );
4985  if ( ! KMP_AFFINITY_CAPABLE() ) {
4986  if ( __kmp_affinity_verbose || ( __kmp_affinity_warnings
4987  && ( __kmp_affinity_type != affinity_default )
4988  && ( __kmp_affinity_type != affinity_none )
4989  && ( __kmp_affinity_type != affinity_disabled ) ) ) {
4990  KMP_WARNING( AffNotSupported, var );
4991  }
4992  __kmp_affinity_type = affinity_disabled;
4993  __kmp_affinity_respect_mask = 0;
4994  __kmp_affinity_gran = affinity_gran_fine;
4995  }
4996  }
4997 
4998 # if OMP_40_ENABLED
4999  if ( __kmp_affinity_type == affinity_disabled ) {
5000  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5001  }
5002  else if ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_true ) {
5003  //
5004  // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
5005  //
5006  __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread;
5007  }
5008 # endif /* OMP_40_ENABLED */
5009 
5010  if ( KMP_AFFINITY_CAPABLE() ) {
5011 
5012 # if KMP_GROUP_AFFINITY
5013 
5014  //
5015  // Handle the Win 64 group affinity stuff if there are multiple
5016  // processor groups, or if the user requested it, and OMP 4.0
5017  // affinity is not in effect.
5018  //
5019  if ( ( ( __kmp_num_proc_groups > 1 )
5020  && ( __kmp_affinity_type == affinity_default )
5021 # if OMP_40_ENABLED
5022  && ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_default ) )
5023 # endif
5024  || ( __kmp_affinity_top_method == affinity_top_method_group ) ) {
5025  if ( __kmp_affinity_respect_mask == affinity_respect_mask_default ) {
5026  __kmp_affinity_respect_mask = FALSE;
5027  }
5028  if ( __kmp_affinity_type == affinity_default ) {
5029  __kmp_affinity_type = affinity_compact;
5030 # if OMP_40_ENABLED
5031  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5032 # endif
5033  }
5034  if ( __kmp_affinity_top_method == affinity_top_method_default ) {
5035  if ( __kmp_affinity_gran == affinity_gran_default ) {
5036  __kmp_affinity_top_method = affinity_top_method_group;
5037  __kmp_affinity_gran = affinity_gran_group;
5038  }
5039  else if ( __kmp_affinity_gran == affinity_gran_group ) {
5040  __kmp_affinity_top_method = affinity_top_method_group;
5041  }
5042  else {
5043  __kmp_affinity_top_method = affinity_top_method_all;
5044  }
5045  }
5046  else if ( __kmp_affinity_top_method == affinity_top_method_group ) {
5047  if ( __kmp_affinity_gran == affinity_gran_default ) {
5048  __kmp_affinity_gran = affinity_gran_group;
5049  }
5050  else if ( ( __kmp_affinity_gran != affinity_gran_group )
5051  && ( __kmp_affinity_gran != affinity_gran_fine )
5052  && ( __kmp_affinity_gran != affinity_gran_thread ) ) {
5053  char *str = NULL;
5054  switch ( __kmp_affinity_gran ) {
5055  case affinity_gran_core: str = "core"; break;
5056  case affinity_gran_package: str = "package"; break;
5057  case affinity_gran_node: str = "node"; break;
5058  default: KMP_DEBUG_ASSERT( 0 );
5059  }
5060  KMP_WARNING( AffGranTopGroup, var, str );
5061  __kmp_affinity_gran = affinity_gran_fine;
5062  }
5063  }
5064  else {
5065  if ( __kmp_affinity_gran == affinity_gran_default ) {
5066  __kmp_affinity_gran = affinity_gran_core;
5067  }
5068  else if ( __kmp_affinity_gran == affinity_gran_group ) {
5069  char *str = NULL;
5070  switch ( __kmp_affinity_type ) {
5071  case affinity_physical: str = "physical"; break;
5072  case affinity_logical: str = "logical"; break;
5073  case affinity_compact: str = "compact"; break;
5074  case affinity_scatter: str = "scatter"; break;
5075  case affinity_explicit: str = "explicit"; break;
5076  // No MIC on windows, so no affinity_balanced case
5077  default: KMP_DEBUG_ASSERT( 0 );
5078  }
5079  KMP_WARNING( AffGranGroupType, var, str );
5080  __kmp_affinity_gran = affinity_gran_core;
5081  }
5082  }
5083  }
5084  else
5085 
5086 # endif /* KMP_GROUP_AFFINITY */
5087 
5088  {
5089  if ( __kmp_affinity_respect_mask == affinity_respect_mask_default ) {
5090 # if KMP_GROUP_AFFINITY
5091  if ( __kmp_num_proc_groups > 1 ) {
5092  __kmp_affinity_respect_mask = FALSE;
5093  }
5094  else
5095 # endif /* KMP_GROUP_AFFINITY */
5096  {
5097  __kmp_affinity_respect_mask = TRUE;
5098  }
5099  }
5100 # if OMP_40_ENABLED
5101  if ( ( __kmp_nested_proc_bind.bind_types[0] != proc_bind_intel )
5102  && ( __kmp_nested_proc_bind.bind_types[0] != proc_bind_default ) ) {
5103  if ( __kmp_affinity_type == affinity_default ) {
5104  __kmp_affinity_type = affinity_compact;
5105  __kmp_affinity_dups = FALSE;
5106  }
5107  }
5108  else
5109 # endif /* OMP_40_ENABLED */
5110  if ( __kmp_affinity_type == affinity_default ) {
5111 #if OMP_40_ENABLED
5112 #if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
5113  if( __kmp_mic_type != non_mic ) {
5114  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5115  } else
5116 #endif
5117  {
5118  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5119  }
5120 #endif /* OMP_40_ENABLED */
5121 #if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
5122  if( __kmp_mic_type != non_mic ) {
5123  __kmp_affinity_type = affinity_scatter;
5124  } else
5125 #endif
5126  {
5127  __kmp_affinity_type = affinity_none;
5128  }
5129 
5130  }
5131  if ( ( __kmp_affinity_gran == affinity_gran_default )
5132  && ( __kmp_affinity_gran_levels < 0 ) ) {
5133 #if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
5134  if( __kmp_mic_type != non_mic ) {
5135  __kmp_affinity_gran = affinity_gran_fine;
5136  } else
5137 #endif
5138  {
5139  __kmp_affinity_gran = affinity_gran_core;
5140  }
5141  }
5142  if ( __kmp_affinity_top_method == affinity_top_method_default ) {
5143  __kmp_affinity_top_method = affinity_top_method_all;
5144  }
5145  }
5146  }
5147 
5148  K_DIAG( 1, ( "__kmp_affinity_type == %d\n", __kmp_affinity_type ) );
5149  K_DIAG( 1, ( "__kmp_affinity_compact == %d\n", __kmp_affinity_compact ) );
5150  K_DIAG( 1, ( "__kmp_affinity_offset == %d\n", __kmp_affinity_offset ) );
5151  K_DIAG( 1, ( "__kmp_affinity_verbose == %d\n", __kmp_affinity_verbose ) );
5152  K_DIAG( 1, ( "__kmp_affinity_warnings == %d\n", __kmp_affinity_warnings ) );
5153  K_DIAG( 1, ( "__kmp_affinity_respect_mask == %d\n", __kmp_affinity_respect_mask ) );
5154  K_DIAG( 1, ( "__kmp_affinity_gran == %d\n", __kmp_affinity_gran ) );
5155 
5156  KMP_DEBUG_ASSERT( __kmp_affinity_type != affinity_default);
5157 # if OMP_40_ENABLED
5158  KMP_DEBUG_ASSERT( __kmp_nested_proc_bind.bind_types[0] != proc_bind_default );
5159 # endif
5160  }
5161 
5162 #endif /* KMP_AFFINITY_SUPPORTED */
5163 
5164  if ( __kmp_version ) {
5165  __kmp_print_version_1();
5166  }; // if
5167 
5168  // Post-initialization step: some env. vars need their value's further processing
5169  if ( string != NULL) { // kmp_set_defaults() was called
5170  __kmp_aux_env_initialize( &block );
5171  }
5172 
5173  __kmp_env_blk_free( & block );
5174 
5175  KMP_MB();
5176 
5177 } // __kmp_env_initialize
5178 
5179 
5180 void
5181 __kmp_env_print() {
5182 
5183  kmp_env_blk_t block;
5184  int i;
5185  kmp_str_buf_t buffer;
5186 
5187  __kmp_stg_init();
5188  __kmp_str_buf_init( & buffer );
5189 
5190  __kmp_env_blk_init( & block, NULL );
5191  __kmp_env_blk_sort( & block );
5192 
5193  // Print real environment values.
5194  __kmp_str_buf_print( & buffer, "\n%s\n\n", KMP_I18N_STR( UserSettings ) );
5195  for ( i = 0; i < block.count; ++ i ) {
5196  char const * name = block.vars[ i ].name;
5197  char const * value = block.vars[ i ].value;
5198  if (
5199  ( KMP_STRLEN( name ) > 4 && strncmp( name, "KMP_", 4 ) == 0 )
5200  || strncmp( name, "OMP_", 4 ) == 0
5201  #ifdef KMP_GOMP_COMPAT
5202  || strncmp( name, "GOMP_", 5 ) == 0
5203  #endif // KMP_GOMP_COMPAT
5204  ) {
5205  __kmp_str_buf_print( & buffer, " %s=%s\n", name, value );
5206  }; // if
5207  }; // for
5208  __kmp_str_buf_print( & buffer, "\n" );
5209 
5210  // Print internal (effective) settings.
5211  __kmp_str_buf_print( & buffer, "%s\n\n", KMP_I18N_STR( EffectiveSettings ) );
5212  for ( int i = 0; i < __kmp_stg_count; ++ i ) {
5213  if ( __kmp_stg_table[ i ].print != NULL ) {
5214  __kmp_stg_table[ i ].print( & buffer, __kmp_stg_table[ i ].name, __kmp_stg_table[ i ].data );
5215  }; // if
5216  }; // for
5217 
5218  __kmp_printf( "%s", buffer.str );
5219 
5220  __kmp_env_blk_free( & block );
5221  __kmp_str_buf_free( & buffer );
5222 
5223  __kmp_printf("\n");
5224 
5225 } // __kmp_env_print
5226 
5227 
5228 #if OMP_40_ENABLED
5229 void
5230 __kmp_env_print_2() {
5231 
5232  kmp_env_blk_t block;
5233  kmp_str_buf_t buffer;
5234 
5235  __kmp_env_format = 1;
5236 
5237  __kmp_stg_init();
5238  __kmp_str_buf_init( & buffer );
5239 
5240  __kmp_env_blk_init( & block, NULL );
5241  __kmp_env_blk_sort( & block );
5242 
5243  __kmp_str_buf_print( & buffer, "\n%s\n", KMP_I18N_STR( DisplayEnvBegin ) );
5244  __kmp_str_buf_print( & buffer, " _OPENMP='%d'\n", __kmp_openmp_version );
5245 
5246  for ( int i = 0; i < __kmp_stg_count; ++ i ) {
5247  if ( __kmp_stg_table[ i ].print != NULL &&
5248  ( ( __kmp_display_env && strncmp( __kmp_stg_table[ i ].name, "OMP_", 4 ) == 0 ) || __kmp_display_env_verbose ) ) {
5249  __kmp_stg_table[ i ].print( & buffer, __kmp_stg_table[ i ].name, __kmp_stg_table[ i ].data );
5250  }; // if
5251  }; // for
5252 
5253  __kmp_str_buf_print( & buffer, "%s\n", KMP_I18N_STR( DisplayEnvEnd ) );
5254  __kmp_str_buf_print( & buffer, "\n" );
5255 
5256  __kmp_printf( "%s", buffer.str );
5257 
5258  __kmp_env_blk_free( & block );
5259  __kmp_str_buf_free( & buffer );
5260 
5261  __kmp_printf("\n");
5262 
5263 } // __kmp_env_print_2
5264 #endif // OMP_40_ENABLED
5265 
5266 
5267 
5268 // end of file
5269