diff --git a/lib/libthr/thread/thr_attr.c b/lib/libthr/thread/thr_attr.c --- a/lib/libthr/thread/thr_attr.c +++ b/lib/libthr/thread/thr_attr.c @@ -129,8 +129,9 @@ int _thr_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr) { - struct pthread_attr attr, *dst; + struct pthread_attr *dst; struct pthread *curthread; + cpuset_t *cpuset; size_t kern_size; int error; @@ -138,34 +139,39 @@ return (EINVAL); kern_size = _get_kern_cpuset_size(); - if (dst->cpuset == NULL) { - dst->cpuset = calloc(1, kern_size); - dst->cpusetsize = kern_size; - } + if ((cpuset = malloc(kern_size)) == NULL) + return (ENOMEM); + } else + cpuset = dst->cpuset; curthread = _get_curthread(); /* Arg 0 is to include dead threads. */ - if ((error = _thr_find_thread(curthread, pthread, 0)) != 0) + if ((error = _thr_find_thread(curthread, pthread, 0)) != 0) { + if (dst->cpuset == NULL) + free(cpuset); return (error); - - attr = pthread->attr; - if ((pthread->flags & THR_FLAGS_DETACHED) != 0) - attr.flags |= PTHREAD_DETACHED; + } error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(pthread), - dst->cpusetsize, dst->cpuset); - if (error == -1) - error = errno; + kern_size, cpuset); + if (error == -1) { + THR_THREAD_UNLOCK(curthread, pthread); + return (errno); + } + + /* + * From this point on, we can't fail, so we can start modifying 'dst'. + */ + + *dst = pthread->attr; + if ((pthread->flags & THR_FLAGS_DETACHED) != 0) + dst->flags |= PTHREAD_DETACHED; THR_THREAD_UNLOCK(curthread, pthread); - if (error == 0) - memcpy(&dst->pthread_attr_start_copy, - &attr.pthread_attr_start_copy, - offsetof(struct pthread_attr, pthread_attr_end_copy) - - offsetof(struct pthread_attr, pthread_attr_start_copy)); - + dst->cpuset = cpuset; + dst->cpusetsize = kern_size; return (0); } diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -261,7 +261,6 @@ }; struct pthread_attr { -#define pthread_attr_start_copy sched_policy int sched_policy; int sched_inherit; int prio; @@ -271,7 +270,6 @@ void *stackaddr_attr; size_t stacksize_attr; size_t guardsize_attr; -#define pthread_attr_end_copy cpuset cpuset_t *cpuset; size_t cpusetsize; };