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