Exemple #1
0
static int
get_num_procs (void)
{
#ifdef HAVE_PTHREAD_AFFINITY_NP
  if (gomp_places_list == NULL)
    {
      /* Count only the CPUs this process can use.  */
      if (gomp_cpusetp
	  && pthread_getaffinity_np (pthread_self (), gomp_get_cpuset_size,
				     gomp_cpusetp) == 0)
	{
	  int ret = gomp_cpuset_popcount (gomp_get_cpuset_size, gomp_cpusetp);
	  return ret != 0 ? ret : 1;
	}
    }
  else
    {
      /* We can't use pthread_getaffinity_np in this case
	 (we have changed it ourselves, it binds to just one CPU).
	 Count instead the number of different CPUs we are
	 using.  gomp_init_affinity updated gomp_available_cpus to
	 the number of CPUs in the GOMP_AFFINITY mask that we are
	 allowed to use though.  */
      return gomp_available_cpus;
    }
#endif
#if defined(__ANDROID__)
  return sc_nprocessors_actu ();
#elif defined(_SC_NPROCESSORS_ONLN)
  return sysconf (_SC_NPROCESSORS_ONLN);
#else
  return gomp_icv (false)->nthreads_var;
#endif
}
Exemple #2
0
int
omp_get_place_num_procs (int place_num)
{
  if (place_num < 0 || place_num >= gomp_places_list_len)
    return 0;

  cpu_set_t *cpusetp = (cpu_set_t *) gomp_places_list[place_num];
  return gomp_cpuset_popcount (gomp_cpuset_size, cpusetp);
}
Exemple #3
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;
}
Exemple #4
0
void
gomp_init_num_threads (void)
{
#ifdef HAVE_PTHREAD_AFFINITY_NP
#if defined (_SC_NPROCESSORS_CONF) && defined (CPU_ALLOC_SIZE)
  gomp_cpuset_size = sysconf (_SC_NPROCESSORS_CONF);
  gomp_cpuset_size = CPU_ALLOC_SIZE (gomp_cpuset_size);
#else
  gomp_cpuset_size = sizeof (cpu_set_t);
#endif

  gomp_cpusetp = (cpu_set_t *) gomp_malloc (gomp_cpuset_size);
  do
    {
      int ret = pthread_getaffinity_np (pthread_self (), gomp_cpuset_size,
					gomp_cpusetp);
      if (ret == 0)
	{
	  /* Count only the CPUs this process can use.  */
	  gomp_global_icv.nthreads_var
	    = gomp_cpuset_popcount (gomp_cpuset_size, gomp_cpusetp);
	  if (gomp_global_icv.nthreads_var == 0)
	    break;
	  gomp_get_cpuset_size = gomp_cpuset_size;
#ifdef CPU_ALLOC_SIZE
	  unsigned long i;
	  for (i = gomp_cpuset_size * 8; i; i--)
	    if (CPU_ISSET_S (i - 1, gomp_cpuset_size, gomp_cpusetp))
	      break;
	  gomp_cpuset_size = CPU_ALLOC_SIZE (i);
#endif
	  return;
	}
      if (ret != EINVAL)
	break;
#ifdef CPU_ALLOC_SIZE
      if (gomp_cpuset_size < sizeof (cpu_set_t))
	gomp_cpuset_size = sizeof (cpu_set_t);
      else
	gomp_cpuset_size = gomp_cpuset_size * 2;
      if (gomp_cpuset_size < 8 * sizeof (cpu_set_t))
	gomp_cpusetp
	  = (cpu_set_t *) gomp_realloc (gomp_cpusetp, gomp_cpuset_size);
      else
	{
	  /* Avoid gomp_fatal if too large memory allocation would be
	     requested, e.g. kernel returning EINVAL all the time.  */
	  void *p = realloc (gomp_cpusetp, gomp_cpuset_size);
	  if (p == NULL)
	    break;
	  gomp_cpusetp = (cpu_set_t *) p;
	}
#else
      break;
#endif
    }
  while (1);
  gomp_cpuset_size = 0;
  gomp_global_icv.nthreads_var = 1;
  free (gomp_cpusetp);
  gomp_cpusetp = NULL;
#endif
#if defined(__ANDROID__)
  gomp_global_icv.nthreads_var = sc_nprocessors_actu ();
#elif defined(_SC_NPROCESSORS_ONLN)
  gomp_global_icv.nthreads_var = sysconf (_SC_NPROCESSORS_ONLN);
#endif
}
Exemple #5
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;
}