kmp_settings.c

Go to the documentation of this file.
00001 /*
00002  * kmp_settings.c -- Initialize environment variables
00003  * $Revision: 42272 $
00004  * $Date: 2013-04-11 16:03:15 -0500 (Thu, 11 Apr 2013) $
00005  */
00006 
00007 /* <copyright>
00008     Copyright (c) 1997-2013 Intel Corporation.  All Rights Reserved.
00009 
00010     Redistribution and use in source and binary forms, with or without
00011     modification, are permitted provided that the following conditions
00012     are met:
00013 
00014       * Redistributions of source code must retain the above copyright
00015         notice, this list of conditions and the following disclaimer.
00016       * Redistributions in binary form must reproduce the above copyright
00017         notice, this list of conditions and the following disclaimer in the
00018         documentation and/or other materials provided with the distribution.
00019       * Neither the name of Intel Corporation nor the names of its
00020         contributors may be used to endorse or promote products derived
00021         from this software without specific prior written permission.
00022 
00023     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026     A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027     HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029     LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 
00035 
00036 ------------------------------------------------------------------------
00037 
00038     Portions of this software are protected under the following patents:
00039         U.S. Patent 5,812,852
00040         U.S. Patent 6,792,599
00041         U.S. Patent 7,069,556
00042         U.S. Patent 7,328,433
00043         U.S. Patent 7,500,242
00044 
00045 </copyright> */
00046 
00047 #include "kmp.h"
00048 #include "kmp_wrapper_getpid.h"
00049 #include "kmp_environment.h"
00050 #include "kmp_atomic.h"
00051 #include "kmp_str.h"
00052 #include "kmp_settings.h"
00053 #include "kmp_i18n.h"
00054 #include "kmp_io.h"
00055 
00056 
00057 #define KMP_MAX( x, y ) ( (x) > (y) ? (x) : (y) )
00058 #define KMP_MIN( x, y ) ( (x) < (y) ? (x) : (y) )
00059 
00060 static int __kmp_env_isDefined( char const * name );
00061 static int __kmp_env_toPrint( char const * name, int flag );
00062 
00063 // -------------------------------------------------------------------------------------------------
00064 // Helper string functions. Subject to move to kmp_str.
00065 // -------------------------------------------------------------------------------------------------
00066 
00067 static double
00068 __kmp_convert_to_double( char const * s )
00069 {
00070     double result;
00071 
00072     if ( sscanf( s, "%lf", &result ) < 1 ) {
00073         result = 0.0;
00074     }
00075 
00076     return result;
00077 }
00078 
00079 static int
00080 __kmp_readstr_with_sentinel(char *dest, char const * src, size_t len, char sentinel) {
00081     int i;
00082     for (i = 0; i < len; i++) {
00083         if ((*src == '\0') || (*src == sentinel)) {
00084             break;
00085         }
00086         *(dest++) = *(src++);
00087     }
00088     *dest = '\0';
00089     return i;
00090 }
00091 
00092 static int
00093 __kmp_match_with_sentinel( char const * a, char const * b, size_t len, char sentinel ) {
00094     size_t l = 0;
00095 
00096     if(a == NULL)
00097         a = "";
00098     if(b == NULL)
00099         b = "";
00100     while(*a && *b && *b != sentinel) {
00101         char ca = *a, cb = *b;
00102 
00103         if(ca >= 'a' && ca <= 'z')
00104             ca -= 'a' - 'A';
00105         if(cb >= 'a' && cb <= 'z')
00106             cb -= 'a' - 'A';
00107         if(ca != cb)
00108             return FALSE;
00109         ++l;
00110         ++a;
00111         ++b;
00112     }
00113     return l >= len;
00114 }
00115 
00116 //
00117 // Expected usage:
00118 //     token is the token to check for.
00119 //     buf is the string being parsed.
00120 //     *end returns the char after the end of the token.
00121 //        it is not modified unless a match occurs.
00122 //
00123 //
00124 // Example 1:
00125 //
00126 //     if (__kmp_match_str("token", buf, *end) {
00127 //         <do something>
00128 //         buf = end;
00129 //     }
00130 //
00131 //  Example 2:
00132 //
00133 //     if (__kmp_match_str("token", buf, *end) {
00134 //         char *save = **end;
00135 //         **end = sentinel;
00136 //         <use any of the __kmp*_with_sentinel() functions>
00137 //         **end = save;
00138 //         buf = end;
00139 //     }
00140 //
00141 
00142 static int
00143 __kmp_match_str( char const *token, char const *buf, const char **end) {
00144 
00145     KMP_ASSERT(token != NULL);
00146     KMP_ASSERT(buf != NULL);
00147     KMP_ASSERT(end != NULL);
00148 
00149     while (*token && *buf) {
00150         char ct = *token, cb = *buf;
00151 
00152         if(ct >= 'a' && ct <= 'z')
00153             ct -= 'a' - 'A';
00154         if(cb >= 'a' && cb <= 'z')
00155             cb -= 'a' - 'A';
00156         if (ct != cb)
00157             return FALSE;
00158         ++token;
00159         ++buf;
00160     }
00161     if (*token) {
00162         return FALSE;
00163     }
00164     *end = buf;
00165     return TRUE;
00166 }
00167 
00168 static char *
00169 __kmp_strip_quotes( char *target, int len) {
00170     char *end = target + len - 1;
00171 
00172     while(*target == '"' || *target == '\'') {
00173         if(end <= target || (*end != '"' && *end != '\''))
00174             return NULL;
00175         *end = 0;
00176         --end;
00177         *target = 0;
00178         ++target;
00179     }
00180     return target;
00181 }
00182 
00183 
00184 static size_t
00185 __kmp_round4k( size_t size ) {
00186     size_t _4k = 4 * 1024;
00187     if ( size & ( _4k - 1 ) ) {
00188         size &= ~ ( _4k - 1 );
00189         if ( size <= KMP_SIZE_T_MAX - _4k ) {
00190             size += _4k;    // Round up if there is no overflow.
00191         }; // if
00192     }; // if
00193     return size;
00194 } // __kmp_round4k
00195 
00196 
00197 static int
00198 __kmp_convert_to_seconds( char const * data )
00199 {
00200     int nvalues, value, factor;
00201     char mult, extra;
00202 
00203     if (data == NULL) return (0);
00204     value = 0;
00205     mult = '\0';
00206     nvalues = sscanf (data, "%d%c%c", &value, &mult, &extra);
00207     if (nvalues < 1) return (0);
00208     if (nvalues == 1) mult = '\0';
00209     if (nvalues == 3) return (-1);
00210 
00211     switch (mult) {
00212     case 's': case 'S':
00213         factor = 1;
00214         break;
00215     case '\0':
00216         factor = 60;
00217         break;
00218     case 'm': case 'M':
00219         factor = 60;
00220         break;
00221     case 'h': case 'H':
00222         factor = 60 * 60;
00223         break;
00224     case 'd': case 'D':
00225         factor = 24 * 60 * 60;
00226         break;
00227     default:
00228         return (-1);
00229     }
00230 
00231     if (value > (INT_MAX / factor))
00232         value = INT_MAX;
00233     else
00234         value *= factor;
00235 
00236     return value;
00237 }
00238 
00239 /*
00240     Here, multipliers are like __kmp_convert_to_seconds, but floating-point
00241     values are allowed, and the return value is in milliseconds.  The default
00242     multiplier is milliseconds.  Returns INT_MAX only if the value specified
00243     matches "infinit*".  Returns -1 if specified string is invalid.
00244 */
00245 int
00246 __kmp_convert_to_milliseconds( char const * data )
00247 {
00248     int ret, nvalues, factor;
00249     char mult, extra;
00250     double value;
00251 
00252     if (data == NULL) return (-1);
00253     if ( __kmp_str_match( "infinit", -1, data)) return (INT_MAX);
00254     value = (double) 0.0;
00255     mult = '\0';
00256     nvalues = sscanf (data, "%lf%c%c", &value, &mult, &extra);
00257     if (nvalues < 1) return (-1);
00258     if (nvalues == 1) mult = '\0';
00259     if (nvalues == 3) return (-1);
00260 
00261     if (value < 0)    return (-1);
00262 
00263     switch (mult) {
00264     case '\0':
00265         /*  default is milliseconds  */
00266         factor = 1;
00267         break;
00268     case 's': case 'S':
00269         factor = 1000;
00270         break;
00271     case 'm': case 'M':
00272         factor = 1000 * 60;
00273         break;
00274     case 'h': case 'H':
00275         factor = 1000 * 60 * 60;
00276         break;
00277     case 'd': case 'D':
00278         factor = 1000 * 24 * 60 * 60;
00279         break;
00280     default:
00281         return (-1);
00282     }
00283 
00284     if ( value >= ( (INT_MAX-1) / factor) )
00285         ret = INT_MAX-1;        /* Don't allow infinite value here */
00286     else
00287         ret = (int) (value * (double) factor);  /* truncate to int  */
00288 
00289     return ret;
00290 }
00291 
00292 static kmp_uint64
00293 __kmp_convert_to_nanoseconds(         // R: Time in nanoseconds, or ~0 in case of error.
00294     char const * str                  // I: String representing time.
00295 ) {
00296 
00297     double     value;    // Parsed value.
00298     char       unit;     // Unit: 's', 'm', 'u', or 'n'.
00299     char       extra;    // Buffer for extra character (if any).
00300     int        rc;       // Return code of sscanf().
00301     double     factor;   // Numeric factor corresponding to unit.
00302     kmp_uint64 result;
00303 
00304     if ( str == NULL || str[ 0 ] == 0 ) {    // No string or empty string.
00305         return 0;                            // Default value.
00306     }; // if
00307     rc = sscanf( str, "%lf%c%c", &value, &unit, &extra );
00308     switch ( rc ) {
00309         case 0: {             // Value is not parsed.
00310             return ~ 0;
00311         } break;
00312         case 1: {             // One value parsed, no unit is specified.
00313             unit = 's';       // Use default unit.
00314         } break;
00315         case 2: {             // Value and unit are parsed.
00316             // Do nothing.
00317         } break;
00318         case 3: {             // Extra characters is specified.
00319             return ~ 0;
00320         } break;
00321     }; // switch
00322     switch ( unit ) {
00323         case 's': {
00324             factor = 1.0E+9;
00325         } break;
00326         case 'm': {
00327             factor = 1.0E+6;
00328         } break;
00329         case 'u': {
00330             factor = 1.0E+3;
00331         } break;
00332         case 'n': {
00333             factor = 1.0;
00334         } break;
00335         default: {                           // Illegal unit.
00336             return ~ 0;                      // Return error.
00337         } break;
00338     }; // switch
00339     result = (kmp_uint64)( value * factor );
00340     return result;
00341 
00342 }; // func __kmp_convert_to_nanoseconds
00343 
00344 
00345 static int
00346 __kmp_strcasecmp_with_sentinel( char const * a, char const * b, char sentinel ) {
00347     if(a == NULL)
00348         a = "";
00349     if(b == NULL)
00350         b = "";
00351     while(*a && *b && *b != sentinel) {
00352         char ca = *a, cb = *b;
00353 
00354         if(ca >= 'a' && ca <= 'z')
00355             ca -= 'a' - 'A';
00356         if(cb >= 'a' && cb <= 'z')
00357             cb -= 'a' - 'A';
00358         if(ca != cb)
00359             return (int)(unsigned char)*a - (int)(unsigned char)*b;
00360         ++a;
00361         ++b;
00362     }
00363     return *a ?
00364         (*b && *b != sentinel) ? (int)(unsigned char)*a - (int)(unsigned char)*b : 1 :
00365         (*b && *b != sentinel) ? -1 : 0;
00366 }
00367 
00368 
00369 // =================================================================================================
00370 // Table structures and helper functions.
00371 // =================================================================================================
00372 
00373 typedef struct __kmp_setting        kmp_setting_t;
00374 typedef struct __kmp_stg_ss_data    kmp_stg_ss_data_t;
00375 typedef struct __kmp_stg_wp_data    kmp_stg_wp_data_t;
00376 typedef struct __kmp_stg_fr_data    kmp_stg_fr_data_t;
00377 
00378 typedef void ( * kmp_stg_parse_func_t )( char const * name, char const * value, void * data );
00379 typedef void ( * kmp_stg_print_func_t )( kmp_str_buf_t * buffer, char const * name, void * data );
00380 
00381 struct __kmp_setting {
00382     char const *         name;        // Name of setting (environment variable).
00383     kmp_stg_parse_func_t parse;       // Parser function.
00384     kmp_stg_print_func_t print;       // Print function.
00385     void *               data;        // Data passed to parser and printer.
00386     int                  set;         // Variable set during this "session"
00387                                       //     (__kmp_env_initialize() or kmp_set_defaults() call).
00388     int                  defined;     // Variable set in any "session".
00389 }; // struct __kmp_setting
00390 
00391 struct __kmp_stg_ss_data {
00392     size_t             factor;  // Default factor: 1 for KMP_STACKSIZE, 1024 for others.
00393     kmp_setting_t * *  rivals;  // Array of pointers to rivals (including itself).
00394 }; // struct __kmp_stg_ss_data
00395 
00396 struct __kmp_stg_wp_data {
00397     int                omp;     // 0 -- KMP_LIBRARY, 1 -- OMP_WAIT_POLICY.
00398     kmp_setting_t * *  rivals;  // Array of pointers to rivals (including itself).
00399 }; // struct __kmp_stg_wp_data
00400 
00401 struct __kmp_stg_fr_data {
00402     int                force;  // 0 -- KMP_DETERMINISTIC_REDUCTION, 1 -- KMP_FORCE_REDUCTION.
00403     kmp_setting_t * *  rivals;  // Array of pointers to rivals (including itself).
00404 }; // struct __kmp_stg_fr_data
00405 
00406 static int
00407 __kmp_stg_check_rivals(          // 0 -- Ok, 1 -- errors found.
00408     char const *       name,     // Name of variable.
00409     char const *       value,    // Value of the variable.
00410     kmp_setting_t * *  rivals    // List of rival settings (the list must include current one).
00411 );
00412 
00413 
00414 // -------------------------------------------------------------------------------------------------
00415 // Helper parse functions.
00416 // -------------------------------------------------------------------------------------------------
00417 
00418 static void
00419 __kmp_stg_parse_bool(
00420     char const * name,
00421     char const * value,
00422     int *        out
00423 ) {
00424     if ( __kmp_str_match_true( value ) ) {
00425         * out = TRUE;
00426     } else if (__kmp_str_match_false( value ) ) {
00427         * out = FALSE;
00428     } else {
00429         __kmp_msg(
00430             kmp_ms_warning,
00431             KMP_MSG( BadBoolValue, name, value ),
00432             KMP_HNT( ValidBoolValues ),
00433             __kmp_msg_null
00434         );
00435     }; // if
00436 } // __kmp_stg_parse_bool
00437 
00438 static void
00439 __kmp_stg_parse_size(
00440     char const * name,
00441     char const * value,
00442     size_t       size_min,
00443     size_t       size_max,
00444     int *        is_specified,
00445     size_t *     out,
00446     size_t       factor
00447 ) {
00448     char const * msg = NULL;
00449     #if KMP_OS_DARWIN
00450         size_min = __kmp_round4k( size_min );
00451         size_max = __kmp_round4k( size_max );
00452     #endif // KMP_OS_DARWIN
00453     if ( value ) {
00454         if ( is_specified != NULL ) {
00455             * is_specified = 1;
00456         }; // if
00457         __kmp_str_to_size( value, out, factor, & msg );
00458         if ( msg == NULL ) {
00459             if ( * out > size_max ) {
00460                 * out = size_max;
00461                 msg = KMP_I18N_STR( ValueTooLarge );
00462             } else if ( * out < size_min ) {
00463                 * out = size_min;
00464                 msg = KMP_I18N_STR( ValueTooSmall );
00465             } else {
00466                 #if KMP_OS_DARWIN
00467                     size_t round4k = __kmp_round4k( * out );
00468                     if ( * out != round4k ) {
00469                         * out = round4k;
00470                         msg = KMP_I18N_STR( NotMultiple4K );
00471                     }; // if
00472                 #endif
00473             }; // if
00474         } else {
00475             // If integer overflow occured, * out == KMP_SIZE_T_MAX. Cut it to size_max silently.
00476             if ( * out < size_min ) {
00477                 * out = size_max;
00478             }
00479             else if ( * out >  size_max ) {
00480                 * out = size_max;
00481             }; // if
00482         }; // if
00483         if ( msg != NULL ) {
00484             // Message is not empty. Print warning.
00485             kmp_str_buf_t buf;
00486             __kmp_str_buf_init( & buf );
00487             __kmp_str_buf_print_size( & buf, * out );
00488             KMP_WARNING( ParseSizeIntWarn, name, value, msg );
00489             KMP_INFORM( Using_str_Value, name, buf.str );
00490             __kmp_str_buf_free( & buf );
00491         }; // if
00492     }; // if
00493 } // __kmp_stg_parse_size
00494 
00495 static void
00496 __kmp_stg_parse_str(
00497     char const *      name,
00498     char const *      value,
00499     char const * *    out
00500 ) {
00501     KMP_INTERNAL_FREE( (void *) * out );
00502     * out = __kmp_str_format( "%s", value );
00503 } // __kmp_stg_parse_str
00504 
00505 
00506 static void
00507 __kmp_stg_parse_int(
00508     char const * name,   // I: Name of environment variable (used in warning messages).
00509     char const * value,  // I: Value of environment variable to parse.
00510     int          min,    // I: Miminal allowed value.
00511     int          max,    // I: Maximum allowed value.
00512     int *        out     // O: Output (parsed) value.
00513 ) {
00514     char const * msg  = NULL;
00515     kmp_uint64   uint = * out;
00516     __kmp_str_to_uint( value, & uint, & msg );
00517     if ( msg == NULL ) {
00518         if ( uint < min ) {
00519             msg = KMP_I18N_STR( ValueTooSmall );
00520             uint = min;
00521         } else if ( uint > max ) {
00522             msg = KMP_I18N_STR( ValueTooLarge );
00523             uint = max;
00524         }; // if
00525     } else {
00526         // If overflow occured msg contains error message and uint is very big. Cut tmp it
00527         // to INT_MAX.
00528         if ( uint < min ) {
00529             uint = min;
00530         }
00531         else if ( uint > max ) {
00532             uint = max;
00533         }; // if
00534     }; // if
00535     if ( msg != NULL ) {
00536         // Message is not empty. Print warning.
00537         kmp_str_buf_t buf;
00538         KMP_WARNING( ParseSizeIntWarn, name, value, msg );
00539         __kmp_str_buf_init( & buf );
00540         __kmp_str_buf_print( &buf, "%" KMP_UINT64_SPEC "", uint );
00541         KMP_INFORM( Using_uint64_Value, name, buf.str );
00542         __kmp_str_buf_free( &buf );
00543     }; // if
00544     * out = uint;
00545 } // __kmp_stg_parse_int
00546 
00547 
00548 static void
00549 __kmp_stg_parse_file(
00550     char const * name,
00551     char const * value,
00552     char *       suffix,
00553     char * *     out
00554 ) {
00555     char buffer[256];
00556     char *t;
00557     int hasSuffix;
00558     KMP_INTERNAL_FREE( (void *) * out );
00559     t = (char *) strrchr(value, '.');
00560     hasSuffix = t && __kmp_str_eqf( t, suffix );
00561     t = __kmp_str_format( "%s%s", value, hasSuffix ? "" : suffix );
00562     __kmp_expand_file_name( buffer, sizeof(buffer), t);
00563     KMP_INTERNAL_FREE(t);
00564     * out = __kmp_str_format( "%s", buffer );
00565 } // __kmp_stg_parse_file
00566 
00567 static char * par_range_to_print = NULL;
00568 
00569 static void
00570 __kmp_stg_parse_par_range(
00571     char const * name,
00572     char const * value,
00573     int *        out_range,
00574     char *       out_routine,
00575     char *       out_file,
00576     int *        out_lb,
00577     int *        out_ub
00578 ) {
00579     size_t len = strlen( value + 1 );
00580     par_range_to_print = (char *) KMP_INTERNAL_MALLOC( len +1 );
00581     strncpy( par_range_to_print, value, len + 1);
00582     __kmp_par_range = +1;
00583     __kmp_par_range_lb = 0;
00584     __kmp_par_range_ub = INT_MAX;
00585     for (;;) {
00586         int len;
00587         if (( value == NULL ) || ( *value == '\0' )) {
00588             break;
00589         }
00590         if ( ! __kmp_strcasecmp_with_sentinel( "routine", value, '=' )) {
00591             value = strchr( value, '=' ) + 1;
00592             len = __kmp_readstr_with_sentinel( out_routine,
00593               value, KMP_PAR_RANGE_ROUTINE_LEN - 1, ',' );
00594             if ( len == 0 ) {
00595                 goto par_range_error;
00596             }
00597             value = strchr( value, ',' );
00598             if ( value != NULL ) {
00599                 value++;
00600             }
00601             continue;
00602         }
00603         if ( ! __kmp_strcasecmp_with_sentinel( "filename", value, '=' )) {
00604             value = strchr( value, '=' ) + 1;
00605             len = __kmp_readstr_with_sentinel( out_file,
00606               value, KMP_PAR_RANGE_FILENAME_LEN - 1, ',' );
00607             if ( len == 0) {
00608                 goto par_range_error;
00609             }
00610             value = strchr( value, ',' );
00611             if ( value != NULL ) {
00612                 value++;
00613             }
00614             continue;
00615         }
00616         if (( ! __kmp_strcasecmp_with_sentinel( "range", value, '=' ))
00617           || ( ! __kmp_strcasecmp_with_sentinel( "incl_range", value, '=' ))) {
00618             value = strchr( value, '=' ) + 1;
00619             if ( sscanf( value, "%d:%d", out_lb, out_ub ) != 2 ) {
00620                 goto par_range_error;
00621             }
00622             *out_range = +1;
00623             value = strchr( value, ',' );
00624             if ( value != NULL ) {
00625                 value++;
00626             }
00627             continue;
00628         }
00629         if ( ! __kmp_strcasecmp_with_sentinel( "excl_range", value, '=' )) {
00630             value = strchr( value, '=' ) + 1;
00631             if ( sscanf( value, "%d:%d", out_lb, out_ub) != 2 ) {
00632                 goto par_range_error;
00633             }
00634             *out_range = -1;
00635             value = strchr( value, ',' );
00636             if ( value != NULL ) {
00637                 value++;
00638             }
00639             continue;
00640         }
00641         par_range_error:
00642         KMP_WARNING( ParRangeSyntax, name );
00643         __kmp_par_range = 0;
00644         break;
00645     }
00646 } // __kmp_stg_parse_par_range
00647 
00648 
00649 int
00650 __kmp_initial_threads_capacity( int req_nproc )
00651 {
00652     int nth = 32;
00653 
00654     /* MIN( MAX( 32, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ), __kmp_max_nth) */
00655     if (nth < (4 * req_nproc))
00656         nth = (4 * req_nproc);
00657     if (nth < (4 * __kmp_xproc))
00658         nth = (4 * __kmp_xproc);
00659 
00660     if (nth > __kmp_max_nth)
00661         nth = __kmp_max_nth;
00662 
00663     return nth;
00664 }
00665 
00666 
00667 int
00668 __kmp_default_tp_capacity( int req_nproc, int max_nth, int all_threads_specified) {
00669     int nth = 128;
00670 
00671     if(all_threads_specified)
00672         return max_nth;
00673     /* MIN( MAX (128, 4 * $OMP_NUM_THREADS, 4 * omp_get_num_procs() ), __kmp_max_nth ) */
00674     if (nth < (4 * req_nproc))
00675         nth = (4 * req_nproc);
00676     if (nth < (4 * __kmp_xproc))
00677         nth = (4 * __kmp_xproc);
00678 
00679     if (nth > __kmp_max_nth)
00680         nth = __kmp_max_nth;
00681 
00682     return nth;
00683 }
00684 
00685 
00686 // -------------------------------------------------------------------------------------------------
00687 // Helper print functions.
00688 // -------------------------------------------------------------------------------------------------
00689 
00690 static void
00691 __kmp_stg_print_bool( kmp_str_buf_t * buffer, char const * name, int value ) {
00692     __kmp_str_buf_print( buffer, "   %s=%s\n", name, value ? "true" : "false" );
00693 } // __kmp_stg_print_bool
00694 
00695 static void
00696 __kmp_stg_print_int( kmp_str_buf_t * buffer, char const * name, int value ) {
00697     __kmp_str_buf_print( buffer, "   %s=%d\n", name, value );
00698 } // __kmp_stg_print_int
00699 
00700 static void
00701 __kmp_stg_print_uint64( kmp_str_buf_t * buffer, char const * name, kmp_uint64 value ) {
00702     __kmp_str_buf_print( buffer, "   %s=%" KMP_UINT64_SPEC "\n", name, value );
00703 } // __kmp_stg_print_uint64
00704 
00705 static void
00706 __kmp_stg_print_str( kmp_str_buf_t * buffer, char const * name, char const * value ) {
00707     __kmp_str_buf_print( buffer, "   %s=%s\n", name, value );
00708 } // __kmp_stg_print_str
00709 
00710 static void
00711 __kmp_stg_print_size( kmp_str_buf_t * buffer, char const * name, size_t value ) {
00712     __kmp_str_buf_print( buffer, "   %s=", name );
00713     __kmp_str_buf_print_size( buffer, value );
00714     __kmp_str_buf_print( buffer, "\n" );
00715 } // __kmp_stg_print_size
00716 
00717 
00718 // =================================================================================================
00719 // Parse and print functions.
00720 // =================================================================================================
00721 
00722 // -------------------------------------------------------------------------------------------------
00723 // KMP_ALL_THREADS, KMP_MAX_THREADS, OMP_THREAD_LIMIT
00724 // -------------------------------------------------------------------------------------------------
00725 
00726 static void
00727 __kmp_stg_parse_all_threads( char const * name, char const * value, void * data ) {
00728 
00729     kmp_setting_t * * rivals = (kmp_setting_t * *) data;
00730     int               rc;
00731     rc = __kmp_stg_check_rivals( name, value, rivals );
00732     if ( rc ) {
00733         return;
00734     }; // if
00735     if ( ! __kmp_strcasecmp_with_sentinel( "all", value, 0 ) ) {
00736         __kmp_max_nth = __kmp_xproc;
00737         __kmp_allThreadsSpecified = 1;
00738     } else {
00739         __kmp_stg_parse_int( name, value, 1, __kmp_sys_max_nth, & __kmp_max_nth );
00740         __kmp_allThreadsSpecified = 0;
00741     }
00742     K_DIAG( 1, ( "__kmp_max_nth == %d\n", __kmp_max_nth ) );
00743 
00744 } // __kmp_stg_parse_all_threads
00745 
00746 static void
00747 __kmp_stg_print_all_threads( kmp_str_buf_t * buffer, char const * name, void * data ) {
00748     __kmp_stg_print_int( buffer, name, __kmp_max_nth );
00749 } // __kmp_stg_print_all_threads
00750 
00751 // -------------------------------------------------------------------------------------------------
00752 // KMP_BLOCKTIME
00753 // -------------------------------------------------------------------------------------------------
00754 
00755 static void
00756 __kmp_stg_parse_blocktime( char const * name, char const * value, void * data ) {
00757     __kmp_dflt_blocktime = __kmp_convert_to_milliseconds( value );
00758     if ( __kmp_dflt_blocktime < 0 ) {
00759         __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME;
00760         __kmp_msg( kmp_ms_warning, KMP_MSG( InvalidValue, name, value ), __kmp_msg_null );
00761         KMP_INFORM( Using_int_Value, name, __kmp_dflt_blocktime );
00762         __kmp_env_blocktime = FALSE;  // Revert to default as if var not set.
00763     } else {
00764         if ( __kmp_dflt_blocktime < KMP_MIN_BLOCKTIME ) {
00765             __kmp_dflt_blocktime = KMP_MIN_BLOCKTIME;
00766             __kmp_msg( kmp_ms_warning, KMP_MSG( SmallValue, name, value ), __kmp_msg_null );
00767             KMP_INFORM( MinValueUsing, name, __kmp_dflt_blocktime );
00768         } else if ( __kmp_dflt_blocktime > KMP_MAX_BLOCKTIME ) {
00769             __kmp_dflt_blocktime = KMP_MAX_BLOCKTIME;
00770             __kmp_msg( kmp_ms_warning, KMP_MSG( LargeValue, name, value ), __kmp_msg_null );
00771             KMP_INFORM( MaxValueUsing, name, __kmp_dflt_blocktime );
00772         }; // if
00773         __kmp_env_blocktime = TRUE;    // KMP_BLOCKTIME was specified.
00774     }; // if
00775     // calculate number of monitor thread wakeup intervals corresonding to blocktime.
00776     __kmp_monitor_wakeups = KMP_WAKEUPS_FROM_BLOCKTIME( __kmp_dflt_blocktime, __kmp_monitor_wakeups );
00777     __kmp_bt_intervals = KMP_INTERVALS_FROM_BLOCKTIME( __kmp_dflt_blocktime, __kmp_monitor_wakeups );
00778     K_DIAG( 1, ( "__kmp_env_blocktime == %d\n", __kmp_env_blocktime ) );
00779     if ( __kmp_env_blocktime ) {
00780         K_DIAG( 1, ( "__kmp_dflt_blocktime == %d\n", __kmp_dflt_blocktime ) );
00781     }
00782 } // __kmp_stg_parse_blocktime
00783 
00784 static void
00785 __kmp_stg_print_blocktime( kmp_str_buf_t * buffer, char const * name, void * data ) {
00786     __kmp_stg_print_int( buffer, name, __kmp_dflt_blocktime );
00787 } // __kmp_stg_print_blocktime
00788 
00789 // -------------------------------------------------------------------------------------------------
00790 // KMP_DUPLICATE_LIB_OK
00791 // -------------------------------------------------------------------------------------------------
00792 
00793 static void
00794 __kmp_stg_parse_duplicate_lib_ok( char const * name, char const * value, void * data ) {
00795     /* actually this variable is not supported,
00796        put here for compatibility with earlier builds and for static/dynamic combination */
00797     __kmp_stg_parse_bool( name, value, & __kmp_duplicate_library_ok );
00798 } // __kmp_stg_parse_duplicate_lib_ok
00799 
00800 static void
00801 __kmp_stg_print_duplicate_lib_ok( kmp_str_buf_t * buffer, char const * name, void * data ) {
00802     __kmp_stg_print_bool( buffer, name, __kmp_duplicate_library_ok );
00803 } // __kmp_stg_print_duplicate_lib_ok
00804 
00805 // -------------------------------------------------------------------------------------------------
00806 // KMP_INHERIT_FP_CONTROL
00807 // -------------------------------------------------------------------------------------------------
00808 
00809 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
00810 
00811 static void
00812 __kmp_stg_parse_inherit_fp_control( char const * name, char const * value, void * data ) {
00813     __kmp_stg_parse_bool( name, value, & __kmp_inherit_fp_control );
00814 #if KMP_MIC1
00815     // AC: enable fp-control functionality for KNC, it works OK there.
00816     if( __kmp_inherit_fp_control != FALSE ) {
00817         KMP_WARNING( LibNotSupport, KMP_LIBRARY_FILE, name );
00818         __kmp_inherit_fp_control = FALSE;
00819     }
00820 #endif // KMP_MIC
00821 } // __kmp_stg_parse_inherit_fp_control
00822 
00823 static void
00824 __kmp_stg_print_inherit_fp_control( kmp_str_buf_t * buffer, char const * name, void * data ) {
00825 #if KMP_DEBUG
00826     __kmp_stg_print_bool( buffer, name, __kmp_inherit_fp_control );
00827 #endif /* KMP_DEBUG */
00828 } // __kmp_stg_print_inherit_fp_control
00829 
00830 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
00831 
00832 // -------------------------------------------------------------------------------------------------
00833 // KMP_LIBRARY, OMP_WAIT_POLICY
00834 // -------------------------------------------------------------------------------------------------
00835 
00836 static void
00837 __kmp_stg_parse_wait_policy( char const * name, char const * value, void * data ) {
00838 
00839     kmp_stg_wp_data_t * wait = (kmp_stg_wp_data_t *) data;
00840     int                 rc;
00841 
00842     rc = __kmp_stg_check_rivals( name, value, wait->rivals );
00843     if ( rc ) {
00844         return;
00845     }; // if
00846 
00847     if ( wait->omp ) {
00848         if ( __kmp_str_match( "ACTIVE", 1, value ) ) {
00849            __kmp_library = library_turnaround;
00850         } else if ( __kmp_str_match( "PASSIVE", 1, value ) ) {
00851            __kmp_library = library_throughput;
00852         } else {
00853             KMP_WARNING( StgInvalidValue, name, value );
00854         }; // if
00855     } else {
00856         if ( __kmp_str_match( "serial", 1, value ) ) {             /* S */
00857            __kmp_library = library_serial;
00858         } else if ( __kmp_str_match( "throughput", 2, value ) ) {  /* TH */
00859            __kmp_library = library_throughput;
00860         } else if ( __kmp_str_match( "turnaround", 2, value ) ) {  /* TU */
00861            __kmp_library = library_turnaround;
00862         } else if ( __kmp_str_match( "dedicated", 1, value ) ) {   /* D */
00863            __kmp_library = library_turnaround;
00864         } else if ( __kmp_str_match( "multiuser", 1, value ) ) {   /* M */
00865            __kmp_library = library_throughput;
00866         } else {
00867             KMP_WARNING( StgInvalidValue, name, value );
00868         }; // if
00869     }; // if
00870     __kmp_aux_set_library( __kmp_library );
00871 
00872 } // __kmp_stg_parse_wait_policy
00873 
00874 static void
00875 __kmp_stg_print_wait_policy( kmp_str_buf_t * buffer, char const * name, void * data ) {
00876 
00877     kmp_stg_wp_data_t * wait = (kmp_stg_wp_data_t *) data;
00878     char const *        value = NULL;
00879 
00880     if ( wait->omp ) {
00881         switch ( __kmp_library ) {
00882             case library_turnaround : {
00883                 value = "ACTIVE";
00884             } break;
00885             case library_throughput : {
00886                 value = "PASSIVE";
00887             } break;
00888         }; // switch
00889     } else {
00890         switch ( __kmp_library ) {
00891             case library_serial : {
00892                 value = "serial";
00893             } break;
00894             case library_turnaround : {
00895                 value = "turnaround";
00896             } break;
00897             case library_throughput : {
00898                 value = "throughput";
00899             } break;
00900         }; // switch
00901     }; // if
00902     if ( value != NULL ) {
00903         __kmp_stg_print_str( buffer, name, value );
00904     }; // if
00905 
00906 } // __kmp_stg_print_wait_policy
00907 
00908 // -------------------------------------------------------------------------------------------------
00909 // KMP_MONITOR_STACKSIZE
00910 // -------------------------------------------------------------------------------------------------
00911 
00912 static void
00913 __kmp_stg_parse_monitor_stacksize( char const * name, char const * value, void * data ) {
00914     __kmp_stg_parse_size(
00915         name,
00916         value,
00917         __kmp_sys_min_stksize,
00918         KMP_MAX_STKSIZE,
00919         NULL,
00920         & __kmp_monitor_stksize,
00921         1
00922     );
00923 } // __kmp_stg_parse_monitor_stacksize
00924 
00925 static void
00926 __kmp_stg_print_monitor_stacksize( kmp_str_buf_t * buffer, char const * name, void * data ) {
00927     if (  __kmp_monitor_stksize > 0 ) {
00928         __kmp_stg_print_size( buffer, name, __kmp_monitor_stksize );
00929     } else {
00930         __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
00931     }
00932 } // __kmp_stg_print_monitor_stacksize
00933 
00934 // -------------------------------------------------------------------------------------------------
00935 // KMP_SETTINGS
00936 // -------------------------------------------------------------------------------------------------
00937 
00938 static void
00939 __kmp_stg_parse_settings( char const * name, char const * value, void * data ) {
00940     __kmp_stg_parse_bool( name, value, & __kmp_settings );
00941 } // __kmp_stg_parse_settings
00942 
00943 static void
00944 __kmp_stg_print_settings( kmp_str_buf_t * buffer, char const * name, void * data ) {
00945     __kmp_stg_print_bool( buffer, name, __kmp_settings );
00946 } // __kmp_stg_print_settings
00947 
00948 // -------------------------------------------------------------------------------------------------
00949 // KMP_STACKOFFSET
00950 // -------------------------------------------------------------------------------------------------
00951 
00952 static void
00953 __kmp_stg_parse_stackoffset( char const * name, char const * value, void * data ) {
00954     __kmp_stg_parse_size(
00955         name,                             // Env var name
00956         value,                            // Env var value
00957         KMP_MIN_STKOFFSET,                // Min value
00958         KMP_MAX_STKOFFSET,                // Max value
00959         NULL,                             //
00960         & __kmp_stkoffset,                // Var to initialize
00961         1
00962     );
00963 } // __kmp_stg_parse_stackoffset
00964 
00965 static void
00966 __kmp_stg_print_stackoffset( kmp_str_buf_t * buffer, char const * name, void * data ) {
00967     __kmp_stg_print_size( buffer, name, __kmp_stkoffset );
00968 } // __kmp_stg_print_stackoffset
00969 
00970 // -------------------------------------------------------------------------------------------------
00971 // KMP_STACKSIZE, OMP_STACKSIZE, GOMP_STACKSIZE
00972 // -------------------------------------------------------------------------------------------------
00973 
00974 static void
00975 __kmp_stg_parse_stacksize( char const * name, char const * value, void * data ) {
00976 
00977     kmp_stg_ss_data_t *  stacksize = (kmp_stg_ss_data_t *) data;
00978     int                  rc;
00979 
00980     rc = __kmp_stg_check_rivals( name, value, stacksize->rivals );
00981     if ( rc ) {
00982         return;
00983     }; // if
00984     __kmp_stg_parse_size(
00985         name,                     // Env var name
00986         value,                    // Env var value
00987         __kmp_sys_min_stksize,    // Min value
00988         KMP_MAX_STKSIZE,          // Max value
00989         & __kmp_env_stksize,      //
00990         & __kmp_stksize,          // Var to initialize
00991         stacksize->factor
00992     );
00993 
00994 } // __kmp_stg_parse_stacksize
00995 
00996 static void
00997 __kmp_stg_print_stacksize( kmp_str_buf_t * buffer, char const * name, void * data ) {
00998     // This function should be called only for printing KMP_STACKSIZE (factor is 1). Check it.
00999     kmp_stg_ss_data_t *  stacksize = (kmp_stg_ss_data_t *) data;
01000     KMP_DEBUG_ASSERT( stacksize->factor == 1 );
01001     __kmp_str_buf_print( buffer, "   %s=", name );
01002     __kmp_str_buf_print_size( buffer, __kmp_stksize );
01003     __kmp_str_buf_print( buffer, "\n" );
01004 } // __kmp_stg_print_stacksize
01005 
01006 // -------------------------------------------------------------------------------------------------
01007 // KMP_VERSION
01008 // -------------------------------------------------------------------------------------------------
01009 
01010 static void
01011 __kmp_stg_parse_version( char const * name, char const * value, void * data ) {
01012     __kmp_stg_parse_bool( name, value, & __kmp_version );
01013 } // __kmp_stg_parse_version
01014 
01015 static void
01016 __kmp_stg_print_version( kmp_str_buf_t * buffer, char const * name, void * data ) {
01017     __kmp_stg_print_bool( buffer, name, __kmp_version );
01018 } // __kmp_stg_print_version
01019 
01020 // -------------------------------------------------------------------------------------------------
01021 // KMP_WARNINGS
01022 // -------------------------------------------------------------------------------------------------
01023 
01024 static void
01025 __kmp_stg_parse_warnings( char const * name, char const * value, void * data ) {
01026     __kmp_stg_parse_bool( name, value, & __kmp_generate_warnings );
01027     if (__kmp_generate_warnings != kmp_warnings_off) {   // AC: we have only 0/1 values documented,
01028         __kmp_generate_warnings = kmp_warnings_explicit; //     so reset it to explicit in order to
01029     }                                                    //     distinguish from default setting
01030 } // __kmp_env_parse_warnings
01031 
01032 static void
01033 __kmp_stg_print_warnings( kmp_str_buf_t * buffer, char const * name, void * data ) {
01034     __kmp_stg_print_bool( buffer, name, __kmp_generate_warnings ); // AC: TODO: change to print_int?
01035 } // __kmp_env_print_warnings                                      //     (needs documentation change)...
01036 
01037 // -------------------------------------------------------------------------------------------------
01038 // OMP_NESTED, OMP_NUM_THREADS
01039 // -------------------------------------------------------------------------------------------------
01040 
01041 static void
01042 __kmp_stg_parse_nested( char const * name, char const * value, void * data ) {
01043     __kmp_stg_parse_bool( name, value, & __kmp_dflt_nested );
01044 } // __kmp_stg_parse_nested
01045 
01046 static void
01047 __kmp_stg_print_nested( kmp_str_buf_t * buffer, char const * name, void * data ) {
01048     __kmp_stg_print_bool( buffer, name, __kmp_dflt_nested );
01049 } // __kmp_stg_print_nested
01050 
01051 static void
01052 __kmp_parse_nested_num_threads( const char *var, const char *env, kmp_nested_nthreads_t *nth_array )
01053 {
01054     const char *next = env;
01055     const char *scan = next;
01056 
01057     int total = 0;          // Count elements that were set. It'll be used as an array size
01058     int prev_comma = FALSE; // For correct processing sequential commas
01059 
01060     // Count the number of values in the env. var string
01061     for ( ; ; ) {
01062         SKIP_WS( next );
01063 
01064         if ( *next == '\0' ) {
01065             break;
01066         }
01067         // Next character is not an integer or not a comma => end of list
01068         if ( ( ( *next < '0' ) || ( *next > '9' ) ) && ( *next !=',') ) {
01069             KMP_WARNING( NthSyntaxError, var, env );
01070             return;
01071         }
01072         // The next character is ','
01073         if ( *next == ',' ) {
01074             // ',' is the fisrt character
01075             if ( total == 0 || prev_comma ) {
01076                 total++;
01077             }
01078             prev_comma = TRUE;
01079             next++; //skip ','
01080             SKIP_WS( next );
01081         }
01082         // Next character is a digit
01083         if ( *next >= '0' && *next <= '9' ) {
01084             prev_comma = FALSE;
01085             SKIP_DIGITS( next );
01086             total++;
01087             const char *tmp = next;
01088             SKIP_WS( tmp );
01089             if ( ( *next == ' ' || *next == '\t' ) && ( *tmp >= '0' && *tmp <= '9' ) ) {
01090                 KMP_WARNING( NthSpacesNotAllowed, var, env );
01091                 return;
01092             }
01093         }
01094     }
01095     KMP_DEBUG_ASSERT( total > 0 );
01096     if( total <= 0 ) {
01097         KMP_WARNING( NthSyntaxError, var, env );
01098         return;
01099     }
01100 
01101     // Check if the nested nthreads array exists
01102     if ( ! nth_array->nth ) {
01103         // Allocate an array of double size
01104         nth_array->nth = ( int * )KMP_INTERNAL_MALLOC( sizeof( int ) * total * 2 );
01105         if ( nth_array->nth == NULL ) {
01106             KMP_FATAL( MemoryAllocFailed );
01107         }
01108         nth_array->size = total * 2;
01109     } else {
01110         if ( nth_array->size < total ) {
01111             // Increase the array size
01112             do {
01113                 nth_array->size *= 2;
01114             } while ( nth_array->size < total );
01115 
01116             nth_array->nth = (int *) KMP_INTERNAL_REALLOC(
01117                 nth_array->nth, sizeof( int ) * nth_array->size );
01118             if ( nth_array->nth == NULL ) {
01119         KMP_FATAL( MemoryAllocFailed );
01120             }
01121         }
01122     }
01123     nth_array->used = total;
01124     int i = 0;
01125 
01126     prev_comma = FALSE;
01127     total = 0;
01128     // Save values in the array
01129     for ( ; ; ) {
01130         SKIP_WS( scan );
01131         if ( *scan == '\0' ) {
01132             break;
01133         }
01134         // The next character is ','
01135         if ( *scan == ',' ) {
01136             // ',' in the beginning of the list
01137             if ( total == 0 ) {
01138                 // The value is supposed to be equal to __kmp_avail_proc but it is unknown at the moment.
01139                 // So let's put a placeholder (#threads = 0) to correct it later.
01140                 nth_array->nth[i++] = 0;
01141                 total++;
01142             }else if ( prev_comma ) {
01143                 // Num threads is inherited from the previous level
01144                 nth_array->nth[i] = nth_array->nth[i - 1];
01145                 i++;
01146                 total++;
01147             }
01148             prev_comma = TRUE;
01149             scan++; //skip ','
01150             SKIP_WS( scan );
01151         }
01152         // Next character is a digit
01153         if ( *scan >= '0' && *scan <= '9' ) {
01154             int num;
01155             const char *buf = scan;
01156             char const * msg  = NULL;
01157             prev_comma = FALSE;
01158             SKIP_DIGITS( scan );
01159             total++;
01160 
01161             num = __kmp_str_to_int( buf, *scan );
01162             if ( num < KMP_MIN_NTH ) {
01163                 msg = KMP_I18N_STR( ValueTooSmall );
01164                 num = KMP_MIN_NTH;
01165             } else if ( num > __kmp_sys_max_nth ) {
01166                 msg = KMP_I18N_STR( ValueTooLarge );
01167                 num = __kmp_sys_max_nth;
01168             }
01169             if ( msg != NULL ) {
01170                 // Message is not empty. Print warning.
01171                 KMP_WARNING( ParseSizeIntWarn, var, env, msg );
01172                 KMP_INFORM( Using_int_Value, var, num );
01173             }
01174             nth_array->nth[i++] = num;
01175         }
01176     }
01177 }
01178 
01179 static void
01180 __kmp_stg_parse_num_threads( char const * name, char const * value, void * data ) {
01181     // TODO: Remove this option. OMP_NUM_THREADS is a list of positive integers!
01182     if ( ! __kmp_strcasecmp_with_sentinel( "all", value, 0 ) ) {
01183         // The array of 1 element
01184         __kmp_nested_nth.nth = ( int* )KMP_INTERNAL_MALLOC( sizeof( int ) );
01185         __kmp_nested_nth.size = __kmp_nested_nth.used = 1;
01186         __kmp_nested_nth.nth[0] = __kmp_dflt_team_nth = __kmp_dflt_team_nth_ub = __kmp_xproc;
01187     } else {
01188         __kmp_parse_nested_num_threads( name, value, & __kmp_nested_nth );
01189         if ( __kmp_nested_nth.nth ) {
01190             __kmp_dflt_team_nth = __kmp_nested_nth.nth[0];
01191             if ( __kmp_dflt_team_nth_ub < __kmp_dflt_team_nth ) {
01192                 __kmp_dflt_team_nth_ub = __kmp_dflt_team_nth;
01193             }
01194         }
01195     }; // if
01196     K_DIAG( 1, ( "__kmp_dflt_team_nth == %d\n", __kmp_dflt_team_nth ) );
01197 } // __kmp_stg_parse_num_threads
01198 
01199 static void
01200 __kmp_stg_print_num_threads( kmp_str_buf_t * buffer, char const * name, void * data ) {
01201     if ( __kmp_nested_nth.used ) {
01202         kmp_str_buf_t buf;
01203         __kmp_str_buf_init( &buf );
01204         for ( int i = 0; i < __kmp_nested_nth.used; i++) {
01205             __kmp_str_buf_print( &buf, "%d", __kmp_nested_nth.nth[i] );
01206             if ( i < __kmp_nested_nth.used - 1 ) {
01207                 __kmp_str_buf_print( &buf, "," );
01208             }
01209         }
01210         __kmp_stg_print_str(buffer, name, buf.str );
01211         __kmp_str_buf_free(&buf);
01212     } else {
01213         __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
01214     }
01215 } // __kmp_stg_print_num_threads
01216 
01217 // -------------------------------------------------------------------------------------------------
01218 // OpenMP 3.0: KMP_TASKING, OMP_MAX_ACTIVE_LEVELS,
01219 // -------------------------------------------------------------------------------------------------
01220 
01221 #if OMP_30_ENABLED
01222 static void
01223 __kmp_stg_parse_tasking( char const * name, char const * value, void * data ) {
01224     __kmp_stg_parse_int( name, value, 0, (int)tskm_max, (int *)&__kmp_tasking_mode );
01225 } // __kmp_stg_parse_tasking
01226 
01227 static void
01228 __kmp_stg_print_tasking( kmp_str_buf_t * buffer, char const * name, void * data ) {
01229     __kmp_stg_print_int( buffer, name, __kmp_tasking_mode );
01230 } // __kmp_stg_print_tasking
01231 
01232 static void
01233 __kmp_stg_parse_task_stealing( char const * name, char const * value, void * data ) {
01234     __kmp_stg_parse_int( name, value, 0, 1, (int *)&__kmp_task_stealing_constraint );
01235 } // __kmp_stg_parse_task_stealing
01236 
01237 static void
01238 __kmp_stg_print_task_stealing( kmp_str_buf_t * buffer, char const * name, void * data ) {
01239     __kmp_stg_print_int( buffer, name, __kmp_task_stealing_constraint );
01240 } // __kmp_stg_print_task_stealing
01241 
01242 static void
01243 __kmp_stg_parse_max_active_levels( char const * name, char const * value, void * data ) {
01244      __kmp_stg_parse_int( name, value, 0, KMP_MAX_ACTIVE_LEVELS_LIMIT, & __kmp_dflt_max_active_levels );
01245 } // __kmp_stg_parse_max_active_levels
01246 
01247 static void
01248 __kmp_stg_print_max_active_levels( kmp_str_buf_t * buffer, char const * name, void * data ) {
01249     __kmp_stg_print_int( buffer, name, __kmp_dflt_max_active_levels );
01250 } // __kmp_stg_print_max_active_levels
01251 #endif // OMP_30_ENABLED
01252 
01253 // -------------------------------------------------------------------------------------------------
01254 // KMP_HANDLE_SIGNALS
01255 // -------------------------------------------------------------------------------------------------
01256 
01257 #if KMP_HANDLE_SIGNALS
01258 
01259 static void
01260 __kmp_stg_parse_handle_signals( char const * name, char const * value, void * data ) {
01261     __kmp_stg_parse_bool( name, value, & __kmp_handle_signals );
01262 } // __kmp_stg_parse_handle_signals
01263 
01264 static void
01265 __kmp_stg_print_handle_signals( kmp_str_buf_t * buffer, char const * name, void * data ) {
01266     __kmp_stg_print_bool( buffer, name, __kmp_handle_signals );
01267 } // __kmp_stg_print_handle_signals
01268 
01269 #endif // KMP_HANDLE_SIGNALS
01270 
01271 // -------------------------------------------------------------------------------------------------
01272 // KMP_X_DEBUG, KMP_DEBUG, KMP_DEBUG_BUF_*, KMP_DIAG
01273 // -------------------------------------------------------------------------------------------------
01274 
01275 #ifdef KMP_DEBUG
01276 
01277 #define KMP_STG_X_DEBUG( x )                                                                            \
01278     static void __kmp_stg_parse_##x##_debug( char const * name, char const * value, void * data ) {     \
01279     __kmp_stg_parse_int( name, value, 0, INT_MAX, & kmp_##x##_debug );                              \
01280     } /* __kmp_stg_parse_x_debug */                                                                     \
01281     static void __kmp_stg_print_##x##_debug( kmp_str_buf_t * buffer, char const * name, void * data ) { \
01282     __kmp_stg_print_int( buffer, name, kmp_##x##_debug );                                           \
01283     } /* __kmp_stg_print_x_debug */
01284 
01285 KMP_STG_X_DEBUG( a )
01286 KMP_STG_X_DEBUG( b )
01287 KMP_STG_X_DEBUG( c )
01288 KMP_STG_X_DEBUG( d )
01289 KMP_STG_X_DEBUG( e )
01290 KMP_STG_X_DEBUG( f )
01291 
01292 #undef KMP_STG_X_DEBUG
01293 
01294 static void
01295 __kmp_stg_parse_debug( char const * name, char const * value, void * data ) {
01296     int debug = 0;
01297     __kmp_stg_parse_int( name, value, 0, INT_MAX, & debug );
01298     if ( kmp_a_debug < debug ) {
01299     kmp_a_debug = debug;
01300     }; // if
01301     if ( kmp_b_debug < debug ) {
01302     kmp_b_debug = debug;
01303     }; // if
01304     if ( kmp_c_debug < debug ) {
01305     kmp_c_debug = debug;
01306     }; // if
01307     if ( kmp_d_debug < debug ) {
01308     kmp_d_debug = debug;
01309     }; // if
01310     if ( kmp_e_debug < debug ) {
01311     kmp_e_debug = debug;
01312     }; // if
01313     if ( kmp_f_debug < debug ) {
01314     kmp_f_debug = debug;
01315     }; // if
01316 } // __kmp_stg_parse_debug
01317 
01318 static void
01319 __kmp_stg_parse_debug_buf( char const * name, char const * value, void * data ) {
01320     __kmp_stg_parse_bool( name, value, & __kmp_debug_buf );
01321     // !!! TODO: Move buffer initialization of of this file! It may works incorrectly if
01322     // KMP_DEBUG_BUF is parsed before KMP_DEBUG_BUF_LINES or KMP_DEBUG_BUF_CHARS.
01323     if ( __kmp_debug_buf ) {
01324     int i;
01325     int elements = __kmp_debug_buf_lines * __kmp_debug_buf_chars;
01326 
01327     /* allocate and initialize all entries in debug buffer to empty */
01328     __kmp_debug_buffer = (char *) __kmp_page_allocate( elements * sizeof( char ) );
01329     for ( i = 0; i < elements; i += __kmp_debug_buf_chars )
01330        __kmp_debug_buffer[i] = '\0';
01331 
01332     __kmp_debug_count = 0;
01333     }
01334     K_DIAG( 1, ( "__kmp_debug_buf = %d\n", __kmp_debug_buf ) );
01335 } // __kmp_stg_parse_debug_buf
01336 
01337 static void
01338 __kmp_stg_print_debug_buf( kmp_str_buf_t * buffer, char const * name, void * data ) {
01339     __kmp_stg_print_bool( buffer, name, __kmp_debug_buf );
01340 } // __kmp_stg_print_debug_buf
01341 
01342 static void
01343 __kmp_stg_parse_debug_buf_atomic( char const * name, char const * value, void * data ) {
01344     __kmp_stg_parse_bool( name, value, & __kmp_debug_buf_atomic );
01345 } // __kmp_stg_parse_debug_buf_atomic
01346 
01347 static void
01348 __kmp_stg_print_debug_buf_atomic( kmp_str_buf_t * buffer, char const * name, void * data ) {
01349     __kmp_stg_print_bool( buffer, name, __kmp_debug_buf_atomic );
01350 } // __kmp_stg_print_debug_buf_atomic
01351 
01352 static void
01353 __kmp_stg_parse_debug_buf_chars( char const * name, char const * value, void * data ) {
01354     __kmp_stg_parse_int(
01355     name,
01356     value,
01357     KMP_DEBUG_BUF_CHARS_MIN,
01358     INT_MAX,
01359     & __kmp_debug_buf_chars
01360     );
01361 } // __kmp_stg_debug_parse_buf_chars
01362 
01363 static void
01364 __kmp_stg_print_debug_buf_chars( kmp_str_buf_t * buffer, char const * name, void * data ) {
01365     __kmp_stg_print_int( buffer, name, __kmp_debug_buf_chars );
01366 } // __kmp_stg_print_debug_buf_chars
01367 
01368 static void
01369 __kmp_stg_parse_debug_buf_lines( char const * name, char const * value, void * data ) {
01370     __kmp_stg_parse_int(
01371     name,
01372     value,
01373     KMP_DEBUG_BUF_LINES_MIN,
01374     INT_MAX,
01375     & __kmp_debug_buf_lines
01376     );
01377 } // __kmp_stg_parse_debug_buf_lines
01378 
01379 static void
01380 __kmp_stg_print_debug_buf_lines( kmp_str_buf_t * buffer, char const * name, void * data ) {
01381     __kmp_stg_print_int( buffer, name, __kmp_debug_buf_lines );
01382 } // __kmp_stg_print_debug_buf_lines
01383 
01384 static void
01385 __kmp_stg_parse_diag( char const * name, char const * value, void * data ) {
01386     __kmp_stg_parse_int( name, value, 0, INT_MAX, & kmp_diag );
01387 } // __kmp_stg_parse_diag
01388 
01389 static void
01390 __kmp_stg_print_diag( kmp_str_buf_t * buffer, char const * name, void * data ) {
01391     __kmp_stg_print_int( buffer, name, kmp_diag );
01392 } // __kmp_stg_print_diag
01393 
01394 #endif // KMP_DEBUG
01395 
01396 // -------------------------------------------------------------------------------------------------
01397 // KMP_ALIGN_ALLOC
01398 // -------------------------------------------------------------------------------------------------
01399 
01400 static void
01401 __kmp_stg_parse_align_alloc( char const * name, char const * value, void * data ) {
01402     __kmp_stg_parse_size(
01403         name,
01404         value,
01405         CACHE_LINE,
01406         INT_MAX,
01407         NULL,
01408         & __kmp_align_alloc,
01409         1
01410     );
01411 } // __kmp_stg_parse_align_alloc
01412 
01413 static void
01414 __kmp_stg_print_align_alloc( kmp_str_buf_t * buffer, char const * name, void * data ) {
01415         __kmp_stg_print_size( buffer, name, __kmp_align_alloc );
01416 } // __kmp_stg_print_align_alloc
01417 
01418 // -------------------------------------------------------------------------------------------------
01419 // KMP_PLAIN_BARRIER, KMP_FORKJOIN_BARRIER, KMP_REDUCTION_BARRIER
01420 // -------------------------------------------------------------------------------------------------
01421 
01422 // TODO: Remove __kmp_barrier_branch_bit_env_name varibale, remove loops from parse and print
01423 //       functions, pass required info through data argument.
01424 
01425 static void
01426 __kmp_stg_parse_barrier_branch_bit( char const * name, char const * value, void * data ) {
01427     const char *var;
01428 
01429     /* ---------- Barrier branch bit control ------------ */
01430 
01431     for ( int i=bs_plain_barrier; i<bs_last_barrier; i++ ) {
01432         var = __kmp_barrier_branch_bit_env_name[ i ];
01433 
01434         if ( ( strcmp( var, name) == 0 ) && ( value != 0 ) ) {
01435             char   *comma;
01436 
01437             comma = (char *) strchr( value, ',' );
01438             __kmp_barrier_gather_branch_bits[ i ] = ( kmp_uint32 ) __kmp_str_to_int( value, ',' );
01439             /* is there a specified release parameter? */
01440             if ( comma == NULL ) {
01441                 __kmp_barrier_release_branch_bits[ i ] = __kmp_barrier_release_bb_dflt;
01442             } else {
01443                 __kmp_barrier_release_branch_bits[ i ] = (kmp_uint32) __kmp_str_to_int( comma + 1, 0 );
01444 
01445                 if ( __kmp_barrier_release_branch_bits[ i ] > KMP_MAX_BRANCH_BITS ) {
01446                     __kmp_msg( kmp_ms_warning, KMP_MSG( BarrReleaseValueInvalid, name, comma + 1 ), __kmp_msg_null );
01447 
01448                     __kmp_barrier_release_branch_bits[ i ] = __kmp_barrier_release_bb_dflt;
01449                 }
01450             }
01451             if ( __kmp_barrier_gather_branch_bits[ i ] > KMP_MAX_BRANCH_BITS ) {
01452                     KMP_WARNING( BarrGatherValueInvalid, name, value );
01453                     KMP_INFORM( Using_uint_Value, name, __kmp_barrier_gather_bb_dflt );
01454                 __kmp_barrier_gather_branch_bits[ i ] =  __kmp_barrier_gather_bb_dflt;
01455             }
01456         }
01457         K_DIAG(1, ("%s == %d,%d\n", __kmp_barrier_branch_bit_env_name[ i ], \
01458                    __kmp_barrier_gather_branch_bits [ i ], \
01459                    __kmp_barrier_release_branch_bits [ i ]))
01460     }
01461 } // __kmp_stg_parse_barrier_branch_bit
01462 
01463 static void
01464 __kmp_stg_print_barrier_branch_bit( kmp_str_buf_t * buffer, char const * name, void * data ) {
01465     const char *var;
01466     for ( int i=bs_plain_barrier; i<bs_last_barrier; i++ ) {
01467         var = __kmp_barrier_branch_bit_env_name[ i ];
01468         if ( strcmp( var, name) == 0  ) {
01469             __kmp_str_buf_print( buffer, "   %s=\"%d,%d\"\n", __kmp_barrier_branch_bit_env_name[ i ], \
01470                        __kmp_barrier_gather_branch_bits [ i ], \
01471                        __kmp_barrier_release_branch_bits [ i ]);
01472         }
01473     }
01474 } // __kmp_stg_print_barrier_branch_bit
01475 
01476 
01477 // -------------------------------------------------------------------------------------------------
01478 // KMP_PLAIN_BARRIER_PATTERN, KMP_FORKJOIN_BARRIER_PATTERN, KMP_REDUCTION_BARRIER_PATTERN
01479 // -------------------------------------------------------------------------------------------------
01480 
01481 // TODO: Remove __kmp_barrier_pattern_name variable, remove loops from parse and print functions,
01482 //       pass required data to functions through data argument.
01483 
01484 static void
01485 __kmp_stg_parse_barrier_pattern( char const * name, char const * value, void * data ) {
01486     const char *var;
01487     /* ---------- Barrier method control ------------ */
01488 
01489     for ( int i=bs_plain_barrier; i<bs_last_barrier; i++ ) {
01490         var = __kmp_barrier_pattern_env_name[ i ];
01491 
01492         if ( ( strcmp ( var, name ) == 0 ) && ( value != 0 ) ) {
01493             int j;
01494             char *comma = (char *) strchr( value, ',' );
01495 
01496             /* handle first parameter: gather pattern */
01497             for ( j = bp_linear_bar; j<bp_last_bar; j++ ) {
01498                 if (__kmp_match_with_sentinel( __kmp_barrier_pattern_name[j], value, 1, ',' )) {
01499                    __kmp_barrier_gather_pattern[ i ] = (kmp_bar_pat_e) j;
01500                    break;
01501                 }
01502             }
01503             if ( j == bp_last_bar ) {
01504                 KMP_WARNING( BarrGatherValueInvalid, name, value );
01505                 KMP_INFORM( Using_str_Value, name, __kmp_barrier_pattern_name[ bp_linear_bar ] );
01506             }
01507 
01508             /* handle second parameter: release pattern */
01509             if ( comma != NULL ) {
01510                 for ( j = bp_linear_bar; j < bp_last_bar; j++ ) {
01511                     if ( __kmp_str_match( __kmp_barrier_pattern_name[j], 1, comma + 1 ) ) {
01512                        __kmp_barrier_release_pattern[ i ] = (kmp_bar_pat_e) j;
01513                        break;
01514                     }
01515                 }
01516                 if (j == bp_last_bar) {
01517                     __kmp_msg( kmp_ms_warning, KMP_MSG( BarrReleaseValueInvalid, name, comma + 1 ), __kmp_msg_null );
01518                     KMP_INFORM( Using_str_Value, name, __kmp_barrier_pattern_name[ bp_linear_bar ] );
01519                 }
01520             }
01521         }
01522     }
01523 } // __kmp_stg_parse_barrier_pattern
01524 
01525 static void
01526 __kmp_stg_print_barrier_pattern( kmp_str_buf_t * buffer, char const * name, void * data ) {
01527     const char *var;
01528     for ( int i=bs_plain_barrier; i<bs_last_barrier; i++ ) {
01529         var = __kmp_barrier_pattern_env_name[ i ];
01530         if ( strcmp ( var, name ) == 0 ) {
01531             int j = __kmp_barrier_gather_pattern [ i ];
01532             int k = __kmp_barrier_release_pattern [ i ];
01533             __kmp_str_buf_print( buffer, "   %s=\"%s,%s\"\n", __kmp_barrier_pattern_env_name[ i ], \
01534                        __kmp_barrier_pattern_name [ j ], \
01535                        __kmp_barrier_pattern_name [ k ]);
01536         }
01537     }
01538 } // __kmp_stg_print_barrier_pattern
01539 
01540 // -------------------------------------------------------------------------------------------------
01541 // KMP_ABORT_DELAY
01542 // -------------------------------------------------------------------------------------------------
01543 
01544 static void
01545 __kmp_stg_parse_abort_delay( char const * name, char const * value, void * data ) {
01546     // Units of KMP_DELAY_ABORT are seconds, units of __kmp_abort_delay is milliseconds.
01547     int delay = __kmp_abort_delay / 1000;
01548     __kmp_stg_parse_int( name, value, 0, INT_MAX / 1000, & delay );
01549     __kmp_abort_delay = delay * 1000;
01550 } // __kmp_stg_parse_abort_delay
01551 
01552 static void
01553 __kmp_stg_print_abort_delay( kmp_str_buf_t * buffer, char const * name, void * data ) {
01554     __kmp_stg_print_int( buffer, name, __kmp_abort_delay );
01555 } // __kmp_stg_print_abort_delay
01556 
01557 // -------------------------------------------------------------------------------------------------
01558 // KMP_CPUINFO_FILE
01559 // -------------------------------------------------------------------------------------------------
01560 
01561 static void
01562 __kmp_stg_parse_cpuinfo_file( char const * name, char const * value, void * data ) {
01563     #if KMP_OS_LINUX || KMP_OS_WINDOWS 
01564         __kmp_stg_parse_str( name, value, & __kmp_cpuinfo_file );
01565         K_DIAG( 1, ( "__kmp_cpuinfo_file == %s\n", __kmp_cpuinfo_file ) );
01566     #elif KMP_OS_DARWIN
01567         // affinity not supported
01568     #else
01569         #error "Unknown or unsupported OS"
01570     #endif
01571 } //__kmp_stg_parse_cpuinfo_file
01572 
01573 static void
01574 __kmp_stg_print_cpuinfo_file( kmp_str_buf_t * buffer, char const * name, void * data ) {
01575     #if KMP_OS_LINUX || KMP_OS_WINDOWS
01576         if ( __kmp_cpuinfo_file ) {
01577             __kmp_stg_print_str( buffer, name, __kmp_cpuinfo_file);
01578         } else {
01579             __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
01580         }
01581     #endif
01582 } //__kmp_stg_print_cpuinfo_file
01583 
01584 // -------------------------------------------------------------------------------------------------
01585 // KMP_FORCE_REDUCTION, KMP_DETERMINISTIC_REDUCTION
01586 // -------------------------------------------------------------------------------------------------
01587 
01588 static void
01589 __kmp_stg_parse_force_reduction( char const * name, char const * value, void * data )
01590 {
01591     kmp_stg_fr_data_t * reduction = (kmp_stg_fr_data_t *) data;
01592     int                 rc;
01593 
01594     rc = __kmp_stg_check_rivals( name, value, reduction->rivals );
01595     if ( rc ) {
01596         return;
01597     }; // if
01598     if ( reduction->force ) {
01599         if( value != 0 ) {
01600             if( __kmp_str_match( "critical", 0, value ) )
01601                __kmp_force_reduction_method = critical_reduce_block;
01602             else if( __kmp_str_match( "atomic", 0, value ) )
01603                __kmp_force_reduction_method = atomic_reduce_block;
01604             else if( __kmp_str_match( "tree", 0, value ) )
01605                __kmp_force_reduction_method = tree_reduce_block;
01606             else {
01607                 KMP_FATAL( UnknownForceReduction, name, value );
01608             }
01609         }
01610     } else {
01611         __kmp_stg_parse_bool( name, value, & __kmp_determ_red );
01612         if( __kmp_determ_red ) {
01613             __kmp_force_reduction_method = tree_reduce_block;
01614         } else {
01615             __kmp_force_reduction_method = reduction_method_not_defined;
01616         }
01617     }
01618     K_DIAG( 1, ( "__kmp_force_reduction_method == %d\n", __kmp_force_reduction_method ) );
01619 } // __kmp_stg_parse_force_reduction
01620 
01621 static void
01622 __kmp_stg_print_force_reduction( kmp_str_buf_t * buffer, char const * name, void * data ) {
01623 
01624     kmp_stg_fr_data_t * reduction = (kmp_stg_fr_data_t *) data;
01625     char const *        value = NULL;
01626     if ( reduction->force ) {
01627         if( __kmp_force_reduction_method == critical_reduce_block) {
01628             __kmp_stg_print_str( buffer, name, "critical");
01629         } else if ( __kmp_force_reduction_method == atomic_reduce_block ) {
01630             __kmp_stg_print_str( buffer, name, "atomic");
01631         } else if ( __kmp_force_reduction_method == tree_reduce_block ) {
01632             __kmp_stg_print_str( buffer, name, "tree");
01633         } else {
01634             __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
01635         }
01636     } else {
01637         __kmp_stg_print_bool( buffer, name, __kmp_determ_red );
01638     }
01639 
01640 
01641 } // __kmp_stg_print_force_reduction
01642 
01643 // -------------------------------------------------------------------------------------------------
01644 // KMP_STORAGE_MAP
01645 // -------------------------------------------------------------------------------------------------
01646 
01647 static void
01648 __kmp_stg_parse_storage_map( char const * name, char const * value, void * data ) {
01649     if ( __kmp_str_match(  "verbose", 1, value ) ) {
01650         __kmp_storage_map         = TRUE;
01651         __kmp_storage_map_verbose = TRUE;
01652         __kmp_storage_map_verbose_specified = TRUE;
01653 
01654     } else {
01655         __kmp_storage_map_verbose = FALSE;
01656         __kmp_stg_parse_bool( name, value, & __kmp_storage_map ); // !!!
01657     }; // if
01658 } // __kmp_stg_parse_storage_map
01659 
01660 static void
01661 __kmp_stg_print_storage_map( kmp_str_buf_t * buffer, char const * name, void * data ) {
01662     if ( __kmp_storage_map_verbose || __kmp_storage_map_verbose_specified ) {
01663         __kmp_stg_print_str( buffer, name, "verbose" );
01664     } else {
01665         __kmp_stg_print_bool( buffer, name, __kmp_storage_map );
01666     }
01667 } // __kmp_stg_print_storage_map
01668 
01669 // -------------------------------------------------------------------------------------------------
01670 // KMP_ALL_THREADPRIVATE
01671 // -------------------------------------------------------------------------------------------------
01672 
01673 static void
01674 __kmp_stg_parse_all_threadprivate( char const * name, char const * value, void * data ) {
01675     __kmp_stg_parse_int( name, value, __kmp_allThreadsSpecified ? __kmp_max_nth : 1, __kmp_max_nth,
01676         & __kmp_tp_capacity );
01677 } // __kmp_stg_parse_all_threadprivate
01678 
01679 static void
01680 __kmp_stg_print_all_threadprivate( kmp_str_buf_t * buffer, char const * name, void * data ) {
01681     __kmp_stg_print_int( buffer, name, __kmp_tp_capacity );
01682 
01683 }
01684 
01685 // -------------------------------------------------------------------------------------------------
01686 // KMP_FOREIGN_THREADS_THREADPRIVATE
01687 // -------------------------------------------------------------------------------------------------
01688 
01689 static void
01690 __kmp_stg_parse_foreign_threads_threadprivate( char const * name, char const * value, void * data ) {
01691     __kmp_stg_parse_bool( name, value, & __kmp_foreign_tp );
01692 } // __kmp_stg_parse_foreign_threads_threadprivate
01693 
01694 static void
01695 __kmp_stg_print_foreign_threads_threadprivate( kmp_str_buf_t * buffer, char const * name, void * data ) {
01696     __kmp_stg_print_bool( buffer, name, __kmp_foreign_tp );
01697 } // __kmp_stg_print_foreign_threads_threadprivate
01698 
01699 
01700 // -------------------------------------------------------------------------------------------------
01701 // KMP_AFFINITY, GOMP_CPU_AFFINITY, KMP_TOPOLOGY_METHOD
01702 // -------------------------------------------------------------------------------------------------
01703 
01704 #if KMP_OS_LINUX || KMP_OS_WINDOWS 
01705 //
01706 // Parse the proc id list.  Return TRUE if successful, FALSE otherwise.
01707 //
01708 static int
01709 __kmp_parse_affinity_proc_id_list( const char *var, const char *env,
01710     const char **nextEnv, char **proclist )
01711 {
01712     const char *scan = env;
01713     const char *next = scan;
01714     int empty = TRUE;
01715 
01716     *proclist = NULL;
01717 
01718     for (;;) {
01719         int start, end, stride;
01720 
01721         SKIP_WS(scan);
01722         next = scan;
01723         if (*next == '\0') {
01724             break;
01725         }
01726 
01727         if (*next == '{') {
01728             int num;
01729             next++;     // skip '{'
01730             SKIP_WS(next);
01731             scan = next;
01732 
01733             //
01734             // Read the first integer in the set.
01735             //
01736             if ((*next < '0') || (*next > '9')) {
01737                 KMP_WARNING( AffSyntaxError, var );
01738                 return FALSE;
01739             }
01740             SKIP_DIGITS(next);
01741             num = __kmp_str_to_int(scan, *next);
01742             KMP_ASSERT(num >= 0);
01743 
01744             for (;;) {
01745                 //
01746                 // Check for end of set.
01747                 //
01748                 SKIP_WS(next);
01749                 if (*next == '}') {
01750                     next++;     // skip '}'
01751                     break;
01752                 }
01753 
01754                 //
01755                 // Skip optional comma.
01756                 //
01757                 if (*next == ',') {
01758                     next++;
01759                 }
01760                 SKIP_WS(next);
01761 
01762                 //
01763                 // Read the next integer in the set.
01764                 //
01765                 scan = next;
01766                 if ((*next < '0') || (*next > '9')) {
01767                     KMP_WARNING( AffSyntaxError, var );
01768                     return FALSE;
01769                 }
01770 
01771                 SKIP_DIGITS(next);
01772                 num = __kmp_str_to_int(scan, *next);
01773                 KMP_ASSERT(num >= 0);
01774             }
01775             empty = FALSE;
01776 
01777             SKIP_WS(next);
01778             if (*next == ',') {
01779                 next++;
01780             }
01781             scan = next;
01782             continue;
01783         }
01784 
01785         //
01786         // Next character is not an integer => end of list
01787         //
01788         if ((*next < '0') || (*next > '9')) {
01789             if (empty) {
01790                 KMP_WARNING( AffSyntaxError, var );
01791                 return FALSE;
01792             }
01793             break;
01794         }
01795 
01796         //
01797         // Read the first integer.
01798         //
01799         SKIP_DIGITS(next);
01800         start = __kmp_str_to_int(scan, *next);
01801         KMP_ASSERT(start >= 0);
01802         SKIP_WS(next);
01803 
01804         //
01805         // If this isn't a range, then go on.
01806         //
01807         if (*next != '-') {
01808             empty = FALSE;
01809 
01810             //
01811             // Skip optional comma.
01812             //
01813             if (*next == ',') {
01814                 next++;
01815             }
01816             scan = next;
01817             continue;
01818         }
01819 
01820         //
01821         // This is a range.  Skip over the '-' and read in the 2nd int.
01822         //
01823         next++;         // skip '-'
01824         SKIP_WS(next);
01825         scan = next;
01826         if ((*next < '0') || (*next > '9')) {
01827             KMP_WARNING( AffSyntaxError, var );
01828             return FALSE;
01829         }
01830         SKIP_DIGITS(next);
01831         end = __kmp_str_to_int(scan, *next);
01832         KMP_ASSERT(end >= 0);
01833 
01834         //
01835         // Check for a stride parameter
01836         //
01837         stride = 1;
01838         SKIP_WS(next);
01839         if (*next == ':') {
01840             //
01841             // A stride is specified.  Skip over the ':" and read the 3rd int.
01842             //
01843             int sign = +1;
01844             next++;         // skip ':'
01845             SKIP_WS(next);
01846             scan = next;
01847             if (*next == '-') {
01848                 sign = -1;
01849                 next++;
01850                 SKIP_WS(next);
01851                 scan = next;
01852             }
01853             if ((*next < '0') || (*next > '9')) {
01854                 KMP_WARNING( AffSyntaxError, var );
01855                 return FALSE;
01856             }
01857             SKIP_DIGITS(next);
01858             stride = __kmp_str_to_int(scan, *next);
01859             KMP_ASSERT(stride >= 0);
01860             stride *= sign;
01861         }
01862 
01863         //
01864         // Do some range checks.
01865         //
01866         if (stride == 0) {
01867             KMP_WARNING( AffZeroStride, var );
01868             return FALSE;
01869         }
01870         if (stride > 0) {
01871             if (start > end) {
01872                 KMP_WARNING( AffStartGreaterEnd, var, start, end );
01873                 return FALSE;
01874             }
01875         }
01876         else {
01877             if (start < end) {
01878                 KMP_WARNING( AffStrideLessZero, var, start, end );
01879                 return FALSE;
01880             }
01881         }
01882         if ((end - start) / stride > 65536 ) {
01883             KMP_WARNING( AffRangeTooBig, var, end, start, stride );
01884             return FALSE;
01885         }
01886 
01887         empty = FALSE;
01888 
01889         //
01890         // Skip optional comma.
01891         //
01892         SKIP_WS(next);
01893         if (*next == ',') {
01894             next++;
01895         }
01896         scan = next;
01897     }
01898 
01899     *nextEnv = next;
01900 
01901     {
01902         int len = next - env;
01903         char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
01904         memcpy(retlist, env, len * sizeof(char));
01905         retlist[len] = '\0';
01906         *proclist = retlist;
01907     }
01908     return TRUE;
01909 }
01910 
01911 
01912 //
01913 // If KMP_AFFINITY is specified without a type, then
01914 // __kmp_affinity_notype should point to its setting.
01915 //
01916 static kmp_setting_t *__kmp_affinity_notype = NULL;
01917 
01918 static void
01919 __kmp_parse_affinity_env( char const * name, char const * value,
01920     enum affinity_type  * out_type,
01921     char                ** out_proclist,
01922     int                 * out_verbose,
01923     int                 * out_warn,
01924     int                 * out_respect,
01925     enum affinity_gran  * out_gran,
01926     int                 * out_gran_levels,
01927     int                 * out_dups,
01928     int                 * out_compact,
01929     int                 * out_offset
01930 )
01931 {
01932     char * buffer = NULL;    // Copy of env var value.
01933     char * buf    = NULL;    // Buffer for strtok_r() function.
01934     char * next = NULL;      // end of token / start of next.
01935     const char * start;      // start of current token (for err msgs)
01936     int    count  = 0;       // Counter of parsed integer numbers.
01937     int    number[ 2 ];      // Parsed numbers.
01938 
01939     // Guards.
01940     int type         = 0;
01941     int proclist     = 0;
01942     int max_proclist = 0;
01943     int verbose      = 0;
01944     int warnings     = 0;
01945     int respect      = 0;
01946     int gran         = 0;
01947     int dups         = 0;
01948 
01949     KMP_ASSERT( value != NULL );
01950 
01951     if ( TCR_4(__kmp_init_middle) ) {
01952         KMP_WARNING( EnvMiddleWarn, name );
01953         __kmp_env_toPrint( name, 0 );
01954         return;
01955     }
01956     __kmp_env_toPrint( name, 1 );
01957 
01958     buffer = __kmp_str_format( "%s", value );         // Copy env var to keep original intact.
01959     buf = buffer;
01960     SKIP_WS(buf);
01961 
01962     // Helper macros.
01963 
01964     //
01965     // If we see a parse error, emit a warning and scan to the next ",".
01966     //
01967     // FIXME - there's got to be a better way to print an error
01968     // message, hopefully without overwritting peices of buf.
01969     //
01970     #define EMIT_WARN(skip,errlist) \
01971         {                                                                     \
01972             char ch;                                                          \
01973             if (skip) {                                                       \
01974                 SKIP_TO(next, ',');                                           \
01975             }                                                                 \
01976             ch = *next;                                                       \
01977             *next = '\0';                                                     \
01978             KMP_WARNING errlist;                                              \
01979             *next = ch;                                                       \
01980             if (skip) {                                                       \
01981                 if (ch == ',') next++;                                        \
01982             }                                                                 \
01983             buf = next;                                                       \
01984         }
01985 
01986     #define _set_param(_guard,_var,_val)                                      \
01987         {                                                                     \
01988             if ( _guard == 0 ) {                                              \
01989                 _var = _val;                                                  \
01990             } else {                                                          \
01991                 EMIT_WARN( FALSE, ( AffParamDefined, name, start ) );         \
01992             };                                                                \
01993             ++ _guard;                                                        \
01994         }
01995 
01996     #define set_type(val)          _set_param( type,     *out_type,        val )
01997     #define set_verbose(val)       _set_param( verbose,  *out_verbose,     val )
01998     #define set_warnings(val)      _set_param( warnings, *out_warn,        val )
01999     #define set_respect(val)       _set_param( respect,  *out_respect,     val )
02000     #define set_dups(val)          _set_param( dups,     *out_dups,        val )
02001     #define set_proclist(val)      _set_param( proclist, *out_proclist,    val )
02002 
02003     #define set_gran(val,levels)                                              \
02004         {                                                                     \
02005             if ( gran == 0 ) {                                                \
02006                 *out_gran = val;                                              \
02007                 *out_gran_levels = levels;                                    \
02008             } else {                                                          \
02009                 EMIT_WARN( FALSE, ( AffParamDefined, name, start ) );         \
02010             };                                                                \
02011             ++ gran;                                                          \
02012         }
02013 
02014 # if OMP_40_ENABLED
02015     KMP_DEBUG_ASSERT( ( __kmp_nested_proc_bind.bind_types != NULL )
02016       && ( __kmp_nested_proc_bind.used > 0 ) );
02017     if ( ( __kmp_affinity_notype != NULL )
02018       && ( ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_default )
02019       || ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_intel ) ) ) {
02020         type = TRUE;
02021     }
02022 # endif
02023 
02024     while ( *buf != '\0' ) {
02025         start = next = buf;
02026 
02027         if (__kmp_match_str("none", buf, (const char **)&next)) {
02028             set_type( affinity_none );
02029             buf = next;
02030         } else if (__kmp_match_str("scatter", buf, (const char **)&next)) {
02031             set_type( affinity_scatter );
02032             buf = next;
02033         } else if (__kmp_match_str("compact", buf, (const char **)&next)) {
02034             set_type( affinity_compact );
02035             buf = next;
02036         } else if (__kmp_match_str("logical", buf, (const char **)&next)) {
02037             set_type( affinity_logical );
02038             buf = next;
02039         } else if (__kmp_match_str("physical", buf, (const char **)&next)) {
02040             set_type( affinity_physical );
02041             buf = next;
02042         } else if (__kmp_match_str("explicit", buf, (const char **)&next)) {
02043             set_type( affinity_explicit );
02044             buf = next;
02045 # if KMP_MIC
02046         } else if (__kmp_match_str("balanced", buf, (const char **)&next)) {
02047             set_type( affinity_balanced );
02048             buf = next;
02049 # endif
02050         } else if (__kmp_match_str("disabled", buf, (const char **)&next)) {
02051             set_type( affinity_disabled );
02052             buf = next;
02053         } else if (__kmp_match_str("verbose", buf, (const char **)&next)) {
02054             set_verbose( TRUE );
02055             buf = next;
02056         } else if (__kmp_match_str("noverbose", buf, (const char **)&next)) {
02057             set_verbose( FALSE );
02058             buf = next;
02059         } else if (__kmp_match_str("warnings", buf, (const char **)&next)) {
02060             set_warnings( TRUE );
02061             buf = next;
02062         } else if (__kmp_match_str("nowarnings", buf, (const char **)&next)) {
02063             set_warnings( FALSE );
02064             buf = next;
02065         } else if (__kmp_match_str("respect", buf, (const char **)&next)) {
02066             set_respect( TRUE );
02067             buf = next;
02068         } else if (__kmp_match_str("norespect", buf, (const char **)&next)) {
02069             set_respect( FALSE );
02070             buf = next;
02071         } else if (__kmp_match_str("duplicates", buf, (const char **)&next)
02072           || __kmp_match_str("dups", buf, (const char **)&next)) {
02073             set_dups( TRUE );
02074             buf = next;
02075         } else if (__kmp_match_str("noduplicates", buf, (const char **)&next)
02076           || __kmp_match_str("nodups", buf, (const char **)&next)) {
02077             set_dups( FALSE );
02078             buf = next;
02079         } else if (__kmp_match_str("granularity", buf, (const char **)&next)
02080           || __kmp_match_str("gran", buf, (const char **)&next)) {
02081             SKIP_WS(next);
02082             if (*next != '=') {
02083                 EMIT_WARN( TRUE, ( AffInvalidParam, name, start ) );
02084                 continue;
02085             }
02086             next++;      // skip '='
02087             SKIP_WS(next);
02088 
02089             buf = next;
02090             if (__kmp_match_str("fine", buf, (const char **)&next)) {
02091                 set_gran( affinity_gran_fine, -1 );
02092                 buf = next;
02093             } else if (__kmp_match_str("thread", buf, (const char **)&next)) {
02094                 set_gran( affinity_gran_thread, -1 );
02095                 buf = next;
02096             } else if (__kmp_match_str("core", buf, (const char **)&next)) {
02097                 set_gran( affinity_gran_core, -1 );
02098                 buf = next;
02099             } else if (__kmp_match_str("package", buf, (const char **)&next)) {
02100                 set_gran( affinity_gran_package, -1 );
02101                 buf = next;
02102             } else if (__kmp_match_str("node", buf, (const char **)&next)) {
02103                 set_gran( affinity_gran_node, -1 );
02104                 buf = next;
02105 # if KMP_OS_WINDOWS && KMP_ARCH_X86_64
02106             } else if (__kmp_match_str("group", buf, (const char **)&next)) {
02107                 set_gran( affinity_gran_group, -1 );
02108                 buf = next;
02109 # endif /* KMP_OS_WINDOWS && KMP_ARCH_X86_64 */
02110             } else if ((*buf >= '0') && (*buf <= '9')) {
02111                 int n;
02112                 next = buf;
02113                 SKIP_DIGITS(next);
02114                 n = __kmp_str_to_int( buf, *next );
02115                 KMP_ASSERT(n >= 0);
02116                 buf = next;
02117                 set_gran( affinity_gran_default, n );
02118             } else {
02119                 EMIT_WARN( TRUE, ( AffInvalidParam, name, start ) );
02120                 continue;
02121             }
02122         } else if (__kmp_match_str("proclist", buf, (const char **)&next)) {
02123             char *temp_proclist;
02124 
02125             SKIP_WS(next);
02126             if (*next != '=') {
02127                 EMIT_WARN( TRUE, ( AffInvalidParam, name, start ) );
02128                 continue;
02129             }
02130             next++;      // skip '='
02131             SKIP_WS(next);
02132             if (*next != '[') {
02133                 EMIT_WARN( TRUE, ( AffInvalidParam, name, start ) );
02134                 continue;
02135             }
02136             next++;      // skip '['
02137             buf = next;
02138             if (! __kmp_parse_affinity_proc_id_list(name, buf,
02139               (const char **)&next, &temp_proclist)) {
02140                 //
02141                 // warning already emitted.
02142                 //
02143                 SKIP_TO(next, ']');
02144                 if (*next == ']') next++;
02145                 SKIP_TO(next, ',');
02146                 if (*next == ',') next++;
02147                 buf = next;
02148                 continue;
02149             }
02150             if (*next != ']') {
02151                 EMIT_WARN( TRUE, ( AffInvalidParam, name, start ) );
02152                 continue;
02153             }
02154             next++;      // skip ']'
02155             set_proclist( temp_proclist );
02156         } else if ((*buf >= '0') && (*buf <= '9')) {
02157             // Parse integer numbers -- permute and offset.
02158             int n;
02159             next = buf;
02160             SKIP_DIGITS(next);
02161             n = __kmp_str_to_int( buf, *next );
02162             KMP_ASSERT(n >= 0);
02163             buf = next;
02164             if ( count < 2 ) {
02165                 number[ count ] = n;
02166             } else {
02167                 KMP_WARNING( AffManyParams, name, start );
02168             }; // if
02169             ++ count;
02170         } else {
02171             EMIT_WARN( TRUE, ( AffInvalidParam, name, start ) );
02172             continue;
02173         }
02174 
02175         SKIP_WS(next);
02176         if (*next == ',') {
02177             next++;
02178             SKIP_WS(next);
02179         }
02180         else if (*next != '\0') {
02181             const char *temp = next;
02182             EMIT_WARN( TRUE, ( ParseExtraCharsWarn, name, temp ) );
02183             continue;
02184         }
02185         buf = next;
02186     } // while
02187 
02188     #undef EMIT_WARN
02189     #undef _set_param
02190     #undef set_type
02191     #undef set_verbose
02192     #undef set_warnings
02193     #undef set_respect
02194     #undef set_granularity
02195 
02196     KMP_INTERNAL_FREE( buffer );
02197 
02198     if ( proclist ) {
02199         if ( ! type ) {
02200             KMP_WARNING( AffProcListNoType, name );
02201             __kmp_affinity_type = affinity_explicit;
02202         }
02203         else if ( __kmp_affinity_type != affinity_explicit ) {
02204             KMP_WARNING( AffProcListNotExplicit, name );
02205             KMP_ASSERT( *out_proclist != NULL );
02206             KMP_INTERNAL_FREE( *out_proclist );
02207             *out_proclist = NULL;
02208         }
02209     }
02210     switch ( *out_type ) {
02211         case affinity_logical:
02212         case affinity_physical: {
02213             if ( count > 0 ) {
02214                 *out_offset = number[ 0 ];
02215             }; // if
02216             if ( count > 1 ) {
02217                 KMP_WARNING( AffManyParamsForLogic, name, number[ 1 ] );
02218             }; // if
02219         } break;
02220 # if KMP_MIC
02221         case affinity_balanced: {
02222             if ( count > 0 ) {
02223                 *out_compact = number[ 0 ];
02224             }; // if
02225             if ( count > 1 ) {
02226                 *out_offset = number[ 1 ];
02227             }; // if
02228 
02229             // If granularity is neither thread nor core let it be default value=fine
02230             if( __kmp_affinity_gran != affinity_gran_default && __kmp_affinity_gran != affinity_gran_fine
02231                 && __kmp_affinity_gran != affinity_gran_thread && __kmp_affinity_gran != affinity_gran_core ) {
02232                 if( __kmp_affinity_verbose || __kmp_affinity_warnings ) {
02233                     KMP_WARNING( AffGranUsing, "KMP_AFFINITY", "core" );
02234                 }
02235                 __kmp_affinity_gran = affinity_gran_fine;
02236             }
02237         } break;
02238 # endif
02239         case affinity_scatter:
02240         case affinity_compact: {
02241             if ( count > 0 ) {
02242                 *out_compact = number[ 0 ];
02243             }; // if
02244             if ( count > 1 ) {
02245                 *out_offset = number[ 1 ];
02246             }; // if
02247         } break;
02248         case affinity_explicit: {
02249             if ( *out_proclist == NULL ) {
02250                 KMP_WARNING( AffNoProcList, name );
02251                 __kmp_affinity_type = affinity_none;
02252             }
02253             if ( count > 0 ) {
02254                 KMP_WARNING( AffNoParam, name, "explicit" );
02255             }
02256         } break;
02257         case affinity_none: {
02258             if ( count > 0 ) {
02259                 KMP_WARNING( AffNoParam, name, "none" );
02260             }; // if
02261         } break;
02262         case affinity_disabled: {
02263             if ( count > 0 ) {
02264                 KMP_WARNING( AffNoParam, name, "disabled" );
02265             }; // if
02266         } break;
02267         case affinity_default: {
02268             if ( count > 0 ) {
02269                 KMP_WARNING( AffNoParam, name, "default" );
02270             }; // if
02271         } break;
02272         default: {
02273             KMP_ASSERT( 0 );
02274         };
02275     }; // switch
02276 } // __kmp_parse_affinity_env
02277 
02278 static void
02279 __kmp_stg_parse_affinity( char const * name, char const * value, void * data )
02280 {
02281     kmp_setting_t **rivals = (kmp_setting_t **) data;
02282     int rc;
02283 
02284     rc = __kmp_stg_check_rivals( name, value, rivals );
02285     if ( rc ) {
02286         return;
02287     }
02288 
02289     __kmp_parse_affinity_env( name, value, & __kmp_affinity_type,
02290       & __kmp_affinity_proclist, & __kmp_affinity_verbose,
02291       & __kmp_affinity_warnings, & __kmp_affinity_respect_mask,
02292       & __kmp_affinity_gran, & __kmp_affinity_gran_levels,
02293       & __kmp_affinity_dups, & __kmp_affinity_compact,
02294       & __kmp_affinity_offset );
02295 
02296 } // __kmp_stg_parse_affinity
02297 
02298 static void
02299 __kmp_stg_print_affinity( kmp_str_buf_t * buffer, char const * name, void * data ) {
02300     if ( __kmp_affinity_verbose ) {
02301         __kmp_str_buf_print( buffer, "   %s=\"%s,", name, "verbose");
02302     } else {
02303         __kmp_str_buf_print( buffer, "   %s=\"%s,", name, "noverbose");
02304     }
02305     if ( __kmp_affinity_warnings ) {
02306         __kmp_str_buf_print( buffer, "%s,", "warnings");
02307     } else {
02308         __kmp_str_buf_print( buffer, "%s,", "nowarnings");
02309     }
02310     if ( KMP_AFFINITY_CAPABLE() ) {
02311         if ( __kmp_affinity_respect_mask ) {
02312             __kmp_str_buf_print( buffer, "%s,", "respect");
02313         } else {
02314             __kmp_str_buf_print( buffer, "%s,", "norespect");
02315         }
02316         switch ( __kmp_affinity_gran ) {
02317             case affinity_gran_default:
02318                 __kmp_str_buf_print( buffer, "%s", "granularity=default,");
02319                 break;
02320             case affinity_gran_fine:
02321                 __kmp_str_buf_print( buffer, "%s", "granularity=fine,");
02322                 break;
02323             case affinity_gran_thread:
02324                 __kmp_str_buf_print( buffer, "%s", "granularity=thread,");
02325                 break;
02326             case affinity_gran_core:
02327                 __kmp_str_buf_print( buffer, "%s", "granularity=core,");
02328                 break;
02329             case affinity_gran_package:
02330                 __kmp_str_buf_print( buffer, "%s", "granularity=package,");
02331                 break;
02332             case affinity_gran_node:
02333                 __kmp_str_buf_print( buffer, "%s", "granularity=node,");
02334                 break;
02335 # if KMP_OS_WINDOWS && KMP_ARCH_X86_64
02336             case affinity_gran_group:
02337                 __kmp_str_buf_print( buffer, "%s", "granularity=group,");
02338                 break;
02339 # endif /* KMP_OS_WINDOWS && KMP_ARCH_X86_64 */
02340         }
02341         if ( __kmp_affinity_dups ) {
02342             __kmp_str_buf_print( buffer, "%s,", "duplicates");
02343         } else {
02344             __kmp_str_buf_print( buffer, "%s,", "noduplicates");
02345         }
02346     }
02347     if ( ! KMP_AFFINITY_CAPABLE() ) {
02348         __kmp_str_buf_print( buffer, "%s\"\n", "disabled" );
02349     }
02350     else switch ( __kmp_affinity_type ){
02351         case affinity_none:
02352             __kmp_str_buf_print( buffer, "%s\"\n", "none");
02353             break;
02354         case affinity_physical:
02355             __kmp_str_buf_print( buffer, "%s,%d\"\n", "physical",
02356               __kmp_affinity_offset );
02357             break;
02358         case affinity_logical:
02359             __kmp_str_buf_print( buffer, "%s,%d\"\n", "logical",
02360               __kmp_affinity_offset );
02361             break;
02362         case affinity_compact:
02363             __kmp_str_buf_print( buffer, "%s,%d,%d\"\n", "compact",
02364               __kmp_affinity_compact, __kmp_affinity_offset );
02365             break;
02366         case affinity_scatter:
02367             __kmp_str_buf_print( buffer, "%s,%d,%d\"\n", "scatter",
02368               __kmp_affinity_compact, __kmp_affinity_offset );
02369             break;
02370         case affinity_explicit:
02371             __kmp_str_buf_print( buffer, "%s=[%s],%s\"\n", "proclist",
02372               __kmp_affinity_proclist, "explicit" );
02373             break;
02374 # if KMP_MIC
02375         case affinity_balanced:
02376             __kmp_str_buf_print( buffer, "%s,%d,%d\"\n", "balanced",
02377               __kmp_affinity_compact, __kmp_affinity_offset );
02378             break;
02379 # endif
02380         case affinity_disabled:
02381             __kmp_str_buf_print( buffer, "%s\"\n", "disabled");
02382             break;
02383         case affinity_default:
02384             __kmp_str_buf_print( buffer, "%s\"\n", "default");
02385             break;
02386         default:
02387             __kmp_str_buf_print( buffer, "%s", "<unknown>\n");
02388             break;
02389     }
02390 } //__kmp_stg_print_affinity
02391 
02392 # ifdef KMP_GOMP_COMPAT
02393 
02394 static void
02395 __kmp_stg_parse_gomp_cpu_affinity( char const * name, char const * value, void * data )
02396 {
02397     const char * next = NULL;
02398     char * temp_proclist;
02399     kmp_setting_t **rivals = (kmp_setting_t **) data;
02400     int rc;
02401 
02402     rc = __kmp_stg_check_rivals( name, value, rivals );
02403     if ( rc ) {
02404         return;
02405     }
02406 
02407     if ( TCR_4(__kmp_init_middle) ) {
02408         KMP_WARNING( EnvMiddleWarn, name );
02409         __kmp_env_toPrint( name, 0 );
02410         return;
02411     }
02412 
02413     __kmp_env_toPrint( name, 1 );
02414 
02415     if ( __kmp_parse_affinity_proc_id_list( name, value, &next,
02416       &temp_proclist )) {
02417         SKIP_WS(next);
02418         if (*next == '\0') {
02419             //
02420             // GOMP_CPU_AFFINITY => granularity=fine,explicit,proclist=...
02421             //
02422             __kmp_affinity_proclist = temp_proclist;
02423             __kmp_affinity_type = affinity_explicit;
02424             __kmp_affinity_gran = affinity_gran_fine;
02425         }
02426         else {
02427             KMP_WARNING( AffSyntaxError, name );
02428             if (temp_proclist != NULL) {
02429                 KMP_INTERNAL_FREE((void *)temp_proclist);
02430             }
02431         }
02432     }
02433     else {
02434         //
02435         // Warning already emitted
02436         //
02437         __kmp_affinity_type = affinity_none;
02438     }
02439 } // __kmp_stg_parse_gomp_cpu_affinity
02440 
02441 # endif /* KMP_GOMP_COMPAT */
02442 
02443 
02444 # if OMP_40_ENABLED
02445 
02446 /*-----------------------------------------------------------------------------
02447 
02448 The OMP_PLACES proc id list parser. Here is the grammar:
02449 
02450 place_list := place
02451 place_list := place , place_list
02452 place := num
02453 place := place : num
02454 place := place : num : signed
02455 place := { subplacelist }
02456 place := ! place                  // (lowest priority)
02457 subplace_list := subplace
02458 subplace_list := subplace , subplace_list
02459 subplace := num
02460 subplace := num : num
02461 subplace := num : num : signed
02462 signed := num
02463 signed := + signed
02464 signed := - signed
02465 
02466 -----------------------------------------------------------------------------*/
02467 
02468 static int
02469 __kmp_parse_subplace_list( const char *var, const char **scan )
02470 {
02471     const char *next;
02472 
02473     for (;;) {
02474         int start, count, stride;
02475 
02476         //
02477         // Read in the starting proc id
02478         //
02479         SKIP_WS(*scan);
02480         if ((**scan < '0') || (**scan > '9')) {
02481             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02482             return FALSE;
02483         }
02484         next = *scan;
02485         SKIP_DIGITS(next);
02486         start = __kmp_str_to_int(*scan, *next);
02487         KMP_ASSERT(start >= 0);
02488         *scan = next;
02489 
02490         //
02491         // valid follow sets are ',' ':' and '}'
02492         //
02493         SKIP_WS(*scan);
02494         if (**scan == '}') {
02495             break;
02496         }
02497         if (**scan == ',') {
02498             (*scan)++;  // skip ','
02499             continue;
02500         }
02501         if (**scan != ':') {
02502             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02503             return FALSE;
02504         }
02505         (*scan)++;      // skip ':'
02506 
02507         //
02508         // Read count parameter
02509         //
02510         SKIP_WS(*scan);
02511         if ((**scan < '0') || (**scan > '9')) {
02512             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02513             return FALSE;
02514         }
02515         next = *scan;
02516         SKIP_DIGITS(next);
02517         count = __kmp_str_to_int(*scan, *next);
02518         KMP_ASSERT(count >= 0);
02519         *scan = next;
02520 
02521         //
02522         // valid follow sets are ',' ':' and '}'
02523         //
02524         SKIP_WS(*scan);
02525         if (**scan == '}') {
02526             break;
02527         }
02528         if (**scan == ',') {
02529             (*scan)++;  // skip ','
02530             continue;
02531         }
02532         if (**scan != ':') {
02533             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02534             return FALSE;
02535         }
02536         (*scan)++;      // skip ':'
02537 
02538         //
02539         // Read stride parameter
02540         //
02541         int sign = +1;
02542         for (;;) {
02543             SKIP_WS(*scan);
02544             if (**scan == '+') {
02545                 (*scan)++; // skip '+'
02546                 continue;
02547             }
02548             if (**scan == '-') {
02549                 sign *= -1;
02550                 (*scan)++; // skip '-'
02551                 continue;
02552             }
02553             break;
02554         }
02555         SKIP_WS(*scan);
02556         if ((**scan < '0') || (**scan > '9')) {
02557             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02558             return FALSE;
02559         }
02560         next = *scan;
02561         SKIP_DIGITS(next);
02562         stride = __kmp_str_to_int(*scan, *next);
02563         KMP_ASSERT(stride >= 0);
02564         *scan = next;
02565         stride *= sign;
02566 
02567         //
02568         // valid follow sets are ',' and '}'
02569         //
02570         SKIP_WS(*scan);
02571         if (**scan == '}') {
02572             break;
02573         }
02574         if (**scan == ',') {
02575             (*scan)++;  // skip ','
02576             continue;
02577         }
02578 
02579         KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02580         return FALSE;
02581     }
02582     return TRUE;
02583 }
02584 
02585 static int
02586 __kmp_parse_place( const char *var, const char ** scan )
02587 {
02588     const char *next;
02589 
02590     //
02591     // valid follow sets are '{' '!' and num
02592     //
02593     SKIP_WS(*scan);
02594     if (**scan == '{') {
02595         (*scan)++;      // skip '{'
02596         if (! __kmp_parse_subplace_list(var, scan)) {
02597             return FALSE;
02598         }
02599         if (**scan != '}') {
02600             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02601             return FALSE;
02602         }
02603         (*scan)++;      // skip '}'
02604     }
02605     else if (**scan == '!') {
02606         (*scan)++;      // skip '!'
02607         return __kmp_parse_place(var, scan); //'!' has lower precedence than ':'
02608     }
02609     else if ((**scan >= '0') && (**scan <= '9')) {
02610         next = *scan;
02611         SKIP_DIGITS(next);
02612         int proc = __kmp_str_to_int(*scan, *next);
02613         KMP_ASSERT(proc >= 0);
02614         *scan = next;
02615     }
02616     else {
02617         KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02618         return FALSE;
02619     }
02620     return TRUE;
02621 }
02622 
02623 static int
02624 __kmp_parse_place_list( const char *var, const char *env, char **place_list )
02625 {
02626     const char *scan = env;
02627     const char *next = scan;
02628 
02629     for (;;) {
02630         int start, count, stride;
02631 
02632         if (! __kmp_parse_place(var, &scan)) {
02633             return FALSE;
02634         }
02635 
02636         //
02637         // valid follow sets are ',' ':' and EOL
02638         //
02639         SKIP_WS(scan);
02640         if (*scan == '\0') {
02641             break;
02642         }
02643         if (*scan == ',') {
02644             scan++;     // skip ','
02645             continue;
02646         }
02647         if (*scan != ':') {
02648             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02649             return FALSE;
02650         }
02651         scan++;         // skip ':'
02652 
02653         //
02654         // Read count parameter
02655         //
02656         SKIP_WS(scan);
02657         if ((*scan < '0') || (*scan > '9')) {
02658             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02659             return FALSE;
02660         }
02661         next = scan;
02662         SKIP_DIGITS(next);
02663         count = __kmp_str_to_int(scan, *next);
02664         KMP_ASSERT(count >= 0);
02665         scan = next;
02666 
02667         //
02668         // valid follow sets are ',' ':' and EOL
02669         //
02670         SKIP_WS(scan);
02671         if (*scan == '\0') {
02672             break;
02673         }
02674         if (*scan == ',') {
02675             scan++;     // skip ','
02676             continue;
02677         }
02678         if (*scan != ':') {
02679             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02680             return FALSE;
02681         }
02682         scan++;         // skip ':'
02683 
02684         //
02685         // Read stride parameter
02686         //
02687         int sign = +1;
02688         for (;;) {
02689             SKIP_WS(scan);
02690             if (*scan == '+') {
02691                 scan++; // skip '+'
02692                 continue;
02693             }
02694             if (*scan == '-') {
02695                 sign *= -1;
02696                 scan++; // skip '-'
02697                 continue;
02698             }
02699             break;
02700         }
02701         SKIP_WS(scan);
02702         if ((*scan < '0') || (*scan > '9')) {
02703             KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02704             return FALSE;
02705         }
02706         next = scan;
02707         SKIP_DIGITS(next);
02708         stride = __kmp_str_to_int(scan, *next);
02709         KMP_ASSERT(stride >= 0);
02710         scan = next;
02711         stride *= sign;
02712 
02713         //
02714         // valid follow sets are ',' and EOL
02715         //
02716         SKIP_WS(scan);
02717         if (*scan == '\0') {
02718             break;
02719         }
02720         if (*scan == ',') {
02721             scan++;     // skip ','
02722             continue;
02723         }
02724 
02725         KMP_WARNING( SyntaxErrorUsing, var, "\"threads\"" );
02726         return FALSE;
02727     }
02728 
02729     {
02730         int len = scan - env;
02731         char *retlist = (char *)__kmp_allocate((len + 1) * sizeof(char));
02732         memcpy(retlist, env, len * sizeof(char));
02733         retlist[len] = '\0';
02734         *place_list = retlist;
02735     }
02736     return TRUE;
02737 }
02738 
02739 static void
02740 __kmp_stg_parse_places( char const * name, char const * value, void * data )
02741 {
02742     int count;
02743     const char *scan = value;
02744     const char *next = scan;
02745     const char *kind = "\"threads\"";
02746 
02747     //__kmp_affinity_num_places = 0;
02748 
02749     if ( __kmp_match_str( "threads", scan, &next ) ) {
02750         scan = next;
02751         __kmp_affinity_type = affinity_compact;
02752         __kmp_affinity_gran = affinity_gran_thread;
02753         __kmp_affinity_dups = FALSE;
02754         kind = "\"threads\"";
02755     }
02756     else if ( __kmp_match_str( "cores", scan, &next ) ) {
02757         scan = next;
02758         __kmp_affinity_type = affinity_compact;
02759         __kmp_affinity_gran = affinity_gran_core;
02760         __kmp_affinity_dups = FALSE;
02761         kind = "\"cores\"";
02762     }
02763     else if ( __kmp_match_str( "sockets", scan, &next ) ) {
02764         scan = next;
02765         __kmp_affinity_type = affinity_compact;
02766         __kmp_affinity_gran = affinity_gran_package;
02767         __kmp_affinity_dups = FALSE;
02768         kind = "\"sockets\"";
02769     }
02770     else {
02771         if ( __kmp_affinity_proclist != NULL ) {
02772             KMP_INTERNAL_FREE( (void *)__kmp_affinity_proclist );
02773             __kmp_affinity_proclist = NULL;
02774         }
02775         if ( __kmp_parse_place_list( name, value, &__kmp_affinity_proclist ) ) {
02776             __kmp_affinity_type = affinity_explicit;
02777             __kmp_affinity_gran = affinity_gran_fine;
02778             __kmp_affinity_dups = FALSE;
02779         }
02780         return;
02781     }
02782 
02783     SKIP_WS(scan);
02784     if ( *scan == '\0' ) {
02785         return;
02786     }
02787 
02788     //
02789     // Parse option count parameter in parentheses
02790     //
02791     if ( *scan != '(' ) {
02792         KMP_WARNING( SyntaxErrorUsing, name, kind );
02793         return;
02794     }
02795     scan++;     // skip '('
02796 
02797     SKIP_WS(scan);
02798     next = scan;
02799     SKIP_DIGITS(next);
02800     count = __kmp_str_to_int(scan, *next);
02801     KMP_ASSERT(count >= 0);
02802     scan = next;
02803 
02804     SKIP_WS(scan);
02805     if ( *scan != ')' ) {
02806         KMP_WARNING( SyntaxErrorUsing, name, kind );
02807         return;
02808     }
02809     scan++;     // skip ')'
02810 
02811     SKIP_WS(scan);
02812     if ( *scan != '\0' ) {
02813         KMP_WARNING( ParseExtraCharsWarn, name, scan );
02814     }
02815     __kmp_affinity_num_places = count;
02816 }
02817 
02818 static void
02819 __kmp_stg_print_places( kmp_str_buf_t * buffer, char const * name,
02820   void * data )
02821 {
02822     if ( ( __kmp_nested_proc_bind.used == 0 )
02823       || ( __kmp_nested_proc_bind.bind_types == NULL )
02824       || ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_false )
02825       || ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_intel ) ) {
02826         __kmp_str_buf_print( buffer, "   %s: %s \n", name,
02827           KMP_I18N_STR( NotDefined ) );
02828     }
02829     else if ( __kmp_affinity_type == affinity_explicit ) {
02830         if ( __kmp_affinity_proclist != NULL ) {
02831             __kmp_str_buf_print( buffer, "   %s=\"%s\" \n", name,
02832               __kmp_affinity_proclist );
02833         }
02834         else {
02835             __kmp_str_buf_print( buffer, "   %s: %s \n", name,
02836               KMP_I18N_STR( NotDefined ) );
02837         }
02838     }
02839     else if ( __kmp_affinity_type == affinity_compact ) {
02840         int num;
02841         if ( __kmp_affinity_num_masks > 0 ) {
02842             num = __kmp_affinity_num_masks;
02843         }
02844         else if ( __kmp_affinity_num_places > 0 ) {
02845             num = __kmp_affinity_num_places;
02846         }
02847         else {
02848             num = 0;
02849         }
02850         if ( __kmp_affinity_gran == affinity_gran_thread ) {
02851             if ( num > 0 ) {
02852                 __kmp_str_buf_print( buffer, "   %s=\"threads(%d)\" \n", name,
02853                   num );
02854             }
02855             else {
02856                 __kmp_str_buf_print( buffer, "   %s=\"threads\" \n", name );
02857             }
02858         }
02859         else if ( __kmp_affinity_gran == affinity_gran_core ) {
02860             if ( num > 0 ) {
02861                 __kmp_str_buf_print( buffer, "   %s=\"cores(%d)\" \n", name,
02862                   num );
02863             }
02864             else {
02865                 __kmp_str_buf_print( buffer, "   %s=\"cores\" \n", name );
02866             }
02867         }
02868         else if ( __kmp_affinity_gran == affinity_gran_package ) {
02869             if ( num > 0 ) {
02870                 __kmp_str_buf_print( buffer, "   %s=\"sockets(%d)\" \n", name,
02871                   num );
02872             }
02873             else {
02874                 __kmp_str_buf_print( buffer, "   %s=\"sockets\" \n", name );
02875             }
02876         }
02877         else {
02878             __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
02879         }
02880     }
02881     else {
02882         __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
02883     }
02884 }
02885 
02886 # endif /* OMP_40_ENABLED */
02887 
02888 # if OMP_30_ENABLED && (! OMP_40_ENABLED)
02889 
02890 static void
02891 __kmp_stg_parse_proc_bind( char const * name, char const * value, void * data )
02892 {
02893     int enabled;
02894     kmp_setting_t **rivals = (kmp_setting_t **) data;
02895     int rc;
02896 
02897     rc = __kmp_stg_check_rivals( name, value, rivals );
02898     if ( rc ) {
02899         return;
02900     }
02901 
02902     //
02903     // in OMP 3.1, OMP_PROC_BIND is strictly a boolean
02904     //
02905     __kmp_stg_parse_bool( name, value, & enabled );
02906     if ( enabled ) {
02907             //
02908             // OMP_PROC_BIND => granularity=core,scatter
02909             //
02910             __kmp_affinity_type = affinity_scatter;
02911             __kmp_affinity_gran = affinity_gran_core;
02912     }
02913     else {
02914         __kmp_affinity_type = affinity_none;
02915     }
02916 } // __kmp_parse_proc_bind
02917 
02918 # endif /* if OMP_30_ENABLED && (! OMP_40_ENABLED) */
02919 
02920 
02921 static void
02922 __kmp_stg_parse_topology_method( char const * name, char const * value,
02923   void * data ) {
02924     if ( __kmp_str_match( "all", 1, value ) ) {
02925        __kmp_affinity_top_method = affinity_top_method_all;
02926     }
02927 # if KMP_ARCH_X86 || KMP_ARCH_X86_64
02928     else if ( __kmp_str_match( "x2apic id", 9, value )
02929       || __kmp_str_match( "x2apic_id", 9, value )
02930       || __kmp_str_match( "x2apic-id", 9, value )
02931       || __kmp_str_match( "x2apicid", 8, value )
02932       || __kmp_str_match( "cpuid leaf 11", 13, value )
02933       || __kmp_str_match( "cpuid_leaf_11", 13, value )
02934       || __kmp_str_match( "cpuid-leaf-11", 13, value )
02935       || __kmp_str_match( "cpuid leaf11", 12, value )
02936       || __kmp_str_match( "cpuid_leaf11", 12, value )
02937       || __kmp_str_match( "cpuid-leaf11", 12, value )
02938       || __kmp_str_match( "cpuidleaf 11", 12, value )
02939       || __kmp_str_match( "cpuidleaf_11", 12, value )
02940       || __kmp_str_match( "cpuidleaf-11", 12, value )
02941       || __kmp_str_match( "cpuidleaf11", 11, value )
02942       || __kmp_str_match( "cpuid 11", 8, value )
02943       || __kmp_str_match( "cpuid_11", 8, value )
02944       || __kmp_str_match( "cpuid-11", 8, value )
02945       || __kmp_str_match( "cpuid11", 7, value )
02946       || __kmp_str_match( "leaf 11", 7, value )
02947       || __kmp_str_match( "leaf_11", 7, value )
02948       || __kmp_str_match( "leaf-11", 7, value )
02949       || __kmp_str_match( "leaf11", 6, value ) ) {
02950         __kmp_affinity_top_method = affinity_top_method_x2apicid;
02951     }
02952     else if ( __kmp_str_match( "apic id", 7, value )
02953       || __kmp_str_match( "apic_id", 7, value )
02954       || __kmp_str_match( "apic-id", 7, value )
02955       || __kmp_str_match( "apicid", 6, value )
02956       || __kmp_str_match( "cpuid leaf 4", 12, value )
02957       || __kmp_str_match( "cpuid_leaf_4", 12, value )
02958       || __kmp_str_match( "cpuid-leaf-4", 12, value )
02959       || __kmp_str_match( "cpuid leaf4", 11, value )
02960       || __kmp_str_match( "cpuid_leaf4", 11, value )
02961       || __kmp_str_match( "cpuid-leaf4", 11, value )
02962       || __kmp_str_match( "cpuidleaf 4", 11, value )
02963       || __kmp_str_match( "cpuidleaf_4", 11, value )
02964       || __kmp_str_match( "cpuidleaf-4", 11, value )
02965       || __kmp_str_match( "cpuidleaf4", 10, value )
02966       || __kmp_str_match( "cpuid 4", 7, value )
02967       || __kmp_str_match( "cpuid_4", 7, value )
02968       || __kmp_str_match( "cpuid-4", 7, value )
02969       || __kmp_str_match( "cpuid4", 6, value )
02970       || __kmp_str_match( "leaf 4", 6, value )
02971       || __kmp_str_match( "leaf_4", 6, value )
02972       || __kmp_str_match( "leaf-4", 6, value )
02973       || __kmp_str_match( "leaf4", 5, value ) ) {
02974         __kmp_affinity_top_method = affinity_top_method_apicid;
02975     }
02976 # endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
02977     else if ( __kmp_str_match( "/proc/cpuinfo", 2, value )
02978       || __kmp_str_match( "cpuinfo", 5, value )) {
02979         __kmp_affinity_top_method = affinity_top_method_cpuinfo;
02980     }
02981 # if KMP_OS_WINDOWS && KMP_ARCH_X86_64
02982     else if ( __kmp_str_match( "group", 1, value ) ) {
02983         __kmp_affinity_top_method = affinity_top_method_group;
02984     }
02985 # endif /* KMP_OS_WINDOWS && KMP_ARCH_X86_64 */
02986     else if ( __kmp_str_match( "flat", 1, value ) ) {
02987         __kmp_affinity_top_method = affinity_top_method_flat;
02988     }
02989     else {
02990         KMP_WARNING( StgInvalidValue, name, value );
02991     }
02992 } // __kmp_stg_parse_topology_method
02993 
02994 static void
02995 __kmp_stg_print_topology_method( kmp_str_buf_t * buffer, char const * name,
02996   void * data ) {
02997 # if KMP_DEBUG
02998     char const * value = NULL;
02999 
03000     switch ( __kmp_affinity_top_method ) {
03001         case affinity_top_method_default:
03002         value = "default";
03003         break;
03004 
03005         case affinity_top_method_all:
03006         value = "all";
03007         break;
03008 
03009 #  if KMP_ARCH_X86 || KMP_ARCH_X86_64
03010         case affinity_top_method_x2apicid:
03011         value = "x2APIC id";
03012         break;
03013 
03014         case affinity_top_method_apicid:
03015         value = "APIC id";
03016         break;
03017 #  endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
03018 
03019         case affinity_top_method_cpuinfo:
03020         value = "cpuinfo";
03021         break;
03022 
03023 #  if KMP_OS_WINDOWS && KMP_ARCH_X86_64
03024         case affinity_top_method_group:
03025         value = "group";
03026         break;
03027 #  endif /* KMP_OS_WINDOWS && KMP_ARCH_X86_64 */
03028 
03029         case affinity_top_method_flat:
03030         value = "flat";
03031         break;
03032     }
03033 
03034     if ( value != NULL ) {
03035         __kmp_stg_print_str( buffer, name, value );
03036     }
03037 # endif /* KMP_DEBUG */
03038 } // __kmp_stg_print_topology_method
03039 
03040 #elif KMP_OS_DARWIN
03041     // affinity not supported
03042 #else
03043     #error "Unknown or unsupported OS"
03044 #endif /* KMP_OS_LINUX || KMP_OS_WINDOWS */
03045 
03046 
03047 #if OMP_40_ENABLED
03048 
03049 //
03050 // OMP_PROC_BIND / bind-var is functional on all 4.0 builds, including OS X*
03051 // OMP_PLACES / place-partition-var is not.
03052 //
03053 static void
03054 __kmp_stg_parse_proc_bind( char const * name, char const * value, void * data )
03055 {
03056     kmp_setting_t **rivals = (kmp_setting_t **) data;
03057     int rc;
03058 
03059     rc = __kmp_stg_check_rivals( name, value, rivals );
03060     if ( rc ) {
03061         return;
03062     }
03063 
03064     //
03065     // in OMP 4.0 OMP_PROC_BIND is a vector of proc_bind types.
03066     //
03067     KMP_DEBUG_ASSERT( (__kmp_nested_proc_bind.bind_types != NULL)
03068       && ( __kmp_nested_proc_bind.used > 0 ) );
03069 
03070     const char *buf = value;
03071     const char *next;
03072     int num;
03073     SKIP_WS( buf );
03074     if ( (*buf >= '0') && (*buf <= '9') ) {
03075         next = buf;
03076         SKIP_DIGITS( next );
03077         num = __kmp_str_to_int( buf, *next );
03078         KMP_ASSERT( num >= 0 );
03079         buf = next;
03080         SKIP_WS( buf );
03081     }
03082     else {
03083         num = -1;
03084     }
03085 
03086     next = buf;
03087     if ( __kmp_match_str( "disabled", buf, &next ) ) {
03088         buf = next;
03089         SKIP_WS( buf );
03090 # if KMP_OS_LINUX || KMP_OS_WINDOWS
03091         __kmp_affinity_type = affinity_disabled;
03092 # endif /* KMP_OS_LINUX || KMP_OS_WINDOWS */
03093         __kmp_nested_proc_bind.used = 1;
03094         __kmp_nested_proc_bind.bind_types[0] = proc_bind_disabled;
03095     }
03096     else if ( ( num == (int)proc_bind_false )
03097       || __kmp_match_str( "false", buf, &next ) ) {
03098         buf = next;
03099         SKIP_WS( buf );
03100 # if KMP_OS_LINUX || KMP_OS_WINDOWS
03101         __kmp_affinity_type = affinity_none;
03102 # endif /* KMP_OS_LINUX || KMP_OS_WINDOWS */
03103         __kmp_nested_proc_bind.used = 1;
03104         __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
03105     }
03106     else if ( ( num == (int)proc_bind_true )
03107       || __kmp_match_str( "true", buf, &next ) ) {
03108         buf = next;
03109         SKIP_WS( buf );
03110         __kmp_nested_proc_bind.used = 1;
03111 
03112         //
03113         // "true" currently maps to "spread"
03114         //
03115         __kmp_nested_proc_bind.bind_types[0] = proc_bind_spread;
03116     }
03117     else {
03118         //
03119         // Count the number of values in the env var string
03120         //
03121         const char *scan;
03122         int nelem = 1;
03123         for ( scan = buf; *scan != '\0'; scan++ ) {
03124             if ( *scan == ',' ) {
03125                 nelem++;
03126             }
03127         }
03128 
03129         //
03130         // Create / expand the nested proc_bind array as needed
03131         //
03132         if ( __kmp_nested_proc_bind.size < nelem ) {
03133             __kmp_nested_proc_bind.bind_types = (kmp_proc_bind_t *)
03134                 KMP_INTERNAL_REALLOC( __kmp_nested_proc_bind.bind_types,
03135                 sizeof(kmp_proc_bind_t) * nelem );
03136             if ( __kmp_nested_proc_bind.bind_types == NULL ) {
03137                 KMP_FATAL( MemoryAllocFailed );
03138             }
03139             __kmp_nested_proc_bind.size = nelem;
03140         }
03141         __kmp_nested_proc_bind.used = nelem;
03142 
03143         //
03144         // Save values in the nested proc_bind array
03145         //
03146         int i = 0;
03147         for (;;) {
03148             enum kmp_proc_bind_t bind;
03149 
03150             if ( ( num == (int)proc_bind_master )
03151               || __kmp_match_str( "master", buf, &next ) ) {
03152                 buf = next;
03153                 SKIP_WS( buf );
03154                 bind = proc_bind_master;
03155             }
03156             else if ( ( num == (int)proc_bind_close )
03157               || __kmp_match_str( "close", buf, &next ) ) {
03158                 buf = next;
03159                 SKIP_WS( buf );
03160                 bind = proc_bind_close;
03161             }
03162             else if ( ( num == (int)proc_bind_spread )
03163               || __kmp_match_str( "spread", buf, &next ) ) {
03164                 buf = next;
03165                 SKIP_WS( buf );
03166                 bind = proc_bind_spread;
03167             }
03168             else {
03169                 KMP_WARNING( StgInvalidValue, name, value );
03170                 __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
03171                 __kmp_nested_proc_bind.used = 1;
03172                 return;
03173             }
03174 
03175             __kmp_nested_proc_bind.bind_types[i++] = bind;
03176             if ( i >= nelem ) {
03177                 break;
03178             }
03179             KMP_DEBUG_ASSERT( *buf == ',' );
03180             buf++;
03181             SKIP_WS( buf );
03182 
03183             //
03184             // Read next value if it was specified as an integer
03185             //
03186             if ( (*buf >= '0') && (*buf <= '9') ) {
03187                 next = buf;
03188                 SKIP_DIGITS( next );
03189                 num = __kmp_str_to_int( buf, *next );
03190                 KMP_ASSERT( num >= 0 );
03191                 buf = next;
03192                 SKIP_WS( buf );
03193             }
03194             else {
03195                 num = -1;
03196             }
03197         }
03198         SKIP_WS( buf );
03199     }
03200     if ( *buf != '\0' ) {
03201         KMP_WARNING( ParseExtraCharsWarn, name, buf );
03202     }
03203 }
03204 
03205 
03206 static void
03207 __kmp_stg_print_proc_bind( kmp_str_buf_t * buffer, char const * name,
03208   void * data )
03209 {
03210     int nelem = __kmp_nested_proc_bind.used;
03211     if ( nelem == 0 ) {
03212         __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
03213     }
03214     else {
03215         int i;
03216         __kmp_str_buf_print( buffer, "   %s=\"", name );
03217         for ( i = 0; i < nelem; i++ ) {
03218             switch ( __kmp_nested_proc_bind.bind_types[i] ) {
03219                 case proc_bind_false:
03220                 __kmp_str_buf_print( buffer, "false" );
03221                 break;
03222 
03223                 case proc_bind_true:
03224                 __kmp_str_buf_print( buffer, "true" );
03225                 break;
03226 
03227                 case proc_bind_master:
03228                 __kmp_str_buf_print( buffer, "master" );
03229                 break;
03230 
03231                 case proc_bind_close:
03232                 __kmp_str_buf_print( buffer, "close" );
03233                 break;
03234 
03235                 case proc_bind_spread:
03236                 __kmp_str_buf_print( buffer, "spread" );
03237                 break;
03238 
03239                 case proc_bind_disabled:
03240                 __kmp_str_buf_print( buffer, "disabled" );
03241                 break;
03242 
03243                 case proc_bind_intel:
03244                 __kmp_str_buf_print( buffer, "intel" );
03245                 break;
03246 
03247                 case proc_bind_default:
03248                 __kmp_str_buf_print( buffer, "default" );
03249                 break;
03250             }
03251             if ( i < nelem - 1 ) {
03252                 __kmp_str_buf_print( buffer, "," );
03253             }
03254         }
03255         __kmp_str_buf_print( buffer, "\"\n" );
03256     }
03257 }
03258 
03259 #endif /* OMP_40_ENABLED */
03260 
03261 
03262 // -------------------------------------------------------------------------------------------------
03263 // OMP_DYNAMIC
03264 // -------------------------------------------------------------------------------------------------
03265 
03266 static void
03267 __kmp_stg_parse_omp_dynamic( char const * name, char const * value, void * data )
03268 {
03269     __kmp_stg_parse_bool( name, value, & (__kmp_global.g.g_dynamic) );
03270 } // __kmp_stg_parse_omp_dynamic
03271 
03272 static void
03273 __kmp_stg_print_omp_dynamic( kmp_str_buf_t * buffer, char const * name, void * data )
03274 {
03275     __kmp_stg_print_bool( buffer, name, __kmp_global.g.g_dynamic );
03276 } // __kmp_stg_print_omp_dynamic
03277 
03278 static void
03279 __kmp_stg_parse_kmp_dynamic_mode( char const * name, char const * value, void * data )
03280 {
03281     if ( TCR_4(__kmp_init_parallel) ) {
03282         KMP_WARNING( EnvParallelWarn, name );
03283         __kmp_env_toPrint( name, 0 );
03284         return;
03285     }
03286 #ifdef USE_LOAD_BALANCE
03287     else if ( __kmp_str_match( "load balance", 2, value )
03288       || __kmp_str_match( "load_balance", 2, value )
03289       || __kmp_str_match( "load-balance", 2, value )
03290       || __kmp_str_match( "loadbalance", 2, value )
03291       || __kmp_str_match( "balance", 1, value ) ) {
03292         __kmp_global.g.g_dynamic_mode = dynamic_load_balance;
03293     }
03294 #endif /* USE_LOAD_BALANCE */
03295     else if ( __kmp_str_match( "thread limit", 1, value )
03296       || __kmp_str_match( "thread_limit", 1, value )
03297       || __kmp_str_match( "thread-limit", 1, value )
03298       || __kmp_str_match( "threadlimit", 1, value )
03299       || __kmp_str_match( "limit", 2, value ) ) {
03300         __kmp_global.g.g_dynamic_mode = dynamic_thread_limit;
03301     }
03302     else if ( __kmp_str_match( "random", 1, value ) ) {
03303         __kmp_global.g.g_dynamic_mode = dynamic_random;
03304     }
03305     else {
03306         KMP_WARNING( StgInvalidValue, name, value );
03307     }
03308 } //__kmp_stg_parse_kmp_dynamic_mode
03309 
03310 static void
03311 __kmp_stg_print_kmp_dynamic_mode( kmp_str_buf_t * buffer, char const * name, void * data )
03312 {
03313 #if KMP_DEBUG
03314     if ( __kmp_global.g.g_dynamic_mode == dynamic_default ) {
03315         __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
03316     }
03317 # ifdef USE_LOAD_BALANCE
03318     else if ( __kmp_global.g.g_dynamic_mode == dynamic_load_balance ) {
03319         __kmp_stg_print_str( buffer, name, "load balance" );
03320     }
03321 # endif /* USE_LOAD_BALANCE */
03322     else if ( __kmp_global.g.g_dynamic_mode == dynamic_thread_limit ) {
03323         __kmp_stg_print_str( buffer, name, "thread limit" );
03324     }
03325     else if ( __kmp_global.g.g_dynamic_mode == dynamic_random ) {
03326         __kmp_stg_print_str( buffer, name, "random" );
03327     }
03328     else {
03329         KMP_ASSERT(0);
03330     }
03331 #endif /* KMP_DEBUG */
03332 } // __kmp_stg_print_kmp_dynamic_mode
03333 
03334 
03335 #ifdef USE_LOAD_BALANCE
03336 
03337 // -------------------------------------------------------------------------------------------------
03338 // KMP_LOAD_BALANCE_INTERVAL
03339 // -------------------------------------------------------------------------------------------------
03340 
03341 static void
03342 __kmp_stg_parse_ld_balance_interval( char const * name, char const * value, void * data )
03343 {
03344     double interval = __kmp_convert_to_double( value );
03345     if ( interval >= 0 ) {
03346         __kmp_load_balance_interval = interval;
03347     } else {
03348         KMP_WARNING( StgInvalidValue, name, value );
03349     }; // if
03350 } // __kmp_stg_parse_load_balance_interval
03351 
03352 static void
03353 __kmp_stg_print_ld_balance_interval( kmp_str_buf_t * buffer, char const * name, void * data ) {
03354 #if KMP_DEBUG
03355     __kmp_str_buf_print( buffer, "   %s=%8.6f\n", name, __kmp_load_balance_interval );
03356 #endif /* KMP_DEBUG */
03357 } // __kmp_stg_print_load_balance_interval
03358 
03359 #endif /* USE_LOAD_BALANCE */
03360 
03361 
03362 
03363 // -------------------------------------------------------------------------------------------------
03364 // KMP_INIT_AT_FORK
03365 // -------------------------------------------------------------------------------------------------
03366 
03367 static void
03368 __kmp_stg_parse_init_at_fork( char const * name, char const * value, void * data ) {
03369     __kmp_stg_parse_bool( name, value, & __kmp_need_register_atfork );
03370     if ( __kmp_need_register_atfork ) {
03371         __kmp_need_register_atfork_specified = TRUE;
03372     };
03373 } // __kmp_stg_parse_init_at_fork
03374 
03375 static void
03376 __kmp_stg_print_init_at_fork( kmp_str_buf_t * buffer, char const * name, void * data ) {
03377     __kmp_stg_print_bool( buffer, name, __kmp_need_register_atfork_specified );
03378 } // __kmp_stg_print_init_at_fork
03379 
03380 // -------------------------------------------------------------------------------------------------
03381 // KMP_SCHEDULE
03382 // -------------------------------------------------------------------------------------------------
03383 
03384 static void
03385 __kmp_stg_parse_schedule( char const * name, char const * value, void * data ) {
03386 
03387     if ( value != NULL ) {
03388         size_t length = strlen( value );
03389         if ( length > INT_MAX ) {
03390             KMP_WARNING( LongValue, name );
03391         } else {
03392             char *semicolon;
03393             if( value[ length - 1 ] == '"' || value[ length -1 ] == '\'' )
03394                 KMP_WARNING( UnbalancedQuotes, name );
03395             do {
03396                 char sentinel;
03397 
03398                 semicolon = (char *) strchr( value, ';' );
03399                 if( *value && semicolon != value ) {
03400                     char *comma = (char *) strchr( value, ',' );
03401 
03402                     if ( comma ) {
03403                         ++comma;
03404                         sentinel = ',';
03405                     } else
03406                         sentinel = ';';
03407                     if ( !__kmp_strcasecmp_with_sentinel( "static", value, sentinel ) ) {
03408                         if( !__kmp_strcasecmp_with_sentinel( "greedy", comma, ';' ) ) {
03409                             __kmp_static = kmp_sch_static_greedy;
03410                             continue;
03411                         } else if( !__kmp_strcasecmp_with_sentinel( "balanced", comma, ';' ) ) {
03412                             __kmp_static = kmp_sch_static_balanced;
03413                             continue;
03414                         }
03415                     } else if ( !__kmp_strcasecmp_with_sentinel( "guided", value, sentinel ) ) {
03416                         if ( !__kmp_strcasecmp_with_sentinel( "iterative", comma, ';' ) ) {
03417                             __kmp_guided = kmp_sch_guided_iterative_chunked;
03418                             continue;
03419                         } else if ( !__kmp_strcasecmp_with_sentinel( "analytical", comma, ';' ) ) {
03420                             /* analytical not allowed for too many threads */
03421                             __kmp_guided = kmp_sch_guided_analytical_chunked;
03422                             continue;
03423                         }
03424                     }
03425                     KMP_WARNING( InvalidClause, name, value );
03426                 } else
03427                     KMP_WARNING( EmptyClause, name );
03428             } while ( value = semicolon ? semicolon + 1 : NULL );
03429         }
03430     }; // if
03431 
03432 } // __kmp_stg_parse__schedule
03433 
03434 static void
03435 __kmp_stg_print_schedule( kmp_str_buf_t * buffer, char const * name, void * data ) {
03436     if ( __kmp_static == kmp_sch_static_greedy ) {
03437         __kmp_str_buf_print( buffer, "   %s=\"%s", name, "static,greedy");
03438     } else if ( __kmp_static == kmp_sch_static_balanced ) {
03439         __kmp_str_buf_print ( buffer, "   %s=\"%s", name, "static,balanced");
03440     }
03441     if ( __kmp_guided == kmp_sch_guided_iterative_chunked ) {
03442         __kmp_str_buf_print( buffer, ";%s\"\n", "guided,iterative");
03443     } else if ( __kmp_guided == kmp_sch_guided_analytical_chunked ) {
03444         __kmp_str_buf_print( buffer, ";%s\"\n", "guided,analytical");
03445     }
03446 } // __kmp_stg_print_schedule
03447 
03448 // -------------------------------------------------------------------------------------------------
03449 // OMP_SCHEDULE
03450 // -------------------------------------------------------------------------------------------------
03451 
03452 static void
03453 __kmp_stg_parse_omp_schedule( char const * name, char const * value, void * data )
03454 {
03455     size_t      length;
03456     if( value ) {
03457         length = strlen( value );
03458         if( length ) {
03459             char *comma = (char *) strchr( value, ',' );
03460             if( value[ length - 1 ] == '"' || value[ length -1 ] == '\'')
03461                 KMP_WARNING( UnbalancedQuotes, name );
03462             /* get the specified scheduling style */
03463             if (!__kmp_strcasecmp_with_sentinel("dynamic", value, ','))          /* DYNAMIC */
03464                 __kmp_sched = kmp_sch_dynamic_chunked;
03465             else if (!__kmp_strcasecmp_with_sentinel("guided", value, ','))      /* GUIDED */
03466                 __kmp_sched = kmp_sch_guided_chunked;
03467 // AC: TODO: add AUTO schedule, and pprobably remove TRAPEZOIDAL (OMP 3.0 does not allow it)
03468             #if OMP_30_ENABLED
03469             else if (!__kmp_strcasecmp_with_sentinel("auto", value, ',')) {       /* AUTO */
03470                 __kmp_sched = kmp_sch_auto;
03471                 if( comma ) {
03472                     __kmp_msg( kmp_ms_warning, KMP_MSG( IgnoreChunk, name, comma ), __kmp_msg_null );
03473                     comma = NULL;
03474                 }
03475             }
03476             #endif // OMP_30_ENABLED
03477             else if (!__kmp_strcasecmp_with_sentinel("trapezoidal", value, ',')) /* TRAPEZOIDAL */
03478                 __kmp_sched = kmp_sch_trapezoidal;
03479             else if (!__kmp_strcasecmp_with_sentinel("static", value, ','))      /* STATIC */
03480                 __kmp_sched = kmp_sch_static;
03481 #ifdef KMP_STATIC_STEAL_ENABLED
03482             else if (KMP_ARCH_X86_64 &&
03483                      !__kmp_strcasecmp_with_sentinel("static_steal", value, ','))
03484                 __kmp_sched = kmp_sch_static_steal;
03485 #endif
03486             else {
03487                 KMP_WARNING( StgInvalidValue, name, value );
03488                 value = NULL; /* skip processing of comma */
03489             }
03490             if( value && comma ) {
03491                 __kmp_env_chunk = TRUE;
03492 
03493                 if(__kmp_sched == kmp_sch_static)
03494                     __kmp_sched = kmp_sch_static_chunked;
03495                 ++comma;
03496                 __kmp_chunk = __kmp_str_to_int( comma, 0 );
03497 //                if (__kmp_chunk < 0)  // AC: value 0 is invalid as well, replaced it with 1
03498                 if ( __kmp_chunk < 1 ) {
03499                     __kmp_chunk = KMP_DEFAULT_CHUNK;
03500                     __kmp_msg( kmp_ms_warning, KMP_MSG( InvalidChunk, name, comma ), __kmp_msg_null );
03501                     KMP_INFORM( Using_int_Value, name, __kmp_chunk );
03502 // AC: next block commented out until KMP_DEFAULT_CHUNK != KMP_MIN_CHUNK (to improve code coverage :)
03503 //     The default chunk size is 1 according to standard, thus making KMP_MIN_CHUNK not 1 we would introduce mess:
03504 //     wrong chunk becomes 1, but it will be impossible to explicitely set 1, because it becomes KMP_MIN_CHUNK...
03505 //                } else if ( __kmp_chunk < KMP_MIN_CHUNK ) {
03506 //                    __kmp_chunk = KMP_MIN_CHUNK;
03507                 } else if ( __kmp_chunk > KMP_MAX_CHUNK ) {
03508                     __kmp_chunk = KMP_MAX_CHUNK;
03509                     __kmp_msg( kmp_ms_warning, KMP_MSG( LargeChunk, name, comma ), __kmp_msg_null );
03510                     KMP_INFORM( Using_int_Value, name, __kmp_chunk );
03511                 }
03512             } else
03513                 __kmp_env_chunk = FALSE;
03514         } else
03515             KMP_WARNING( EmptyString, name );
03516     }
03517 //    if( __kmp_sched == kmp_sch_static ) {
03518 //        __kmp_sched = __kmp_static;        // AC: moved to __kmp_get_schedule_global
03519 //    }
03520 
03521     K_DIAG(1, ("__kmp_static == %d\n", __kmp_static))
03522     K_DIAG(1, ("__kmp_guided == %d\n", __kmp_guided))
03523     K_DIAG(1, ("__kmp_sched == %d\n", __kmp_sched))
03524     K_DIAG(1, ("__kmp_chunk == %d\n", __kmp_chunk))
03525 } // __kmp_stg_parse_omp_schedule
03526 
03527 static void
03528 __kmp_stg_print_omp_schedule( kmp_str_buf_t * buffer, char const * name, void * data ) {
03529     if ( __kmp_chunk ) {
03530         switch ( __kmp_sched ) {
03531             case kmp_sch_dynamic_chunked:
03532                 __kmp_str_buf_print( buffer, "   %s=\"%s, %d\"\n", name, "dynamic", __kmp_chunk);
03533                 break;
03534             case kmp_sch_guided_iterative_chunked:
03535             case kmp_sch_guided_analytical_chunked:
03536                 __kmp_str_buf_print( buffer, "   %s=\"%s, %d\"\n", name, "guided", __kmp_chunk);
03537                 break;
03538             case kmp_sch_trapezoidal:
03539                 __kmp_str_buf_print( buffer, "   %s=\"%s, %d\"\n", name, "trapezoidal", __kmp_chunk);
03540                 break;
03541             case kmp_sch_static_chunked:
03542             case kmp_sch_static_balanced:
03543             case kmp_sch_static_greedy:
03544                 __kmp_str_buf_print( buffer, "   %s=\"%s, %d\"\n", name, "static", __kmp_chunk);
03545                 break;
03546             case kmp_sch_static_steal:
03547                 __kmp_str_buf_print( buffer, "   %s=\"%s, %d\"\n", name, "static_steal", __kmp_chunk);
03548                 break;
03549         }
03550     } else {
03551         switch ( __kmp_sched ) {
03552             case kmp_sch_dynamic_chunked:
03553                 __kmp_stg_print_str( buffer, name, "dynamic");
03554                 break;
03555             case kmp_sch_guided_iterative_chunked:
03556             case kmp_sch_guided_analytical_chunked:
03557                 __kmp_stg_print_str( buffer, name, "guided");
03558                 break;
03559             case kmp_sch_trapezoidal:
03560                 __kmp_stg_print_str( buffer, name, "trapezoidal");
03561                 break;
03562             case kmp_sch_static_chunked:
03563             case kmp_sch_static_balanced:
03564             case kmp_sch_static_greedy:
03565                 __kmp_stg_print_str( buffer, name, "static");
03566                 break;
03567             case kmp_sch_static_steal:
03568                 __kmp_stg_print_str( buffer, name, "static_steal");
03569                 break;
03570         }
03571     }
03572 } // __kmp_stg_print_omp_schedule
03573 
03574 // -------------------------------------------------------------------------------------------------
03575 // KMP_ATOMIC_MODE
03576 // -------------------------------------------------------------------------------------------------
03577 
03578 static void
03579 __kmp_stg_parse_atomic_mode( char const * name, char const * value, void * data ) {
03580     // Modes: 0 -- do not change default; 1 -- Intel perf mode, 2 -- GOMP compatibility mode.
03581     int mode = 0;
03582     int max  = 1;
03583     #ifdef KMP_GOMP_COMPAT
03584         max = 2;
03585     #endif /* KMP_GOMP_COMPAT */
03586     __kmp_stg_parse_int( name, value, 0, max, & mode );
03587     // TODO; parse_int is not very suitable for this case. In case of overflow it is better to use
03588     // 0 rather that max value.
03589     if ( mode > 0 ) {
03590         __kmp_atomic_mode = mode;
03591     }; // if
03592 } // __kmp_stg_parse_atomic_mode
03593 
03594 static void
03595 __kmp_stg_print_atomic_mode( kmp_str_buf_t * buffer, char const * name, void * data ) {
03596     __kmp_stg_print_int( buffer, name, __kmp_atomic_mode );
03597 } // __kmp_stg_print_atomic_mode
03598 
03599 
03600 // -------------------------------------------------------------------------------------------------
03601 // KMP_CONSISTENCY_CHECK
03602 // -------------------------------------------------------------------------------------------------
03603 
03604 static void
03605 __kmp_stg_parse_consistency_check( char const * name, char const * value, void * data ) {
03606     if ( ! __kmp_strcasecmp_with_sentinel( "all", value, 0 ) ) {
03607         // Note, this will not work from kmp_set_defaults because th_cons stack was not allocated
03608         // for existed thread(s) thus the first __kmp_push_<construct> will break with assertion.
03609         // TODO: allocate th_cons if called from kmp_set_defaults.
03610         __kmp_env_consistency_check = TRUE;
03611     } else if ( ! __kmp_strcasecmp_with_sentinel( "none", value, 0 ) ) {
03612         __kmp_env_consistency_check = FALSE;
03613     } else {
03614         KMP_WARNING( StgInvalidValue, name, value );
03615     }; // if
03616 } // __kmp_stg_parse_consistency_check
03617 
03618 static void
03619 __kmp_stg_print_consistency_check( kmp_str_buf_t * buffer, char const * name, void * data ) {
03620 #if KMP_DEBUG
03621     const char *value = NULL;
03622 
03623     if ( __kmp_env_consistency_check ) {
03624         value = "all";
03625     } else {
03626         value = "none";
03627     }
03628 
03629     if ( value != NULL ) {
03630         __kmp_stg_print_str( buffer, name, value );
03631     }
03632 #endif /* KMP_DEBUG */
03633 } // __kmp_stg_print_consistency_check
03634 
03635 
03636 
03637 // -------------------------------------------------------------------------------------------------
03638 // KMP_MALLOC_POOL_INCR
03639 // -------------------------------------------------------------------------------------------------
03640 
03641 static void
03642 __kmp_stg_parse_malloc_pool_incr( char const * name, char const * value, void * data ) {
03643     __kmp_stg_parse_size(
03644             name,
03645             value,
03646             KMP_MIN_MALLOC_POOL_INCR,
03647             KMP_MAX_MALLOC_POOL_INCR,
03648             NULL,
03649             & __kmp_malloc_pool_incr,
03650             1
03651         );
03652 } // __kmp_stg_parse_malloc_pool_incr
03653 
03654 static void
03655 __kmp_stg_print_malloc_pool_incr( kmp_str_buf_t * buffer, char const * name, void * data ) {
03656        __kmp_stg_print_size( buffer, name, __kmp_malloc_pool_incr );
03657 
03658 } // _kmp_stg_print_malloc_pool_incr
03659 
03660 
03661 #ifdef KMP_DEBUG
03662 
03663 // -------------------------------------------------------------------------------------------------
03664 // KMP_PAR_RANGE
03665 // -------------------------------------------------------------------------------------------------
03666 
03667 static void
03668 __kmp_stg_parse_par_range_env( char const * name, char const * value, void * data ) {
03669         __kmp_stg_parse_par_range(
03670             name,
03671             value,
03672             & __kmp_par_range,
03673             __kmp_par_range_routine,
03674             __kmp_par_range_filename,
03675             & __kmp_par_range_lb,
03676             & __kmp_par_range_ub
03677         );
03678 } // __kmp_stg_parse_par_range_env
03679 
03680 static void
03681 __kmp_stg_print_par_range_env( kmp_str_buf_t * buffer, char const * name, void * data ) {
03682     if (__kmp_par_range != 0) {
03683         __kmp_stg_print_str( buffer, name, par_range_to_print );
03684     }
03685 } // __kmp_stg_print_par_range_env
03686 
03687 // -------------------------------------------------------------------------------------------------
03688 // KMP_YIELD_CYCLE, KMP_YIELD_ON, KMP_YIELD_OFF
03689 // -------------------------------------------------------------------------------------------------
03690 
03691 static void
03692 __kmp_stg_parse_yield_cycle( char const * name, char const * value, void * data ) {
03693     int flag = __kmp_yield_cycle;
03694     __kmp_stg_parse_bool( name, value, & flag );
03695     __kmp_yield_cycle = flag;
03696 } // __kmp_stg_parse_yield_cycle
03697 
03698 static void
03699 __kmp_stg_print_yield_cycle( kmp_str_buf_t * buffer, char const * name, void * data ) {
03700     __kmp_stg_print_bool( buffer, name, __kmp_yield_cycle );
03701 } // __kmp_stg_print_yield_cycle
03702 
03703 static void
03704 __kmp_stg_parse_yield_on( char const * name, char const * value, void * data ) {
03705         __kmp_stg_parse_int( name, value, 2, INT_MAX, & __kmp_yield_on_count );
03706 } // __kmp_stg_parse_yield_on
03707 
03708 static void
03709 __kmp_stg_print_yield_on( kmp_str_buf_t * buffer, char const * name, void * data ) {
03710     __kmp_stg_print_int( buffer, name, __kmp_yield_on_count );
03711 } // __kmp_stg_print_yield_on
03712 
03713 static void
03714 __kmp_stg_parse_yield_off( char const * name, char const * value, void * data ) {
03715         __kmp_stg_parse_int( name, value, 2, INT_MAX, & __kmp_yield_off_count );
03716 } // __kmp_stg_parse_yield_off
03717 
03718 static void
03719 __kmp_stg_print_yield_off( kmp_str_buf_t * buffer, char const * name, void * data ) {
03720     __kmp_stg_print_int( buffer, name, __kmp_yield_off_count );
03721 } // __kmp_stg_print_yield_off
03722 
03723 #endif
03724 
03725 // -------------------------------------------------------------------------------------------------
03726 // KMP_INIT_WAIT, KMP_NEXT_WAIT
03727 // -------------------------------------------------------------------------------------------------
03728 
03729 static void
03730 __kmp_stg_parse_init_wait( char const * name, char const * value, void * data ) {
03731    int wait;
03732    KMP_ASSERT( ( __kmp_init_wait & 1 ) == 0 );
03733    wait = __kmp_init_wait / 2;
03734     __kmp_stg_parse_int( name, value, KMP_MIN_INIT_WAIT, KMP_MAX_INIT_WAIT, & wait );
03735     __kmp_init_wait = wait * 2;
03736     KMP_ASSERT( ( __kmp_init_wait & 1 ) == 0 );
03737     __kmp_yield_init = __kmp_init_wait;
03738 } // __kmp_stg_parse_init_wait
03739 
03740 static void
03741 __kmp_stg_print_init_wait( kmp_str_buf_t * buffer, char const * name, void * data ) {
03742     __kmp_stg_print_int( buffer, name, __kmp_init_wait );
03743 } // __kmp_stg_print_init_wait
03744 
03745 static void
03746 __kmp_stg_parse_next_wait( char const * name, char const * value, void * data ) {
03747     int wait;
03748     KMP_ASSERT( ( __kmp_next_wait & 1 ) == 0 );
03749     wait = __kmp_next_wait / 2;
03750     __kmp_stg_parse_int( name, value, KMP_MIN_NEXT_WAIT, KMP_MAX_NEXT_WAIT, & wait );
03751     __kmp_next_wait = wait * 2;
03752     KMP_ASSERT( ( __kmp_next_wait & 1 ) == 0 );
03753     __kmp_yield_next = __kmp_next_wait;
03754 } // __kmp_stg_parse_next_wait
03755 
03756 static void
03757 __kmp_stg_print_next_wait( kmp_str_buf_t * buffer, char const * name, void * data ) {
03758     __kmp_stg_print_int( buffer, name, __kmp_next_wait );
03759 } //__kmp_stg_print_next_wait
03760 
03761 
03762 // -------------------------------------------------------------------------------------------------
03763 // KMP_GTID_MODE
03764 // -------------------------------------------------------------------------------------------------
03765 
03766 static void
03767 __kmp_stg_parse_gtid_mode( char const * name, char const * value, void * data ) {
03768     //
03769     // Modes:
03770     //   0 -- do not change default
03771     //   1 -- sp search
03772     //   2 -- use "keyed" TLS var, i.e.
03773     //        pthread_getspecific(Linux* OS/OS X*) or TlsGetValue(Windows* OS)
03774     //   3 -- __declspec(thread) TLS var in tdata section
03775     //
03776     int mode = 0;
03777     int max  = 2;
03778     #ifdef KMP_TDATA_GTID
03779         max = 3;
03780     #endif /* KMP_TDATA_GTID */
03781     __kmp_stg_parse_int( name, value, 0, max, & mode );
03782     // TODO; parse_int is not very suitable for this case. In case of overflow it is better to use
03783     // 0 rather that max value.
03784     if ( mode == 0 ) {
03785         __kmp_adjust_gtid_mode = TRUE;
03786     }
03787     else {
03788         __kmp_gtid_mode = mode;
03789         __kmp_adjust_gtid_mode = FALSE;
03790     }; // if
03791 } // __kmp_str_parse_gtid_mode
03792 
03793 static void
03794 __kmp_stg_print_gtid_mode( kmp_str_buf_t * buffer, char const * name, void * data ) {
03795     if ( __kmp_adjust_gtid_mode ) {
03796         __kmp_stg_print_int( buffer, name, 0 );
03797     }
03798     else {
03799         __kmp_stg_print_int( buffer, name, __kmp_gtid_mode );
03800     }
03801 } // __kmp_stg_print_gtid_mode
03802 
03803 
03804 // -------------------------------------------------------------------------------------------------
03805 // KMP_NUM_LOCKS_IN_BLOCK
03806 // -------------------------------------------------------------------------------------------------
03807 
03808 static void
03809 __kmp_stg_parse_lock_block( char const * name, char const * value, void * data ) {
03810     __kmp_stg_parse_int( name, value, 0, KMP_INT_MAX, & __kmp_num_locks_in_block );
03811 } // __kmp_str_parse_lock_block
03812 
03813 static void
03814 __kmp_stg_print_lock_block( kmp_str_buf_t * buffer, char const * name, void * data ) {
03815     __kmp_stg_print_int( buffer, name, __kmp_num_locks_in_block );
03816 } // __kmp_stg_print_lock_block
03817 
03818 // -------------------------------------------------------------------------------------------------
03819 // KMP_LOCK_KIND
03820 // -------------------------------------------------------------------------------------------------
03821 
03822 static void
03823 __kmp_stg_parse_lock_kind( char const * name, char const * value, void * data ) {
03824     if ( __kmp_init_user_locks ) {
03825         KMP_WARNING( EnvLockWarn, name );
03826         return;
03827     }
03828 
03829     if ( __kmp_str_match( "tas", 2, value )
03830       || __kmp_str_match( "test and set", 2, value )
03831       || __kmp_str_match( "test_and_set", 2, value )
03832       || __kmp_str_match( "test-and-set", 2, value )
03833       || __kmp_str_match( "test andset", 2, value )
03834       || __kmp_str_match( "test_andset", 2, value )
03835       || __kmp_str_match( "test-andset", 2, value )
03836       || __kmp_str_match( "testand set", 2, value )
03837       || __kmp_str_match( "testand_set", 2, value )
03838       || __kmp_str_match( "testand-set", 2, value )
03839       || __kmp_str_match( "testandset", 2, value ) ) {
03840         __kmp_user_lock_kind = lk_tas;
03841     }
03842 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
03843     else if ( __kmp_str_match( "futex", 1, value ) ) {
03844         if ( __kmp_futex_determine_capable() ) {
03845             __kmp_user_lock_kind = lk_futex;
03846         }
03847         else {
03848             KMP_WARNING( FutexNotSupported, name, value );
03849         }
03850     }
03851 #endif
03852     else if ( __kmp_str_match( "ticket", 2, value ) ) {
03853         __kmp_user_lock_kind = lk_ticket;
03854     }
03855     else if ( __kmp_str_match( "queuing", 1, value )
03856       || __kmp_str_match( "queue", 1, value ) ) {
03857         __kmp_user_lock_kind = lk_queuing;
03858     }
03859     else if ( __kmp_str_match( "drdpa ticket", 1, value )
03860       || __kmp_str_match( "drdpa_ticket", 1, value )
03861       || __kmp_str_match( "drdpa-ticket", 1, value )
03862       || __kmp_str_match( "drdpaticket", 1, value )
03863       || __kmp_str_match( "drdpa", 1, value ) ) {
03864         __kmp_user_lock_kind = lk_drdpa;
03865     }
03866     else {
03867         KMP_WARNING( StgInvalidValue, name, value );
03868     }
03869 }
03870 
03871 static void
03872 __kmp_stg_print_lock_kind( kmp_str_buf_t * buffer, char const * name, void * data ) {
03873     const char *value = NULL;
03874 
03875     switch ( __kmp_user_lock_kind ) {
03876         case lk_default:
03877         value = "default";
03878         break;
03879 
03880         case lk_tas:
03881         value = "tas";
03882         break;
03883 
03884 #if KMP_OS_LINUX && (KMP_ARCH_X86 || KMP_ARCH_X86_64)
03885         case lk_futex:
03886         value = "futex";
03887         break;
03888 #endif
03889 
03890         case lk_ticket:
03891         value = "ticket";
03892         break;
03893 
03894         case lk_queuing:
03895         value = "queuing";
03896         break;
03897 
03898         case lk_drdpa:
03899         value = "drdpa";
03900         break;
03901     }
03902 
03903     if ( value != NULL ) {
03904         __kmp_stg_print_str( buffer, name, value );
03905     }
03906 }
03907 
03908 #if KMP_MIC
03909 // -------------------------------------------------------------------------------------------------
03910 // KMP_PLACE_THREADS
03911 // -------------------------------------------------------------------------------------------------
03912 
03913 static void
03914 __kmp_stg_parse_place_threads( char const * name, char const * value, void * data ) {
03915     // Value example: 5Cx2Tx15O
03916     // Which means "use 5 cores with offset 15, 2 threads per core"
03917 
03918     int         num;
03919     int         prev_delim = 0;
03920     const char *next = value;
03921     const char *prev;
03922 
03923     SKIP_WS( next );
03924     if ( *next == '\0' ) {
03925         return;   // leave default values
03926     }
03927 
03928     // Get num_cores first
03929     if ( *next >= '0' && *next <= '9' ) {
03930         prev = next;
03931         SKIP_DIGITS( next );
03932         num = __kmp_str_to_int( prev, *next );
03933         SKIP_WS( next );
03934         if ( *next == 'C' || *next == 'c' ) {
03935             __kmp_place_num_cores = num;
03936             next++;
03937         } else if ( *next == ',' || *next == 'x' ) {
03938             __kmp_place_num_cores = num;
03939             prev_delim = 1;
03940             next++;
03941         } else if ( *next == 'T' || *next == 't' ) {
03942             __kmp_place_num_threads_per_core = num;
03943             return;   // we ignore offset value in case all cores are used
03944         } else if ( *next == '\0' ) {
03945             __kmp_place_num_cores = num;
03946             return;   // the only value provided
03947         } else {
03948             KMP_WARNING( AffThrPlaceInvalid, name, value );
03949             return;
03950         }
03951     } else if ( *next == ',' || *next == 'x' ) {
03952         // First character is delimiter, skip it, leave num_cores default value
03953         prev_delim = 2;
03954         next++;
03955     } else {
03956         KMP_WARNING( AffThrPlaceInvalid, name, value );
03957         return;
03958     }
03959     SKIP_WS( next );
03960     if ( *next == '\0' ) {
03961         return;   // " n  " - something like this
03962     }
03963     if ( ( *next == ',' || *next == 'x' ) && !prev_delim ) {
03964         prev_delim = 1;
03965         next++;   // skip delimiter after num_core value
03966         SKIP_WS( next );
03967     }
03968 
03969     // Get threads_per_core next
03970     if ( *next >= '0' && *next <= '9' ) {
03971         prev_delim = 0;
03972         prev = next;
03973         SKIP_DIGITS( next );
03974         num = __kmp_str_to_int( prev, *next );
03975         SKIP_WS( next );
03976         if ( *next == 'T' || *next == 't' ) {
03977             __kmp_place_num_threads_per_core = num;
03978             next++;
03979         } else if ( *next == ',' || *next == 'x' ) {
03980             __kmp_place_num_threads_per_core = num;
03981             prev_delim = 1;
03982             next++;
03983         } else if ( *next == 'O' || *next == 'o' ) {
03984             __kmp_place_core_offset = num;
03985             return;   // threads_per_core remains default
03986         } else if ( *next == '\0' ) {
03987             __kmp_place_num_threads_per_core = num;
03988             return;
03989         } else {
03990             KMP_WARNING( AffThrPlaceInvalid, name, value );
03991             return;
03992         }
03993     } else if ( *next == ',' || *next == 'x' ) {
03994         if ( prev_delim == 2 ) {
03995             return; // no sense in the only offset value, thus skip the rest
03996         }
03997         KMP_DEBUG_ASSERT( prev_delim == 1 );
03998         next++;     // no value for threads_per_core provided
03999     } else {
04000         KMP_WARNING( AffThrPlaceInvalid, name, value );
04001         return;
04002     }
04003     SKIP_WS( next );
04004     if ( *next == '\0' ) {
04005         return;   // " nC,mT  " - something like this
04006     }
04007     if ( ( *next == ',' || *next == 'x' ) && !prev_delim ) {
04008         prev_delim = 1;
04009         next++;   // skip delimiter after threads_per_core value
04010         SKIP_WS( next );
04011     }
04012 
04013     // Get core offset last if any,
04014     // don't bother checking syntax after all data obtained
04015     if ( *next >= '0' && *next <= '9' ) {
04016         prev = next;
04017         SKIP_DIGITS( next );
04018         num = __kmp_str_to_int( prev, *next );
04019         __kmp_place_core_offset = num;
04020     }
04021 }
04022 
04023 static void
04024 __kmp_stg_print_place_threads( kmp_str_buf_t * buffer, char const * name, void * data ) {
04025     if ( __kmp_place_num_cores + __kmp_place_num_threads_per_core ) {
04026         kmp_str_buf_t buf;
04027         __kmp_str_buf_init( &buf );
04028         __kmp_str_buf_print( &buf, "%dC", __kmp_place_num_cores );
04029         __kmp_str_buf_print( &buf, "x%dT", __kmp_place_num_threads_per_core );
04030         if ( __kmp_place_core_offset ) {
04031             __kmp_str_buf_print( &buf, ",%dO", __kmp_place_core_offset );
04032         }
04033         __kmp_stg_print_str(buffer, name, buf.str );
04034         __kmp_str_buf_free(&buf);
04035 /*
04036     } else {
04037         __kmp_str_buf_print( buffer, "   %s: %s \n", name, KMP_I18N_STR( NotDefined ) );
04038 */
04039     }
04040 }
04041 #endif
04042 
04043 // -------------------------------------------------------------------------------------------------
04044 // KMP_FORKJOIN_FRAMES
04045 // -------------------------------------------------------------------------------------------------
04046 
04047 static void
04048 __kmp_stg_parse_forkjoin_frames( char const * name, char const * value, void * data ) {
04049     __kmp_stg_parse_bool( name, value, & __kmp_forkjoin_frames );
04050 } // __kmp_stg_parse_forkjoin_frames
04051 
04052 static void
04053 __kmp_stg_print_forkjoin_frames( kmp_str_buf_t * buffer, char const * name, void * data ) {
04054     __kmp_stg_print_bool( buffer, name, __kmp_forkjoin_frames );
04055 } // __kmp_stg_print_forkjoin_frames
04056 
04057 // -------------------------------------------------------------------------------------------------
04058 // Table.
04059 // -------------------------------------------------------------------------------------------------
04060 
04061 
04062 static kmp_setting_t __kmp_stg_table[] = {
04063 
04064     { "KMP_ALL_THREADS",                   __kmp_stg_parse_all_threads,        __kmp_stg_print_all_threads,        NULL, 0, 0 },
04065     { "KMP_BLOCKTIME",                     __kmp_stg_parse_blocktime,          __kmp_stg_print_blocktime,          NULL, 0, 0 },
04066     { "KMP_DUPLICATE_LIB_OK",              __kmp_stg_parse_duplicate_lib_ok,   __kmp_stg_print_duplicate_lib_ok,   NULL, 0, 0 },
04067     { "KMP_LIBRARY",                       __kmp_stg_parse_wait_policy,        __kmp_stg_print_wait_policy,        NULL, 0, 0 },
04068     { "KMP_MAX_THREADS",                   __kmp_stg_parse_all_threads,        NULL,                               NULL, 0, 0 }, // For backward compatibility
04069     { "KMP_MONITOR_STACKSIZE",             __kmp_stg_parse_monitor_stacksize,  __kmp_stg_print_monitor_stacksize,  NULL, 0, 0 },
04070     { "KMP_SETTINGS",                      __kmp_stg_parse_settings,           __kmp_stg_print_settings,           NULL, 0, 0 },
04071     { "KMP_STACKOFFSET",                   __kmp_stg_parse_stackoffset,        __kmp_stg_print_stackoffset,        NULL, 0, 0 },
04072     { "KMP_STACKSIZE",                     __kmp_stg_parse_stacksize,          __kmp_stg_print_stacksize,          NULL, 0, 0 },
04073     { "KMP_VERSION",                       __kmp_stg_parse_version,            __kmp_stg_print_version,            NULL, 0, 0 },
04074     { "KMP_WARNINGS",                      __kmp_stg_parse_warnings,           __kmp_stg_print_warnings,           NULL, 0, 0 },
04075 
04076     { "OMP_NESTED",                        __kmp_stg_parse_nested,             __kmp_stg_print_nested,             NULL, 0, 0 },
04077     { "OMP_NUM_THREADS",                   __kmp_stg_parse_num_threads,        __kmp_stg_print_num_threads,        NULL, 0, 0 },
04078     { "OMP_STACKSIZE",                     __kmp_stg_parse_stacksize,          NULL,                               NULL, 0, 0 },
04079 
04080 #if OMP_30_ENABLED
04081     { "KMP_TASKING",                       __kmp_stg_parse_tasking,            __kmp_stg_print_tasking,            NULL, 0, 0 },
04082     { "KMP_TASK_STEALING_CONSTRAINT",      __kmp_stg_parse_task_stealing,      __kmp_stg_print_task_stealing,      NULL, 0, 0 },
04083     { "OMP_MAX_ACTIVE_LEVELS",             __kmp_stg_parse_max_active_levels,  __kmp_stg_print_max_active_levels,  NULL, 0, 0 },
04084     { "OMP_THREAD_LIMIT",                  __kmp_stg_parse_all_threads,        NULL,                               NULL, 0, 0 },
04085     { "OMP_WAIT_POLICY",                   __kmp_stg_parse_wait_policy,        __kmp_stg_print_wait_policy,        NULL, 0, 0 },
04086 #endif // OMP_30_ENABLED
04087 
04088 #if KMP_HANDLE_SIGNALS
04089     { "KMP_HANDLE_SIGNALS",                __kmp_stg_parse_handle_signals,     __kmp_stg_print_handle_signals,     NULL, 0, 0 },
04090 #endif
04091 
04092 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
04093     { "KMP_INHERIT_FP_CONTROL",            __kmp_stg_parse_inherit_fp_control, __kmp_stg_print_inherit_fp_control, NULL, 0, 0 },
04094 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
04095 
04096 #ifdef KMP_GOMP_COMPAT
04097     { "GOMP_STACKSIZE",                    __kmp_stg_parse_stacksize,          NULL,                               NULL, 0, 0 },
04098 #endif
04099 
04100 #ifdef KMP_DEBUG
04101     { "KMP_A_DEBUG",                       __kmp_stg_parse_a_debug,            __kmp_stg_print_a_debug,            NULL, 0, 0 },
04102     { "KMP_B_DEBUG",                       __kmp_stg_parse_b_debug,            __kmp_stg_print_b_debug,            NULL, 0, 0 },
04103     { "KMP_C_DEBUG",                       __kmp_stg_parse_c_debug,            __kmp_stg_print_c_debug,            NULL, 0, 0 },
04104     { "KMP_D_DEBUG",                       __kmp_stg_parse_d_debug,            __kmp_stg_print_d_debug,            NULL, 0, 0 },
04105     { "KMP_E_DEBUG",                       __kmp_stg_parse_e_debug,            __kmp_stg_print_e_debug,            NULL, 0, 0 },
04106     { "KMP_F_DEBUG",                       __kmp_stg_parse_f_debug,            __kmp_stg_print_f_debug,            NULL, 0, 0 },
04107     { "KMP_DEBUG",                         __kmp_stg_parse_debug,              NULL, /* no print */                NULL, 0, 0 },
04108     { "KMP_DEBUG_BUF",                     __kmp_stg_parse_debug_buf,          __kmp_stg_print_debug_buf,          NULL, 0, 0 },
04109     { "KMP_DEBUG_BUF_ATOMIC",              __kmp_stg_parse_debug_buf_atomic,   __kmp_stg_print_debug_buf_atomic,   NULL, 0, 0 },
04110     { "KMP_DEBUG_BUF_CHARS",               __kmp_stg_parse_debug_buf_chars,    __kmp_stg_print_debug_buf_chars,    NULL, 0, 0 },
04111     { "KMP_DEBUG_BUF_LINES",               __kmp_stg_parse_debug_buf_lines,    __kmp_stg_print_debug_buf_lines,    NULL, 0, 0 },
04112     { "KMP_DIAG",                          __kmp_stg_parse_diag,               __kmp_stg_print_diag,               NULL, 0, 0 },
04113 
04114     { "KMP_PAR_RANGE",                     __kmp_stg_parse_par_range_env,      __kmp_stg_print_par_range_env,      NULL, 0, 0 },
04115     { "KMP_YIELD_CYCLE",                   __kmp_stg_parse_yield_cycle,        __kmp_stg_print_yield_cycle,        NULL, 0, 0 },
04116     { "KMP_YIELD_ON",                      __kmp_stg_parse_yield_on,           __kmp_stg_print_yield_on,           NULL, 0, 0 },
04117     { "KMP_YIELD_OFF",                     __kmp_stg_parse_yield_off,          __kmp_stg_print_yield_off,          NULL, 0, 0 },
04118 #endif // KMP_DEBUG
04119 
04120     { "KMP_ALIGN_ALLOC",                   __kmp_stg_parse_align_alloc,        __kmp_stg_print_align_alloc,        NULL, 0, 0 },
04121 
04122     { "KMP_PLAIN_BARRIER",                 __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
04123     { "KMP_PLAIN_BARRIER_PATTERN",         __kmp_stg_parse_barrier_pattern,    __kmp_stg_print_barrier_pattern,    NULL, 0, 0 },
04124     { "KMP_FORKJOIN_BARRIER",              __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
04125     { "KMP_FORKJOIN_BARRIER_PATTERN",      __kmp_stg_parse_barrier_pattern,    __kmp_stg_print_barrier_pattern,    NULL, 0, 0 },
04126 #if KMP_FAST_REDUCTION_BARRIER
04127     { "KMP_REDUCTION_BARRIER",             __kmp_stg_parse_barrier_branch_bit, __kmp_stg_print_barrier_branch_bit, NULL, 0, 0 },
04128     { "KMP_REDUCTION_BARRIER_PATTERN",     __kmp_stg_parse_barrier_pattern,    __kmp_stg_print_barrier_pattern,    NULL, 0, 0 },
04129 #endif
04130 
04131     { "KMP_ABORT_DELAY",                   __kmp_stg_parse_abort_delay,        __kmp_stg_print_abort_delay,        NULL, 0, 0 },
04132     { "KMP_CPUINFO_FILE",                  __kmp_stg_parse_cpuinfo_file,       __kmp_stg_print_cpuinfo_file,       NULL, 0, 0 },
04133     { "KMP_FORCE_REDUCTION",               __kmp_stg_parse_force_reduction,    __kmp_stg_print_force_reduction,    NULL, 0, 0 },
04134     { "KMP_DETERMINISTIC_REDUCTION",       __kmp_stg_parse_force_reduction,    __kmp_stg_print_force_reduction,    NULL, 0, 0 },
04135     { "KMP_STORAGE_MAP",                   __kmp_stg_parse_storage_map,        __kmp_stg_print_storage_map,        NULL, 0, 0 },
04136     { "KMP_ALL_THREADPRIVATE",             __kmp_stg_parse_all_threadprivate,  __kmp_stg_print_all_threadprivate,  NULL, 0, 0 },
04137     { "KMP_FOREIGN_THREADS_THREADPRIVATE", __kmp_stg_parse_foreign_threads_threadprivate, __kmp_stg_print_foreign_threads_threadprivate,     NULL, 0, 0 },
04138 
04139 #if KMP_OS_LINUX || KMP_OS_WINDOWS
04140     { "KMP_AFFINITY",                      __kmp_stg_parse_affinity,           __kmp_stg_print_affinity,           NULL, 0, 0 },
04141 # ifdef KMP_GOMP_COMPAT
04142     { "GOMP_CPU_AFFINITY",                 __kmp_stg_parse_gomp_cpu_affinity,  NULL, /* no print */                NULL, 0, 0 },
04143 # endif /* KMP_GOMP_COMPAT */
04144 # if OMP_30_ENABLED
04145 #  if OMP_40_ENABLED
04146     { "OMP_PROC_BIND",                     __kmp_stg_parse_proc_bind,          __kmp_stg_print_proc_bind,          NULL, 0, 0 },
04147     { "OMP_PLACES",                        __kmp_stg_parse_places,             __kmp_stg_print_places,             NULL, 0, 0 },
04148 #  else
04149     { "OMP_PROC_BIND",                     __kmp_stg_parse_proc_bind,          NULL, /* no print */                NULL, 0, 0 },
04150 #  endif /* OMP_40_ENABLED */
04151 # endif /* OMP_30_ENABLED */
04152 
04153     { "KMP_TOPOLOGY_METHOD",               __kmp_stg_parse_topology_method,    __kmp_stg_print_topology_method,    NULL, 0, 0 },
04154 
04155 #elif KMP_OS_DARWIN
04156 
04157     //
04158     // KMP_AFFINITY is not supported on OS X*, nor is OMP_PLACES.
04159     // OMP_PROC_BIND and proc-bind-var are supported, however.
04160     //
04161 # if OMP_40_ENABLED
04162     { "OMP_PROC_BIND",                     __kmp_stg_parse_proc_bind,          __kmp_stg_print_proc_bind,          NULL, 0, 0 },
04163 # endif
04164 
04165 #else
04166     #error "Unknown or unsupported OS"
04167 #endif // KMP_OS_LINUX || KMP_OS_WINDOWS 
04168 
04169     { "KMP_INIT_AT_FORK",                  __kmp_stg_parse_init_at_fork,       __kmp_stg_print_init_at_fork,       NULL, 0, 0 },
04170     { "KMP_SCHEDULE",                      __kmp_stg_parse_schedule,           __kmp_stg_print_schedule,           NULL, 0, 0 },
04171     { "OMP_SCHEDULE",                      __kmp_stg_parse_omp_schedule,       __kmp_stg_print_omp_schedule,       NULL, 0, 0 },
04172     { "KMP_ATOMIC_MODE",                   __kmp_stg_parse_atomic_mode,        __kmp_stg_print_atomic_mode,        NULL, 0, 0 },
04173     { "KMP_CONSISTENCY_CHECK",             __kmp_stg_parse_consistency_check,  __kmp_stg_print_consistency_check,  NULL, 0, 0 },
04174 
04175     { "KMP_MALLOC_POOL_INCR",              __kmp_stg_parse_malloc_pool_incr,   __kmp_stg_print_malloc_pool_incr,   NULL, 0, 0 },
04176     { "KMP_INIT_WAIT",                     __kmp_stg_parse_init_wait,          __kmp_stg_print_init_wait,          NULL, 0, 0 },
04177     { "KMP_NEXT_WAIT",                     __kmp_stg_parse_next_wait,          __kmp_stg_print_next_wait,          NULL, 0, 0 },
04178     { "KMP_GTID_MODE",                     __kmp_stg_parse_gtid_mode,          __kmp_stg_print_gtid_mode,          NULL, 0, 0 },
04179     { "OMP_DYNAMIC",                       __kmp_stg_parse_omp_dynamic,        __kmp_stg_print_omp_dynamic,        NULL, 0, 0 },
04180     { "KMP_DYNAMIC_MODE",                  __kmp_stg_parse_kmp_dynamic_mode,   __kmp_stg_print_kmp_dynamic_mode,   NULL, 0, 0 },
04181 
04182 #ifdef USE_LOAD_BALANCE
04183     { "KMP_LOAD_BALANCE_INTERVAL",         __kmp_stg_parse_ld_balance_interval,__kmp_stg_print_ld_balance_interval,NULL, 0, 0 },
04184 #endif
04185 
04186 
04187 
04188     { "KMP_NUM_LOCKS_IN_BLOCK",            __kmp_stg_parse_lock_block,         __kmp_stg_print_lock_block,         NULL, 0, 0 },
04189     { "KMP_LOCK_KIND",                     __kmp_stg_parse_lock_kind,          __kmp_stg_print_lock_kind,          NULL, 0, 0 },
04190 #if KMP_MIC
04191     { "KMP_PLACE_THREADS",                 __kmp_stg_parse_place_threads,      __kmp_stg_print_place_threads,      NULL, 0, 0 },
04192 #endif
04193     { "KMP_FORKJOIN_FRAMES",               __kmp_stg_parse_forkjoin_frames,    __kmp_stg_print_forkjoin_frames,    NULL, 0, 0 },
04194 
04195     { "",                                  NULL,                               NULL,                               NULL, 0, 0 }
04196 }; // settings
04197 
04198 static int const __kmp_stg_count = sizeof( __kmp_stg_table ) / sizeof( kmp_setting_t );
04199 
04200 static inline
04201 kmp_setting_t *
04202 __kmp_stg_find( char const * name ) {
04203 
04204     int i;
04205     if ( name != NULL ) {
04206         for ( i = 0; i < __kmp_stg_count; ++ i ) {
04207             if ( strcmp( __kmp_stg_table[ i ].name, name ) == 0 ) {
04208                 return & __kmp_stg_table[ i ];
04209             }; // if
04210         }; // for
04211     }; // if
04212     return NULL;
04213 
04214 } // __kmp_stg_find
04215 
04216 
04217 static int
04218 __kmp_stg_cmp( void const * _a, void const * _b ) {
04219     kmp_setting_t * a = (kmp_setting_t *) _a;
04220     kmp_setting_t * b = (kmp_setting_t *) _b;
04221 
04222     //
04223     // Process KMP_AFFINITY last.
04224     // It needs to come after OMP_PLACES and GOMP_CPU_AFFINITY.
04225     //
04226     if ( strcmp( a->name, "KMP_AFFINITY" ) == 0 ) {
04227         if ( strcmp( b->name, "KMP_AFFINITY" ) == 0 ) {
04228             return 0;
04229         }
04230         return 1;
04231     }
04232     else if ( strcmp( b->name, "KMP_AFFINITY" ) == 0 ) {
04233         return -1;
04234     }
04235     return strcmp( a->name, b->name );
04236 } // __kmp_stg_cmp
04237 
04238 
04239 static void
04240 __kmp_stg_init( void
04241 ) {
04242 
04243     static int initialized = 0;
04244 
04245     if ( ! initialized ) {
04246 
04247         // Sort table.
04248         qsort( __kmp_stg_table, __kmp_stg_count - 1, sizeof( kmp_setting_t ), __kmp_stg_cmp );
04249 
04250         { // Initialize *_STACKSIZE data.
04251 
04252             kmp_setting_t * kmp_stacksize  = __kmp_stg_find( "KMP_STACKSIZE"  );      // 1st priority.
04253 #ifdef KMP_GOMP_COMPAT
04254             kmp_setting_t * gomp_stacksize = __kmp_stg_find( "GOMP_STACKSIZE" );      // 2nd priority.
04255 #endif
04256             kmp_setting_t * omp_stacksize  = __kmp_stg_find( "OMP_STACKSIZE"  );      // 3rd priority.
04257 
04258             // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
04259             // !!! Compiler does not understand rivals is used and optimizes out assignments
04260             // !!!     rivals[ i ++ ] = ...;
04261             static kmp_setting_t * volatile rivals[ 4 ];
04262             static kmp_stg_ss_data_t kmp_data  = {    1, (kmp_setting_t **)rivals };
04263 #ifdef KMP_GOMP_COMPAT
04264             static kmp_stg_ss_data_t gomp_data = { 1024, (kmp_setting_t **)rivals };
04265 #endif
04266             static kmp_stg_ss_data_t omp_data  = { 1024, (kmp_setting_t **)rivals };
04267             int i = 0;
04268 
04269             rivals[ i ++ ] = kmp_stacksize;
04270 #ifdef KMP_GOMP_COMPAT
04271             if ( gomp_stacksize != NULL ) {
04272                 rivals[ i ++ ] = gomp_stacksize;
04273             }; // if
04274 #endif
04275             rivals[ i ++ ] = omp_stacksize;
04276             rivals[ i ++ ] = NULL;
04277 
04278             kmp_stacksize->data = & kmp_data;
04279 #ifdef KMP_GOMP_COMPAT
04280             if ( gomp_stacksize != NULL ) {
04281                 gomp_stacksize->data = & gomp_data;
04282             }; // if
04283 #endif
04284             omp_stacksize->data = & omp_data;
04285 
04286         }
04287 
04288 #if OMP_30_ENABLED
04289         { // Initialize KMP_LIBRARY and OMP_WAIT_POLICY data.
04290 
04291             kmp_setting_t * kmp_library     = __kmp_stg_find( "KMP_LIBRARY" );        // 1st priority.
04292             kmp_setting_t * omp_wait_policy = __kmp_stg_find( "OMP_WAIT_POLICY" );    // 2nd priority.
04293 
04294             // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
04295             static kmp_setting_t * volatile rivals[ 3 ];
04296             static kmp_stg_wp_data_t kmp_data  = { 0, (kmp_setting_t **)rivals };
04297             static kmp_stg_wp_data_t omp_data  = { 1, (kmp_setting_t **)rivals };
04298             int i = 0;
04299 
04300             rivals[ i ++ ] = kmp_library;
04301             if ( omp_wait_policy != NULL ) {
04302                 rivals[ i ++ ] = omp_wait_policy;
04303             }; // if
04304             rivals[ i ++ ] = NULL;
04305 
04306             kmp_library->data  = & kmp_data;
04307             if ( omp_wait_policy != NULL ) {
04308                 omp_wait_policy->data = & omp_data;
04309             }; // if
04310 
04311         }
04312 #endif /* OMP_30_ENABLED */
04313 
04314         { // Initialize KMP_ALL_THREADS, KMP_MAX_THREADS, and OMP_THREAD_LIMIT data.
04315 
04316             kmp_setting_t * kmp_all_threads  = __kmp_stg_find( "KMP_ALL_THREADS"  );  // 1st priority.
04317             kmp_setting_t * kmp_max_threads  = __kmp_stg_find( "KMP_MAX_THREADS"  );  // 2nd priority.
04318 #if OMP_30_ENABLED
04319             kmp_setting_t * omp_thread_limit = __kmp_stg_find( "OMP_THREAD_LIMIT" );  // 3rd priority.
04320 #endif
04321 
04322             // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
04323             static kmp_setting_t * volatile rivals[ 4 ];
04324             int i = 0;
04325 
04326             rivals[ i ++ ] = kmp_all_threads;
04327             rivals[ i ++ ] = kmp_max_threads;
04328 #if OMP_30_ENABLED
04329             if ( omp_thread_limit != NULL ) {
04330                 rivals[ i ++ ] = omp_thread_limit;
04331             }; // if
04332 #endif
04333             rivals[ i ++ ] = NULL;
04334 
04335             kmp_all_threads->data = (void*)& rivals;
04336             kmp_max_threads->data = (void*)& rivals;
04337 #if OMP_30_ENABLED
04338             if ( omp_thread_limit != NULL ) {
04339                 omp_thread_limit->data = (void*)& rivals;
04340             }; // if
04341 #endif
04342 
04343         }
04344 
04345 #if KMP_OS_LINUX || KMP_OS_WINDOWS 
04346         { // Initialize KMP_AFFINITY, GOMP_CPU_AFFINITY, and OMP_PROC_BIND data.
04347 
04348             kmp_setting_t * kmp_affinity = __kmp_stg_find( "KMP_AFFINITY"  );  // 1st priority.
04349             KMP_DEBUG_ASSERT( kmp_affinity != NULL );
04350 
04351 # ifdef KMP_GOMP_COMPAT
04352             kmp_setting_t * gomp_cpu_affinity = __kmp_stg_find( "GOMP_CPU_AFFINITY"  );  // 2nd priority.
04353             KMP_DEBUG_ASSERT( gomp_cpu_affinity != NULL );
04354 # endif
04355 
04356 # if OMP_30_ENABLED
04357             kmp_setting_t * omp_proc_bind = __kmp_stg_find( "OMP_PROC_BIND" );  // 3rd priority.
04358             KMP_DEBUG_ASSERT( omp_proc_bind != NULL );
04359 # endif
04360 
04361 # if OMP_40_ENABLED
04362             kmp_setting_t * omp_places = __kmp_stg_find( "OMP_PLACES" );  // 3rd priority.
04363             KMP_DEBUG_ASSERT( omp_places != NULL );
04364 # endif
04365 
04366             // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
04367             static kmp_setting_t * volatile rivals[ 5 ];
04368             int i = 0;
04369 
04370             rivals[ i ++ ] = kmp_affinity;
04371 
04372 # ifdef KMP_GOMP_COMPAT
04373             rivals[ i ++ ] = gomp_cpu_affinity;
04374             gomp_cpu_affinity->data = (void*)& rivals;
04375 # endif
04376 
04377 # if OMP_30_ENABLED
04378             rivals[ i ++ ] = omp_proc_bind;
04379             omp_proc_bind->data = (void*)& rivals;
04380 # endif
04381 
04382 # if OMP_40_ENABLED
04383             rivals[ i ++ ] = omp_places;
04384             omp_places->data = (void*)& rivals;
04385 # endif
04386 
04387             rivals[ i ++ ] = NULL;
04388         }
04389 
04390 #elif KMP_OS_DARWIN
04391     // KMP_AFFINITY not supported, so OMP_PROC_BIND has no rivals.
04392     // OMP_PLACES not supported yet.
04393 #else
04394     #error "Unknown or unsupported OS"
04395 #endif
04396 
04397         { // Initialize KMP_DETERMINISTIC_REDUCTION and KMP_FORCE_REDUCTION data.
04398 
04399             kmp_setting_t * kmp_force_red  = __kmp_stg_find( "KMP_FORCE_REDUCTION" );         // 1st priority.
04400             kmp_setting_t * kmp_determ_red = __kmp_stg_find( "KMP_DETERMINISTIC_REDUCTION" ); // 2nd priority.
04401 
04402             // !!! volatile keyword is Intel (R) C Compiler bug CQ49908 workaround.
04403             static kmp_setting_t * volatile rivals[ 3 ];
04404             static kmp_stg_fr_data_t force_data   = { 1, (kmp_setting_t **)rivals };
04405             static kmp_stg_fr_data_t determ_data  = { 0, (kmp_setting_t **)rivals };
04406             int i = 0;
04407 
04408             rivals[ i ++ ] = kmp_force_red;
04409             if ( kmp_determ_red != NULL ) {
04410                 rivals[ i ++ ] = kmp_determ_red;
04411             }; // if
04412             rivals[ i ++ ] = NULL;
04413 
04414             kmp_force_red->data = & force_data;
04415             if ( kmp_determ_red != NULL ) {
04416                 kmp_determ_red->data  = & determ_data;
04417             }; // if
04418         }
04419 
04420         initialized = 1;
04421 
04422     }; // if
04423 
04424     // Reset flags.
04425     int i;
04426     for ( i = 0; i < __kmp_stg_count; ++ i ) {
04427         __kmp_stg_table[ i ].set = 0;
04428     }; // for
04429 
04430 } // __kmp_stg_init
04431 
04432 
04433 static void
04434 __kmp_stg_parse(
04435     char const * name,
04436     char const * value
04437 ) {
04438 
04439     // On Windows* OS there are some nameless variables like "C:=C:\" (yeah, really nameless, they are
04440     // presented in environment block as "=C:=C\\\x00=D:=D:\\\x00...", so let us skip them.
04441     if ( name[ 0 ] == 0 ) {
04442         return;
04443     }; // if
04444 
04445     if ( value != NULL ) {
04446         kmp_setting_t * setting = __kmp_stg_find( name );
04447         if ( setting != NULL ) {
04448             setting->parse( name, value, setting->data );
04449             setting->defined = 1;
04450         }; // if
04451     }; // if
04452 
04453 } // __kmp_stg_parse
04454 
04455 
04456 static int
04457 __kmp_stg_check_rivals(          // 0 -- Ok, 1 -- errors found.
04458     char const *       name,     // Name of variable.
04459     char const *       value,    // Value of the variable.
04460     kmp_setting_t * *  rivals    // List of rival settings (the list must include current one).
04461 ) {
04462 
04463     if ( rivals == NULL ) {
04464         return 0;
04465     }
04466 
04467     // Loop thru higher priority settings (listed before current).
04468     int i = 0;
04469     for ( ; strcmp( rivals[ i ]->name, name ) != 0; i++ ) {
04470         KMP_DEBUG_ASSERT( rivals[ i ] != NULL );
04471 
04472 #if KMP_OS_LINUX || KMP_OS_WINDOWS
04473         if ( rivals[ i ] == __kmp_affinity_notype ) {
04474             //
04475             // If KMP_AFFINITY is specified without a type name,
04476             // it does not rival OMP_PROC_BIND or GOMP_CPU_AFFINITY.
04477             //
04478             continue;
04479         }
04480 #endif
04481 
04482         if ( rivals[ i ]->set ) {
04483             KMP_WARNING( StgIgnored, name, value, rivals[ i ]->name );
04484             return 1;
04485         }; // if
04486     }; // while
04487 
04488     ++ i; // Skip current setting.
04489     return 0;
04490 
04491 }; // __kmp_stg_check_rivals
04492 
04493 
04494 
04495 static int
04496 __kmp_env_isDefined( char const * name ) {
04497     int rc = 0;
04498     kmp_setting_t * setting = __kmp_stg_find( name );
04499     if ( setting != NULL ) {
04500         rc = setting->set;
04501     }; // if
04502     return rc;
04503 }
04504 
04505 static int
04506 __kmp_env_toPrint( char const * name, int flag ) {
04507     int rc = 0;
04508     kmp_setting_t * setting = __kmp_stg_find( name );
04509     if ( setting != NULL ) {
04510         rc = setting->defined;
04511         if ( flag >= 0 ) {
04512             setting->defined = flag;
04513         }; // if
04514     }; // if
04515     return rc;
04516 }
04517 
04518 
04519 static void
04520 __kmp_aux_env_initialize( kmp_env_blk_t* block ) {
04521 
04522     char const * value;
04523 
04524     /* OMP_NUM_THREADS */
04525     value = __kmp_env_blk_var( block, "OMP_NUM_THREADS" );
04526     if ( value ) {
04527         ompc_set_num_threads( __kmp_dflt_team_nth );
04528     }
04529 
04530     /* KMP_BLOCKTIME */
04531     value = __kmp_env_blk_var( block, "KMP_BLOCKTIME" );
04532     if ( value ) {
04533         kmpc_set_blocktime( __kmp_dflt_blocktime );
04534     }
04535 
04536     /* OMP_NESTED */
04537     value = __kmp_env_blk_var( block, "OMP_NESTED" );
04538     if ( value ) {
04539         ompc_set_nested( __kmp_dflt_nested );
04540     }
04541 
04542     /* OMP_DYNAMIC */
04543     value = __kmp_env_blk_var( block, "OMP_DYNAMIC" );
04544     if ( value ) {
04545         ompc_set_dynamic( __kmp_global.g.g_dynamic );
04546     }
04547 
04548 }
04549 
04550 void
04551 __kmp_env_initialize( char const * string ) {
04552 
04553     kmp_env_blk_t block;
04554     int           i;
04555 
04556     __kmp_stg_init();
04557 
04558     // Hack!!!
04559     if ( string == NULL ) {
04560         // __kmp_max_nth = __kmp_sys_max_nth;
04561         __kmp_threads_capacity = __kmp_initial_threads_capacity( __kmp_dflt_team_nth_ub );
04562     }; // if
04563     __kmp_env_blk_init( & block, string );
04564 
04565     //
04566     // update the set flag on all entries that have an env var
04567     //
04568     for ( i = 0; i < block.count; ++ i ) {
04569         if (( block.vars[ i ].name == NULL )
04570           || ( *block.vars[ i ].name == '\0')) {
04571             continue;
04572         }
04573         if ( block.vars[ i ].value == NULL ) {
04574             continue;
04575         }
04576         kmp_setting_t * setting = __kmp_stg_find( block.vars[ i ].name );
04577         if ( setting != NULL ) {
04578             setting->set = 1;
04579         }
04580     }; // for i
04581 
04582     // Special case. If we parse environment, not a string, process KMP_WARNINGS first.
04583     if ( string == NULL ) {
04584         char const * name  = "KMP_WARNINGS";
04585         char const * value = __kmp_env_blk_var( & block, name );
04586         __kmp_stg_parse( name, value );
04587     }; // if
04588 
04589 #if KMP_OS_LINUX || KMP_OS_WINDOWS
04590     //
04591     // Special case. KMP_AFFINITY is not a rival to other affinity env vars
04592     // if no affinity type is specified.  We want to allow
04593     // KMP_AFFINITY=[no],verbose/[no]warnings/etc.  to be enabled when
04594     // specifying the affinity type via GOMP_CPU_AFFINITY or the OMP 4.0
04595     // affinity mechanism.
04596     //
04597     __kmp_affinity_notype = NULL;
04598     char const *aff_str = __kmp_env_blk_var( & block, "KMP_AFFINITY" );
04599     if ( aff_str != NULL ) {
04600         //
04601         // Check if the KMP_AFFINITY type is specified in the string.
04602         // We just search the string for "compact", "scatter", etc.
04603         // without really parsing the string.  The syntax of the
04604         // KMP_AFFINITY env var is such that none of the affinity
04605         // type names can appear anywhere other that the type
04606         // specifier, even as substrings.
04607         //
04608         // I can't find a case-insensitive version of strstr on Windows* OS.
04609         // Use the case-sensitive version for now.
04610         //
04611 
04612 # if KMP_OS_WINDOWS
04613 #  define FIND strstr
04614 # else
04615 #  define FIND strcasestr
04616 # endif
04617 
04618         if ( ( FIND( aff_str, "none" ) == NULL )
04619           && ( FIND( aff_str, "physical" ) == NULL )
04620           && ( FIND( aff_str, "logical" ) == NULL )
04621           && ( FIND( aff_str, "compact" ) == NULL )
04622           && ( FIND( aff_str, "scatter" ) == NULL )
04623           && ( FIND( aff_str, "explicit" ) == NULL )
04624 # if KMP_MIC
04625           && ( FIND( aff_str, "balanced" ) == NULL )
04626 # endif
04627           && ( FIND( aff_str, "disabled" ) == NULL ) ) {
04628             __kmp_affinity_notype = __kmp_stg_find( "KMP_AFFINITY"  );
04629         }
04630 # undef FIND
04631     }
04632 #endif /* KMP_OS_LINUX || KMP_OS_WINDOWS */
04633 
04634 #if OMP_40_ENABLED
04635     //
04636     // Set up the nested proc bind type vector.
04637     //
04638     if ( __kmp_nested_proc_bind.bind_types == NULL ) {
04639         __kmp_nested_proc_bind.bind_types = (kmp_proc_bind_t *)
04640           KMP_INTERNAL_MALLOC( sizeof(kmp_proc_bind_t) );
04641         if ( __kmp_nested_proc_bind.bind_types == NULL ) {
04642             KMP_FATAL( MemoryAllocFailed );
04643         }
04644         __kmp_nested_proc_bind.size = 1;
04645         __kmp_nested_proc_bind.used = 1;
04646         __kmp_nested_proc_bind.bind_types[0] = proc_bind_default;
04647     }
04648 #endif /* OMP_40_ENABLED */
04649 
04650     //
04651     // Now process all of the settings.
04652     //
04653     for ( i = 0; i < block.count; ++ i ) {
04654         __kmp_stg_parse( block.vars[ i ].name, block.vars[ i ].value );
04655     }; // for i
04656 
04657     //
04658     // If user locks have been allocated yet, don't reset the lock vptr table.
04659     //
04660     if ( ! __kmp_init_user_locks ) {
04661         if ( __kmp_user_lock_kind == lk_default ) {
04662             __kmp_user_lock_kind = lk_queuing;
04663         }
04664         __kmp_set_user_lock_vptrs( __kmp_user_lock_kind );
04665     }
04666     else {
04667         KMP_DEBUG_ASSERT( string != NULL); // kmp_set_defaults() was called
04668         KMP_DEBUG_ASSERT( __kmp_user_lock_kind != lk_default );
04669     }
04670 
04671 #if KMP_OS_LINUX || KMP_OS_WINDOWS 
04672     if ( ! TCR_4(__kmp_init_middle) ) {
04673         //
04674         // Determine if the machine/OS is actually capable of supporting
04675         // affinity.
04676         //
04677         const char *var = "KMP_AFFINITY";
04678         if ( __kmp_affinity_type == affinity_disabled ) {
04679             __kmp_affin_mask_size = 0;  // should already be 0
04680         }
04681         else if ( ! KMP_AFFINITY_CAPABLE() ) {
04682             __kmp_affinity_determine_capable( var );
04683             if ( ! KMP_AFFINITY_CAPABLE() ) {
04684                 if ( __kmp_affinity_verbose || ( __kmp_affinity_warnings
04685                   && ( __kmp_affinity_type != affinity_default )
04686                   && ( __kmp_affinity_type != affinity_none )
04687                   && ( __kmp_affinity_type != affinity_disabled ) ) ) {
04688                     KMP_WARNING( AffNotSupported, var );
04689                 }
04690                 __kmp_affinity_type = affinity_disabled;
04691                 __kmp_affinity_respect_mask = 0;
04692                 __kmp_affinity_gran = affinity_gran_fine;
04693             }
04694         }
04695 
04696 # if OMP_40_ENABLED
04697 
04698         if ( __kmp_affinity_type == affinity_disabled )  {
04699             __kmp_nested_proc_bind.bind_types[0] = proc_bind_disabled;
04700         }
04701         else if ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_default ) {
04702             //
04703             // On Windows* OS & Linux* OS, the default is to use the KMP_AFFINITY
04704             // mechanism.  On OS X*, it is none.
04705             //
04706 #  if KMP_OS_WINDOWS || KMP_OS_LINUX
04707             __kmp_nested_proc_bind.bind_types[0] = proc_bind_intel;
04708 #  else
04709             __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
04710 #  endif
04711         }
04712 
04713         //
04714         // If OMP_PROC_BIND was specified (so we are using OpenMP 4.0 affinity)
04715         // but OMP_PLACES was not, then it defaults to the equivalent of
04716         // KMP_AFFINITY=compact,noduplicates,granularity=fine.
04717         //
04718         if ( __kmp_nested_proc_bind.bind_types[0] == proc_bind_intel ) {
04719             if ( ( __kmp_affinity_type == affinity_none )
04720 #  if ! KMP_MIC
04721               || ( __kmp_affinity_type == affinity_default )
04722 #  endif
04723               ) {
04724                   __kmp_nested_proc_bind.bind_types[0] = proc_bind_false;
04725             }
04726         }
04727         else if ( ( __kmp_nested_proc_bind.bind_types[0] != proc_bind_false )
04728           && ( __kmp_nested_proc_bind.bind_types[0] != proc_bind_disabled ) ) {
04729             if ( __kmp_affinity_type == affinity_default ) {
04730                 __kmp_affinity_type = affinity_compact;
04731                 __kmp_affinity_dups = FALSE;
04732             }
04733             if ( __kmp_affinity_gran == affinity_gran_default ) {
04734                 __kmp_affinity_gran = affinity_gran_fine;
04735             }
04736         }
04737 # endif //  OMP_40_ENABLED
04738 
04739         if ( KMP_AFFINITY_CAPABLE() ) {
04740 
04741 # if KMP_OS_WINDOWS && KMP_ARCH_X86_64
04742 
04743             if ( __kmp_num_proc_groups > 1 ) {
04744                 if ( __kmp_affinity_respect_mask == affinity_respect_mask_default ) {
04745                    __kmp_affinity_respect_mask = FALSE;
04746                 }
04747 
04748                 if ( ( __kmp_affinity_type == affinity_default )
04749                   || ( __kmp_affinity_type == affinity_none ) ) {
04750                     if ( __kmp_affinity_type == affinity_none ) {
04751                         if ( __kmp_affinity_verbose || ( __kmp_affinity_warnings
04752                           && ( __kmp_affinity_type != affinity_none ) ) ) {
04753                             KMP_WARNING( AffTypeCantUseMultGroups, "none", "compact" );
04754                         }
04755                     }
04756                     __kmp_affinity_type = affinity_compact;
04757                     if ( __kmp_affinity_top_method == affinity_top_method_default ) {
04758                        __kmp_affinity_top_method = affinity_top_method_group;
04759                     }
04760                 }
04761                 else if ( __kmp_affinity_top_method == affinity_top_method_default ) {
04762                     __kmp_affinity_top_method = affinity_top_method_all;
04763                 }
04764 
04765                 if ( __kmp_affinity_gran_levels < 0 ) {
04766                     if ( __kmp_affinity_top_method == affinity_top_method_group ) {
04767                         if ( __kmp_affinity_gran == affinity_gran_default ) {
04768                            __kmp_affinity_gran = affinity_gran_group;
04769                         }
04770                         else if ( __kmp_affinity_gran == affinity_gran_core ) {
04771                             if ( __kmp_affinity_verbose || ( __kmp_affinity_warnings
04772                               && ( __kmp_affinity_type != affinity_none ) ) ) {
04773                                 KMP_WARNING( AffGranCantUseMultGroups, "core", "thread" );
04774                             }
04775                             __kmp_affinity_gran = affinity_gran_thread;
04776                         }
04777                         else if ( __kmp_affinity_gran == affinity_gran_package ) {
04778                             if ( __kmp_affinity_verbose || ( __kmp_affinity_warnings
04779                               && ( __kmp_affinity_type != affinity_none ) ) ) {
04780                                 KMP_WARNING( AffGranCantUseMultGroups, "package", "group" );
04781                             }
04782                            __kmp_affinity_gran = affinity_gran_group;
04783                         }
04784                         else if ( __kmp_affinity_gran == affinity_gran_node ) {
04785                             if ( __kmp_affinity_verbose || ( __kmp_affinity_warnings
04786                               && ( __kmp_affinity_type != affinity_none ) ) ) {
04787                                 KMP_WARNING( AffGranCantUseMultGroups, "node", "group" );
04788                             }
04789                            __kmp_affinity_gran = affinity_gran_group;
04790                         }
04791                     }
04792                     else if ( __kmp_affinity_gran == affinity_gran_default ) {
04793                         __kmp_affinity_gran = affinity_gran_core;
04794                     }
04795                 }
04796             }
04797             else
04798 
04799 # endif /* KMP_OS_WINDOWS && KMP_ARCH_X86_64 */
04800             {
04801                 if ( __kmp_affinity_respect_mask == affinity_respect_mask_default ) {
04802                    __kmp_affinity_respect_mask = TRUE;
04803                 }
04804                 if ( __kmp_affinity_type == affinity_default ) {
04805 # if KMP_MIC
04806                    __kmp_affinity_type = affinity_scatter;
04807 # else
04808                    __kmp_affinity_type = affinity_none;
04809 # endif
04810                 }
04811                 if ( ( __kmp_affinity_gran == affinity_gran_default )
04812                   &&  ( __kmp_affinity_gran_levels < 0 ) ) {
04813 # if KMP_MIC
04814                    __kmp_affinity_gran = affinity_gran_fine;
04815 # else
04816                    __kmp_affinity_gran = affinity_gran_core;
04817 # endif
04818                 }
04819                 if ( __kmp_affinity_top_method == affinity_top_method_default ) {
04820                    __kmp_affinity_top_method = affinity_top_method_all;
04821                 }
04822             }
04823         }
04824 
04825         K_DIAG( 1, ( "__kmp_affinity_type         == %d\n", __kmp_affinity_type         ) );
04826         K_DIAG( 1, ( "__kmp_affinity_compact      == %d\n", __kmp_affinity_compact      ) );
04827         K_DIAG( 1, ( "__kmp_affinity_offset       == %d\n", __kmp_affinity_offset       ) );
04828         K_DIAG( 1, ( "__kmp_affinity_verbose      == %d\n", __kmp_affinity_verbose      ) );
04829         K_DIAG( 1, ( "__kmp_affinity_warnings     == %d\n", __kmp_affinity_warnings     ) );
04830         K_DIAG( 1, ( "__kmp_affinity_respect_mask == %d\n", __kmp_affinity_respect_mask ) );
04831         K_DIAG( 1, ( "__kmp_affinity_gran         == %d\n", __kmp_affinity_gran         ) );
04832 
04833         KMP_DEBUG_ASSERT( __kmp_affinity_type != affinity_default);
04834 # if OMP_40_ENABLED
04835         KMP_DEBUG_ASSERT( __kmp_nested_proc_bind.bind_types[0]
04836           != proc_bind_default );
04837 # endif
04838     }
04839 
04840 #elif KMP_OS_DARWIN
04841     // affinity not supported
04842 #else
04843     #error "Unknown or unsupported OS"
04844 #endif /* KMP_OS_LINUX || KMP_OS_WINDOWS */
04845 
04846     if ( __kmp_version ) {
04847         __kmp_print_version_1();
04848     }; // if
04849 
04850     // Post-initialization step: some env. vars need their value's further processing
04851     if ( string != NULL) { // kmp_set_defaults() was called
04852         __kmp_aux_env_initialize( &block );
04853     }
04854 
04855     __kmp_env_blk_free( & block );
04856 
04857     KMP_MB();
04858 
04859 } // __kmp_env_initialize
04860 
04861 
04862 void
04863 __kmp_env_print() {
04864 
04865     kmp_env_blk_t block;
04866     int           i;
04867     kmp_str_buf_t buffer;
04868 
04869     __kmp_stg_init();
04870     __kmp_str_buf_init( & buffer );
04871 
04872     __kmp_env_blk_init( & block, NULL );
04873     __kmp_env_blk_sort( & block );
04874 
04875     // Print real environment values.
04876     __kmp_str_buf_print( & buffer, "\n%s\n\n", KMP_I18N_STR( UserSettings )  );
04877     for ( i = 0; i < block.count; ++ i ) {
04878         char const * name  = block.vars[ i ].name;
04879         char const * value = block.vars[ i ].value;
04880         if (
04881             strlen( name ) > 4
04882             &&
04883             ( strncmp( name, "KMP_", 4 ) == 0 ) || strncmp( name, "OMP_", 4 ) == 0
04884             #ifdef KMP_GOMP_COMPAT
04885                 || strncmp( name, "GOMP_", 5 ) == 0
04886             #endif /* KMP_GOMP_COMPAT */
04887         ) {
04888             __kmp_str_buf_print( & buffer, "   %s=%s\n", name, value );
04889         }; // if
04890     }; // for
04891     __kmp_str_buf_print( & buffer, "\n" );
04892 
04893     // Print internal (effective) settings.
04894     __kmp_str_buf_print( & buffer, "%s\n\n", KMP_I18N_STR( EffectiveSettings ) );
04895     for ( int i = 0; i < __kmp_stg_count; ++ i ) {
04896         if (  __kmp_stg_table[ i ].print != NULL ) {
04897             __kmp_stg_table[ i ].print( & buffer, __kmp_stg_table[ i ].name, __kmp_stg_table[ i ].data );
04898         }; // if
04899     }; // for
04900 
04901     __kmp_printf( "%s", buffer.str );
04902 
04903     __kmp_env_blk_free( & block );
04904     __kmp_str_buf_free( & buffer );
04905 
04906     __kmp_printf("\n");
04907 
04908 } // __kmp_env_print
04909 
04910 
04911 
04912 // end of file

Generated on 25 Aug 2013 for libomp_oss by  doxygen 1.6.1