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