OSDN Git Service

* gcse.c (gcse_main): Do jump bypassing in CPROP2.
[pf3gnuchains/gcc-fork.git] / libgomp / env.c
index 0a80b87..4a07bfa 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>.
 
    This file is part of the GNU OpenMP Library (libgomp).
@@ -42,6 +42,8 @@ bool gomp_dyn_var = false;
 bool gomp_nest_var = false;
 enum gomp_schedule_type gomp_run_sched_var = GFS_DYNAMIC;
 unsigned long gomp_run_sched_chunk = 1;
+unsigned short *gomp_cpu_affinity;
+size_t gomp_cpu_affinity_len;
 
 /* Parse the OMP_SCHEDULE environment variable.  */
 
@@ -49,6 +51,7 @@ static void
 parse_schedule (void)
 {
   char *env, *end;
+  unsigned long value;
 
   env = getenv ("OMP_SCHEDULE");
   if (env == NULL)
@@ -85,11 +88,17 @@ parse_schedule (void)
   if (*env == '\0')
     goto invalid;
 
-  gomp_run_sched_chunk = strtoul (env, &end, 10);
+  errno = 0;
+  value = strtoul (env, &end, 10);
+  if (errno)
+    goto invalid;
+
   while (isspace ((unsigned char) *end))
     ++end;
   if (*end != '\0')
     goto invalid;
+
+  gomp_run_sched_chunk = value;
   return;
 
  unknown:
@@ -99,7 +108,6 @@ parse_schedule (void)
  invalid:
   gomp_error ("Invalid value for chunk size in "
              "environment variable OMP_SCHEDULE");
-  gomp_run_sched_chunk = 1;
   return;
 }
 
@@ -121,7 +129,11 @@ parse_unsigned_long (const char *name, unsigned long *pvalue)
   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')
@@ -167,6 +179,97 @@ parse_boolean (const char *name, bool *value)
     gomp_error ("Invalid value for environment variable %s", name);
 }
 
+/* Parse the GOMP_CPU_AFFINITY environment varible.  Return true if one was
+   present and it was successfully parsed.  */
+
+static bool
+parse_affinity (void)
+{
+  char *env, *end;
+  unsigned long cpu_beg, cpu_end, cpu_stride;
+  unsigned short *cpus = NULL;
+  size_t allocated = 0, used = 0, needed;
+
+  env = getenv ("GOMP_CPU_AFFINITY");
+  if (env == NULL)
+    return false;
+
+  do
+    {
+      while (*env == ' ' || *env == '\t')
+       env++;
+
+      cpu_beg = strtoul (env, &end, 0);
+      cpu_end = cpu_beg;
+      cpu_stride = 1;
+      if (env == end || cpu_beg >= 65536)
+       goto invalid;
+
+      env = end;
+      if (*env == '-')
+       {
+         cpu_end = strtoul (++env, &end, 0);
+         if (env == end || cpu_end >= 65536 || cpu_end < cpu_beg)
+           goto invalid;
+
+         env = end;
+         if (*env == ':')
+           {
+             cpu_stride = strtoul (++env, &end, 0);
+             if (env == end || cpu_stride == 0 || cpu_stride >= 65536)
+               goto invalid;
+
+             env = end;
+           }
+       }
+
+      needed = (cpu_end - cpu_beg) / cpu_stride + 1;
+      if (used + needed >= allocated)
+       {
+         unsigned short *new_cpus;
+
+         if (allocated < 64)
+           allocated = 64;
+         if (allocated > needed)
+           allocated <<= 1;
+         else
+           allocated += 2 * needed;
+         new_cpus = realloc (cpus, allocated * sizeof (unsigned short));
+         if (new_cpus == NULL)
+           {
+             free (cpus);
+             gomp_error ("not enough memory to store GOMP_CPU_AFFINITY list");
+             return false;
+           }
+
+         cpus = new_cpus;
+       }
+
+      while (needed--)
+       {
+         cpus[used++] = cpu_beg;
+         cpu_beg += cpu_stride;
+       }
+
+      while (*env == ' ' || *env == '\t')
+       env++;
+
+      if (*env == ',')
+       env++;
+      else if (*env == '\0')
+       break;
+    }
+  while (1);
+
+  gomp_cpu_affinity = cpus;
+  gomp_cpu_affinity_len = used;
+  return true;
+
+ invalid:
+  gomp_error ("Invalid value for enviroment variable GOMP_CPU_AFFINITY");
+  return false;
+}
+
 static void __attribute__((constructor))
 initialize_env (void)
 {
@@ -180,6 +283,8 @@ initialize_env (void)
   parse_boolean ("OMP_NESTED", &gomp_nest_var);
   if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var))
     gomp_init_num_threads ();
+  if (parse_affinity ())
+    gomp_init_affinity ();
 
   /* Not strictly environment related, but ordering constructors is tricky.  */
   pthread_attr_init (&gomp_thread_attr);
@@ -215,7 +320,7 @@ initialize_env (void)
 void
 omp_set_num_threads (int n)
 {
-  gomp_nthreads_var = n;
+  gomp_nthreads_var = (n > 0 ? n : 1);
 }
 
 void