int __pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stacksize) { struct pthread_attr *iattr; assert (sizeof (*attr) >= sizeof (struct pthread_attr)); iattr = (struct pthread_attr *) attr; /* Catch invalid sizes. */ int ret = check_stacksize_attr (stacksize); if (ret) return ret; #ifdef EXTRA_PARAM_CHECKS EXTRA_PARAM_CHECKS; #endif iattr->stacksize = stacksize; #if _STACK_GROWS_DOWN iattr->stackaddr = (char *) stackaddr + stacksize; #else iattr->stackaddr = (char *) stackaddr; #endif iattr->flags |= ATTR_FLAG_STACKADDR; return 0; }
int __pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize) { struct pthread_attr *iattr; assert (sizeof (*attr) >= sizeof (struct pthread_attr)); iattr = (struct pthread_attr *) attr; /* Catch invalid sizes. */ int ret = check_stacksize_attr (stacksize); if (ret) return ret; iattr->stacksize = stacksize; return 0; }
int pthread_setattr_default_np (const pthread_attr_t *in) { const struct pthread_attr *real_in; struct pthread_attr attrs; int ret; assert (sizeof (*in) >= sizeof (struct pthread_attr)); real_in = (struct pthread_attr *) in; /* Catch invalid values. */ int policy = real_in->schedpolicy; ret = check_sched_policy_attr (policy); if (ret) return ret; const struct sched_param *param = &real_in->schedparam; if (param->sched_priority > 0) { ret = check_sched_priority_attr (param->sched_priority, policy); if (ret) return ret; } ret = check_cpuset_attr (real_in->cpuset, real_in->cpusetsize); if (ret) return ret; /* stacksize == 0 is fine. It means that we don't change the current value. */ if (real_in->stacksize != 0) { ret = check_stacksize_attr (real_in->stacksize); if (ret) return ret; } /* Having a default stack address is wrong. */ if (real_in->flags & ATTR_FLAG_STACKADDR) return EINVAL; attrs = *real_in; /* Now take the lock because we start writing into __default_pthread_attr. */ lll_lock (__default_pthread_attr_lock, LLL_PRIVATE); /* Free the cpuset if the input is 0. Otherwise copy in the cpuset contents. */ size_t cpusetsize = attrs.cpusetsize; if (cpusetsize == 0) { free (__default_pthread_attr.cpuset); __default_pthread_attr.cpuset = NULL; } else if (cpusetsize == __default_pthread_attr.cpusetsize) { attrs.cpuset = __default_pthread_attr.cpuset; memcpy (attrs.cpuset, real_in->cpuset, cpusetsize); } else { /* This may look wrong at first sight, but it isn't. We're freeing __default_pthread_attr.cpuset and allocating to attrs.cpuset because we'll copy over all of attr to __default_pthread_attr later. */ cpu_set_t *newp = realloc (__default_pthread_attr.cpuset, cpusetsize); if (newp == NULL) { ret = ENOMEM; goto out; } attrs.cpuset = newp; memcpy (attrs.cpuset, real_in->cpuset, cpusetsize); } /* We don't want to accidentally set the default stacksize to zero. */ if (attrs.stacksize == 0) attrs.stacksize = __default_pthread_attr.stacksize; __default_pthread_attr = attrs; out: lll_unlock (__default_pthread_attr_lock, LLL_PRIVATE); return ret; }