aboutsummaryrefslogtreecommitdiff
path: root/lib/libthr/thread
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr/thread')
-rw-r--r--lib/libthr/thread/Makefile.inc2
-rw-r--r--lib/libthr/thread/thr_affinity.c1
-rw-r--r--lib/libthr/thread/thr_attr.c495
-rw-r--r--lib/libthr/thread/thr_autoinit.c1
-rw-r--r--lib/libthr/thread/thr_barrier.c1
-rw-r--r--lib/libthr/thread/thr_barrierattr.c1
-rw-r--r--lib/libthr/thread/thr_cancel.c26
-rw-r--r--lib/libthr/thread/thr_clean.c1
-rw-r--r--lib/libthr/thread/thr_concurrency.c1
-rw-r--r--lib/libthr/thread/thr_cond.c2
-rw-r--r--lib/libthr/thread/thr_condattr.c2
-rw-r--r--lib/libthr/thread/thr_create.c19
-rw-r--r--lib/libthr/thread/thr_ctrdtr.c1
-rw-r--r--lib/libthr/thread/thr_detach.c1
-rw-r--r--lib/libthr/thread/thr_equal.c1
-rw-r--r--lib/libthr/thread/thr_event.c1
-rw-r--r--lib/libthr/thread/thr_exit.c1
-rw-r--r--lib/libthr/thread/thr_fork.c21
-rw-r--r--lib/libthr/thread/thr_getcpuclockid.c1
-rw-r--r--lib/libthr/thread/thr_getprio.c1
-rw-r--r--lib/libthr/thread/thr_getschedparam.c1
-rw-r--r--lib/libthr/thread/thr_getthreadid_np.c3
-rw-r--r--lib/libthr/thread/thr_info.c1
-rw-r--r--lib/libthr/thread/thr_init.c15
-rw-r--r--lib/libthr/thread/thr_join.c1
-rw-r--r--lib/libthr/thread/thr_kern.c1
-rw-r--r--lib/libthr/thread/thr_kill.c1
-rw-r--r--lib/libthr/thread/thr_list.c52
-rw-r--r--lib/libthr/thread/thr_main_np.c1
-rw-r--r--lib/libthr/thread/thr_malloc.c15
-rw-r--r--lib/libthr/thread/thr_multi_np.c1
-rw-r--r--lib/libthr/thread/thr_mutex.c2
-rw-r--r--lib/libthr/thread/thr_mutexattr.c1
-rw-r--r--lib/libthr/thread/thr_once.c1
-rw-r--r--lib/libthr/thread/thr_printf.c1
-rw-r--r--lib/libthr/thread/thr_private.h27
-rw-r--r--lib/libthr/thread/thr_pshared.c1
-rw-r--r--lib/libthr/thread/thr_pspinlock.c1
-rw-r--r--lib/libthr/thread/thr_resume_np.c6
-rw-r--r--lib/libthr/thread/thr_rtld.c45
-rw-r--r--lib/libthr/thread/thr_rwlock.c3
-rw-r--r--lib/libthr/thread/thr_rwlockattr.c1
-rw-r--r--lib/libthr/thread/thr_self.c1
-rw-r--r--lib/libthr/thread/thr_sem.c1
-rw-r--r--lib/libthr/thread/thr_setprio.c1
-rw-r--r--lib/libthr/thread/thr_setschedparam.c1
-rw-r--r--lib/libthr/thread/thr_sig.c62
-rw-r--r--lib/libthr/thread/thr_sigqueue.c79
-rw-r--r--lib/libthr/thread/thr_single_np.c1
-rw-r--r--lib/libthr/thread/thr_sleepq.c5
-rw-r--r--lib/libthr/thread/thr_spec.c1
-rw-r--r--lib/libthr/thread/thr_spinlock.c1
-rw-r--r--lib/libthr/thread/thr_stack.c6
-rw-r--r--lib/libthr/thread/thr_suspend_np.c6
-rw-r--r--lib/libthr/thread/thr_switch_np.c6
-rw-r--r--lib/libthr/thread/thr_symbols.c1
-rw-r--r--lib/libthr/thread/thr_syscalls.c55
-rw-r--r--lib/libthr/thread/thr_umtx.c11
-rw-r--r--lib/libthr/thread/thr_umtx.h1
-rw-r--r--lib/libthr/thread/thr_yield.c1
60 files changed, 486 insertions, 515 deletions
diff --git a/lib/libthr/thread/Makefile.inc b/lib/libthr/thread/Makefile.inc
index 33b95e9dd76d..c7442284bd51 100644
--- a/lib/libthr/thread/Makefile.inc
+++ b/lib/libthr/thread/Makefile.inc
@@ -1,4 +1,3 @@
-
# thr sources
.PATH: ${.CURDIR}/thread
@@ -47,6 +46,7 @@ SRCS+= \
thr_setprio.c \
thr_setschedparam.c \
thr_sig.c \
+ thr_sigqueue.c \
thr_single_np.c \
thr_sleepq.c \
thr_spec.c \
diff --git a/lib/libthr/thread/thr_affinity.c b/lib/libthr/thread/thr_affinity.c
index 89f654ebffc2..78c89e146a79 100644
--- a/lib/libthr/thread/thr_affinity.c
+++ b/lib/libthr/thread/thr_affinity.c
@@ -26,7 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread_np.h>
#include <sys/param.h>
diff --git a/lib/libthr/thread/thr_attr.c b/lib/libthr/thread/thr_attr.c
index 9740bed6ebd3..1d0bc8cb7b91 100644
--- a/lib/libthr/thread/thr_attr.c
+++ b/lib/libthr/thread/thr_attr.c
@@ -93,7 +93,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -113,26 +112,14 @@ __weak_reference(_thr_attr_destroy, pthread_attr_destroy);
int
_thr_attr_destroy(pthread_attr_t *attr)
{
- int ret;
- /* Check for invalid arguments: */
if (attr == NULL || *attr == NULL)
- /* Invalid argument: */
- ret = EINVAL;
- else {
- if ((*attr)->cpuset != NULL)
- free((*attr)->cpuset);
- /* Free the memory allocated to the attribute object: */
- free(*attr);
+ return (EINVAL);
- /*
- * Leave the attribute pointer NULL now that the memory
- * has been freed:
- */
- *attr = NULL;
- ret = 0;
- }
- return (ret);
+ free((*attr)->cpuset);
+ free(*attr);
+ *attr = NULL;
+ return (0);
}
__weak_reference(_thr_attr_get_np, pthread_attr_get_np);
@@ -141,36 +128,53 @@ __weak_reference(_thr_attr_get_np, _pthread_attr_get_np);
int
_thr_attr_get_np(pthread_t pthread, pthread_attr_t *dstattr)
{
+ struct pthread_attr *dst;
struct pthread *curthread;
- struct pthread_attr attr, *dst;
- int ret;
- size_t kern_size;
+ cpuset_t *cpuset;
+ size_t kern_size;
+ int error;
if (pthread == NULL || dstattr == NULL || (dst = *dstattr) == NULL)
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();
- if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)) != 0)
- return (ret);
- attr = pthread->attr;
- if (pthread->flags & THR_FLAGS_DETACHED)
- attr.flags |= PTHREAD_DETACHED;
- ret = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(pthread),
- dst->cpusetsize, dst->cpuset);
- if (ret == -1)
- ret = errno;
- THR_THREAD_UNLOCK(curthread, pthread);
- if (ret == 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));
+ /* Arg 0 is to include dead threads. */
+ if ((error = _thr_find_thread(curthread, pthread, 0)) != 0)
+ goto free_and_exit;
+
+ error = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, TID(pthread),
+ kern_size, cpuset);
+ if (error == -1) {
+ THR_THREAD_UNLOCK(curthread, pthread);
+ error = errno;
+ goto free_and_exit;
}
- return (ret);
+
+ /*
+ * 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);
+
+ dst->cpuset = cpuset;
+ dst->cpusetsize = kern_size;
+ return (0);
+
+free_and_exit:
+ if (dst->cpuset == NULL)
+ free(cpuset);
+ return (error);
}
__weak_reference(_thr_attr_getdetachstate, pthread_attr_getdetachstate);
@@ -179,22 +183,15 @@ __weak_reference(_thr_attr_getdetachstate, _pthread_attr_getdetachstate);
int
_thr_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
{
- int ret;
- /* Check for invalid arguments: */
if (attr == NULL || *attr == NULL || detachstate == NULL)
- ret = EINVAL;
- else {
- /* Check if the detached flag is set: */
- if ((*attr)->flags & PTHREAD_DETACHED)
- /* Return detached: */
- *detachstate = PTHREAD_CREATE_DETACHED;
- else
- /* Return joinable: */
- *detachstate = PTHREAD_CREATE_JOINABLE;
- ret = 0;
- }
- return (ret);
+ return (EINVAL);
+
+ if (((*attr)->flags & PTHREAD_DETACHED) != 0)
+ *detachstate = PTHREAD_CREATE_DETACHED;
+ else
+ *detachstate = PTHREAD_CREATE_JOINABLE;
+ return (0);
}
__weak_reference(_thr_attr_getguardsize, pthread_attr_getguardsize);
@@ -204,17 +201,12 @@ int
_thr_attr_getguardsize(const pthread_attr_t * __restrict attr,
size_t * __restrict guardsize)
{
- int ret;
- /* Check for invalid arguments: */
if (attr == NULL || *attr == NULL || guardsize == NULL)
- ret = EINVAL;
- else {
- /* Return the guard size: */
- *guardsize = (*attr)->guardsize_attr;
- ret = 0;
- }
- return (ret);
+ return (EINVAL);
+
+ *guardsize = (*attr)->guardsize_attr;
+ return (0);
}
__weak_reference(_thr_attr_getinheritsched, pthread_attr_getinheritsched);
@@ -224,14 +216,12 @@ int
_thr_attr_getinheritsched(const pthread_attr_t * __restrict attr,
int * __restrict sched_inherit)
{
- int ret = 0;
- if ((attr == NULL) || (*attr == NULL))
- ret = EINVAL;
- else
- *sched_inherit = (*attr)->sched_inherit;
+ if (attr == NULL || *attr == NULL)
+ return (EINVAL);
- return (ret);
+ *sched_inherit = (*attr)->sched_inherit;
+ return (0);
}
__weak_reference(_thr_attr_getschedparam, pthread_attr_getschedparam);
@@ -241,14 +231,12 @@ int
_thr_attr_getschedparam(const pthread_attr_t * __restrict attr,
struct sched_param * __restrict param)
{
- int ret = 0;
- if ((attr == NULL) || (*attr == NULL) || (param == NULL))
- ret = EINVAL;
- else
- param->sched_priority = (*attr)->prio;
+ if (attr == NULL || *attr == NULL || param == NULL)
+ return (EINVAL);
- return (ret);
+ param->sched_priority = (*attr)->prio;
+ return (0);
}
__weak_reference(_thr_attr_getschedpolicy, pthread_attr_getschedpolicy);
@@ -258,14 +246,12 @@ int
_thr_attr_getschedpolicy(const pthread_attr_t * __restrict attr,
int * __restrict policy)
{
- int ret = 0;
- if ((attr == NULL) || (*attr == NULL) || (policy == NULL))
- ret = EINVAL;
- else
- *policy = (*attr)->sched_policy;
+ if (attr == NULL || *attr == NULL || policy == NULL)
+ return (EINVAL);
- return (ret);
+ *policy = (*attr)->sched_policy;
+ return (0);
}
__weak_reference(_thr_attr_getscope, pthread_attr_getscope);
@@ -275,17 +261,13 @@ int
_thr_attr_getscope(const pthread_attr_t * __restrict attr,
int * __restrict contentionscope)
{
- int ret = 0;
-
- if ((attr == NULL) || (*attr == NULL) || (contentionscope == NULL))
- /* Return an invalid argument: */
- ret = EINVAL;
- else
- *contentionscope = (*attr)->flags & PTHREAD_SCOPE_SYSTEM ?
- PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS;
+ if (attr == NULL || *attr == NULL || contentionscope == NULL)
+ return (EINVAL);
- return (ret);
+ *contentionscope = ((*attr)->flags & PTHREAD_SCOPE_SYSTEM) != 0 ?
+ PTHREAD_SCOPE_SYSTEM : PTHREAD_SCOPE_PROCESS;
+ return (0);
}
__weak_reference(_pthread_attr_getstack, pthread_attr_getstack);
@@ -294,19 +276,14 @@ int
_pthread_attr_getstack(const pthread_attr_t * __restrict attr,
void ** __restrict stackaddr, size_t * __restrict stacksize)
{
- int ret;
-
- /* Check for invalid arguments: */
- if (attr == NULL || *attr == NULL || stackaddr == NULL
- || stacksize == NULL )
- ret = EINVAL;
- else {
- /* Return the stack address and size */
- *stackaddr = (*attr)->stackaddr_attr;
- *stacksize = (*attr)->stacksize_attr;
- ret = 0;
- }
- return (ret);
+
+ if (attr == NULL || *attr == NULL || stackaddr == NULL ||
+ stacksize == NULL)
+ return (EINVAL);
+
+ *stackaddr = (*attr)->stackaddr_attr;
+ *stacksize = (*attr)->stacksize_attr;
+ return (0);
}
__weak_reference(_thr_attr_getstackaddr, pthread_attr_getstackaddr);
@@ -315,17 +292,12 @@ __weak_reference(_thr_attr_getstackaddr, _pthread_attr_getstackaddr);
int
_thr_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
{
- int ret;
- /* Check for invalid arguments: */
if (attr == NULL || *attr == NULL || stackaddr == NULL)
- ret = EINVAL;
- else {
- /* Return the stack address: */
- *stackaddr = (*attr)->stackaddr_attr;
- ret = 0;
- }
- return (ret);
+ return (EINVAL);
+
+ *stackaddr = (*attr)->stackaddr_attr;
+ return (0);
}
__weak_reference(_thr_attr_getstacksize, pthread_attr_getstacksize);
@@ -335,17 +307,12 @@ int
_thr_attr_getstacksize(const pthread_attr_t * __restrict attr,
size_t * __restrict stacksize)
{
- int ret;
-
- /* Check for invalid arguments: */
- if (attr == NULL || *attr == NULL || stacksize == NULL)
- ret = EINVAL;
- else {
- /* Return the stack size: */
- *stacksize = (*attr)->stacksize_attr;
- ret = 0;
- }
- return (ret);
+
+ if (attr == NULL || *attr == NULL || stacksize == NULL)
+ return (EINVAL);
+
+ *stacksize = (*attr)->stacksize_attr;
+ return (0);
}
__weak_reference(_thr_attr_init, pthread_attr_init);
@@ -354,40 +321,30 @@ __weak_reference(_thr_attr_init, _pthread_attr_init);
int
_thr_attr_init(pthread_attr_t *attr)
{
- int ret;
- pthread_attr_t pattr;
+ pthread_attr_t pattr;
_thr_check_init();
- /* Allocate memory for the attribute object: */
- if ((pattr = (pthread_attr_t) malloc(sizeof(struct pthread_attr))) == NULL)
- /* Insufficient memory: */
- ret = ENOMEM;
- else {
- /* Initialise the attribute object with the defaults: */
- memcpy(pattr, &_pthread_attr_default, sizeof(struct pthread_attr));
-
- /* Return a pointer to the attribute object: */
- *attr = pattr;
- ret = 0;
- }
- return (ret);
+ if ((pattr = malloc(sizeof(*pattr))) == NULL)
+ return (ENOMEM);
+
+ memcpy(pattr, &_pthread_attr_default, sizeof(*pattr));
+ *attr = pattr;
+ return (0);
}
-__weak_reference(_pthread_attr_setcreatesuspend_np, pthread_attr_setcreatesuspend_np);
+__weak_reference(_pthread_attr_setcreatesuspend_np, \
+ pthread_attr_setcreatesuspend_np);
int
_pthread_attr_setcreatesuspend_np(pthread_attr_t *attr)
{
- int ret;
- if (attr == NULL || *attr == NULL) {
- ret = EINVAL;
- } else {
- (*attr)->suspend = THR_CREATE_SUSPENDED;
- ret = 0;
- }
- return (ret);
+ if (attr == NULL || *attr == NULL)
+ return (EINVAL);
+
+ (*attr)->suspend = THR_CREATE_SUSPENDED;
+ return (0);
}
__weak_reference(_thr_attr_setdetachstate, pthread_attr_setdetachstate);
@@ -396,24 +353,17 @@ __weak_reference(_thr_attr_setdetachstate, _pthread_attr_setdetachstate);
int
_thr_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
{
- int ret;
- /* Check for invalid arguments: */
if (attr == NULL || *attr == NULL ||
(detachstate != PTHREAD_CREATE_DETACHED &&
detachstate != PTHREAD_CREATE_JOINABLE))
- ret = EINVAL;
- else {
- /* Check if detached state: */
- if (detachstate == PTHREAD_CREATE_DETACHED)
- /* Set the detached flag: */
- (*attr)->flags |= PTHREAD_DETACHED;
- else
- /* Reset the detached flag: */
- (*attr)->flags &= ~PTHREAD_DETACHED;
- ret = 0;
- }
- return (ret);
+ return (EINVAL);
+
+ if (detachstate == PTHREAD_CREATE_DETACHED)
+ (*attr)->flags |= PTHREAD_DETACHED;
+ else
+ (*attr)->flags &= ~PTHREAD_DETACHED;
+ return (0);
}
__weak_reference(_thr_attr_setguardsize, pthread_attr_setguardsize);
@@ -422,17 +372,12 @@ __weak_reference(_thr_attr_setguardsize, _pthread_attr_setguardsize);
int
_thr_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
{
- int ret;
- /* Check for invalid arguments. */
if (attr == NULL || *attr == NULL)
- ret = EINVAL;
- else {
- /* Save the stack size. */
- (*attr)->guardsize_attr = guardsize;
- ret = 0;
- }
- return (ret);
+ return (EINVAL);
+
+ (*attr)->guardsize_attr = guardsize;
+ return (0);
}
__weak_reference(_thr_attr_setinheritsched, pthread_attr_setinheritsched);
@@ -441,17 +386,14 @@ __weak_reference(_thr_attr_setinheritsched, _pthread_attr_setinheritsched);
int
_thr_attr_setinheritsched(pthread_attr_t *attr, int sched_inherit)
{
- int ret = 0;
- if ((attr == NULL) || (*attr == NULL))
- ret = EINVAL;
- else if (sched_inherit != PTHREAD_INHERIT_SCHED &&
- sched_inherit != PTHREAD_EXPLICIT_SCHED)
- ret = ENOTSUP;
- else
- (*attr)->sched_inherit = sched_inherit;
+ if (attr == NULL || *attr == NULL ||
+ (sched_inherit != PTHREAD_INHERIT_SCHED &&
+ sched_inherit != PTHREAD_EXPLICIT_SCHED))
+ return (EINVAL);
- return (ret);
+ (*attr)->sched_inherit = sched_inherit;
+ return (0);
}
__weak_reference(_thr_attr_setschedparam, pthread_attr_setschedparam);
@@ -463,18 +405,15 @@ _thr_attr_setschedparam(pthread_attr_t * __restrict attr,
{
int policy;
- if ((attr == NULL) || (*attr == NULL))
+ if (attr == NULL || *attr == NULL || param == NULL)
return (EINVAL);
- if (param == NULL)
- return (ENOTSUP);
-
policy = (*attr)->sched_policy;
if (policy == SCHED_FIFO || policy == SCHED_RR) {
if (param->sched_priority < _thr_priorities[policy-1].pri_min ||
param->sched_priority > _thr_priorities[policy-1].pri_max)
- return (ENOTSUP);
+ return (EINVAL);
} else {
/*
* Ignore it for SCHED_OTHER now, patches for glib ports
@@ -494,17 +433,14 @@ __weak_reference(_thr_attr_setschedpolicy, _pthread_attr_setschedpolicy);
int
_thr_attr_setschedpolicy(pthread_attr_t *attr, int policy)
{
- int ret = 0;
- if ((attr == NULL) || (*attr == NULL))
- ret = EINVAL;
- else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) {
- ret = ENOTSUP;
- } else {
- (*attr)->sched_policy = policy;
- (*attr)->prio = _thr_priorities[policy-1].pri_default;
- }
- return (ret);
+ if (attr == NULL || *attr == NULL ||
+ policy < SCHED_FIFO || policy > SCHED_RR)
+ return (EINVAL);
+
+ (*attr)->sched_policy = policy;
+ (*attr)->prio = _thr_priorities[policy-1].pri_default;
+ return (0);
}
__weak_reference(_thr_attr_setscope, pthread_attr_setscope);
@@ -513,41 +449,33 @@ __weak_reference(_thr_attr_setscope, _pthread_attr_setscope);
int
_thr_attr_setscope(pthread_attr_t *attr, int contentionscope)
{
- int ret = 0;
-
- if ((attr == NULL) || (*attr == NULL)) {
- /* Return an invalid argument: */
- ret = EINVAL;
- } else if ((contentionscope != PTHREAD_SCOPE_PROCESS) &&
- (contentionscope != PTHREAD_SCOPE_SYSTEM)) {
- ret = EINVAL;
- } else if (contentionscope == PTHREAD_SCOPE_SYSTEM) {
- (*attr)->flags |= contentionscope;
- } else {
+
+ if (attr == NULL || *attr == NULL ||
+ (contentionscope != PTHREAD_SCOPE_PROCESS &&
+ contentionscope != PTHREAD_SCOPE_SYSTEM))
+ return (EINVAL);
+
+ if (contentionscope == PTHREAD_SCOPE_SYSTEM)
+ (*attr)->flags |= PTHREAD_SCOPE_SYSTEM;
+ else
(*attr)->flags &= ~PTHREAD_SCOPE_SYSTEM;
- }
- return (ret);
+ return (0);
}
__weak_reference(_pthread_attr_setstack, pthread_attr_setstack);
int
_pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr,
- size_t stacksize)
+ size_t stacksize)
{
- int ret;
-
- /* Check for invalid arguments: */
- if (attr == NULL || *attr == NULL || stackaddr == NULL
- || stacksize < PTHREAD_STACK_MIN)
- ret = EINVAL;
- else {
- /* Save the stack address and stack size */
- (*attr)->stackaddr_attr = stackaddr;
- (*attr)->stacksize_attr = stacksize;
- ret = 0;
- }
- return (ret);
+
+ if (attr == NULL || *attr == NULL || stackaddr == NULL ||
+ stacksize < PTHREAD_STACK_MIN)
+ return (EINVAL);
+
+ (*attr)->stackaddr_attr = stackaddr;
+ (*attr)->stacksize_attr = stacksize;
+ return (0);
}
__weak_reference(_thr_attr_setstackaddr, pthread_attr_setstackaddr);
@@ -556,17 +484,12 @@ __weak_reference(_thr_attr_setstackaddr, _pthread_attr_setstackaddr);
int
_thr_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
{
- int ret;
- /* Check for invalid arguments: */
if (attr == NULL || *attr == NULL || stackaddr == NULL)
- ret = EINVAL;
- else {
- /* Save the stack address: */
- (*attr)->stackaddr_attr = stackaddr;
- ret = 0;
- }
- return(ret);
+ return (EINVAL);
+
+ (*attr)->stackaddr_attr = stackaddr;
+ return (0);
}
__weak_reference(_thr_attr_setstacksize, pthread_attr_setstacksize);
@@ -575,17 +498,12 @@ __weak_reference(_thr_attr_setstacksize, _pthread_attr_setstacksize);
int
_thr_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
{
- int ret;
- /* Check for invalid arguments: */
if (attr == NULL || *attr == NULL || stacksize < PTHREAD_STACK_MIN)
- ret = EINVAL;
- else {
- /* Save the stack size: */
- (*attr)->stacksize_attr = stacksize;
- ret = 0;
- }
- return (ret);
+ return (EINVAL);
+
+ (*attr)->stacksize_attr = stacksize;
+ return (0);
}
static size_t
@@ -608,71 +526,70 @@ _get_kern_cpuset_size(void)
}
__weak_reference(_pthread_attr_setaffinity_np, pthread_attr_setaffinity_np);
+
int
_pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize,
- const cpuset_t *cpusetp)
+ const cpuset_t *cpusetp)
{
pthread_attr_t attr;
- int ret;
+ size_t kern_size;
if (pattr == NULL || (attr = (*pattr)) == NULL)
- ret = EINVAL;
- else {
- if (cpusetsize == 0 || cpusetp == NULL) {
- if (attr->cpuset != NULL) {
- free(attr->cpuset);
- attr->cpuset = NULL;
- attr->cpusetsize = 0;
- }
- return (0);
- }
- 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 (((const char *)cpusetp)[i])
- return (EINVAL);
- }
- }
- if (attr->cpuset == NULL) {
- attr->cpuset = calloc(1, kern_size);
- if (attr->cpuset == NULL)
- return (errno);
- attr->cpusetsize = kern_size;
+ return (EINVAL);
+
+ if (cpusetsize == 0 || cpusetp == NULL) {
+ if (attr->cpuset != NULL) {
+ free(attr->cpuset);
+ attr->cpuset = NULL;
+ attr->cpusetsize = 0;
}
- memcpy(attr->cpuset, cpusetp, kern_size);
- ret = 0;
+ return (0);
+ }
+
+ 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 (((const char *)cpusetp)[i] != 0)
+ return (EINVAL);
+ }
+ if (attr->cpuset == NULL) {
+ attr->cpuset = malloc(kern_size);
+ if (attr->cpuset == NULL)
+ return (errno);
+ attr->cpusetsize = kern_size;
}
- return (ret);
+ memcpy(attr->cpuset, cpusetp, kern_size);
+ return (0);
}
__weak_reference(_pthread_attr_getaffinity_np, pthread_attr_getaffinity_np);
+
int
_pthread_attr_getaffinity_np(const pthread_attr_t *pattr, size_t cpusetsize,
- cpuset_t *cpusetp)
+ cpuset_t *cpusetp)
{
pthread_attr_t attr;
- int ret = 0;
if (pattr == NULL || (attr = (*pattr)) == NULL)
- ret = EINVAL;
- else {
- /* Kernel rejects small set, we check it here too. */
- size_t kern_size = _get_kern_cpuset_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,
- cpusetsize - kern_size);
- }
- return (ret);
+ return (EINVAL);
+
+ /* Kernel rejects small set, we check it here too. */
+ size_t kern_size = _get_kern_cpuset_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,
+ cpusetsize - kern_size);
+ return (0);
}
diff --git a/lib/libthr/thread/thr_autoinit.c b/lib/libthr/thread/thr_autoinit.c
index f18f53517e06..b0b4e601eff7 100644
--- a/lib/libthr/thread/thr_autoinit.c
+++ b/lib/libthr/thread/thr_autoinit.c
@@ -33,7 +33,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <pthread.h>
#include "thr_private.h"
diff --git a/lib/libthr/thread/thr_barrier.c b/lib/libthr/thread/thr_barrier.c
index 8f5936409c05..13dec864e2f6 100644
--- a/lib/libthr/thread/thr_barrier.c
+++ b/lib/libthr/thread/thr_barrier.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <stdlib.h>
diff --git a/lib/libthr/thread/thr_barrierattr.c b/lib/libthr/thread/thr_barrierattr.c
index 7af7e40f9159..6e5de86973f2 100644
--- a/lib/libthr/thread/thr_barrierattr.c
+++ b/lib/libthr/thread/thr_barrierattr.c
@@ -28,7 +28,6 @@
* DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <stdlib.h>
diff --git a/lib/libthr/thread/thr_cancel.c b/lib/libthr/thread/thr_cancel.c
index 86632e41449b..4189a2640d14 100644
--- a/lib/libthr/thread/thr_cancel.c
+++ b/lib/libthr/thread/thr_cancel.c
@@ -26,7 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include "un-namespace.h"
@@ -84,25 +83,25 @@ int
_thr_setcancelstate(int state, int *oldstate)
{
struct pthread *curthread = _get_curthread();
- int oldval;
+ int oldval, val;
- oldval = curthread->cancel_enable;
switch (state) {
case PTHREAD_CANCEL_DISABLE:
- curthread->cancel_enable = 0;
+ val = 0;
break;
case PTHREAD_CANCEL_ENABLE:
- curthread->cancel_enable = 1;
- if (curthread->cancel_async)
- testcancel(curthread);
+ val = 1;
break;
default:
return (EINVAL);
}
- if (oldstate) {
+ oldval = atomic_swap_int(&curthread->cancel_enable, val);
+ if (state == PTHREAD_CANCEL_ENABLE && curthread->cancel_async)
+ testcancel(curthread);
+ if (oldstate != NULL) {
*oldstate = oldval ? PTHREAD_CANCEL_ENABLE :
- PTHREAD_CANCEL_DISABLE;
+ PTHREAD_CANCEL_DISABLE;
}
return (0);
}
@@ -126,9 +125,9 @@ _thr_setcanceltype(int type, int *oldtype)
return (EINVAL);
}
- if (oldtype) {
+ if (oldtype != NULL) {
*oldtype = oldval ? PTHREAD_CANCEL_ASYNCHRONOUS :
- PTHREAD_CANCEL_DEFERRED;
+ PTHREAD_CANCEL_DEFERRED;
}
return (0);
}
@@ -167,9 +166,8 @@ void
_thr_cancel_leave(struct pthread *curthread, int maycancel)
{
curthread->cancel_point = 0;
- if (__predict_false(SHOULD_CANCEL(curthread) &&
- !THR_IN_CRITICAL(curthread) && maycancel))
- _pthread_exit(PTHREAD_CANCELED);
+ if (maycancel)
+ testcancel(curthread);
}
void
diff --git a/lib/libthr/thread/thr_clean.c b/lib/libthr/thread/thr_clean.c
index ba699f0376d8..43fd570fd1df 100644
--- a/lib/libthr/thread/thr_clean.c
+++ b/lib/libthr/thread/thr_clean.c
@@ -30,7 +30,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <signal.h>
#include <errno.h>
diff --git a/lib/libthr/thread/thr_concurrency.c b/lib/libthr/thread/thr_concurrency.c
index cc0d1075b92d..64c605f7d058 100644
--- a/lib/libthr/thread/thr_concurrency.c
+++ b/lib/libthr/thread/thr_concurrency.c
@@ -32,7 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c
index bec7933537b3..0eb3dac068ca 100644
--- a/lib/libthr/thread/thr_cond.c
+++ b/lib/libthr/thread/thr_cond.c
@@ -30,7 +30,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <stdlib.h>
#include <errno.h>
@@ -64,6 +63,7 @@ __weak_reference(__thr_cond_wait, pthread_cond_wait);
__weak_reference(__thr_cond_wait, __pthread_cond_wait);
__weak_reference(_thr_cond_wait, _pthread_cond_wait);
__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait);
+__weak_reference(_thr_cond_timedwait, _pthread_cond_timedwait);
__weak_reference(_thr_cond_init, pthread_cond_init);
__weak_reference(_thr_cond_init, _pthread_cond_init);
__weak_reference(_thr_cond_destroy, pthread_cond_destroy);
diff --git a/lib/libthr/thread/thr_condattr.c b/lib/libthr/thread/thr_condattr.c
index c5f675f0023d..dc56363fc084 100644
--- a/lib/libthr/thread/thr_condattr.c
+++ b/lib/libthr/thread/thr_condattr.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <stdlib.h>
#include <string.h>
@@ -95,6 +94,7 @@ _pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
if (attr == NULL || *attr == NULL)
return (EINVAL);
if (clock_id != CLOCK_REALTIME &&
+ clock_id != CLOCK_TAI &&
clock_id != CLOCK_VIRTUAL &&
clock_id != CLOCK_PROF &&
clock_id != CLOCK_MONOTONIC) {
diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c
index 4b9f45ac49de..e56dbcfe30e1 100644
--- a/lib/libthr/thread/thr_create.c
+++ b/lib/libthr/thread/thr_create.c
@@ -27,11 +27,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
+#define _WANT_P_OSREL
#include "namespace.h"
#include <sys/types.h>
#include <sys/rtprio.h>
#include <sys/signalvar.h>
+#include <sys/exterrvar.h>
#include <errno.h>
#include <link.h>
#include <stdlib.h>
@@ -44,9 +45,13 @@
#include "libc_private.h"
#include "thr_private.h"
+int __getosreldate(void);
+
static int create_stack(struct pthread_attr *pattr);
static void thread_start(struct pthread *curthread);
+int __thr_new_flags = THR_C_RUNTIME;
+
__weak_reference(_pthread_create, pthread_create);
int
@@ -147,7 +152,7 @@ _pthread_create(pthread_t * __restrict thread,
_thr_stack_fix_protection(new_thread);
/* Return thread pointer eariler so that new thread can use it. */
- (*thread) = new_thread;
+ *thread = new_thread;
if (SHOULD_REPORT_EVENT(curthread, TD_CREATE) || cpusetp != NULL) {
THR_THREAD_LOCK(curthread, new_thread);
locked = 1;
@@ -161,7 +166,7 @@ _pthread_create(pthread_t * __restrict thread,
param.tls_size = sizeof(struct tcb);
param.child_tid = &new_thread->tid;
param.parent_tid = &new_thread->tid;
- param.flags = 0;
+ param.flags = __thr_new_flags;
if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM)
param.flags |= THR_SYSTEM_SCOPE;
if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED)
@@ -227,8 +232,8 @@ _pthread_create(pthread_t * __restrict thread,
THR_THREAD_UNLOCK(curthread, new_thread);
}
out:
- if (ret)
- (*thread) = 0;
+ if (ret != 0)
+ *thread = NULL;
return (ret);
}
@@ -286,6 +291,10 @@ thread_start(struct pthread *curthread)
curthread->attr.stacksize_attr;
#endif
+ curthread->uexterr.ver = UEXTERROR_VER;
+ if (__getosreldate() >= P_OSREL_EXTERRCTL)
+ exterrctl(EXTERRCTL_ENABLE, 0, &curthread->uexterr);
+
/* Run the current thread's start routine with argument: */
_pthread_exit(curthread->start_routine(curthread->arg));
diff --git a/lib/libthr/thread/thr_ctrdtr.c b/lib/libthr/thread/thr_ctrdtr.c
index ae8fa38d3cb0..6fa462a81d86 100644
--- a/lib/libthr/thread/thr_ctrdtr.c
+++ b/lib/libthr/thread/thr_ctrdtr.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <rtld_tls.h>
diff --git a/lib/libthr/thread/thr_detach.c b/lib/libthr/thread/thr_detach.c
index 214d5e76262e..c7a60bb26129 100644
--- a/lib/libthr/thread/thr_detach.c
+++ b/lib/libthr/thread/thr_detach.c
@@ -27,7 +27,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/types.h>
#include <errno.h>
diff --git a/lib/libthr/thread/thr_equal.c b/lib/libthr/thread/thr_equal.c
index 2a4cc9f6d049..e5b2ab881138 100644
--- a/lib/libthr/thread/thr_equal.c
+++ b/lib/libthr/thread/thr_equal.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include "un-namespace.h"
diff --git a/lib/libthr/thread/thr_event.c b/lib/libthr/thread/thr_event.c
index afe0b307423c..f0b1805894fb 100644
--- a/lib/libthr/thread/thr_event.c
+++ b/lib/libthr/thread/thr_event.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "thr_private.h"
void
diff --git a/lib/libthr/thread/thr_exit.c b/lib/libthr/thread/thr_exit.c
index 001b30f6671a..5a9dcf99fa21 100644
--- a/lib/libthr/thread/thr_exit.c
+++ b/lib/libthr/thread/thr_exit.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#ifdef _PTHREAD_FORCED_UNWIND
diff --git a/lib/libthr/thread/thr_fork.c b/lib/libthr/thread/thr_fork.c
index fc7d77180e8b..aa54b0444cf4 100644
--- a/lib/libthr/thread/thr_fork.c
+++ b/lib/libthr/thread/thr_fork.c
@@ -57,7 +57,6 @@
*
*/
-#include <sys/cdefs.h>
#include <sys/syscall.h>
#include "namespace.h"
#include <errno.h>
@@ -85,20 +84,24 @@ _thr_atfork(void (*prepare)(void), void (*parent)(void),
struct pthread *curthread;
struct pthread_atfork *af;
- _thr_check_init();
-
if ((af = malloc(sizeof(struct pthread_atfork))) == NULL)
return (ENOMEM);
- curthread = _get_curthread();
af->prepare = prepare;
af->parent = parent;
af->child = child;
- THR_CRITICAL_ENTER(curthread);
- _thr_rwl_wrlock(&_thr_atfork_lock);
- TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe);
- _thr_rwl_unlock(&_thr_atfork_lock);
- THR_CRITICAL_LEAVE(curthread);
+
+ if (_thr_initial != NULL) {
+ curthread = _get_curthread();
+ THR_CRITICAL_ENTER(curthread);
+ _thr_rwl_wrlock(&_thr_atfork_lock);
+ TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe);
+ _thr_rwl_unlock(&_thr_atfork_lock);
+ THR_CRITICAL_LEAVE(curthread);
+ } else {
+ TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe);
+ }
+
return (0);
}
diff --git a/lib/libthr/thread/thr_getcpuclockid.c b/lib/libthr/thread/thr_getcpuclockid.c
index 0281fc626882..dee3a2a9447a 100644
--- a/lib/libthr/thread/thr_getcpuclockid.c
+++ b/lib/libthr/thread/thr_getcpuclockid.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
diff --git a/lib/libthr/thread/thr_getprio.c b/lib/libthr/thread/thr_getprio.c
index 5ab147af212c..d338287342ac 100644
--- a/lib/libthr/thread/thr_getprio.c
+++ b/lib/libthr/thread/thr_getprio.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
diff --git a/lib/libthr/thread/thr_getschedparam.c b/lib/libthr/thread/thr_getschedparam.c
index 557bcc834950..3abe9be6937b 100644
--- a/lib/libthr/thread/thr_getschedparam.c
+++ b/lib/libthr/thread/thr_getschedparam.c
@@ -32,7 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/types.h>
#include <sys/rtprio.h>
diff --git a/lib/libthr/thread/thr_getthreadid_np.c b/lib/libthr/thread/thr_getthreadid_np.c
index 1fe927435b02..ffecd0bc7ea9 100644
--- a/lib/libthr/thread/thr_getthreadid_np.c
+++ b/lib/libthr/thread/thr_getthreadid_np.c
@@ -25,7 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include <pthread_np.h>
@@ -37,7 +36,7 @@ __weak_reference(_thr_getthreadid_np, _pthread_getthreadid_np);
__weak_reference(_thr_getthreadid_np, pthread_getthreadid_np);
/*
- * Provide the equivelant to AIX pthread_getthreadid_np() function.
+ * Provide the equivalent to AIX pthread_getthreadid_np() function.
*/
int
_thr_getthreadid_np(void)
diff --git a/lib/libthr/thread/thr_info.c b/lib/libthr/thread/thr_info.c
index 41ab7f0bcf0c..f6bf81203f9c 100644
--- a/lib/libthr/thread/thr_info.c
+++ b/lib/libthr/thread/thr_info.c
@@ -33,7 +33,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/errno.h>
#include <stdlib.h>
diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c
index b59678c3f6c3..0f9e3749d75f 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
+#define _WANT_P_OSREL
#include "namespace.h"
#include <sys/param.h>
#include <sys/auxv.h>
@@ -60,6 +60,7 @@
#include "libc_private.h"
#include "thr_private.h"
+int __getosreldate(void);
char *_usrstack;
struct pthread *_thr_initial;
int _libthr_debug;
@@ -169,7 +170,6 @@ STATIC_LIB_REQUIRE(_sem_trywait);
STATIC_LIB_REQUIRE(_sem_wait);
STATIC_LIB_REQUIRE(_sigaction);
STATIC_LIB_REQUIRE(_sigprocmask);
-STATIC_LIB_REQUIRE(_sigsuspend);
STATIC_LIB_REQUIRE(_sigtimedwait);
STATIC_LIB_REQUIRE(_sigwait);
STATIC_LIB_REQUIRE(_sigwaitinfo);
@@ -272,6 +272,8 @@ static pthread_func_t jmp_table[][2] = {
[PJT_GETTHREADID_NP] = {DUAL_ENTRY(_thr_getthreadid_np)},
[PJT_ATTR_GET_NP] = {DUAL_ENTRY(_thr_attr_get_np)},
[PJT_GETNAME_NP] = {DUAL_ENTRY(_thr_getname_np)},
+ [PJT_SUSPEND_ALL_NP] = {DUAL_ENTRY(_thr_suspend_all_np)},
+ [PJT_RESUME_ALL_NP] = {DUAL_ENTRY(_thr_resume_all_np)},
};
static int init_once = 0;
@@ -333,6 +335,8 @@ _libpthread_init(struct pthread *curthread)
/* Set the initial thread. */
if (curthread == NULL) {
first = 1;
+ /* Force _get_curthread() return NULL until set. */
+ _tcb_get()->tcb_thread = NULL;
/* Create and initialize the initial thread. */
curthread = _thr_alloc(NULL);
if (curthread == NULL)
@@ -349,7 +353,7 @@ _libpthread_init(struct pthread *curthread)
_thread_active_threads = 1;
/* Setup the thread specific data */
- _tcb_set(curthread->tcb);
+ __thr_setup_tsd(curthread);
if (first) {
_thr_initial = curthread;
@@ -430,6 +434,10 @@ init_main_thread(struct pthread *thread)
thread->unwind_stackend = _usrstack;
#endif
+ thread->uexterr.ver = UEXTERROR_VER;
+ if (__getosreldate() >= P_OSREL_EXTERRCTL)
+ exterrctl(EXTERRCTL_ENABLE, EXTERRCTLF_FORCE, &thread->uexterr);
+
/* Others cleared to zero by thr_alloc() */
}
@@ -520,7 +528,6 @@ init_private(void)
env = getenv("LIBPTHREAD_QUEUE_FIFO");
if (env)
_thr_queuefifo = atoi(env);
- TAILQ_INIT(&_thr_atfork_list);
env = getenv("LIBPTHREAD_UMTX_MIN_TIMEOUT");
if (env) {
char *endptr;
diff --git a/lib/libthr/thread/thr_join.c b/lib/libthr/thread/thr_join.c
index 4b48249489f6..53f28daa258d 100644
--- a/lib/libthr/thread/thr_join.c
+++ b/lib/libthr/thread/thr_join.c
@@ -26,7 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
diff --git a/lib/libthr/thread/thr_kern.c b/lib/libthr/thread/thr_kern.c
index 05522569fbfb..913b0d3ef44c 100644
--- a/lib/libthr/thread/thr_kern.c
+++ b/lib/libthr/thread/thr_kern.c
@@ -27,7 +27,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/signalvar.h>
#include <sys/rtprio.h>
diff --git a/lib/libthr/thread/thr_kill.c b/lib/libthr/thread/thr_kill.c
index dd7beddd5c33..5fb40b3bc496 100644
--- a/lib/libthr/thread/thr_kill.c
+++ b/lib/libthr/thread/thr_kill.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <signal.h>
diff --git a/lib/libthr/thread/thr_list.c b/lib/libthr/thread/thr_list.c
index 72018d94f496..cbf16179f619 100644
--- a/lib/libthr/thread/thr_list.c
+++ b/lib/libthr/thread/thr_list.c
@@ -27,17 +27,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/queue.h>
+#include <machine/tls.h>
+
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "libc_private.h"
#include "thr_private.h"
-#include "static_tls.h"
/*#define DEBUG_THREAD_LIST */
#ifdef DEBUG_THREAD_LIST
@@ -150,16 +150,18 @@ _thr_alloc(struct pthread *curthread)
if (thread == NULL) {
if (total_threads > MAX_THREADS)
return (NULL);
- atomic_fetchadd_int(&total_threads, 1);
- thread = calloc(1, sizeof(struct pthread));
+ atomic_add_int(&total_threads, 1);
+ thread = __thr_aligned_alloc_offset(_Alignof(struct pthread),
+ sizeof(struct pthread), 0);
if (thread == NULL) {
- atomic_fetchadd_int(&total_threads, -1);
+ atomic_add_int(&total_threads, -1);
return (NULL);
}
+ memset(thread, 0, sizeof(*thread));
if ((thread->sleepqueue = _sleepq_alloc()) == NULL ||
(thread->wake_addr = _thr_alloc_wake_addr()) == NULL) {
thr_destroy(curthread, thread);
- atomic_fetchadd_int(&total_threads, -1);
+ atomic_add_int(&total_threads, -1);
return (NULL);
}
} else {
@@ -177,7 +179,7 @@ _thr_alloc(struct pthread *curthread)
thread->tcb = tcb;
} else {
thr_destroy(curthread, thread);
- atomic_fetchadd_int(&total_threads, -1);
+ atomic_add_int(&total_threads, -1);
thread = NULL;
}
return (thread);
@@ -203,7 +205,7 @@ _thr_free(struct pthread *curthread, struct pthread *thread)
thread->tcb = NULL;
if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) {
thr_destroy(curthread, thread);
- atomic_fetchadd_int(&total_threads, -1);
+ atomic_add_int(&total_threads, -1);
} else {
/*
* Add the thread to the free thread list, this also avoids
@@ -223,7 +225,7 @@ thr_destroy(struct pthread *curthread __unused, struct pthread *thread)
_sleepq_free(thread->sleepqueue);
if (thread->wake_addr != NULL)
_thr_release_wake_addr(thread->wake_addr);
- free(thread);
+ __thr_free(thread);
}
/*
@@ -361,35 +363,3 @@ _thr_find_thread(struct pthread *curthread, struct pthread *thread,
THREAD_LIST_UNLOCK(curthread);
return (ret);
}
-
-#include "pthread_tls.h"
-
-static void
-thr_distribute_static_tls(uintptr_t tlsbase, void *src, size_t len,
- size_t total_len)
-{
-
- memcpy((void *)tlsbase, src, len);
- memset((char *)tlsbase + len, 0, total_len - len);
-}
-
-void
-__pthread_distribute_static_tls(size_t offset, void *src, size_t len,
- size_t total_len)
-{
- struct pthread *curthread, *thrd;
- uintptr_t tlsbase;
-
- if (!_thr_is_inited()) {
- tlsbase = _libc_get_static_tls_base(offset);
- thr_distribute_static_tls(tlsbase, src, len, total_len);
- return;
- }
- curthread = _get_curthread();
- THREAD_LIST_RDLOCK(curthread);
- TAILQ_FOREACH(thrd, &_thread_list, tle) {
- tlsbase = _get_static_tls_base(thrd, offset);
- thr_distribute_static_tls(tlsbase, src, len, total_len);
- }
- THREAD_LIST_UNLOCK(curthread);
-}
diff --git a/lib/libthr/thread/thr_main_np.c b/lib/libthr/thread/thr_main_np.c
index 9dd8b1820acd..1d34dc21b84c 100644
--- a/lib/libthr/thread/thr_main_np.c
+++ b/lib/libthr/thread/thr_main_np.c
@@ -27,7 +27,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include <pthread_np.h>
diff --git a/lib/libthr/thread/thr_malloc.c b/lib/libthr/thread/thr_malloc.c
index d60fbc1b1fe8..48af9d1ea929 100644
--- a/lib/libthr/thread/thr_malloc.c
+++ b/lib/libthr/thread/thr_malloc.c
@@ -2,7 +2,6 @@
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
* under sponsorship from the FreeBSD Foundation.
@@ -29,7 +28,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <rtld_malloc.h>
@@ -122,6 +120,19 @@ __thr_malloc(size_t nbytes)
}
void *
+__thr_aligned_alloc_offset(size_t align, size_t size, size_t offset)
+{
+ struct pthread *curthread;
+ void *res;
+
+ curthread = _get_curthread();
+ thr_malloc_lock(curthread);
+ res = __crt_aligned_alloc_offset(align, size, offset);
+ thr_malloc_unlock(curthread);
+ return (res);
+}
+
+void *
__thr_realloc(void *cp, size_t nbytes)
{
struct pthread *curthread;
diff --git a/lib/libthr/thread/thr_multi_np.c b/lib/libthr/thread/thr_multi_np.c
index cbd3f31fddf0..bac58ca85dca 100644
--- a/lib/libthr/thread/thr_multi_np.c
+++ b/lib/libthr/thread/thr_multi_np.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include <pthread_np.h>
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c
index 5dd624a269e4..32bdc4afe65f 100644
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -38,7 +38,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <stdlib.h>
#include <errno.h>
@@ -620,6 +619,7 @@ __Tthr_mutex_trylock(pthread_mutex_t *mutex)
uint32_t id;
int ret, robust;
+ _thr_check_init();
ret = check_and_init_mutex(mutex, &m);
if (ret != 0)
return (ret);
diff --git a/lib/libthr/thread/thr_mutexattr.c b/lib/libthr/thread/thr_mutexattr.c
index 6d38f164df52..d78aad518ee8 100644
--- a/lib/libthr/thread/thr_mutexattr.c
+++ b/lib/libthr/thread/thr_mutexattr.c
@@ -59,7 +59,6 @@
*
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <string.h>
#include <stdlib.h>
diff --git a/lib/libthr/thread/thr_once.c b/lib/libthr/thread/thr_once.c
index 065781907771..89b76ee58c1e 100644
--- a/lib/libthr/thread/thr_once.c
+++ b/lib/libthr/thread/thr_once.c
@@ -26,7 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include "un-namespace.h"
diff --git a/lib/libthr/thread/thr_printf.c b/lib/libthr/thread/thr_printf.c
index 5304cc00c5c8..e1edffe5acb2 100644
--- a/lib/libthr/thread/thr_printf.c
+++ b/lib/libthr/thread/thr_printf.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index 3475029f8996..d7b889930365 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -37,10 +37,10 @@
*/
#include <sys/types.h>
#include <sys/time.h>
-#include <sys/cdefs.h>
#include <sys/queue.h>
#include <sys/param.h>
#include <sys/cpuset.h>
+#include <sys/exterrvar.h>
#include <machine/atomic.h>
#include <errno.h>
#include <limits.h>
@@ -261,7 +261,6 @@ struct pthread_atfork {
};
struct pthread_attr {
-#define pthread_attr_start_copy sched_policy
int sched_policy;
int sched_inherit;
int prio;
@@ -271,7 +270,6 @@ struct pthread_attr {
void *stackaddr_attr;
size_t stacksize_attr;
size_t guardsize_attr;
-#define pthread_attr_end_copy cpuset
cpuset_t *cpuset;
size_t cpusetsize;
};
@@ -565,8 +563,12 @@ struct pthread {
/* Deferred threads from pthread_cond_signal. */
unsigned int *defer_waiters[MAX_DEFER_WAITERS];
-#define _pthread_endzero wake_addr
+ /* rtld thread-local dlerror message and seen control */
+ char dlerror_msg[512];
+ int dlerror_seen;
+
+#define _pthread_endzero wake_addr
struct wake_addr *wake_addr;
#define WAKE_ADDR(td) ((td)->wake_addr)
@@ -576,9 +578,7 @@ struct pthread {
/* pthread_set/get_name_np */
char *name;
- /* rtld thread-local dlerror message and seen control */
- char dlerror_msg[512];
- int dlerror_seen;
+ struct uexterror uexterr;
};
#define THR_SHOULD_GC(thrd) \
@@ -779,6 +779,8 @@ extern struct pthread *_single_thread __hidden;
extern bool _thr_after_fork __hidden;
+extern int __thr_new_flags;
+
/*
* Function prototype definitions.
*/
@@ -843,6 +845,8 @@ void _thr_signal_postfork(void) __hidden;
void _thr_signal_postfork_child(void) __hidden;
void _thr_suspend_all_lock(struct pthread *) __hidden;
void _thr_suspend_all_unlock(struct pthread *) __hidden;
+void _thr_suspend_all_np(void) __hidden;
+void _thr_resume_all_np(void) __hidden;
void _thr_try_gc(struct pthread *, struct pthread *) __hidden;
int _rtp_to_schedparam(const struct rtprio *rtp, int *policy,
struct sched_param *param) __hidden;
@@ -867,8 +871,8 @@ int _pthread_mutexattr_setrobust(pthread_mutexattr_t * _Nonnull, int);
/* #include <fcntl.h> */
#ifdef _SYS_FCNTL_H_
#ifndef _LIBC_PRIVATE_H_
-int __sys_fcntl(int, int, ...);
-int __sys_openat(int, const char *, int, ...);
+int __sys_fcntl(int, int, intptr_t);
+int __sys_openat(int, const char *, int, int);
#endif /* _LIBC_PRIVATE_H_ */
#endif /* _SYS_FCNTL_H_ */
@@ -982,8 +986,6 @@ void __pthread_cxa_finalize(struct dl_phdr_info *phdr_info);
void _thr_tsd_unload(struct dl_phdr_info *phdr_info) __hidden;
void _thr_sigact_unload(struct dl_phdr_info *phdr_info) __hidden;
void _thr_stack_fix_protection(struct pthread *thrd);
-void __pthread_distribute_static_tls(size_t offset, void *src, size_t len,
- size_t total_len);
int *__error_threaded(void) __hidden;
void __thr_interpose_libc(void) __hidden;
@@ -1015,6 +1017,7 @@ void __thr_pshared_destroy(void *key) __hidden;
void __thr_pshared_atfork_pre(void) __hidden;
void __thr_pshared_atfork_post(void) __hidden;
+void *__thr_aligned_alloc_offset(size_t align, size_t size, size_t offset);
void *__thr_calloc(size_t num, size_t size);
void __thr_free(void *cp);
void *__thr_malloc(size_t nbytes);
@@ -1105,6 +1108,8 @@ int __Tthr_mutex_lock(pthread_mutex_t *);
int __Tthr_mutex_trylock(pthread_mutex_t *);
bool __thr_get_main_stack_base(char **base);
bool __thr_get_main_stack_lim(size_t *lim);
+int _Tthr_sigqueue(pthread_t pthread, int sig, const union sigval value);
+void _thr_resolve_machdep(void);
__END_DECLS
__NULLABILITY_PRAGMA_POP
diff --git a/lib/libthr/thread/thr_pshared.c b/lib/libthr/thread/thr_pshared.c
index 42b1430907ad..d20d66e21ea3 100644
--- a/lib/libthr/thread/thr_pshared.c
+++ b/lib/libthr/thread/thr_pshared.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/queue.h>
diff --git a/lib/libthr/thread/thr_pspinlock.c b/lib/libthr/thread/thr_pspinlock.c
index 37f14d22909d..4820490ab6af 100644
--- a/lib/libthr/thread/thr_pspinlock.c
+++ b/lib/libthr/thread/thr_pspinlock.c
@@ -30,7 +30,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <stdlib.h>
diff --git a/lib/libthr/thread/thr_resume_np.c b/lib/libthr/thread/thr_resume_np.c
index 6dac28ab1f4b..c5669fd4f0ff 100644
--- a/lib/libthr/thread/thr_resume_np.c
+++ b/lib/libthr/thread/thr_resume_np.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -39,7 +38,8 @@
#include "thr_private.h"
__weak_reference(_pthread_resume_np, pthread_resume_np);
-__weak_reference(_pthread_resume_all_np, pthread_resume_all_np);
+__weak_reference(_thr_resume_all_np, pthread_resume_all_np);
+__weak_reference(_thr_resume_all_np, _pthread_resume_all_np);
static void resume_common(struct pthread *thread);
@@ -60,7 +60,7 @@ _pthread_resume_np(pthread_t thread)
}
void
-_pthread_resume_all_np(void)
+_thr_resume_all_np(void)
{
struct pthread *curthread = _get_curthread();
struct pthread *thread;
diff --git a/lib/libthr/thread/thr_rtld.c b/lib/libthr/thread/thr_rtld.c
index 9026abf941e2..3cfdfc548cf2 100644
--- a/lib/libthr/thread/thr_rtld.c
+++ b/lib/libthr/thread/thr_rtld.c
@@ -26,11 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
/*
* A lockless rwlock for rtld.
*/
-#include <sys/cdefs.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <link.h>
@@ -41,8 +39,7 @@
#include "rtld_lock.h"
#include "thr_private.h"
-#undef errno
-extern int errno;
+extern int __libsys_errno;
static int _thr_rtld_clr_flag(int);
static void *_thr_rtld_lock_create(void);
@@ -53,8 +50,11 @@ static int _thr_rtld_set_flag(int);
static void _thr_rtld_wlock_acquire(void *);
struct rtld_lock {
- struct urwlock lock;
- char _pad[CACHE_LINE_SIZE - sizeof(struct urwlock)];
+ struct urwlock lock;
+ struct pthread *wowner;
+ u_int rlocks;
+ char _pad[CACHE_LINE_SIZE - sizeof(struct urwlock) -
+ sizeof(struct pthread *) - sizeof(u_int)];
};
static struct rtld_lock lock_place[MAX_RTLD_LOCKS] __aligned(CACHE_LINE_SIZE);
@@ -98,14 +98,14 @@ _thr_rtld_lock_destroy(void *lock)
if (curthread != _thr_initial) \
errsave = curthread->error; \
else \
- errsave = errno; \
+ errsave = __libsys_errno; \
}
#define RESTORE_ERRNO() { \
if (curthread != _thr_initial) \
curthread->error = errsave; \
else \
- errno = errsave; \
+ __libsys_errno = errsave; \
}
static void
@@ -119,9 +119,13 @@ _thr_rtld_rlock_acquire(void *lock)
SAVE_ERRNO();
l = (struct rtld_lock *)lock;
- THR_CRITICAL_ENTER(curthread);
- while (_thr_rwlock_rdlock(&l->lock, 0, NULL) != 0)
- ;
+ if (l->wowner == curthread) {
+ l->rlocks++;
+ } else {
+ THR_CRITICAL_ENTER(curthread);
+ while (_thr_rwlock_rdlock(&l->lock, 0, NULL) != 0)
+ ;
+ }
curthread->rdlock_count++;
RESTORE_ERRNO();
}
@@ -140,6 +144,7 @@ _thr_rtld_wlock_acquire(void *lock)
THR_CRITICAL_ENTER(curthread);
while (_thr_rwlock_wrlock(&l->lock, NULL) != 0)
;
+ l->wowner = curthread;
RESTORE_ERRNO();
}
@@ -167,6 +172,14 @@ _thr_rtld_lock_release(void *lock)
l->lock.rw_blocked_readers = 0;
l->lock.rw_blocked_writers = 0;
}
+ if ((state & URWLOCK_WRITE_OWNER) != 0) {
+ if (l->rlocks > 0) {
+ l->rlocks--;
+ return;
+ } else {
+ l->wowner = NULL;
+ }
+ }
if (_thr_rwlock_unlock(&l->lock) == 0) {
if ((state & URWLOCK_WRITE_OWNER) == 0)
curthread->rdlock_count--;
@@ -222,22 +235,23 @@ _thr_rtld_init(void)
struct RtldLockInfo li;
struct pthread *curthread;
ucontext_t *uc;
- long dummy = -1;
int uc_len;
+ char dummy[2] = {};
curthread = _get_curthread();
/* force to resolve _umtx_op PLT */
- _umtx_op_err((struct umtx *)&dummy, UMTX_OP_WAKE, 1, 0, 0);
+ _umtx_op_err(&dummy, UMTX_OP_WAKE, 1, 0, 0);
/* force to resolve errno() PLT */
__error();
/* force to resolve memcpy PLT */
- memcpy(&dummy, &dummy, sizeof(dummy));
+ memcpy(&dummy[0], &dummy[1], 1);
mprotect(NULL, 0, 0);
_rtld_get_stack_prot();
+ thr_wake(-1);
li.rtli_version = RTLI_VERSION;
li.lock_create = _thr_rtld_lock_create;
@@ -277,6 +291,9 @@ _thr_rtld_init(void)
_thr_signal_block_check_fast();
_thr_signal_block_setup(curthread);
+ /* resolve machine depended functions, if any */
+ _thr_resolve_machdep();
+
uc_len = __getcontextx_size();
uc = alloca(uc_len);
getcontext(uc);
diff --git a/lib/libthr/thread/thr_rwlock.c b/lib/libthr/thread/thr_rwlock.c
index f8d5fa4f673f..084181ba922a 100644
--- a/lib/libthr/thread/thr_rwlock.c
+++ b/lib/libthr/thread/thr_rwlock.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
@@ -60,7 +59,7 @@ __weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock);
static int init_static(struct pthread *thread, pthread_rwlock_t *rwlock);
static int init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out);
-static int __always_inline
+static __always_inline int
check_and_init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out)
{
if (__predict_false(*rwlock == THR_PSHARED_PTR ||
diff --git a/lib/libthr/thread/thr_rwlockattr.c b/lib/libthr/thread/thr_rwlockattr.c
index 068ad7d3acbf..34bbbb20e611 100644
--- a/lib/libthr/thread/thr_rwlockattr.c
+++ b/lib/libthr/thread/thr_rwlockattr.c
@@ -26,7 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <stdlib.h>
diff --git a/lib/libthr/thread/thr_self.c b/lib/libthr/thread/thr_self.c
index f5b1ce8fdb98..cbdadb13ccc4 100644
--- a/lib/libthr/thread/thr_self.c
+++ b/lib/libthr/thread/thr_self.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include "un-namespace.h"
diff --git a/lib/libthr/thread/thr_sem.c b/lib/libthr/thread/thr_sem.c
index c7b5ac009a8c..76180604c183 100644
--- a/lib/libthr/thread/thr_sem.c
+++ b/lib/libthr/thread/thr_sem.c
@@ -30,7 +30,6 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/types.h>
#include <sys/queue.h>
diff --git a/lib/libthr/thread/thr_setprio.c b/lib/libthr/thread/thr_setprio.c
index 6ee60ffeb205..fddf664457bd 100644
--- a/lib/libthr/thread/thr_setprio.c
+++ b/lib/libthr/thread/thr_setprio.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include "un-namespace.h"
diff --git a/lib/libthr/thread/thr_setschedparam.c b/lib/libthr/thread/thr_setschedparam.c
index e3e4174c753b..49ec2ae7a7fd 100644
--- a/lib/libthr/thread/thr_setschedparam.c
+++ b/lib/libthr/thread/thr_setschedparam.c
@@ -32,7 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/param.h>
#include <errno.h>
diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c
index e082f0601be1..4bff5497a804 100644
--- a/lib/libthr/thread/thr_sig.c
+++ b/lib/libthr/thread/thr_sig.c
@@ -26,7 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/param.h>
#include <sys/auxv.h>
@@ -38,6 +37,7 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <pthread_np.h>
#include "un-namespace.h"
#include "libc_private.h"
@@ -164,6 +164,24 @@ _thr_signal_block_setup(struct pthread *curthread)
__sys_sigfastblock(SIGFASTBLOCK_SETPTR, &curthread->fsigblock);
}
+void
+pthread_signals_block_np(void)
+{
+ struct pthread *curthread;
+
+ curthread = _get_curthread();
+ _thr_signal_block(curthread);
+}
+
+void
+pthread_signals_unblock_np(void)
+{
+ struct pthread *curthread;
+
+ curthread = _get_curthread();
+ _thr_signal_unblock(curthread);
+}
+
int
_thr_send_sig(struct pthread *thread, int sig)
{
@@ -186,8 +204,7 @@ thr_remove_thr_signals(const sigset_t *set, sigset_t *newset)
}
static void
-sigcancel_handler(int sig __unused,
- siginfo_t *info __unused, ucontext_t *ucp)
+sigcancel_handler(int sig __unused, siginfo_t *info __unused, ucontext_t *ucp)
{
struct pthread *curthread = _get_curthread();
int err;
@@ -248,7 +265,6 @@ static void
handle_signal(struct sigaction *actp, int sig, siginfo_t *info, ucontext_t *ucp)
{
struct pthread *curthread = _get_curthread();
- ucontext_t uc2;
__siginfohandler_t *sigfunc;
int cancel_point;
int cancel_async;
@@ -308,13 +324,11 @@ handle_signal(struct sigaction *actp, int sig, siginfo_t *info, ucontext_t *ucp)
curthread->cancel_point = cancel_point;
curthread->cancel_enable = cancel_enable;
- memcpy(&uc2, ucp, sizeof(uc2));
- SIGDELSET(uc2.uc_sigmask, SIGCANCEL);
+ SIGDELSET(ucp->uc_sigmask, SIGCANCEL);
/* reschedule cancellation */
- check_cancel(curthread, &uc2);
+ check_cancel(curthread, ucp);
errno = err;
- syscall(SYS_sigreturn, &uc2);
}
void
@@ -358,9 +372,11 @@ check_cancel(struct pthread *curthread, ucontext_t *ucp)
* on getting a signal before it agrees to return.
*/
if (curthread->cancel_point) {
- if (curthread->in_sigsuspend && ucp) {
- SIGADDSET(ucp->uc_sigmask, SIGCANCEL);
- curthread->unblock_sigcancel = 1;
+ if (curthread->in_sigsuspend) {
+ if (ucp != NULL) {
+ SIGADDSET(ucp->uc_sigmask, SIGCANCEL);
+ curthread->unblock_sigcancel = 1;
+ }
_thr_send_sig(curthread, SIGCANCEL);
} else
thr_wake(curthread->tid);
@@ -369,8 +385,8 @@ check_cancel(struct pthread *curthread, ucontext_t *ucp)
* asynchronous cancellation mode, act upon
* immediately.
*/
- _pthread_exit_mask(PTHREAD_CANCELED,
- ucp? &ucp->uc_sigmask : NULL);
+ _pthread_exit_mask(PTHREAD_CANCELED, ucp != NULL ?
+ &ucp->uc_sigmask : NULL);
}
}
@@ -401,6 +417,7 @@ check_deferred_signal(struct pthread *curthread)
/* remove signal */
curthread->deferred_siginfo.si_signo = 0;
handle_signal(&act, info.si_signo, &info, uc);
+ syscall(SYS_sigreturn, uc);
}
static void
@@ -408,9 +425,8 @@ check_suspend(struct pthread *curthread)
{
uint32_t cycle;
- if (__predict_true((curthread->flags &
- (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED))
- != THR_FLAGS_NEED_SUSPEND))
+ if (__predict_true((curthread->flags & (THR_FLAGS_NEED_SUSPEND |
+ THR_FLAGS_SUSPENDED)) != THR_FLAGS_NEED_SUSPEND))
return;
if (curthread == _single_thread)
return;
@@ -667,15 +683,7 @@ _thr_sigmask(int how, const sigset_t *set, sigset_t *oset)
}
int
-_sigsuspend(const sigset_t * set)
-{
- sigset_t newset;
-
- return (__sys_sigsuspend(thr_remove_thr_signals(set, &newset)));
-}
-
-int
-__thr_sigsuspend(const sigset_t * set)
+__thr_sigsuspend(const sigset_t *set)
{
struct pthread *curthread;
sigset_t newset;
@@ -701,7 +709,7 @@ __thr_sigsuspend(const sigset_t * set)
int
_sigtimedwait(const sigset_t *set, siginfo_t *info,
- const struct timespec * timeout)
+ const struct timespec *timeout)
{
sigset_t newset;
@@ -716,7 +724,7 @@ _sigtimedwait(const sigset_t *set, siginfo_t *info,
*/
int
__thr_sigtimedwait(const sigset_t *set, siginfo_t *info,
- const struct timespec * timeout)
+ const struct timespec *timeout)
{
struct pthread *curthread = _get_curthread();
sigset_t newset;
diff --git a/lib/libthr/thread/thr_sigqueue.c b/lib/libthr/thread/thr_sigqueue.c
new file mode 100644
index 000000000000..6f7ad8c63bad
--- /dev/null
+++ b/lib/libthr/thread/thr_sigqueue.c
@@ -0,0 +1,79 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
+ * All rights reserved.
+ *
+ * Copyright 2024 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * <kib@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "namespace.h"
+#include <errno.h>
+#include <signal.h>
+#include <pthread.h>
+#include "un-namespace.h"
+
+#include "thr_private.h"
+
+__weak_reference(_Tthr_sigqueue, _pthread_sigqueue);
+__weak_reference(_Tthr_sigqueue, pthread_sigqueue);
+
+int
+_Tthr_sigqueue(pthread_t pthread, int sig, const union sigval value)
+{
+ struct pthread *curthread;
+ int e, ret;
+
+ if (sig < 0 || sig > _SIG_MAXSIG)
+ return (EINVAL);
+
+ curthread = _get_curthread();
+ ret = 0;
+
+ if (curthread == pthread) {
+ if (sig > 0) {
+ e = sigqueue(pthread->tid, sig | __SIGQUEUE_TID,
+ value);
+ if (e == -1)
+ ret = errno;
+ }
+ } else if ((ret = _thr_find_thread(curthread, pthread,
+ 0)) == 0) {
+ if (sig > 0) {
+ e = sigqueue(pthread->tid, sig | __SIGQUEUE_TID,
+ value);
+ if (e == -1)
+ ret = errno;
+ }
+ THR_THREAD_UNLOCK(curthread, pthread);
+ }
+
+ return (ret);
+}
diff --git a/lib/libthr/thread/thr_single_np.c b/lib/libthr/thread/thr_single_np.c
index e772fb5d3bb7..3aa7adba954d 100644
--- a/lib/libthr/thread/thr_single_np.c
+++ b/lib/libthr/thread/thr_single_np.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include <pthread_np.h>
diff --git a/lib/libthr/thread/thr_sleepq.c b/lib/libthr/thread/thr_sleepq.c
index b3feef8c9381..9c680acd0ac0 100644
--- a/lib/libthr/thread/thr_sleepq.c
+++ b/lib/libthr/thread/thr_sleepq.c
@@ -26,7 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <stdlib.h>
#include "thr_private.h"
@@ -63,7 +62,7 @@ _sleepq_alloc(void)
{
struct sleepqueue *sq;
- sq = calloc(1, sizeof(struct sleepqueue));
+ sq = __thr_calloc(1, sizeof(struct sleepqueue));
TAILQ_INIT(&sq->sq_blocked);
SLIST_INIT(&sq->sq_freeq);
return (sq);
@@ -72,7 +71,7 @@ _sleepq_alloc(void)
void
_sleepq_free(struct sleepqueue *sq)
{
- free(sq);
+ __thr_free(sq);
}
void
diff --git a/lib/libthr/thread/thr_spec.c b/lib/libthr/thread/thr_spec.c
index ee58bb37f6f7..44a124785085 100644
--- a/lib/libthr/thread/thr_spec.c
+++ b/lib/libthr/thread/thr_spec.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <sys/mman.h>
#include <signal.h>
diff --git a/lib/libthr/thread/thr_spinlock.c b/lib/libthr/thread/thr_spinlock.c
index 13744569b94f..bf3401c92780 100644
--- a/lib/libthr/thread/thr_spinlock.c
+++ b/lib/libthr/thread/thr_spinlock.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <pthread.h>
#include <libc_private.h>
diff --git a/lib/libthr/thread/thr_stack.c b/lib/libthr/thread/thr_stack.c
index 5e888bbfe9b6..d249bb5606fd 100644
--- a/lib/libthr/thread/thr_stack.c
+++ b/lib/libthr/thread/thr_stack.c
@@ -27,7 +27,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/auxv.h>
#include <sys/mman.h>
@@ -127,10 +126,7 @@ static char *last_stack = NULL;
static inline size_t
round_up(size_t size)
{
- if (size % _thr_page_size != 0)
- size = ((size / _thr_page_size) + 1) *
- _thr_page_size;
- return size;
+ return (roundup2(size, _thr_page_size));
}
void
diff --git a/lib/libthr/thread/thr_suspend_np.c b/lib/libthr/thread/thr_suspend_np.c
index b594ea562480..cf4e9e8a96b1 100644
--- a/lib/libthr/thread/thr_suspend_np.c
+++ b/lib/libthr/thread/thr_suspend_np.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -42,7 +41,8 @@ static int suspend_common(struct pthread *, struct pthread *,
int);
__weak_reference(_pthread_suspend_np, pthread_suspend_np);
-__weak_reference(_pthread_suspend_all_np, pthread_suspend_all_np);
+__weak_reference(_thr_suspend_all_np, pthread_suspend_all_np);
+__weak_reference(_thr_suspend_all_np, _pthread_suspend_all_np);
/* Suspend a thread: */
int
@@ -102,7 +102,7 @@ _thr_suspend_all_unlock(struct pthread *curthread)
}
void
-_pthread_suspend_all_np(void)
+_thr_suspend_all_np(void)
{
struct pthread *curthread = _get_curthread();
struct pthread *thread;
diff --git a/lib/libthr/thread/thr_switch_np.c b/lib/libthr/thread/thr_switch_np.c
index cbf959f161e3..59a9a4c7e1a3 100644
--- a/lib/libthr/thread/thr_switch_np.c
+++ b/lib/libthr/thread/thr_switch_np.c
@@ -32,7 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -41,10 +40,13 @@
#include "thr_private.h"
-
__weak_reference(_pthread_switch_add_np, pthread_switch_add_np);
__weak_reference(_pthread_switch_delete_np, pthread_switch_delete_np);
+typedef void (*pthread_switch_routine_t)(pthread_t, pthread_t);
+int _pthread_switch_add_np(pthread_switch_routine_t routine);
+int _pthread_switch_delete_np(pthread_switch_routine_t routine);
+
int
_pthread_switch_add_np(pthread_switch_routine_t routine __unused)
{
diff --git a/lib/libthr/thread/thr_symbols.c b/lib/libthr/thread/thr_symbols.c
index 7d5adcbbfb0b..f2de1f777558 100644
--- a/lib/libthr/thread/thr_symbols.c
+++ b/lib/libthr/thread/thr_symbols.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <stddef.h>
#include <pthread.h>
diff --git a/lib/libthr/thread/thr_syscalls.c b/lib/libthr/thread/thr_syscalls.c
index d68ca60e5993..188374a30070 100644
--- a/lib/libthr/thread/thr_syscalls.c
+++ b/lib/libthr/thread/thr_syscalls.c
@@ -65,11 +65,10 @@
*
*/
-#include <sys/cdefs.h>
#include "namespace.h"
-#include <sys/types.h>
-#include <sys/mman.h>
#include <sys/param.h>
+#include <sys/exterrvar.h>
+#include <sys/mman.h>
#include <sys/select.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
@@ -189,22 +188,19 @@ __thr_connect(int fd, const struct sockaddr *name, socklen_t namelen)
* if it is canceled.
*/
static int
-__thr_fcntl(int fd, int cmd, ...)
+__thr_fcntl(int fd, int cmd, __intptr_t arg)
{
struct pthread *curthread;
int ret;
- va_list ap;
curthread = _get_curthread();
- va_start(ap, cmd);
if (cmd == F_OSETLKW || cmd == F_SETLKW) {
_thr_cancel_enter(curthread);
- ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
+ ret = __sys_fcntl(fd, cmd, arg);
_thr_cancel_leave(curthread, ret == -1);
} else {
- ret = __sys_fcntl(fd, cmd, va_arg(ap, void *));
+ ret = __sys_fcntl(fd, cmd, arg);
}
- va_end(ap);
return (ret);
}
@@ -295,23 +291,11 @@ __thr_nanosleep(const struct timespec *time_to_sleep,
* If the thread is canceled, file is not opened.
*/
static int
-__thr_openat(int fd, const char *path, int flags, ...)
+__thr_openat(int fd, const char *path, int flags, int mode)
{
struct pthread *curthread;
- int mode, ret;
- va_list ap;
+ int ret;
-
- /* Check if the file is being created: */
- if ((flags & O_CREAT) != 0) {
- /* Get the creation mode: */
- va_start(ap, flags);
- mode = va_arg(ap, int);
- va_end(ap);
- } else {
- mode = 0;
- }
-
curthread = _get_curthread();
_thr_cancel_enter(curthread);
ret = __sys_openat(fd, path, flags, mode);
@@ -636,6 +620,15 @@ __thr_writev(int fd, const struct iovec *iov, int iovcnt)
return (ret);
}
+static int
+__thr_uexterr_gettext(char *buf, size_t bufsz)
+{
+ struct pthread *curthread;
+
+ curthread = _get_curthread();
+ return (__uexterr_format(&curthread->uexterr, buf, bufsz));
+}
+
void
__thr_interpose_libc(void)
{
@@ -644,6 +637,16 @@ __thr_interpose_libc(void)
#define SLOT(name) \
*(__libc_interposing_slot(INTERPOS_##name)) = \
(interpos_func_t)__thr_##name;
+ SLOT(system);
+ SLOT(tcdrain);
+ SLOT(spinlock);
+ SLOT(spinunlock);
+ SLOT(map_stacks_exec);
+#undef SLOT
+
+#define SLOT(name) \
+ *(__libc_interposing_slot(INTERPOS_##name)) = \
+ (interpos_func_t)__thr_##name;
SLOT(accept);
SLOT(accept4);
SLOT(aio_suspend);
@@ -672,20 +675,16 @@ __thr_interpose_libc(void)
SLOT(sigtimedwait);
SLOT(sigwaitinfo);
SLOT(swapcontext);
- SLOT(system);
- SLOT(tcdrain);
SLOT(wait4);
SLOT(write);
SLOT(writev);
- SLOT(spinlock);
- SLOT(spinunlock);
SLOT(kevent);
SLOT(wait6);
SLOT(ppoll);
- SLOT(map_stacks_exec);
SLOT(fdatasync);
SLOT(clock_nanosleep);
SLOT(pdfork);
+ SLOT(uexterr_gettext);
#undef SLOT
*(__libc_interposing_slot(
INTERPOS__pthread_mutex_init_calloc_cb)) =
diff --git a/lib/libthr/thread/thr_umtx.c b/lib/libthr/thread/thr_umtx.c
index 37b378e74405..bbc68d0e30c6 100644
--- a/lib/libthr/thread/thr_umtx.c
+++ b/lib/libthr/thread/thr_umtx.c
@@ -26,20 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "thr_private.h"
#include "thr_umtx.h"
-#ifndef HAS__UMTX_OP_ERR
-int _umtx_op_err(void *obj, int op, u_long val, void *uaddr, void *uaddr2)
-{
-
- if (_umtx_op(obj, op, val, uaddr, uaddr2) == -1)
- return (errno);
- return (0);
-}
-#endif
-
void
_thr_umutex_init(struct umutex *mtx)
{
diff --git a/lib/libthr/thread/thr_umtx.h b/lib/libthr/thread/thr_umtx.h
index a56997871ed1..89f70e4ab14f 100644
--- a/lib/libthr/thread/thr_umtx.h
+++ b/lib/libthr/thread/thr_umtx.h
@@ -39,7 +39,6 @@
#endif
#define DEFAULT_URWLOCK {0,0,0,0,{0,0,0,0}}
-int _umtx_op_err(void *, int op, u_long, void *, void *) __hidden;
int __thr_umutex_lock(struct umutex *mtx, uint32_t id) __hidden;
int __thr_umutex_lock_spin(struct umutex *mtx, uint32_t id) __hidden;
int __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
diff --git a/lib/libthr/thread/thr_yield.c b/lib/libthr/thread/thr_yield.c
index b391e69cabc1..057fc789de02 100644
--- a/lib/libthr/thread/thr_yield.c
+++ b/lib/libthr/thread/thr_yield.c
@@ -29,7 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include "namespace.h"
#include <pthread.h>
#include <sched.h>