Intel® OpenMP* Runtime Library
 All Classes Functions Variables Typedefs Enumerations Enumerator Groups 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  // AC: extended to sockets level, examples of
4247  // "use 2 sockets with offset 6, 2 cores with offset 2 per socket, 2 threads per core":
4248  // 2s,6o,2c,2o,2t; 2s,6o,2c,2t,2o; 2s@6,2c@2,2t
4249  // To not break legacy code core-offset can be last;
4250  // postfix "o" or prefix @ can be offset designator.
4251  // Note: not all syntax errors are analyzed, some may be skipped.
4252 #define CHECK_DELIM(_x) (*(_x) == ',' || *(_x) == 'x')
4253  int num;
4254  int single_warning = 0;
4255  int flagS = 0, flagC = 0, flagT = 0, flagSO = 0, flagCO = 0;
4256  const char *next = value;
4257  const char *prev;
4258 
4259  SKIP_WS(next); // skip white spaces
4260  if (*next == '\0')
4261  return; // no data provided, retain default values
4262  // Get num_sockets first (or whatever specified)
4263  if (*next >= '0' && *next <= '9') {
4264  prev = next;
4265  SKIP_DIGITS(next);
4266  num = __kmp_str_to_int(prev, *next);
4267  SKIP_WS(next);
4268  if (*next == 's' || *next == 'S') { // e.g. "2s"
4269  __kmp_place_num_sockets = num;
4270  flagS = 1; // got num sockets
4271  next++;
4272  if (*next == '@') { // socket offset, e.g. "2s@4"
4273  flagSO = 1;
4274  prev = ++next; // don't allow spaces for simplicity
4275  if (!(*next >= '0' && *next <= '9')) {
4276  KMP_WARNING(AffThrPlaceInvalid, name, value);
4277  return;
4278  }
4279  SKIP_DIGITS(next);
4280  num = __kmp_str_to_int(prev, *next);
4281  __kmp_place_socket_offset = num;
4282  }
4283  } else if (*next == 'c' || *next == 'C') {
4284  __kmp_place_num_cores = num;
4285  flagS = flagC = 1; // sockets were not specified - use default
4286  next++;
4287  if (*next == '@') { // core offset, e.g. "2c@6"
4288  flagCO = 1;
4289  prev = ++next; // don't allow spaces for simplicity
4290  if (!(*next >= '0' && *next <= '9')) {
4291  KMP_WARNING(AffThrPlaceInvalid, name, value);
4292  return;
4293  }
4294  SKIP_DIGITS(next);
4295  num = __kmp_str_to_int(prev, *next);
4296  __kmp_place_core_offset = num;
4297  }
4298  } else if (CHECK_DELIM(next)) {
4299  __kmp_place_num_cores = num; // no letter-designator - num cores
4300  flagS = flagC = 1; // sockets were not specified - use default
4301  next++;
4302  } else if (*next == 't' || *next == 'T') {
4303  __kmp_place_num_threads_per_core = num;
4304  // sockets, cores were not specified - use default
4305  return; // we ignore offset value in case all cores are used
4306  } else if (*next == '\0') {
4307  __kmp_place_num_cores = num;
4308  return; // the only value provided - set num cores
4309  } else {
4310  KMP_WARNING(AffThrPlaceInvalid, name, value);
4311  return;
4312  }
4313  } else {
4314  KMP_WARNING(AffThrPlaceInvalid, name, value);
4315  return;
4316  }
4317  KMP_DEBUG_ASSERT(flagS); // num sockets should already be set here
4318  SKIP_WS(next);
4319  if (*next == '\0')
4320  return; // " n " - something like this
4321  if (CHECK_DELIM(next)) {
4322  next++; // skip delimiter
4323  SKIP_WS(next);
4324  }
4325 
4326  // Get second value (could be offset, num_cores, num_threads)
4327  if (*next >= '0' && *next <= '9') {
4328  prev = next;
4329  SKIP_DIGITS(next);
4330  num = __kmp_str_to_int(prev, *next);
4331  SKIP_WS(next);
4332  if (*next == 'c' || *next == 'C') {
4333  KMP_DEBUG_ASSERT(flagC == 0);
4334  __kmp_place_num_cores = num;
4335  flagC = 1;
4336  next++;
4337  if (*next == '@') { // core offset, e.g. "2c@6"
4338  flagCO = 1;
4339  prev = ++next; // don't allow spaces for simplicity
4340  if (!(*next >= '0' && *next <= '9')) {
4341  KMP_WARNING(AffThrPlaceInvalid, name, value);
4342  return;
4343  }
4344  SKIP_DIGITS(next);
4345  num = __kmp_str_to_int(prev, *next);
4346  __kmp_place_core_offset = num;
4347  }
4348  } else if (*next == 'o' || *next == 'O') { // offset specified
4349  KMP_WARNING(AffThrPlaceDeprecated);
4350  single_warning = 1;
4351  if (flagC) { // whether num_cores already specified (sockets skipped)
4352  KMP_DEBUG_ASSERT(!flagCO); // either "o" or @, not both
4353  __kmp_place_core_offset = num;
4354  } else {
4355  KMP_DEBUG_ASSERT(!flagSO); // either "o" or @, not both
4356  __kmp_place_socket_offset = num;
4357  }
4358  next++;
4359  } else if (*next == 't' || *next == 'T') {
4360  KMP_DEBUG_ASSERT(flagT == 0);
4361  __kmp_place_num_threads_per_core = num;
4362  flagC = 1; // num_cores could be skipped ?
4363  flagT = 1;
4364  next++; // can have core-offset specified after num threads
4365  } else if (*next == '\0') {
4366  KMP_DEBUG_ASSERT(flagC); // 4x2 means 4 cores 2 threads per core
4367  __kmp_place_num_threads_per_core = num;
4368  return; // two values provided without letter-designator
4369  } else {
4370  KMP_WARNING(AffThrPlaceInvalid, name, value);
4371  return;
4372  }
4373  } else {
4374  KMP_WARNING(AffThrPlaceInvalid, name, value);
4375  return;
4376  }
4377  SKIP_WS(next);
4378  if (*next == '\0')
4379  return; // " Ns,Nc " - something like this
4380  if (CHECK_DELIM(next)) {
4381  next++; // skip delimiter
4382  SKIP_WS(next);
4383  }
4384 
4385  // Get third value (could be core-offset, num_cores, num_threads)
4386  if (*next >= '0' && *next <= '9') {
4387  prev = next;
4388  SKIP_DIGITS(next);
4389  num = __kmp_str_to_int(prev, *next);
4390  SKIP_WS(next);
4391  if (*next == 't' || *next == 'T') {
4392  KMP_DEBUG_ASSERT(flagT == 0);
4393  __kmp_place_num_threads_per_core = num;
4394  if (flagC == 0)
4395  return; // num_cores could be skipped (e.g. 2s,4o,2t)
4396  flagT = 1;
4397  next++; // can have core-offset specified later (e.g. 2s,1c,2t,3o)
4398  } else if (*next == 'c' || *next == 'C') {
4399  KMP_DEBUG_ASSERT(flagC == 0);
4400  __kmp_place_num_cores = num;
4401  flagC = 1;
4402  next++;
4403  //KMP_DEBUG_ASSERT(*next != '@'); // socket offset used "o" designator
4404  } else if (*next == 'o' || *next == 'O') {
4405  KMP_WARNING(AffThrPlaceDeprecated);
4406  single_warning = 1;
4407  KMP_DEBUG_ASSERT(flagC);
4408  //KMP_DEBUG_ASSERT(!flagSO); // socket offset couldn't use @ designator
4409  __kmp_place_core_offset = num;
4410  next++;
4411  } else {
4412  KMP_WARNING(AffThrPlaceInvalid, name, value);
4413  return;
4414  }
4415  } else {
4416  KMP_WARNING(AffThrPlaceInvalid, name, value);
4417  return;
4418  }
4419  KMP_DEBUG_ASSERT(flagC);
4420  SKIP_WS(next);
4421  if ( *next == '\0' )
4422  return;
4423  if (CHECK_DELIM(next)) {
4424  next++; // skip delimiter
4425  SKIP_WS(next);
4426  }
4427 
4428  // Get 4-th value (could be core-offset, num_threads)
4429  if (*next >= '0' && *next <= '9') {
4430  prev = next;
4431  SKIP_DIGITS(next);
4432  num = __kmp_str_to_int(prev, *next);
4433  SKIP_WS(next);
4434  if (*next == 'o' || *next == 'O') {
4435  if (!single_warning) { // warn once
4436  KMP_WARNING(AffThrPlaceDeprecated);
4437  }
4438  KMP_DEBUG_ASSERT(!flagSO); // socket offset couldn't use @ designator
4439  __kmp_place_core_offset = num;
4440  next++;
4441  } else if (*next == 't' || *next == 'T') {
4442  KMP_DEBUG_ASSERT(flagT == 0);
4443  __kmp_place_num_threads_per_core = num;
4444  flagT = 1;
4445  next++; // can have core-offset specified after num threads
4446  } else {
4447  KMP_WARNING(AffThrPlaceInvalid, name, value);
4448  return;
4449  }
4450  } else {
4451  KMP_WARNING(AffThrPlaceInvalid, name, value);
4452  return;
4453  }
4454  SKIP_WS(next);
4455  if ( *next == '\0' )
4456  return;
4457  if (CHECK_DELIM(next)) {
4458  next++; // skip delimiter
4459  SKIP_WS(next);
4460  }
4461 
4462  // Get 5-th value (could be core-offset, num_threads)
4463  if (*next >= '0' && *next <= '9') {
4464  prev = next;
4465  SKIP_DIGITS(next);
4466  num = __kmp_str_to_int(prev, *next);
4467  SKIP_WS(next);
4468  if (*next == 'o' || *next == 'O') {
4469  if (!single_warning) { // warn once
4470  KMP_WARNING(AffThrPlaceDeprecated);
4471  }
4472  KMP_DEBUG_ASSERT(flagT);
4473  KMP_DEBUG_ASSERT(!flagSO); // socket offset couldn't use @ designator
4474  __kmp_place_core_offset = num;
4475  } else if (*next == 't' || *next == 'T') {
4476  KMP_DEBUG_ASSERT(flagT == 0);
4477  __kmp_place_num_threads_per_core = num;
4478  } else {
4479  KMP_WARNING(AffThrPlaceInvalid, name, value);
4480  }
4481  } else {
4482  KMP_WARNING(AffThrPlaceInvalid, name, value);
4483  }
4484  return;
4485 #undef CHECK_DELIM
4486 }
4487 
4488 static void
4489 __kmp_stg_print_place_threads( kmp_str_buf_t * buffer, char const * name, void * data ) {
4490  if (__kmp_place_num_sockets + __kmp_place_num_cores + __kmp_place_num_threads_per_core) {
4491  int comma = 0;
4492  kmp_str_buf_t buf;
4493  __kmp_str_buf_init(&buf);
4494  if(__kmp_env_format)
4495  KMP_STR_BUF_PRINT_NAME_EX(name);
4496  else
4497  __kmp_str_buf_print(buffer, " %s='", name);
4498  if (__kmp_place_num_sockets) {
4499  __kmp_str_buf_print(&buf, "%ds", __kmp_place_num_sockets);
4500  if (__kmp_place_socket_offset)
4501  __kmp_str_buf_print(&buf, "@%d", __kmp_place_socket_offset);
4502  comma = 1;
4503  }
4504  if (__kmp_place_num_cores) {
4505  __kmp_str_buf_print(&buf, "%s%dc", comma?",":"", __kmp_place_num_cores);
4506  if (__kmp_place_core_offset)
4507  __kmp_str_buf_print(&buf, "@%d", __kmp_place_core_offset);
4508  comma = 1;
4509  }
4510  if (__kmp_place_num_threads_per_core)
4511  __kmp_str_buf_print(&buf, "%s%dt", comma?",":"", __kmp_place_num_threads_per_core);
4512  __kmp_str_buf_print(buffer, "%s'\n", buf.str );
4513  __kmp_str_buf_free(&buf);
4514 /*
4515  } else {
4516  __kmp_str_buf_print( buffer, " %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
4517 */
4518  }
4519 }
4520 
4521 #if USE_ITT_BUILD
4522 // -------------------------------------------------------------------------------------------------
4523 // KMP_FORKJOIN_FRAMES
4524 // -------------------------------------------------------------------------------------------------
4525 
4526 static void
4527 __kmp_stg_parse_forkjoin_frames( char const * name, char const * value, void * data ) {
4528  __kmp_stg_parse_bool( name, value, & __kmp_forkjoin_frames );
4529 } // __kmp_stg_parse_forkjoin_frames
4530 
4531 static void
4532 __kmp_stg_print_forkjoin_frames( kmp_str_buf_t * buffer, char const * name, void * data ) {
4533  __kmp_stg_print_bool( buffer, name, __kmp_forkjoin_frames );
4534 } // __kmp_stg_print_forkjoin_frames
4535 
4536 // -------------------------------------------------------------------------------------------------
4537 // KMP_FORKJOIN_FRAMES_MODE
4538 // -------------------------------------------------------------------------------------------------
4539 
4540 static void
4541 __kmp_stg_parse_forkjoin_frames_mode( char const * name, char const * value, void * data ) {
4542  __kmp_stg_parse_int( name, value, 0, 3, & __kmp_forkjoin_frames_mode );
4543 } // __kmp_stg_parse_forkjoin_frames
4544 
4545 static void
4546 __kmp_stg_print_forkjoin_frames_mode( kmp_str_buf_t * buffer, char const * name, void * data ) {
4547  __kmp_stg_print_int( buffer, name, __kmp_forkjoin_frames_mode );
4548 } // __kmp_stg_print_forkjoin_frames
4549 #endif /* USE_ITT_BUILD */
4550 
4551 // -------------------------------------------------------------------------------------------------
4552 // OMP_DISPLAY_ENV
4553 // -------------------------------------------------------------------------------------------------
4554 
4555 #if OMP_40_ENABLED
4556 
4557 static void
4558 __kmp_stg_parse_omp_display_env( char const * name, char const * value, void * data )
4559 {
4560  if ( __kmp_str_match( "VERBOSE", 1, value ) )
4561  {
4562  __kmp_display_env_verbose = TRUE;
4563  } else {
4564  __kmp_stg_parse_bool( name, value, & __kmp_display_env );
4565  }
4566 
4567 } // __kmp_stg_parse_omp_display_env
4568 
4569 static void
4570 __kmp_stg_print_omp_display_env( kmp_str_buf_t * buffer, char const * name, void * data )
4571 {
4572  if ( __kmp_display_env_verbose )
4573  {
4574  __kmp_stg_print_str( buffer, name, "VERBOSE" );
4575  } else {
4576  __kmp_stg_print_bool( buffer, name, __kmp_display_env );
4577  }
4578 } // __kmp_stg_print_omp_display_env
4579 
4580 static void
4581 __kmp_stg_parse_omp_cancellation( char const * name, char const * value, void * data ) {
4582  if ( TCR_4(__kmp_init_parallel) ) {
4583  KMP_WARNING( EnvParallelWarn, name );
4584  return;
4585  } // read value before first parallel only
4586  __kmp_stg_parse_bool( name, value, & __kmp_omp_cancellation );
4587 } // __kmp_stg_parse_omp_cancellation
4588 
4589 static void
4590 __kmp_stg_print_omp_cancellation( kmp_str_buf_t * buffer, char const * name, void * data ) {
4591  __kmp_stg_print_bool( buffer, name, __kmp_omp_cancellation );
4592 } // __kmp_stg_print_omp_cancellation
4593 
4594 #endif
4595 
4596 // -------------------------------------------------------------------------------------------------
4597 
4598 
4599 // -------------------------------------------------------------------------------------------------
4600 // Table.
4601 // -------------------------------------------------------------------------------------------------
4602 
4603 
4604 static kmp_setting_t __kmp_stg_table[] = {
4605 
4606  { "KMP_ALL_THREADS", __kmp_stg_parse_all_threads, __kmp_stg_print_all_threads, NULL, 0, 0 },
4607  { "KMP_BLOCKTIME", __kmp_stg_parse_blocktime, __kmp_stg_print_blocktime, NULL, 0, 0 },
4608  { "KMP_DUPLICATE_LIB_OK", __kmp_stg_parse_duplicate_lib_ok, __kmp_stg_print_duplicate_lib_ok, NULL, 0, 0 },
4609  { "KMP_LIBRARY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy, NULL, 0, 0 },
4610  { "KMP_MAX_THREADS", __kmp_stg_parse_all_threads, NULL, NULL, 0, 0 }, // For backward compatibility
4611  { "KMP_MONITOR_STACKSIZE", __kmp_stg_parse_monitor_stacksize, __kmp_stg_print_monitor_stacksize, NULL, 0, 0 },
4612  { "KMP_SETTINGS", __kmp_stg_parse_settings, __kmp_stg_print_settings, NULL, 0, 0 },
4613  { "KMP_STACKOFFSET", __kmp_stg_parse_stackoffset, __kmp_stg_print_stackoffset, NULL, 0, 0 },
4614  { "KMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize, NULL, 0, 0 },
4615  { "KMP_STACKPAD", __kmp_stg_parse_stackpad, __kmp_stg_print_stackpad, NULL, 0, 0 },
4616  { "KMP_VERSION", __kmp_stg_parse_version, __kmp_stg_print_version, NULL, 0, 0 },
4617  { "KMP_WARNINGS", __kmp_stg_parse_warnings, __kmp_stg_print_warnings, NULL, 0, 0 },
4618 
4619  { "OMP_NESTED", __kmp_stg_parse_nested, __kmp_stg_print_nested, NULL, 0, 0 },
4620  { "OMP_NUM_THREADS", __kmp_stg_parse_num_threads, __kmp_stg_print_num_threads, NULL, 0, 0 },
4621  { "OMP_STACKSIZE", __kmp_stg_parse_stacksize, __kmp_stg_print_stacksize, NULL, 0, 0 },
4622 
4623  { "KMP_TASKING", __kmp_stg_parse_tasking, __kmp_stg_print_tasking, NULL, 0, 0 },
4624  { "KMP_TASK_STEALING_CONSTRAINT", __kmp_stg_parse_task_stealing, __kmp_stg_print_task_stealing, NULL, 0, 0 },
4625  { "OMP_MAX_ACTIVE_LEVELS", __kmp_stg_parse_max_active_levels, __kmp_stg_print_max_active_levels, NULL, 0, 0 },
4626  { "OMP_THREAD_LIMIT", __kmp_stg_parse_all_threads, __kmp_stg_print_all_threads, NULL, 0, 0 },
4627  { "OMP_WAIT_POLICY", __kmp_stg_parse_wait_policy, __kmp_stg_print_wait_policy, NULL, 0, 0 },
4628 #if KMP_NESTED_HOT_TEAMS
4629  { "KMP_HOT_TEAMS_MAX_LEVEL", __kmp_stg_parse_hot_teams_level, __kmp_stg_print_hot_teams_level, NULL, 0, 0 },
4630  { "KMP_HOT_TEAMS_MODE", __kmp_stg_parse_hot_teams_mode, __kmp_stg_print_hot_teams_mode, NULL, 0, 0 },
4631 #endif // KMP_NESTED_HOT_TEAMS
4632 
4633 #if KMP_HANDLE_SIGNALS
4634  { "KMP_HANDLE_SIGNALS", __kmp_stg_parse_handle_signals, __kmp_stg_print_handle_signals, NULL, 0, 0 },
4635 #endif
4636 
4637 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
4638  { "KMP_INHERIT_FP_CONTROL", __kmp_stg_parse_inherit_fp_control, __kmp_stg_print_inherit_fp_control, NULL, 0, 0 },
4639 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
4640 
4641 #ifdef KMP_GOMP_COMPAT
4642  { "GOMP_STACKSIZE", __kmp_stg_parse_stacksize, NULL, NULL, 0, 0 },
4643 #endif
4644 
4645 #ifdef KMP_DEBUG
4646  { "KMP_A_DEBUG", __kmp_stg_parse_a_debug, __kmp_stg_print_a_debug, NULL, 0, 0 },
4647  { "KMP_B_DEBUG", __kmp_stg_parse_b_debug, __kmp_stg_print_b_debug, NULL, 0, 0 },
4648  { "KMP_C_DEBUG", __kmp_stg_parse_c_debug, __kmp_stg_print_c_debug, NULL, 0, 0 },
4649  { "KMP_D_DEBUG", __kmp_stg_parse_d_debug, __kmp_stg_print_d_debug, NULL, 0, 0 },
4650  { "KMP_E_DEBUG", __kmp_stg_parse_e_debug, __kmp_stg_print_e_debug, NULL, 0, 0 },
4651  { "KMP_F_DEBUG", __kmp_stg_parse_f_debug, __kmp_stg_print_f_debug, NULL, 0, 0 },
4652  { "KMP_DEBUG", __kmp_stg_parse_debug, NULL, /* no print */ NULL, 0, 0 },
4653  { "KMP_DEBUG_BUF", __kmp_stg_parse_debug_buf, __kmp_stg_print_debug_buf, NULL, 0, 0 },
4654  { "KMP_DEBUG_BUF_ATOMIC", __kmp_stg_parse_debug_buf_atomic, __kmp_stg_print_debug_buf_atomic, NULL, 0, 0 },
4655  { "KMP_DEBUG_BUF_CHARS", __kmp_stg_parse_debug_buf_chars, __kmp_stg_print_debug_buf_chars, NULL, 0, 0 },
4656  { "KMP_DEBUG_BUF_LINES", __kmp_stg_parse_debug_buf_lines, __kmp_stg_print_debug_buf_lines, NULL, 0, 0 },
4657  { "KMP_DIAG", __kmp_stg_parse_diag, __kmp_stg_print_diag, NULL, 0, 0 },
4658 
4659  { "KMP_PAR_RANGE", __kmp_stg_parse_par_range_env, __kmp_stg_print_par_range_env, NULL, 0, 0 },
4660  { "KMP_YIELD_CYCLE", __kmp_stg_parse_yield_cycle, __kmp_stg_print_yield_cycle, NULL, 0, 0 },
4661  { "KMP_YIELD_ON", __kmp_stg_parse_yield_on, __kmp_stg_print_yield_on, NULL, 0, 0 },
4662  { "KMP_YIELD_OFF", __kmp_stg_parse_yield_off, __kmp_stg_print_yield_off, NULL, 0, 0 },
4663 #endif // KMP_DEBUG
4664 
4665  { "KMP_ALIGN_ALLOC", __kmp_stg_parse_align_alloc, __kmp_stg_print_align_alloc, NULL, 0, 0 },
4666 
4667  { "KMP_PLAIN_BARRIER", __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
4668  { "KMP_PLAIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, __kmp_stg_print_barrier_pattern, NULL, 0, 0 },
4669  { "KMP_FORKJOIN_BARRIER", __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
4670  { "KMP_FORKJOIN_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, __kmp_stg_print_barrier_pattern, NULL, 0, 0 },
4671 #if KMP_FAST_REDUCTION_BARRIER
4672  { "KMP_REDUCTION_BARRIER", __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
4673  { "KMP_REDUCTION_BARRIER_PATTERN", __kmp_stg_parse_barrier_pattern, __kmp_stg_print_barrier_pattern, NULL, 0, 0 },
4674 #endif
4675 
4676  { "KMP_ABORT_DELAY", __kmp_stg_parse_abort_delay, __kmp_stg_print_abort_delay, NULL, 0, 0 },
4677  { "KMP_CPUINFO_FILE", __kmp_stg_parse_cpuinfo_file, __kmp_stg_print_cpuinfo_file, NULL, 0, 0 },
4678  { "KMP_FORCE_REDUCTION", __kmp_stg_parse_force_reduction, __kmp_stg_print_force_reduction, NULL, 0, 0 },
4679  { "KMP_DETERMINISTIC_REDUCTION", __kmp_stg_parse_force_reduction, __kmp_stg_print_force_reduction, NULL, 0, 0 },
4680  { "KMP_STORAGE_MAP", __kmp_stg_parse_storage_map, __kmp_stg_print_storage_map, NULL, 0, 0 },
4681  { "KMP_ALL_THREADPRIVATE", __kmp_stg_parse_all_threadprivate, __kmp_stg_print_all_threadprivate, NULL, 0, 0 },
4682  { "KMP_FOREIGN_THREADS_THREADPRIVATE", __kmp_stg_parse_foreign_threads_threadprivate, __kmp_stg_print_foreign_threads_threadprivate, NULL, 0, 0 },
4683 
4684 #if KMP_AFFINITY_SUPPORTED
4685  { "KMP_AFFINITY", __kmp_stg_parse_affinity, __kmp_stg_print_affinity, NULL, 0, 0 },
4686 # ifdef KMP_GOMP_COMPAT
4687  { "GOMP_CPU_AFFINITY", __kmp_stg_parse_gomp_cpu_affinity, NULL, /* no print */ NULL, 0, 0 },
4688 # endif /* KMP_GOMP_COMPAT */
4689 # if OMP_40_ENABLED
4690  { "OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind, NULL, 0, 0 },
4691  { "OMP_PLACES", __kmp_stg_parse_places, __kmp_stg_print_places, NULL, 0, 0 },
4692 # else
4693  { "OMP_PROC_BIND", __kmp_stg_parse_proc_bind, NULL, /* no print */ NULL, 0, 0 },
4694 # endif /* OMP_40_ENABLED */
4695 
4696  { "KMP_TOPOLOGY_METHOD", __kmp_stg_parse_topology_method, __kmp_stg_print_topology_method, NULL, 0, 0 },
4697 
4698 #else
4699 
4700  //
4701  // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
4702  // OMP_PROC_BIND and proc-bind-var are supported, however.
4703  //
4704 # if OMP_40_ENABLED
4705  { "OMP_PROC_BIND", __kmp_stg_parse_proc_bind, __kmp_stg_print_proc_bind, NULL, 0, 0 },
4706 # endif
4707 
4708 #endif // KMP_AFFINITY_SUPPORTED
4709 
4710  { "KMP_INIT_AT_FORK", __kmp_stg_parse_init_at_fork, __kmp_stg_print_init_at_fork, NULL, 0, 0 },
4711  { "KMP_SCHEDULE", __kmp_stg_parse_schedule, __kmp_stg_print_schedule, NULL, 0, 0 },
4712  { "OMP_SCHEDULE", __kmp_stg_parse_omp_schedule, __kmp_stg_print_omp_schedule, NULL, 0, 0 },
4713  { "KMP_ATOMIC_MODE", __kmp_stg_parse_atomic_mode, __kmp_stg_print_atomic_mode, NULL, 0, 0 },
4714  { "KMP_CONSISTENCY_CHECK", __kmp_stg_parse_consistency_check, __kmp_stg_print_consistency_check, NULL, 0, 0 },
4715 
4716 #if USE_ITT_BUILD && USE_ITT_NOTIFY
4717  { "KMP_ITT_PREPARE_DELAY", __kmp_stg_parse_itt_prepare_delay, __kmp_stg_print_itt_prepare_delay, NULL, 0, 0 },
4718 #endif /* USE_ITT_BUILD && USE_ITT_NOTIFY */
4719  { "KMP_MALLOC_POOL_INCR", __kmp_stg_parse_malloc_pool_incr, __kmp_stg_print_malloc_pool_incr, NULL, 0, 0 },
4720  { "KMP_INIT_WAIT", __kmp_stg_parse_init_wait, __kmp_stg_print_init_wait, NULL, 0, 0 },
4721  { "KMP_NEXT_WAIT", __kmp_stg_parse_next_wait, __kmp_stg_print_next_wait, NULL, 0, 0 },
4722  { "KMP_GTID_MODE", __kmp_stg_parse_gtid_mode, __kmp_stg_print_gtid_mode, NULL, 0, 0 },
4723  { "OMP_DYNAMIC", __kmp_stg_parse_omp_dynamic, __kmp_stg_print_omp_dynamic, NULL, 0, 0 },
4724  { "KMP_DYNAMIC_MODE", __kmp_stg_parse_kmp_dynamic_mode, __kmp_stg_print_kmp_dynamic_mode, NULL, 0, 0 },
4725 
4726 #ifdef USE_LOAD_BALANCE
4727  { "KMP_LOAD_BALANCE_INTERVAL", __kmp_stg_parse_ld_balance_interval,__kmp_stg_print_ld_balance_interval,NULL, 0, 0 },
4728 #endif
4729 
4730 
4731 
4732  { "KMP_NUM_LOCKS_IN_BLOCK", __kmp_stg_parse_lock_block, __kmp_stg_print_lock_block, NULL, 0, 0 },
4733  { "KMP_LOCK_KIND", __kmp_stg_parse_lock_kind, __kmp_stg_print_lock_kind, NULL, 0, 0 },
4734 #if KMP_USE_ADAPTIVE_LOCKS
4735  { "KMP_ADAPTIVE_LOCK_PROPS", __kmp_stg_parse_adaptive_lock_props,__kmp_stg_print_adaptive_lock_props, NULL, 0, 0 },
4736 #if KMP_DEBUG_ADAPTIVE_LOCKS
4737  { "KMP_SPECULATIVE_STATSFILE", __kmp_stg_parse_speculative_statsfile,__kmp_stg_print_speculative_statsfile, NULL, 0, 0 },
4738 #endif
4739 #endif // KMP_USE_ADAPTIVE_LOCKS
4740  { "KMP_PLACE_THREADS", __kmp_stg_parse_place_threads, __kmp_stg_print_place_threads, NULL, 0, 0 },
4741 #if USE_ITT_BUILD
4742  { "KMP_FORKJOIN_FRAMES", __kmp_stg_parse_forkjoin_frames, __kmp_stg_print_forkjoin_frames, NULL, 0, 0 },
4743  { "KMP_FORKJOIN_FRAMES_MODE", __kmp_stg_parse_forkjoin_frames_mode,__kmp_stg_print_forkjoin_frames_mode, NULL, 0, 0 },
4744 #endif
4745 
4746 # if OMP_40_ENABLED
4747  { "OMP_DISPLAY_ENV", __kmp_stg_parse_omp_display_env, __kmp_stg_print_omp_display_env, NULL, 0, 0 },
4748  { "OMP_CANCELLATION", __kmp_stg_parse_omp_cancellation, __kmp_stg_print_omp_cancellation, NULL, 0, 0 },
4749 #endif
4750  { "", NULL, NULL, NULL, 0, 0 }
4751 }; // settings
4752 
4753 static int const __kmp_stg_count = sizeof( __kmp_stg_table ) / sizeof( kmp_setting_t );
4754 
4755 static inline
4756 kmp_setting_t *
4757 __kmp_stg_find( char const * name ) {
4758 
4759  int i;
4760  if ( name != NULL ) {
4761  for ( i = 0; i < __kmp_stg_count; ++ i ) {
4762  if ( strcmp( __kmp_stg_table[ i ].name, name ) == 0 ) {
4763  return & __kmp_stg_table[ i ];
4764  }; // if
4765  }; // for
4766  }; // if
4767  return NULL;
4768 
4769 } // __kmp_stg_find
4770 
4771 
4772 static int
4773 __kmp_stg_cmp( void const * _a, void const * _b ) {
4774  kmp_setting_t * a = (kmp_setting_t *) _a;
4775  kmp_setting_t * b = (kmp_setting_t *) _b;
4776 
4777  //
4778  // Process KMP_AFFINITY last.
4779  // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
4780  //
4781  if ( strcmp( a->name, "KMP_AFFINITY" ) == 0 ) {
4782  if ( strcmp( b->name, "KMP_AFFINITY" ) == 0 ) {
4783  return 0;
4784  }
4785  return 1;
4786  }
4787  else if ( strcmp( b->name, "KMP_AFFINITY" ) == 0 ) {
4788  return -1;
4789  }
4790  return strcmp( a->name, b->name );
4791 } // __kmp_stg_cmp
4792 
4793 
4794 static void
4795 __kmp_stg_init( void
4796 ) {
4797 
4798  static int initialized = 0;
4799 
4800  if ( ! initialized ) {
4801 
4802  // Sort table.
4803  qsort( __kmp_stg_table, __kmp_stg_count - 1, sizeof( kmp_setting_t ), __kmp_stg_cmp );
4804 
4805  { // Initialize *_STACKSIZE data.
4806 
4807  kmp_setting_t * kmp_stacksize = __kmp_stg_find( "KMP_STACKSIZE" ); // 1st priority.
4808 #ifdef KMP_GOMP_COMPAT
4809  kmp_setting_t * gomp_stacksize = __kmp_stg_find( "GOMP_STACKSIZE" ); // 2nd priority.
4810 #endif
4811  kmp_setting_t * omp_stacksize = __kmp_stg_find( "OMP_STACKSIZE" ); // 3rd priority.
4812 
4813  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4814  // !!! Compiler does not understand rivals is used and optimizes out assignments
4815  // !!! rivals[ i ++ ] = ...;
4816  static kmp_setting_t * volatile rivals[ 4 ];
4817  static kmp_stg_ss_data_t kmp_data = { 1, (kmp_setting_t **)rivals };
4818 #ifdef KMP_GOMP_COMPAT
4819  static kmp_stg_ss_data_t gomp_data = { 1024, (kmp_setting_t **)rivals };
4820 #endif
4821  static kmp_stg_ss_data_t omp_data = { 1024, (kmp_setting_t **)rivals };
4822  int i = 0;
4823 
4824  rivals[ i ++ ] = kmp_stacksize;
4825 #ifdef KMP_GOMP_COMPAT
4826  if ( gomp_stacksize != NULL ) {
4827  rivals[ i ++ ] = gomp_stacksize;
4828  }; // if
4829 #endif
4830  rivals[ i ++ ] = omp_stacksize;
4831  rivals[ i ++ ] = NULL;
4832 
4833  kmp_stacksize->data = & kmp_data;
4834 #ifdef KMP_GOMP_COMPAT
4835  if ( gomp_stacksize != NULL ) {
4836  gomp_stacksize->data = & gomp_data;
4837  }; // if
4838 #endif
4839  omp_stacksize->data = & omp_data;
4840 
4841  }
4842 
4843  { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
4844 
4845  kmp_setting_t * kmp_library = __kmp_stg_find( "KMP_LIBRARY" ); // 1st priority.
4846  kmp_setting_t * omp_wait_policy = __kmp_stg_find( "OMP_WAIT_POLICY" ); // 2nd priority.
4847 
4848  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4849  static kmp_setting_t * volatile rivals[ 3 ];
4850  static kmp_stg_wp_data_t kmp_data = { 0, (kmp_setting_t **)rivals };
4851  static kmp_stg_wp_data_t omp_data = { 1, (kmp_setting_t **)rivals };
4852  int i = 0;
4853 
4854  rivals[ i ++ ] = kmp_library;
4855  if ( omp_wait_policy != NULL ) {
4856  rivals[ i ++ ] = omp_wait_policy;
4857  }; // if
4858  rivals[ i ++ ] = NULL;
4859 
4860  kmp_library->data = & kmp_data;
4861  if ( omp_wait_policy != NULL ) {
4862  omp_wait_policy->data = & omp_data;
4863  }; // if
4864 
4865  }
4866 
4867  { // Initialize KMP_ALL_THREADS, KMP_MAX_THREADS, and OMP_THREAD_LIMIT data.
4868 
4869  kmp_setting_t * kmp_all_threads = __kmp_stg_find( "KMP_ALL_THREADS" ); // 1st priority.
4870  kmp_setting_t * kmp_max_threads = __kmp_stg_find( "KMP_MAX_THREADS" ); // 2nd priority.
4871  kmp_setting_t * omp_thread_limit = __kmp_stg_find( "OMP_THREAD_LIMIT" ); // 3rd priority.
4872 
4873  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4874  static kmp_setting_t * volatile rivals[ 4 ];
4875  int i = 0;
4876 
4877  rivals[ i ++ ] = kmp_all_threads;
4878  rivals[ i ++ ] = kmp_max_threads;
4879  if ( omp_thread_limit != NULL ) {
4880  rivals[ i ++ ] = omp_thread_limit;
4881  }; // if
4882  rivals[ i ++ ] = NULL;
4883 
4884  kmp_all_threads->data = (void*)& rivals;
4885  kmp_max_threads->data = (void*)& rivals;
4886  if ( omp_thread_limit != NULL ) {
4887  omp_thread_limit->data = (void*)& rivals;
4888  }; // if
4889 
4890  }
4891 
4892 #if KMP_AFFINITY_SUPPORTED
4893  { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
4894 
4895  kmp_setting_t * kmp_affinity = __kmp_stg_find( "KMP_AFFINITY" ); // 1st priority.
4896  KMP_DEBUG_ASSERT( kmp_affinity != NULL );
4897 
4898 # ifdef KMP_GOMP_COMPAT
4899  kmp_setting_t * gomp_cpu_affinity = __kmp_stg_find( "GOMP_CPU_AFFINITY" ); // 2nd priority.
4900  KMP_DEBUG_ASSERT( gomp_cpu_affinity != NULL );
4901 # endif
4902 
4903  kmp_setting_t * omp_proc_bind = __kmp_stg_find( "OMP_PROC_BIND" ); // 3rd priority.
4904  KMP_DEBUG_ASSERT( omp_proc_bind != NULL );
4905 
4906  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4907  static kmp_setting_t * volatile rivals[ 4 ];
4908  int i = 0;
4909 
4910  rivals[ i ++ ] = kmp_affinity;
4911 
4912 # ifdef KMP_GOMP_COMPAT
4913  rivals[ i ++ ] = gomp_cpu_affinity;
4914  gomp_cpu_affinity->data = (void*)& rivals;
4915 # endif
4916 
4917  rivals[ i ++ ] = omp_proc_bind;
4918  omp_proc_bind->data = (void*)& rivals;
4919  rivals[ i ++ ] = NULL;
4920 
4921 # if OMP_40_ENABLED
4922  static kmp_setting_t * volatile places_rivals[ 4 ];
4923  i = 0;
4924 
4925  kmp_setting_t * omp_places = __kmp_stg_find( "OMP_PLACES" ); // 3rd priority.
4926  KMP_DEBUG_ASSERT( omp_places != NULL );
4927 
4928  places_rivals[ i ++ ] = kmp_affinity;
4929 # ifdef KMP_GOMP_COMPAT
4930  places_rivals[ i ++ ] = gomp_cpu_affinity;
4931 # endif
4932  places_rivals[ i ++ ] = omp_places;
4933  omp_places->data = (void*)& places_rivals;
4934  places_rivals[ i ++ ] = NULL;
4935 # endif
4936  }
4937 #else
4938  // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
4939  // OMP_PLACES not supported yet.
4940 #endif // KMP_AFFINITY_SUPPORTED
4941 
4942  { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
4943 
4944  kmp_setting_t * kmp_force_red = __kmp_stg_find( "KMP_FORCE_REDUCTION" ); // 1st priority.
4945  kmp_setting_t * kmp_determ_red = __kmp_stg_find( "KMP_DETERMINISTIC_REDUCTION" ); // 2nd priority.
4946 
4947  // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
4948  static kmp_setting_t * volatile rivals[ 3 ];
4949  static kmp_stg_fr_data_t force_data = { 1, (kmp_setting_t **)rivals };
4950  static kmp_stg_fr_data_t determ_data = { 0, (kmp_setting_t **)rivals };
4951  int i = 0;
4952 
4953  rivals[ i ++ ] = kmp_force_red;
4954  if ( kmp_determ_red != NULL ) {
4955  rivals[ i ++ ] = kmp_determ_red;
4956  }; // if
4957  rivals[ i ++ ] = NULL;
4958 
4959  kmp_force_red->data = & force_data;
4960  if ( kmp_determ_red != NULL ) {
4961  kmp_determ_red->data = & determ_data;
4962  }; // if
4963  }
4964 
4965  initialized = 1;
4966 
4967  }; // if
4968 
4969  // Reset flags.
4970  int i;
4971  for ( i = 0; i < __kmp_stg_count; ++ i ) {
4972  __kmp_stg_table[ i ].set = 0;
4973  }; // for
4974 
4975 } // __kmp_stg_init
4976 
4977 
4978 static void
4979 __kmp_stg_parse(
4980  char const * name,
4981  char const * value
4982 ) {
4983 
4984  // On Windows* OS there are some nameless variables like "C:=C:\" (yeah, really nameless, they are
4985  // presented in environment block as "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
4986  if ( name[ 0 ] == 0 ) {
4987  return;
4988  }; // if
4989 
4990  if ( value != NULL ) {
4991  kmp_setting_t * setting = __kmp_stg_find( name );
4992  if ( setting != NULL ) {
4993  setting->parse( name, value, setting->data );
4994  setting->defined = 1;
4995  }; // if
4996  }; // if
4997 
4998 } // __kmp_stg_parse
4999 
5000 
5001 static int
5002 __kmp_stg_check_rivals( // 0 -- Ok, 1 -- errors found.
5003  char const * name, // Name of variable.
5004  char const * value, // Value of the variable.
5005  kmp_setting_t * * rivals // List of rival settings (the list must include current one).
5006 ) {
5007 
5008  if ( rivals == NULL ) {
5009  return 0;
5010  }
5011 
5012  // Loop thru higher priority settings (listed before current).
5013  int i = 0;
5014  for ( ; strcmp( rivals[ i ]->name, name ) != 0; i++ ) {
5015  KMP_DEBUG_ASSERT( rivals[ i ] != NULL );
5016 
5017 #if KMP_AFFINITY_SUPPORTED
5018  if ( rivals[ i ] == __kmp_affinity_notype ) {
5019  //
5020  // If KMP_AFFINITY is specified without a type name,
5021  // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
5022  //
5023  continue;
5024  }
5025 #endif
5026 
5027  if ( rivals[ i ]->set ) {
5028  KMP_WARNING( StgIgnored, name, rivals[ i ]->name );
5029  return 1;
5030  }; // if
5031  }; // while
5032 
5033  ++ i; // Skip current setting.
5034  return 0;
5035 
5036 }; // __kmp_stg_check_rivals
5037 
5038 
5039 
5040 static int
5041 __kmp_env_isDefined( char const * name ) {
5042  int rc = 0;
5043  kmp_setting_t * setting = __kmp_stg_find( name );
5044  if ( setting != NULL ) {
5045  rc = setting->set;
5046  }; // if
5047  return rc;
5048 }
5049 
5050 static int
5051 __kmp_env_toPrint( char const * name, int flag ) {
5052  int rc = 0;
5053  kmp_setting_t * setting = __kmp_stg_find( name );
5054  if ( setting != NULL ) {
5055  rc = setting->defined;
5056  if ( flag >= 0 ) {
5057  setting->defined = flag;
5058  }; // if
5059  }; // if
5060  return rc;
5061 }
5062 
5063 
5064 static void
5065 __kmp_aux_env_initialize( kmp_env_blk_t* block ) {
5066 
5067  char const * value;
5068 
5069  /* OMP_NUM_THREADS */
5070  value = __kmp_env_blk_var( block, "OMP_NUM_THREADS" );
5071  if ( value ) {
5072  ompc_set_num_threads( __kmp_dflt_team_nth );
5073  }
5074 
5075  /* KMP_BLOCKTIME */
5076  value = __kmp_env_blk_var( block, "KMP_BLOCKTIME" );
5077  if ( value ) {
5078  kmpc_set_blocktime( __kmp_dflt_blocktime );
5079  }
5080 
5081  /* OMP_NESTED */
5082  value = __kmp_env_blk_var( block, "OMP_NESTED" );
5083  if ( value ) {
5084  ompc_set_nested( __kmp_dflt_nested );
5085  }
5086 
5087  /* OMP_DYNAMIC */
5088  value = __kmp_env_blk_var( block, "OMP_DYNAMIC" );
5089  if ( value ) {
5090  ompc_set_dynamic( __kmp_global.g.g_dynamic );
5091  }
5092 
5093 }
5094 
5095 void
5096 __kmp_env_initialize( char const * string ) {
5097 
5098  kmp_env_blk_t block;
5099  int i;
5100 
5101  __kmp_stg_init();
5102 
5103  // Hack!!!
5104  if ( string == NULL ) {
5105  // __kmp_max_nth = __kmp_sys_max_nth;
5106  __kmp_threads_capacity = __kmp_initial_threads_capacity( __kmp_dflt_team_nth_ub );
5107  }; // if
5108  __kmp_env_blk_init( & block, string );
5109 
5110  //
5111  // update the set flag on all entries that have an env var
5112  //
5113  for ( i = 0; i < block.count; ++ i ) {
5114  if (( block.vars[ i ].name == NULL )
5115  || ( *block.vars[ i ].name == '\0')) {
5116  continue;
5117  }
5118  if ( block.vars[ i ].value == NULL ) {
5119  continue;
5120  }
5121  kmp_setting_t * setting = __kmp_stg_find( block.vars[ i ].name );
5122  if ( setting != NULL ) {
5123  setting->set = 1;
5124  }
5125  }; // for i
5126 
5127  // Special case. If we parse environment, not a string, process KMP_WARNINGS first.
5128  if ( string == NULL ) {
5129  char const * name = "KMP_WARNINGS";
5130  char const * value = __kmp_env_blk_var( & block, name );
5131  __kmp_stg_parse( name, value );
5132  }; // if
5133 
5134 #if KMP_AFFINITY_SUPPORTED
5135  //
5136  // Special case. KMP_AFFINITY is not a rival to other affinity env vars
5137  // if no affinity type is specified. We want to allow
5138  // KMP_AFFINITY=[no],verbose/[no]warnings/etc. to be enabled when
5139  // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
5140  // affinity mechanism.
5141  //
5142  __kmp_affinity_notype = NULL;
5143  char const *aff_str = __kmp_env_blk_var( & block, "KMP_AFFINITY" );
5144  if ( aff_str != NULL ) {
5145  //
5146  // Check if the KMP_AFFINITY type is specified in the string.
5147  // We just search the string for "compact", "scatter", etc.
5148  // without really parsing the string. The syntax of the
5149  // KMP_AFFINITY env var is such that none of the affinity
5150  // type names can appear anywhere other that the type
5151  // specifier, even as substrings.
5152  //
5153  // I can't find a case-insensitive version of strstr on Windows* OS.
5154  // Use the case-sensitive version for now.
5155  //
5156 
5157 # if KMP_OS_WINDOWS
5158 # define FIND strstr
5159 # else
5160 # define FIND strcasestr
5161 # endif
5162 
5163  if ( ( FIND( aff_str, "none" ) == NULL )
5164  && ( FIND( aff_str, "physical" ) == NULL )
5165  && ( FIND( aff_str, "logical" ) == NULL )
5166  && ( FIND( aff_str, "compact" ) == NULL )
5167  && ( FIND( aff_str, "scatter" ) == NULL )
5168  && ( FIND( aff_str, "explicit" ) == NULL )
5169  && ( FIND( aff_str, "balanced" ) == NULL )
5170  && ( FIND( aff_str, "disabled" ) == NULL ) ) {
5171  __kmp_affinity_notype = __kmp_stg_find( "KMP_AFFINITY" );
5172  }
5173  else {
5174  //
5175  // A new affinity type is specified.
5176  // Reset the affinity flags to their default values,
5177  // in case this is called from kmp_set_defaults().
5178  //
5179  __kmp_affinity_type = affinity_default;
5180  __kmp_affinity_gran = affinity_gran_default;
5181  __kmp_affinity_top_method = affinity_top_method_default;
5182  __kmp_affinity_respect_mask = affinity_respect_mask_default;
5183  }
5184 # undef FIND
5185 
5186 #if OMP_40_ENABLED
5187  //
5188  // Also reset the affinity flags if OMP_PROC_BIND is specified.
5189  //
5190  aff_str = __kmp_env_blk_var( & block, "OMP_PROC_BIND" );
5191  if ( aff_str != NULL ) {
5192  __kmp_affinity_type = affinity_default;
5193  __kmp_affinity_gran = affinity_gran_default;
5194  __kmp_affinity_top_method = affinity_top_method_default;
5195  __kmp_affinity_respect_mask = affinity_respect_mask_default;
5196  }
5197 #endif /* OMP_40_ENABLED */
5198  }
5199 
5200 #endif /* KMP_AFFINITY_SUPPORTED */
5201 
5202 #if OMP_40_ENABLED
5203  //
5204  // Set up the nested proc bind type vector.
5205  //
5206  if ( __kmp_nested_proc_bind.bind_types == NULL ) {
5207  __kmp_nested_proc_bind.bind_types = (kmp_proc_bind_t *)
5208  KMP_INTERNAL_MALLOC( sizeof(kmp_proc_bind_t) );
5209  if ( __kmp_nested_proc_bind.bind_types == NULL ) {
5210  KMP_FATAL( MemoryAllocFailed );
5211  }
5212  __kmp_nested_proc_bind.size = 1;
5213  __kmp_nested_proc_bind.used = 1;
5214 # if KMP_AFFINITY_SUPPORTED
5215  __kmp_nested_proc_bind.bind_types[0] = proc_bind_default;
5216 # else
5217  // default proc bind is false if affinity not supported
5218  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5219 # endif
5220 
5221  }
5222 #endif /* OMP_40_ENABLED */
5223 
5224  //
5225  // Now process all of the settings.
5226  //
5227  for ( i = 0; i < block.count; ++ i ) {
5228  __kmp_stg_parse( block.vars[ i ].name, block.vars[ i ].value );
5229  }; // for i
5230 
5231  //
5232  // If user locks have been allocated yet, don't reset the lock vptr table.
5233  //
5234  if ( ! __kmp_init_user_locks ) {
5235  if ( __kmp_user_lock_kind == lk_default ) {
5236  __kmp_user_lock_kind = lk_queuing;
5237  }
5238 #if KMP_USE_DYNAMIC_LOCK
5239  __kmp_init_dynamic_user_locks();
5240 #else
5241  __kmp_set_user_lock_vptrs( __kmp_user_lock_kind );
5242 #endif
5243  }
5244  else {
5245  KMP_DEBUG_ASSERT( string != NULL); // kmp_set_defaults() was called
5246  KMP_DEBUG_ASSERT( __kmp_user_lock_kind != lk_default );
5247  // Binds lock functions again to follow the transition between different
5248  // KMP_CONSISTENCY_CHECK values. Calling this again is harmless as long
5249  // as we do not allow lock kind changes after making a call to any
5250  // user lock functions (true).
5251 #if KMP_USE_DYNAMIC_LOCK
5252  __kmp_init_dynamic_user_locks();
5253 #else
5254  __kmp_set_user_lock_vptrs( __kmp_user_lock_kind );
5255 #endif
5256  }
5257 
5258 #if KMP_AFFINITY_SUPPORTED
5259 
5260  if ( ! TCR_4(__kmp_init_middle) ) {
5261  //
5262  // Determine if the machine/OS is actually capable of supporting
5263  // affinity.
5264  //
5265  const char *var = "KMP_AFFINITY";
5266  if ( __kmp_affinity_type == affinity_disabled ) {
5267  KMP_AFFINITY_DISABLE();
5268  }
5269  else if ( ! KMP_AFFINITY_CAPABLE() ) {
5270  __kmp_affinity_determine_capable( var );
5271  if ( ! KMP_AFFINITY_CAPABLE() ) {
5272  if ( __kmp_affinity_verbose || ( __kmp_affinity_warnings
5273  && ( __kmp_affinity_type != affinity_default )
5274  && ( __kmp_affinity_type != affinity_none )
5275  && ( __kmp_affinity_type != affinity_disabled ) ) ) {
5276  KMP_WARNING( AffNotSupported, var );
5277  }
5278  __kmp_affinity_type = affinity_disabled;
5279  __kmp_affinity_respect_mask = 0;
5280  __kmp_affinity_gran = affinity_gran_fine;
5281  }
5282  }
5283 
5284 # if OMP_40_ENABLED
5285  if ( __kmp_affinity_type == affinity_disabled ) {
5286  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5287  }
5288  else if ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_true ) {
5289  //
5290  // OMP_PROC_BIND=true maps to OMP_PROC_BIND=spread.
5291  //
5292  __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread;
5293  }
5294 # endif /* OMP_40_ENABLED */
5295 
5296  if ( KMP_AFFINITY_CAPABLE() ) {
5297 
5298 # if KMP_GROUP_AFFINITY
5299 
5300  //
5301  // Handle the Win 64 group affinity stuff if there are multiple
5302  // processor groups, or if the user requested it, and OMP 4.0
5303  // affinity is not in effect.
5304  //
5305  if ( ( ( __kmp_num_proc_groups > 1 )
5306  && ( __kmp_affinity_type == affinity_default )
5307 # if OMP_40_ENABLED
5308  && ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_default ) )
5309 # endif
5310  || ( __kmp_affinity_top_method == affinity_top_method_group ) ) {
5311  if ( __kmp_affinity_respect_mask == affinity_respect_mask_default ) {
5312  __kmp_affinity_respect_mask = FALSE;
5313  }
5314  if ( __kmp_affinity_type == affinity_default ) {
5315  __kmp_affinity_type = affinity_compact;
5316 # if OMP_40_ENABLED
5317  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5318 # endif
5319  }
5320  if ( __kmp_affinity_top_method == affinity_top_method_default ) {
5321  if ( __kmp_affinity_gran == affinity_gran_default ) {
5322  __kmp_affinity_top_method = affinity_top_method_group;
5323  __kmp_affinity_gran = affinity_gran_group;
5324  }
5325  else if ( __kmp_affinity_gran == affinity_gran_group ) {
5326  __kmp_affinity_top_method = affinity_top_method_group;
5327  }
5328  else {
5329  __kmp_affinity_top_method = affinity_top_method_all;
5330  }
5331  }
5332  else if ( __kmp_affinity_top_method == affinity_top_method_group ) {
5333  if ( __kmp_affinity_gran == affinity_gran_default ) {
5334  __kmp_affinity_gran = affinity_gran_group;
5335  }
5336  else if ( ( __kmp_affinity_gran != affinity_gran_group )
5337  && ( __kmp_affinity_gran != affinity_gran_fine )
5338  && ( __kmp_affinity_gran != affinity_gran_thread ) ) {
5339  char *str = NULL;
5340  switch ( __kmp_affinity_gran ) {
5341  case affinity_gran_core: str = "core"; break;
5342  case affinity_gran_package: str = "package"; break;
5343  case affinity_gran_node: str = "node"; break;
5344  default: KMP_DEBUG_ASSERT( 0 );
5345  }
5346  KMP_WARNING( AffGranTopGroup, var, str );
5347  __kmp_affinity_gran = affinity_gran_fine;
5348  }
5349  }
5350  else {
5351  if ( __kmp_affinity_gran == affinity_gran_default ) {
5352  __kmp_affinity_gran = affinity_gran_core;
5353  }
5354  else if ( __kmp_affinity_gran == affinity_gran_group ) {
5355  char *str = NULL;
5356  switch ( __kmp_affinity_type ) {
5357  case affinity_physical: str = "physical"; break;
5358  case affinity_logical: str = "logical"; break;
5359  case affinity_compact: str = "compact"; break;
5360  case affinity_scatter: str = "scatter"; break;
5361  case affinity_explicit: str = "explicit"; break;
5362  // No MIC on windows, so no affinity_balanced case
5363  default: KMP_DEBUG_ASSERT( 0 );
5364  }
5365  KMP_WARNING( AffGranGroupType, var, str );
5366  __kmp_affinity_gran = affinity_gran_core;
5367  }
5368  }
5369  }
5370  else
5371 
5372 # endif /* KMP_GROUP_AFFINITY */
5373 
5374  {
5375  if ( __kmp_affinity_respect_mask == affinity_respect_mask_default ) {
5376 # if KMP_GROUP_AFFINITY
5377  if ( __kmp_num_proc_groups > 1 ) {
5378  __kmp_affinity_respect_mask = FALSE;
5379  }
5380  else
5381 # endif /* KMP_GROUP_AFFINITY */
5382  {
5383  __kmp_affinity_respect_mask = TRUE;
5384  }
5385  }
5386 # if OMP_40_ENABLED
5387  if ( ( __kmp_nested_proc_bind.bind_types[0] != proc_bind_intel )
5388  && ( __kmp_nested_proc_bind.bind_types[0] != proc_bind_default ) ) {
5389  if ( __kmp_affinity_type == affinity_default ) {
5390  __kmp_affinity_type = affinity_compact;
5391  __kmp_affinity_dups = FALSE;
5392  }
5393  }
5394  else
5395 # endif /* OMP_40_ENABLED */
5396  if ( __kmp_affinity_type == affinity_default ) {
5397 #if OMP_40_ENABLED
5398 #if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
5399  if( __kmp_mic_type != non_mic ) {
5400  __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
5401  } else
5402 #endif
5403  {
5404  __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
5405  }
5406 #endif /* OMP_40_ENABLED */
5407 #if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
5408  if( __kmp_mic_type != non_mic ) {
5409  __kmp_affinity_type = affinity_scatter;
5410  } else
5411 #endif
5412  {
5413  __kmp_affinity_type = affinity_none;
5414  }
5415 
5416  }
5417  if ( ( __kmp_affinity_gran == affinity_gran_default )
5418  && ( __kmp_affinity_gran_levels < 0 ) ) {
5419 #if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
5420  if( __kmp_mic_type != non_mic ) {
5421  __kmp_affinity_gran = affinity_gran_fine;
5422  } else
5423 #endif
5424  {
5425  __kmp_affinity_gran = affinity_gran_core;
5426  }
5427  }
5428  if ( __kmp_affinity_top_method == affinity_top_method_default ) {
5429  __kmp_affinity_top_method = affinity_top_method_all;
5430  }
5431  }
5432  }
5433 
5434  K_DIAG( 1, ( "__kmp_affinity_type == %d\n", __kmp_affinity_type ) );
5435  K_DIAG( 1, ( "__kmp_affinity_compact == %d\n", __kmp_affinity_compact ) );
5436  K_DIAG( 1, ( "__kmp_affinity_offset == %d\n", __kmp_affinity_offset ) );
5437  K_DIAG( 1, ( "__kmp_affinity_verbose == %d\n", __kmp_affinity_verbose ) );
5438  K_DIAG( 1, ( "__kmp_affinity_warnings == %d\n", __kmp_affinity_warnings ) );
5439  K_DIAG( 1, ( "__kmp_affinity_respect_mask == %d\n", __kmp_affinity_respect_mask ) );
5440  K_DIAG( 1, ( "__kmp_affinity_gran == %d\n", __kmp_affinity_gran ) );
5441 
5442  KMP_DEBUG_ASSERT( __kmp_affinity_type != affinity_default);
5443 # if OMP_40_ENABLED
5444  KMP_DEBUG_ASSERT( __kmp_nested_proc_bind.bind_types[0] != proc_bind_default );
5445 # endif
5446  }
5447 
5448 #endif /* KMP_AFFINITY_SUPPORTED */
5449 
5450  if ( __kmp_version ) {
5451  __kmp_print_version_1();
5452  }; // if
5453 
5454  // Post-initialization step: some env. vars need their value's further processing
5455  if ( string != NULL) { // kmp_set_defaults() was called
5456  __kmp_aux_env_initialize( &block );
5457  }
5458 
5459  __kmp_env_blk_free( & block );
5460 
5461  KMP_MB();
5462 
5463 } // __kmp_env_initialize
5464 
5465 
5466 void
5467 __kmp_env_print() {
5468 
5469  kmp_env_blk_t block;
5470  int i;
5471  kmp_str_buf_t buffer;
5472 
5473  __kmp_stg_init();
5474  __kmp_str_buf_init( & buffer );
5475 
5476  __kmp_env_blk_init( & block, NULL );
5477  __kmp_env_blk_sort( & block );
5478 
5479  // Print real environment values.
5480  __kmp_str_buf_print( & buffer, "\n%s\n\n", KMP_I18N_STR( UserSettings ) );
5481  for ( i = 0; i < block.count; ++ i ) {
5482  char const * name = block.vars[ i ].name;
5483  char const * value = block.vars[ i ].value;
5484  if (
5485  ( KMP_STRLEN( name ) > 4 && strncmp( name, "KMP_", 4 ) == 0 )
5486  || strncmp( name, "OMP_", 4 ) == 0
5487  #ifdef KMP_GOMP_COMPAT
5488  || strncmp( name, "GOMP_", 5 ) == 0
5489  #endif // KMP_GOMP_COMPAT
5490  ) {
5491  __kmp_str_buf_print( & buffer, " %s=%s\n", name, value );
5492  }; // if
5493  }; // for
5494  __kmp_str_buf_print( & buffer, "\n" );
5495 
5496  // Print internal (effective) settings.
5497  __kmp_str_buf_print( & buffer, "%s\n\n", KMP_I18N_STR( EffectiveSettings ) );
5498  for ( int i = 0; i < __kmp_stg_count; ++ i ) {
5499  if ( __kmp_stg_table[ i ].print != NULL ) {
5500  __kmp_stg_table[ i ].print( & buffer, __kmp_stg_table[ i ].name, __kmp_stg_table[ i ].data );
5501  }; // if
5502  }; // for
5503 
5504  __kmp_printf( "%s", buffer.str );
5505 
5506  __kmp_env_blk_free( & block );
5507  __kmp_str_buf_free( & buffer );
5508 
5509  __kmp_printf("\n");
5510 
5511 } // __kmp_env_print
5512 
5513 
5514 #if OMP_40_ENABLED
5515 void
5516 __kmp_env_print_2() {
5517 
5518  kmp_env_blk_t block;
5519  int i;
5520  kmp_str_buf_t buffer;
5521 
5522  __kmp_env_format = 1;
5523 
5524  __kmp_stg_init();
5525  __kmp_str_buf_init( & buffer );
5526 
5527  __kmp_env_blk_init( & block, NULL );
5528  __kmp_env_blk_sort( & block );
5529 
5530  __kmp_str_buf_print( & buffer, "\n%s\n", KMP_I18N_STR( DisplayEnvBegin ) );
5531  __kmp_str_buf_print( & buffer, " _OPENMP='%d'\n", __kmp_openmp_version );
5532 
5533  for ( int i = 0; i < __kmp_stg_count; ++ i ) {
5534  if ( __kmp_stg_table[ i ].print != NULL &&
5535  ( ( __kmp_display_env && strncmp( __kmp_stg_table[ i ].name, "OMP_", 4 ) == 0 ) || __kmp_display_env_verbose ) ) {
5536  __kmp_stg_table[ i ].print( & buffer, __kmp_stg_table[ i ].name, __kmp_stg_table[ i ].data );
5537  }; // if
5538  }; // for
5539 
5540  __kmp_str_buf_print( & buffer, "%s\n", KMP_I18N_STR( DisplayEnvEnd ) );
5541  __kmp_str_buf_print( & buffer, "\n" );
5542 
5543  __kmp_printf( "%s", buffer.str );
5544 
5545  __kmp_env_blk_free( & block );
5546  __kmp_str_buf_free( & buffer );
5547 
5548  __kmp_printf("\n");
5549 
5550 } // __kmp_env_print_2
5551 #endif // OMP_40_ENABLED
5552 
5553 
5554 
5555 // end of file
5556