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