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