Esempio n. 1
0
void
gomp_init_affinity (void)
{
  cpu_set_t cpuset;
  size_t idx, widx;

  if (pthread_getaffinity_np (pthread_self (), sizeof (cpuset), &cpuset))
    {
      gomp_error ("could not get CPU affinity set");
      free (gomp_cpu_affinity);
      gomp_cpu_affinity = NULL;
      gomp_cpu_affinity_len = 0;
      return;
    }

  for (widx = idx = 0; idx < gomp_cpu_affinity_len; idx++)
    if (gomp_cpu_affinity[idx] < CPU_SETSIZE
        && CPU_ISSET (gomp_cpu_affinity[idx], &cpuset))
      gomp_cpu_affinity[widx++] = gomp_cpu_affinity[idx];

  if (widx == 0)
    {
      gomp_error ("no CPUs left for affinity setting");
      free (gomp_cpu_affinity);
      gomp_cpu_affinity = NULL;
      gomp_cpu_affinity_len = 0;
      return;
    }

  gomp_cpu_affinity_len = widx;
  CPU_ZERO (&cpuset);
  CPU_SET (gomp_cpu_affinity[0], &cpuset);
  pthread_setaffinity_np (pthread_self (), sizeof (cpuset), &cpuset);
  affinity_counter = 1;
}
Esempio n. 2
0
bool
gomp_affinity_add_cpus (void *p, unsigned long num,
			unsigned long len, long stride, bool quiet)
{
  cpu_set_t *cpusetp = (cpu_set_t *) p;
  unsigned long max = 8 * gomp_cpuset_size;
  for (;;)
    {
      if (num >= max)
	{
	  if (!quiet)
	    gomp_error ("Logical CPU number %lu out of range", num);
	  return false;
	}
      CPU_SET_S (num, gomp_cpuset_size, cpusetp);
      if (--len == 0)
	return true;
      if ((stride < 0 && num + stride > num)
	  || (stride > 0 && num + stride < num))
	{
	  if (!quiet)
	    gomp_error ("Logical CPU number %lu+%ld out of range",
			num, stride);
	  return false;
	}
      num += stride;
    }
}
Esempio n. 3
0
static void
parse_boolean (const char *name, bool *value)
{
  const char *env;

  env = getenv (name);
  if (env == NULL)
    return;

  while (isspace ((unsigned char) *env))
    ++env;
  if (strncasecmp (env, "true", 4) == 0)
    {
      *value = true;
      env += 4;
    }
  else if (strncasecmp (env, "false", 5) == 0)
    {
      *value = false;
      env += 5;
    }
  else
    env = "X";
  while (isspace ((unsigned char) *env))
    ++env;
  if (*env != '\0')
    gomp_error ("Invalid value for environment variable %s", name);
}
Esempio n. 4
0
static bool
parse_unsigned_long (const char *name, unsigned long *pvalue)
{
  char *env, *end;
  unsigned long value;

  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')
    goto invalid;

  *pvalue = value;
  return true;

 invalid:
  gomp_error ("Invalid value for environment variable %s", name);
  return false;
}
Esempio n. 5
0
bool
gomp_affinity_remove_cpu (void *p, unsigned long num)
{
  cpu_set_t *cpusetp = (cpu_set_t *) p;
  if (num >= 8 * gomp_cpuset_size)
    {
      gomp_error ("Logical CPU number %lu out of range", num);
      return false;
    }
  if (!CPU_ISSET_S (num, gomp_cpuset_size, cpusetp))
    {
      gomp_error ("Logical CPU %lu to be removed is not in the set", num);
      return false;
    }
  CPU_CLR_S (num, gomp_cpuset_size, cpusetp);
  return true;
}
Esempio n. 6
0
bool
gomp_affinity_init_level (int level, unsigned long count, bool quiet)
{
  (void) level;
  (void) count;
  (void) quiet;
  if (!quiet)
    gomp_error ("Affinity not supported on this configuration");
  return NULL;
}
Esempio n. 7
0
initialize_env (void)
{
  unsigned long stacksize;

  /* Do a compile time check that mkomp_h.pl did good job.  */
  omp_check_defines ();

  parse_schedule ();
  parse_boolean ("OMP_DYNAMIC", &gomp_dyn_var);
  parse_boolean ("OMP_NESTED", &gomp_nest_var);
  if (!parse_unsigned_long ("OMP_NUM_THREADS", &gomp_nthreads_var))
    gomp_init_num_threads ();

  /* Not strictly environment related, but ordering constructors is tricky.  */
  pthread_attr_init (&gomp_thread_attr);
  pthread_attr_setdetachstate (&gomp_thread_attr, PTHREAD_CREATE_DETACHED);

  if (parse_unsigned_long ("GOMP_STACKSIZE", &stacksize))
    {
      int err;

      stacksize *= 1024;
      err = pthread_attr_setstacksize (&gomp_thread_attr, stacksize);

#ifdef PTHREAD_STACK_MIN
      if (err == EINVAL)
	{
	  if (stacksize < PTHREAD_STACK_MIN)
	    gomp_error ("Stack size less than minimum of %luk",
			PTHREAD_STACK_MIN / 1024ul
			+ (PTHREAD_STACK_MIN % 1024 != 0));
	  else
	    gomp_error ("Stack size larger than system limit");
	}
      else
#endif
      if (err != 0)
	gomp_error ("Stack size change failed: %s", strerror (err));
    }
}
Esempio n. 8
0
bool
gomp_affinity_finalize_place_list (bool quiet)
{
  unsigned long i, j;

  for (i = 0, j = 0; i < gomp_places_list_len; i++)
    {
      cpu_set_t *cpusetp = (cpu_set_t *) gomp_places_list[i];
      bool nonempty = false;
#ifdef CPU_AND_S
      CPU_AND_S (gomp_cpuset_size, cpusetp, cpusetp, gomp_cpusetp);
      nonempty = gomp_cpuset_popcount (gomp_cpuset_size, cpusetp) != 0;
#else
      unsigned long k, max = gomp_cpuset_size / sizeof (cpusetp->__bits[0]);
      for (k = 0; k < max; k++)
	if ((cpusetp->__bits[k] &= gomp_cpusetp->__bits[k]) != 0)
	  nonempty = true;
#endif
      if (nonempty)
	gomp_places_list[j++] = gomp_places_list[i];
    }

  if (j == 0)
    {
      if (!quiet)
	gomp_error ("None of the places contain usable logical CPUs");
      return false;
    }
  else if (j < gomp_places_list_len)
    {
      if (!quiet)
	gomp_error ("Number of places reduced from %ld to %ld because some "
		    "places didn't contain any usable logical CPUs",
		    gomp_places_list_len, j);
      gomp_places_list_len = j;
    }
  return true;
}
Esempio n. 9
0
bool
gomp_affinity_copy_place (void *p, void *q, long stride)
{
  unsigned long i, max = 8 * gomp_cpuset_size;
  cpu_set_t *destp = (cpu_set_t *) p;
  cpu_set_t *srcp = (cpu_set_t *) q;

  CPU_ZERO_S (gomp_cpuset_size, destp);
  for (i = 0; i < max; i++)
    if (CPU_ISSET_S (i, gomp_cpuset_size, srcp))
      {
	if ((stride < 0 && i + stride > i)
	    || (stride > 0 && (i + stride < i || i + stride >= max)))
	  {
	    gomp_error ("Logical CPU number %lu+%ld out of range", i, stride);
	    return false;
	  }
	CPU_SET_S (i + stride, gomp_cpuset_size, destp);
      }
  return true;
}
Esempio n. 10
0
bool
gomp_affinity_init_level (int level, unsigned long count, bool quiet)
{
  unsigned long i, max = 8 * gomp_cpuset_size;

  if (gomp_cpusetp)
    {
      unsigned long maxcount
	= gomp_cpuset_popcount (gomp_cpuset_size, gomp_cpusetp);
      if (count > maxcount)
	count = maxcount;
    }
  gomp_places_list = gomp_affinity_alloc (count, quiet);
  gomp_places_list_len = 0;
  if (gomp_places_list == NULL)
    return false;
  /* SMT (threads).  */
  if (level == 1)
    {
      for (i = 0; i < max && gomp_places_list_len < count; i++)
	if (CPU_ISSET_S (i, gomp_cpuset_size, gomp_cpusetp))
	  {
	    gomp_affinity_init_place (gomp_places_list[gomp_places_list_len]);
	    gomp_affinity_add_cpus (gomp_places_list[gomp_places_list_len],
				    i, 1, 0, true);
	    ++gomp_places_list_len;
	  }
      return true;
    }
  else
    {
      char name[sizeof ("/sys/devices/system/cpu/cpu/topology/"
			"thread_siblings_list") + 3 * sizeof (unsigned long)];
      size_t prefix_len = sizeof ("/sys/devices/system/cpu/cpu") - 1;
      cpu_set_t *copy = gomp_alloca (gomp_cpuset_size);
      FILE *f;
      char *line = NULL;
      size_t linelen = 0;

      memcpy (name, "/sys/devices/system/cpu/cpu", prefix_len);
      memcpy (copy, gomp_cpusetp, gomp_cpuset_size);
      for (i = 0; i < max && gomp_places_list_len < count; i++)
	if (CPU_ISSET_S (i, gomp_cpuset_size, copy))
	  {
	    sprintf (name + prefix_len, "%lu/topology/%s_siblings_list",
		     i, level == 2 ? "thread" : "core");
	    f = fopen (name, "r");
	    if (f != NULL)
	      {
		if (getline (&line, &linelen, f) > 0)
		  {
		    char *p = line;
		    bool seen_i = false;
		    void *pl = gomp_places_list[gomp_places_list_len];
		    gomp_affinity_init_place (pl);
		    while (*p && *p != '\n')
		      {
			unsigned long first, last;
			errno = 0;
			first = strtoul (p, &p, 10);
			if (errno)
			  break;
			last = first;
			if (*p == '-')
			  {
			    errno = 0;
			    last = strtoul (p + 1, &p, 10);
			    if (errno || last < first)
			      break;
			  }
			for (; first <= last; first++)
			  if (CPU_ISSET_S (first, gomp_cpuset_size, copy)
			      && gomp_affinity_add_cpus (pl, first, 1, 0,
							 true))
			    {
			      CPU_CLR_S (first, gomp_cpuset_size, copy);
			      if (first == i)
				seen_i = true;
			    }
			if (*p == ',')
			  ++p;
		      }
		    if (seen_i)
		      gomp_places_list_len++;
		  }
		fclose (f);
	      }
	  }
      if (gomp_places_list_len == 0)
	{
	  if (!quiet)
	    gomp_error ("Error reading %s topology",
			level == 2 ? "core" : "socket");
	  free (gomp_places_list);
	  gomp_places_list = NULL;
	  return false;
	}
      return true;
    }
  return false;
}
Esempio n. 11
0
static void
parse_schedule (void)
{
  char *env, *end;
  unsigned long value;

  env = getenv ("OMP_SCHEDULE");
  if (env == NULL)
    return;

  while (isspace ((unsigned char) *env))
    ++env;
  if (strncasecmp (env, "static", 6) == 0)
    {
      gomp_run_sched_var = GFS_STATIC;
      env += 6;
    }
  else if (strncasecmp (env, "dynamic", 7) == 0)
    {
      gomp_run_sched_var = GFS_DYNAMIC;
      env += 7;
    }
  else if (strncasecmp (env, "guided", 6) == 0)
    {
      gomp_run_sched_var = GFS_GUIDED;
      env += 6;
    }
  else
    goto unknown;

  while (isspace ((unsigned char) *env))
    ++env;
  if (*env == '\0')
    return;
  if (*env++ != ',')
    goto unknown;
  while (isspace ((unsigned char) *env))
    ++env;
  if (*env == '\0')
    goto invalid;

  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:
  gomp_error ("Unknown value for environment variable OMP_SCHEDULE");
  return;

 invalid:
  gomp_error ("Invalid value for chunk size in "
	      "environment variable OMP_SCHEDULE");
  return;
}