X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libgomp%2Fenv.c;h=aff7490a8b71f6b2d6321f3df3501c9a61919b87;hb=96d817912ed6de393c29981eeedef0bfc68714da;hp=b1349c8e69af3cfb6b400366eb45e4c0d590df4c;hpb=04752a80fdb1cb2e38757ebaec356af67045d1eb;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libgomp/env.c b/libgomp/env.c index b1349c8e69a..aff7490a8b7 100644 --- a/libgomp/env.c +++ b/libgomp/env.c @@ -1,29 +1,27 @@ -/* Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Free Software Foundation, Inc. Contributed by Richard Henderson . This file is part of the GNU OpenMP Library (libgomp). Libgomp is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with libgomp; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. -/* As a special exception, if you link this library with other files, some - of which are compiled with GCC, to produce an executable, this library - does not by itself cause the resulting executable to be covered by the - GNU General Public License. This exception does not however invalidate - any other reasons why the executable file might be covered by the GNU - General Public License. */ + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ /* This file defines the OpenMP internal control variables, and arranges for them to be initialized from environment variables at startup. */ @@ -69,6 +67,7 @@ gomp_mutex_t gomp_remaining_threads_lock; #endif unsigned long gomp_available_cpus = 1, gomp_managed_threads = 1; unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var; +unsigned long *gomp_nthreads_var_list, gomp_nthreads_var_list_len; /* Parse the OMP_SCHEDULE environment variable. */ @@ -110,7 +109,11 @@ parse_schedule (void) while (isspace ((unsigned char) *env)) ++env; if (*env == '\0') - return; + { + gomp_global_icv.run_sched_modifier + = gomp_global_icv.run_sched_var != GFS_STATIC; + return; + } if (*env++ != ',') goto unknown; while (isspace ((unsigned char) *env)) @@ -131,6 +134,8 @@ parse_schedule (void) if ((int)value != value) goto invalid; + if (value == 0 && gomp_global_icv.run_sched_var != GFS_STATIC) + value = 1; gomp_global_icv.run_sched_modifier = value; return; @@ -148,7 +153,7 @@ parse_schedule (void) present and it was successfully parsed. */ static bool -parse_unsigned_long (const char *name, unsigned long *pvalue) +parse_unsigned_long (const char *name, unsigned long *pvalue, bool allow_zero) { char *env, *end; unsigned long value; @@ -164,7 +169,7 @@ parse_unsigned_long (const char *name, unsigned long *pvalue) errno = 0; value = strtoul (env, &end, 10); - if (errno || (long) value <= 0) + if (errno || (long) value <= 0 - allow_zero) goto invalid; while (isspace ((unsigned char) *end)) @@ -180,6 +185,95 @@ parse_unsigned_long (const char *name, unsigned long *pvalue) return false; } +/* Parse an unsigned long list environment variable. Return true if one was + present and it was successfully parsed. */ + +static bool +parse_unsigned_long_list (const char *name, unsigned long *p1stvalue, + unsigned long **pvalues, + unsigned long *pnvalues) +{ + char *env, *end; + unsigned long value, *values = NULL; + + env = getenv (name); + if (env == NULL) + return false; + + while (isspace ((unsigned char) *env)) + ++env; + if (*env == '\0') + goto invalid; + + errno = 0; + value = strtoul (env, &end, 10); + if (errno || (long) value <= 0) + goto invalid; + + while (isspace ((unsigned char) *end)) + ++end; + if (*end != '\0') + { + if (*end == ',') + { + unsigned long nvalues = 0, nalloced = 0; + + do + { + env = end + 1; + if (nvalues == nalloced) + { + unsigned long *n; + nalloced = nalloced ? nalloced * 2 : 16; + n = realloc (values, nalloced * sizeof (unsigned long)); + if (n == NULL) + { + free (values); + gomp_error ("Out of memory while trying to parse" + " environment variable %s", name); + return false; + } + values = n; + if (nvalues == 0) + values[nvalues++] = value; + } + + while (isspace ((unsigned char) *env)) + ++env; + if (*env == '\0') + goto invalid; + + errno = 0; + value = strtoul (env, &end, 10); + if (errno || (long) value <= 0) + goto invalid; + + values[nvalues++] = value; + while (isspace ((unsigned char) *end)) + ++end; + if (*end == '\0') + break; + if (*end != ',') + goto invalid; + } + while (1); + *p1stvalue = values[0]; + *pvalues = values; + *pnvalues = nvalues; + return true; + } + goto invalid; + } + + *p1stvalue = value; + return true; + + invalid: + free (values); + gomp_error ("Invalid value for environment variable %s", name); + return false; +} + /* Parse the OMP_STACKSIZE environment varible. Return true if one was present and it was successfully parsed. */ @@ -207,7 +301,7 @@ parse_stacksize (const char *name, unsigned long *pvalue) ++end; if (*end != '\0') { - switch (tolower (*end)) + switch (tolower ((unsigned char) *end)) { case 'b': shift = 0; @@ -276,7 +370,7 @@ parse_spincount (const char *name, unsigned long long *pvalue) ++end; if (*end != '\0') { - switch (tolower (*end)) + switch (tolower ((unsigned char) *end)) { case 'k': mult = 1000LL; @@ -477,6 +571,7 @@ initialize_env (void) { unsigned long stacksize; int wait_policy; + bool bind_var = false; /* Do a compile time check that mkomp_h.pl did good job. */ omp_check_defines (); @@ -484,8 +579,10 @@ initialize_env (void) parse_schedule (); parse_boolean ("OMP_DYNAMIC", &gomp_global_icv.dyn_var); parse_boolean ("OMP_NESTED", &gomp_global_icv.nest_var); - parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var); - parse_unsigned_long ("OMP_THREAD_LIMIT", &gomp_thread_limit_var); + parse_boolean ("OMP_PROC_BIND", &bind_var); + parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var, + true); + parse_unsigned_long ("OMP_THREAD_LIMIT", &gomp_thread_limit_var, false); if (gomp_thread_limit_var != ULONG_MAX) gomp_remaining_threads_count = gomp_thread_limit_var - 1; #ifndef HAVE_SYNC_BUILTINS @@ -493,23 +590,26 @@ initialize_env (void) #endif gomp_init_num_threads (); gomp_available_cpus = gomp_global_icv.nthreads_var; - if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_global_icv.nthreads_var)) + if (!parse_unsigned_long_list ("OMP_NUM_THREADS", + &gomp_global_icv.nthreads_var, + &gomp_nthreads_var_list, + &gomp_nthreads_var_list_len)) gomp_global_icv.nthreads_var = gomp_available_cpus; - if (parse_affinity ()) + if (parse_affinity () || bind_var) gomp_init_affinity (); wait_policy = parse_wait_policy (); if (!parse_spincount ("GOMP_SPINCOUNT", &gomp_spin_count_var)) { /* Using a rough estimation of 100000 spins per msec, use 5 min blocking for OMP_WAIT_POLICY=active, - 200 msec blocking when OMP_WAIT_POLICY is not specificed + 3 msec blocking when OMP_WAIT_POLICY is not specificed and 0 when OMP_WAIT_POLICY=passive. Depending on the CPU speed, this can be e.g. 5 times longer or 5 times shorter. */ if (wait_policy > 0) gomp_spin_count_var = 30000000000LL; else if (wait_policy < 0) - gomp_spin_count_var = 20000000LL; + gomp_spin_count_var = 300000LL; } /* gomp_throttled_spin_count_var is used when there are more libgomp managed threads than available CPUs. Use very short spinning. */ @@ -635,7 +735,7 @@ omp_get_thread_limit (void) void omp_set_max_active_levels (int max_levels) { - if (max_levels > 0) + if (max_levels >= 0) gomp_max_active_levels_var = max_levels; }