summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr/thread')
-rw-r--r--lib/libthr/thread/thr_attr.c80
-rw-r--r--lib/libthr/thread/thr_mutex.c27
-rw-r--r--lib/libthr/thread/thr_sig.c10
3 files changed, 45 insertions, 72 deletions
diff --git a/lib/libthr/thread/thr_attr.c b/lib/libthr/thread/thr_attr.c
index 7fe50034..c2969e7 100644
--- a/lib/libthr/thread/thr_attr.c
+++ b/lib/libthr/thread/thr_attr.c
@@ -141,19 +141,14 @@ _pthread_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr)
struct pthread *curthread;
struct pthread_attr attr, *dst;
int ret;
- size_t cpusetsize;
+ size_t kern_size;
if (pthread == NULL || dstattr == NULL || (dst = *dstattr) == NULL)
return (EINVAL);
- cpusetsize = _get_kern_cpuset_size();
- if (dst->cpusetsize < cpusetsize) {
- char *newset = realloc(dst->cpuset, cpusetsize);
- if (newset == NULL)
- return (errno);
- memset(newset + dst->cpusetsize, 0, cpusetsize -
- dst->cpusetsize);
- dst->cpuset = (cpuset_t *)newset;
- dst->cpusetsize = cpusetsize;
+ kern_size = _get_kern_cpuset_size();
+ if (dst->cpuset == NULL) {
+ dst->cpuset = calloc(1, kern_size);
+ dst->cpusetsize = kern_size;
}
curthread = _get_curthread();
if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)) != 0)
@@ -574,13 +569,14 @@ _get_kern_cpuset_size(void)
if (kern_cpuset_size == 0) {
size_t len;
+ int maxcpus;
- len = sizeof(kern_cpuset_size);
- if (sysctlbyname("kern.smp.maxcpus", &kern_cpuset_size,
- &len, NULL, 0))
+ len = sizeof(maxcpus);
+ if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &len, NULL, 0))
PANIC("failed to get sysctl kern.smp.maxcpus");
-
- kern_cpuset_size = (kern_cpuset_size + 7) / 8;
+ int nbits_long = sizeof(long) * NBBY;
+ int num_long = (maxcpus + nbits_long - 1) / nbits_long;
+ kern_cpuset_size = num_long * sizeof(long);
}
return (kern_cpuset_size);
@@ -605,27 +601,25 @@ _pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize,
}
return (0);
}
-
- if (cpusetsize > attr->cpusetsize) {
- size_t kern_size = _get_kern_cpuset_size();
- if (cpusetsize > kern_size) {
- size_t i;
- for (i = kern_size; i < cpusetsize; ++i) {
- if (((char *)cpusetp)[i])
- return (EINVAL);
- }
+ size_t kern_size = _get_kern_cpuset_size();
+ /* Kernel rejects small set, we check it here too. */
+ if (cpusetsize < kern_size)
+ return (ERANGE);
+ if (cpusetsize > kern_size) {
+ /* Kernel checks invalid bits, we check it here too. */
+ size_t i;
+ for (i = kern_size; i < cpusetsize; ++i) {
+ if (((char *)cpusetp)[i])
+ return (EINVAL);
}
- void *newset = realloc(attr->cpuset, cpusetsize);
- if (newset == NULL)
- return (ENOMEM);
- attr->cpuset = newset;
- attr->cpusetsize = cpusetsize;
- } else {
- memset(((char *)attr->cpuset) + cpusetsize, 0,
- attr->cpusetsize - cpusetsize);
- attr->cpusetsize = cpusetsize;
}
- memcpy(attr->cpuset, cpusetp, cpusetsize);
+ if (attr->cpuset == NULL) {
+ attr->cpuset = calloc(1, kern_size);
+ if (attr->cpuset == NULL)
+ return (errno);
+ attr->cpusetsize = kern_size;
+ }
+ memcpy(attr->cpuset, cpusetp, kern_size);
ret = 0;
}
return (ret);
@@ -641,16 +635,18 @@ _pthread_attr_getaffinity_np(const pthread_attr_t *pattr, size_t cpusetsize,
if (pattr == NULL || (attr = (*pattr)) == NULL)
ret = EINVAL;
- else if (attr->cpuset != NULL) {
- memcpy(cpusetp, attr->cpuset, MIN(cpusetsize, attr->cpusetsize));
- if (cpusetsize > attr->cpusetsize)
- memset(((char *)cpusetp) + attr->cpusetsize, 0,
- cpusetsize - attr->cpusetsize);
- } else {
+ else {
+ /* Kernel rejects small set, we check it here too. */
size_t kern_size = _get_kern_cpuset_size();
- memset(cpusetp, -1, MIN(cpusetsize, kern_size));
+ if (cpusetsize < kern_size)
+ return (ERANGE);
+ if (attr->cpuset != NULL)
+ memcpy(cpusetp, attr->cpuset, MIN(cpusetsize,
+ attr->cpusetsize));
+ else
+ memset(cpusetp, -1, kern_size);
if (cpusetsize > kern_size)
- memset(((char *)cpusetp) + kern_size, 0,
+ memset(((char *)cpusetp) + kern_size, 0,
cpusetsize - kern_size);
}
return (ret);
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c
index a83454a..29f91ec 100644
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -257,10 +257,8 @@ _mutex_fork(struct pthread *curthread)
int
_pthread_mutex_destroy(pthread_mutex_t *mutex)
{
- struct pthread *curthread = _get_curthread();
pthread_mutex_t m;
- uint32_t id;
- int ret = 0;
+ int ret;
m = *mutex;
if (m < THR_MUTEX_DESTROYED) {
@@ -268,34 +266,13 @@ _pthread_mutex_destroy(pthread_mutex_t *mutex)
} else if (m == THR_MUTEX_DESTROYED) {
ret = EINVAL;
} else {
- id = TID(curthread);
-
- /*
- * Try to lock the mutex structure, we only need to
- * try once, if failed, the mutex is in used.
- */
- ret = _thr_umutex_trylock(&m->m_lock, id);
- if (ret)
- return (ret);
- /*
- * Check mutex other fields to see if this mutex is
- * in use. Mostly for prority mutex types, or there
- * are condition variables referencing it.
- */
if (m->m_owner != NULL || m->m_refcount != 0) {
- if (m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)
- set_inherited_priority(curthread, m);
- _thr_umutex_unlock(&m->m_lock, id);
ret = EBUSY;
} else {
*mutex = THR_MUTEX_DESTROYED;
-
- if (m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)
- set_inherited_priority(curthread, m);
- _thr_umutex_unlock(&m->m_lock, id);
-
MUTEX_ASSERT_NOT_OWNED(m);
free(m);
+ ret = 0;
}
}
diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c
index a2c1e53..4acfe40 100644
--- a/lib/libthr/thread/thr_sig.c
+++ b/lib/libthr/thread/thr_sig.c
@@ -317,14 +317,11 @@ check_deferred_signal(struct pthread *curthread)
ucontext_t uc;
struct sigaction act;
siginfo_t info;
- volatile int first;
if (__predict_true(curthread->deferred_siginfo.si_signo == 0))
return;
- first = 1;
getcontext(&uc);
- if (first) {
- first = 0;
+ if (curthread->deferred_siginfo.si_signo == 0) {
act = curthread->deferred_sigact;
uc.uc_sigmask = curthread->deferred_sigmask;
memcpy(&info, &curthread->deferred_siginfo, sizeof(siginfo_t));
@@ -550,7 +547,10 @@ _sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
if (oldact.sa_handler != SIG_DFL &&
oldact.sa_handler != SIG_IGN) {
- oldact = _thr_sigact[sig-1].sigact;
+ if (act != NULL)
+ oldact = oldact2;
+ else if (oact != NULL)
+ oldact = _thr_sigact[sig-1].sigact;
}
_thr_rwl_unlock(&_thr_sigact[sig-1].lock);
OpenPOWER on IntegriCloud