int
__pthread_setaffinity_new (pthread_t th, size_t cpusetsize,
			   const cpu_set_t *cpuset)
{
  const struct pthread *pd = (const struct pthread *) th;

  INTERNAL_SYSCALL_DECL (err);
  int res;

  if (__builtin_expect (__kernel_cpumask_size == 0, 0))
    {
      res = __determine_cpumask_size (pd->tid);
      if (res != 0)
	return res;
    }

  /* We now know the size of the kernel cpumask_t.  Make sure the user
     does not request to set a bit beyond that.  */
  for (size_t cnt = __kernel_cpumask_size; cnt < cpusetsize; ++cnt)
    if (((char *) cpuset)[cnt] != '\0')
      /* Found a nonzero byte.  This means the user request cannot be
	 fulfilled.  */
      return EINVAL;

  res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid, cpusetsize,
			  cpuset);
  return (INTERNAL_SYSCALL_ERROR_P (res, err)
	  ? INTERNAL_SYSCALL_ERRNO (res, err)
	  : 0);
}
int
pthread_attr_setaffinity_np (pthread_attr_t *attr, size_t cpusetsize,
				const cpu_set_t *cpuset)
{
  struct pthread_attr *iattr;

  assert (sizeof (*attr) >= sizeof (struct pthread_attr));
  iattr = (struct pthread_attr *) attr;

  if (cpuset == NULL || cpusetsize == 0)
    {
      free (iattr->cpuset);
      iattr->cpuset = NULL;
      iattr->cpusetsize = 0;
    }
  else
    {
      if (__kernel_cpumask_size == 0)
	{
	  int res = __determine_cpumask_size (THREAD_SELF->tid);
	  if (res != 0)
	    /* Some serious problem.  */
	    return res;
	}

      /* Check whether the new bitmask has any bit set beyond the
	 last one the kernel accepts.  */
      size_t cnt;
      for (cnt = __kernel_cpumask_size; cnt < cpusetsize; ++cnt)
	if (((char *) cpuset)[cnt] != '\0')
	  /* Found a nonzero byte.  This means the user request cannot be
	     fulfilled.  */
	  return EINVAL;

      if (iattr->cpusetsize != cpusetsize)
	{
	  void *newp = (cpu_set_t *) realloc (iattr->cpuset, cpusetsize);
	  if (newp == NULL)
	    return ENOMEM;

	  iattr->cpuset = newp;
	  iattr->cpusetsize = cpusetsize;
	}

      memcpy (iattr->cpuset, cpuset, cpusetsize);
    }

  return 0;
}