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