aboutsummaryrefslogtreecommitdiff
path: root/lib/libthr
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/Makefile34
-rw-r--r--lib/libthr/Makefile.depend1
-rw-r--r--lib/libthr/arch/aarch64/Makefile.inc1
-rw-r--r--lib/libthr/arch/aarch64/include/pthread_md.h7
-rw-r--r--lib/libthr/arch/aarch64/include/pthread_tls.h44
-rw-r--r--lib/libthr/arch/amd64/Makefile.inc5
-rw-r--r--lib/libthr/arch/amd64/amd64/_umtx_op_err.S40
-rw-r--r--lib/libthr/arch/amd64/amd64/thr_machdep.c48
-rw-r--r--lib/libthr/arch/amd64/include/pthread_md.h11
-rw-r--r--lib/libthr/arch/amd64/include/pthread_tls.h44
-rw-r--r--lib/libthr/arch/arm/Makefile.inc3
-rw-r--r--lib/libthr/arch/arm/include/pthread_md.h2
-rw-r--r--lib/libthr/arch/arm/include/pthread_tls.h44
-rw-r--r--lib/libthr/arch/arm/thr_rtld_arm.c67
-rw-r--r--lib/libthr/arch/i386/Makefile.inc3
-rw-r--r--lib/libthr/arch/i386/i386/_umtx_op_err.S39
-rw-r--r--lib/libthr/arch/i386/include/pthread_md.h11
-rw-r--r--lib/libthr/arch/i386/include/pthread_tls.h44
-rw-r--r--lib/libthr/arch/powerpc/Makefile.inc2
-rw-r--r--lib/libthr/arch/powerpc/include/pthread_md.h7
-rw-r--r--lib/libthr/arch/powerpc/include/pthread_tls.h44
-rw-r--r--lib/libthr/arch/powerpc/powerpc/_umtx_op_err.S39
-rw-r--r--lib/libthr/arch/riscv/include/pthread_md.h7
-rw-r--r--lib/libthr/arch/riscv/include/pthread_tls.h44
-rw-r--r--lib/libthr/libthr.38
-rw-r--r--lib/libthr/plockstat.d1
-rw-r--r--lib/libthr/pthread.map10
-rw-r--r--lib/libthr/sys/Makefile.inc1
-rw-r--r--lib/libthr/sys/thr_error.c5
-rw-r--r--lib/libthr/tests/Makefile3
-rw-r--r--lib/libthr/tests/atfork_test.c280
-rw-r--r--lib/libthr/tests/dlopen/Makefile1
-rw-r--r--lib/libthr/tests/dlopen/dso/Makefile2
-rw-r--r--lib/libthr/tests/pthread_sigqueue_test.c120
-rw-r--r--lib/libthr/tests/umtx_op_test.c3
-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
95 files changed, 1089 insertions, 937 deletions
diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile
index dde2a9dce94e..c87be9475390 100644
--- a/lib/libthr/Makefile
+++ b/lib/libthr/Makefile
@@ -1,17 +1,22 @@
-#
-# All library objects contain FreeBSD revision strings by default; they may be
-# excluded as a space-saving measure. To produce a library that does
-# not contain these strings, add -DSTRIP_FBSDID (see <sys/cdefs.h>) to CFLAGS
-# below.
-
PACKAGE= clibs
SHLIBDIR?= /lib
+LIBADD= c sys
+.if defined(COMPAT_libcompat)
+# XXX: work around gcc -m32 + bfd ld path issue for DT_NEEDED symbols.
+# https://sourceware.org/bugzilla/show_bug.cgi?id=31395
+LDFLAGS+= -Wl,--rpath=/usr/lib${COMPAT_libcompat}
+.endif
+
.include <src.opts.mk>
MK_SSP= no
+# SSP forced off already implies FORTIFY_SOURCE=0, but we must make sure that
+# one cannot turn it back on.
+FORTIFY_SOURCE= 0
LIB=thr
SHLIB_MAJOR= 3
+
NO_WTHREAD_SAFETY=1
NO_WCAST_ALIGN.gcc=1 # for gcc 4.2
CFLAGS+=-DPTHREAD_KERNEL
@@ -26,6 +31,10 @@ CFLAGS+=-I${SRCTOP}/lib/libthread_db
CFLAGS.thr_stack.c+= -Wno-cast-align
CFLAGS.rtld_malloc.c+= -Wno-cast-align
+# Disable compiler builtins so that the compiler does not optimize away rtld's
+# attempts to force early PLT resolution for certain functions that may be
+# replaced by builtins.
+CFLAGS.thr_rtld.c+= -fno-builtin
CFLAGS.thr_symbols.c+= -Wno-missing-variable-declarations
.if ${MK_ASAN} != "no"
# False-positive ASAN error claiming the local "struct sigaction act;" is
@@ -44,6 +53,8 @@ CFLAGS+=-D_PTHREAD_FORCED_UNWIND
.endif
LDFLAGS+=-Wl,-znodelete
+LDFLAGS+=-Wl,-zinitfirst
+LDFLAGS+=-Wl,--auxiliary,libsys.so.7
VERSION_DEF=${SRCTOP}/lib/libc/Versions.def
SYMBOL_MAPS=${.CURDIR}/pthread.map
@@ -67,15 +78,20 @@ PRECIOUSLIB=
.include "${.CURDIR}/thread/Makefile.inc"
SRCS+= rtld_malloc.c
+LIBSYS_SRCTOP= ${.CURDIR:H}/libsys
+.if exists(${LIBSYS_SRCTOP}/${MACHINE_CPUARCH}/_umtx_op_err.S)
+.PATH: ${LIBSYS_SRCTOP}/${MACHINE_CPUARCH}
+.else
+.PATH: ${LIBSYS_SRCTOP}
+.endif
+OBJS+= _umtx_op_err.o
+
.if ${MK_INSTALLLIB} != "no"
SYMLINKS+=lib${LIB}.a ${LIBDIR}/libpthread.a
.endif
.if !defined(NO_PIC)
SYMLINKS+=lib${LIB}.so ${LIBDIR}/libpthread.so
.endif
-.if ${MK_PROFILE} != "no"
-SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a
-.endif
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
diff --git a/lib/libthr/Makefile.depend b/lib/libthr/Makefile.depend
index 6ef78fac5cbf..e0d18fcef3a4 100644
--- a/lib/libthr/Makefile.depend
+++ b/lib/libthr/Makefile.depend
@@ -6,6 +6,7 @@ DIRDEPS = \
lib/${CSU_DIR} \
lib/libc \
lib/libcompiler_rt \
+ lib/libsys \
.include <dirdeps.mk>
diff --git a/lib/libthr/arch/aarch64/Makefile.inc b/lib/libthr/arch/aarch64/Makefile.inc
index 8b137891791f..e69de29bb2d1 100644
--- a/lib/libthr/arch/aarch64/Makefile.inc
+++ b/lib/libthr/arch/aarch64/Makefile.inc
@@ -1 +0,0 @@
-
diff --git a/lib/libthr/arch/aarch64/include/pthread_md.h b/lib/libthr/arch/aarch64/include/pthread_md.h
index 75e6abf445ba..4316955f1d3d 100644
--- a/lib/libthr/arch/aarch64/include/pthread_md.h
+++ b/lib/libthr/arch/aarch64/include/pthread_md.h
@@ -49,4 +49,11 @@ _get_curthread(void)
return (_tcb_get()->tcb_thread);
}
+static __inline void
+_thr_resolve_machdep(void)
+{
+}
+
+#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb)
+
#endif /* _PTHREAD_MD_H_ */
diff --git a/lib/libthr/arch/aarch64/include/pthread_tls.h b/lib/libthr/arch/aarch64/include/pthread_tls.h
deleted file mode 100644
index 4e02f8d4e03f..000000000000
--- a/lib/libthr/arch/aarch64/include/pthread_tls.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 The FreeBSD Foundation
- *
- * This software was 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
- */
-
-#ifndef _ARCH_AARCH64_PTHREAD_TLS_H
-#define _ARCH_AARCH64_PTHREAD_TLS_H
-
-static __inline uintptr_t
-_get_static_tls_base(struct pthread *thr, size_t offset)
-{
- uintptr_t tlsbase;
-
- tlsbase = (uintptr_t)thr->tcb;
- tlsbase += offset;
- return (tlsbase);
-}
-
-#endif
diff --git a/lib/libthr/arch/amd64/Makefile.inc b/lib/libthr/arch/amd64/Makefile.inc
index 24e5dd7c9b03..fe80e1a73cc9 100644
--- a/lib/libthr/arch/amd64/Makefile.inc
+++ b/lib/libthr/arch/amd64/Makefile.inc
@@ -1,8 +1,7 @@
-
-SRCS+= _umtx_op_err.S
-
# With the current compiler and libthr code, using SSE in libthr
# does not provide enough performance improvement to outweigh
# the extra context switch cost. This can measurably impact
# performance when the application also does not use enough SSE.
CFLAGS+=${CFLAGS_NO_SIMD}
+
+SRCS+= thr_machdep.c
diff --git a/lib/libthr/arch/amd64/amd64/_umtx_op_err.S b/lib/libthr/arch/amd64/amd64/_umtx_op_err.S
deleted file mode 100644
index c5fb2f26d6f6..000000000000
--- a/lib/libthr/arch/amd64/amd64/_umtx_op_err.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * Copyright (C) 2008 David Xu <davidxu@freebsd.org>
- * All rights reserved.
- *
- * 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. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 <sys/syscall.h>
-#include <machine/asm.h>
-
-#define RSYSCALL_ERR(x) ENTRY(__CONCAT(x, _err)); \
- mov __CONCAT($SYS_,x),%rax; \
- KERNCALL; \
- ret; \
- END(__CONCAT(x, _err));
-
-#define KERNCALL movq %rcx, %r10; syscall
-
-RSYSCALL_ERR(_umtx_op)
-
- .section .note.GNU-stack,"",%progbits
diff --git a/lib/libthr/arch/amd64/amd64/thr_machdep.c b/lib/libthr/arch/amd64/amd64/thr_machdep.c
new file mode 100644
index 000000000000..d23e1689779c
--- /dev/null
+++ b/lib/libthr/arch/amd64/amd64/thr_machdep.c
@@ -0,0 +1,48 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ */
+
+#define _WANT_P_OSREL
+#include <sys/param.h>
+#include <errno.h>
+#include <machine/sysarch.h>
+
+#include "libc_private.h"
+#include "thr_private.h"
+
+void
+__thr_setup_tsd(struct pthread *thread)
+{
+ void *base;
+ int error;
+
+ if (__getosreldate() < P_OSREL_TLSBASE) {
+ amd64_set_tlsbase(thread->tcb);
+ return;
+ }
+
+ /*
+ * Make tlsbase handling more compatible with code, like Go
+ * runtime, which wants to manage fsbase itself, and which do
+ * not need assistance in setting fsbase for signal handlers.
+ *
+ * If the main thread did not used amd64_set_tlsbase(), which
+ * means that rtld/libc was not utilized, do not use
+ * amd64_set_tlsbase() either. Also do not mark new threads
+ * as using C runtime with the THR_C_RUNTIME flag.
+ */
+ error = sysarch(AMD64_GET_TLSBASE, &base);
+ if (error != 0 && errno == ESRCH) {
+ __thr_new_flags &= ~THR_C_RUNTIME;
+ amd64_set_fsbase(thread->tcb);
+ } else {
+ amd64_set_tlsbase(thread->tcb);
+ }
+}
diff --git a/lib/libthr/arch/amd64/include/pthread_md.h b/lib/libthr/arch/amd64/include/pthread_md.h
index fa0802e64ebb..02b73d90f006 100644
--- a/lib/libthr/arch/amd64/include/pthread_md.h
+++ b/lib/libthr/arch/amd64/include/pthread_md.h
@@ -47,11 +47,16 @@ _get_curthread(void)
{
struct pthread *thr;
- __asm __volatile("movq %%fs:%1, %0" : "=r" (thr)
- : "m" (*(volatile u_long *)offsetof(struct tcb, tcb_thread)));
+ __asm __volatile("movq %%fs:%c1, %0" : "=r" (thr)
+ : "i" (offsetof(struct tcb, tcb_thread)));
return (thr);
}
-#define HAS__UMTX_OP_ERR 1
+static __inline void
+_thr_resolve_machdep(void)
+{
+}
+
+void __thr_setup_tsd(struct pthread *thread);
#endif
diff --git a/lib/libthr/arch/amd64/include/pthread_tls.h b/lib/libthr/arch/amd64/include/pthread_tls.h
deleted file mode 100644
index 2af0aeda4c85..000000000000
--- a/lib/libthr/arch/amd64/include/pthread_tls.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 The FreeBSD Foundation
- *
- * This software was 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
- */
-
-#ifndef _ARCH_AMD64_PTHREAD_TLS_H
-#define _ARCH_AMD64_PTHREAD_TLS_H
-
-static __inline uintptr_t
-_get_static_tls_base(struct pthread *thr, size_t offset)
-{
- uintptr_t tlsbase;
-
- tlsbase = (uintptr_t)thr->tcb;
- tlsbase -= offset;
- return (tlsbase);
-}
-
-#endif
diff --git a/lib/libthr/arch/arm/Makefile.inc b/lib/libthr/arch/arm/Makefile.inc
new file mode 100644
index 000000000000..4e770cf6b90f
--- /dev/null
+++ b/lib/libthr/arch/arm/Makefile.inc
@@ -0,0 +1,3 @@
+.PATH: ${.CURDIR}/arch/arm
+SRCS+= \
+ thr_rtld_arm.c
diff --git a/lib/libthr/arch/arm/include/pthread_md.h b/lib/libthr/arch/arm/include/pthread_md.h
index d616868bdee4..b90568e249ee 100644
--- a/lib/libthr/arch/arm/include/pthread_md.h
+++ b/lib/libthr/arch/arm/include/pthread_md.h
@@ -48,4 +48,6 @@ _get_curthread(void)
return (NULL);
}
+#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb)
+
#endif /* _PTHREAD_MD_H_ */
diff --git a/lib/libthr/arch/arm/include/pthread_tls.h b/lib/libthr/arch/arm/include/pthread_tls.h
deleted file mode 100644
index 27a07f69f474..000000000000
--- a/lib/libthr/arch/arm/include/pthread_tls.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 The FreeBSD Foundation
- *
- * This software was 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
- */
-
-#ifndef _ARCH_ARM_PTHREAD_TLS_H
-#define _ARCH_ARM_PTHREAD_TLS_H
-
-static __inline uintptr_t
-_get_static_tls_base(struct pthread *thr, size_t offset)
-{
- uintptr_t tlsbase;
-
- tlsbase = (uintptr_t)thr->tcb;
- tlsbase += offset;
- return (tlsbase);
-}
-
-#endif
diff --git a/lib/libthr/arch/arm/thr_rtld_arm.c b/lib/libthr/arch/arm/thr_rtld_arm.c
new file mode 100644
index 000000000000..35f5fe56cfff
--- /dev/null
+++ b/lib/libthr/arch/arm/thr_rtld_arm.c
@@ -0,0 +1,67 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024, Michal Meloun <mmel@freebsd.org>
+ *
+ * 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 unmodified, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 <stdlib.h>
+#include <string.h>
+
+#include "thr_private.h"
+
+int __aeabi_idiv(int , int );
+unsigned __aeabi_uidiv(unsigned, unsigned );
+
+struct {int q; int r;} __aeabi_idivmod(int, int );
+struct {unsigned q; unsigned r;} __aeabi_uidivmod(unsigned, unsigned);
+
+struct {int64_t q; int64_t r;} __aeabi_ldivmod(int64_t, int64_t);
+struct {uint64_t q; uint64_t r;} __aeabi_uldivmod(uint64_t, uint64_t);
+
+void __aeabi_memset(void *dest, size_t n, int c);
+void __aeabi_memclr(void *dest, size_t n);
+void __aeabi_memmove(void *dest, void *src, size_t n);
+void __aeabi_memcpy(void *dest, void *src, size_t n);
+void __aeabi_memcmp(void *dest, void *src, size_t n);
+
+void
+_thr_resolve_machdep(void)
+{
+ char tmp[2];
+
+ __aeabi_idiv(1, 1);
+ __aeabi_uidiv(1, 1);
+
+ __aeabi_idivmod(1, 1);
+ __aeabi_uidivmod(1, 1);
+
+ __aeabi_ldivmod(1, 1);
+ __aeabi_uldivmod(1, 1);
+
+ __aeabi_memset(tmp, 1, 0);
+ __aeabi_memclr(tmp, 1);
+ __aeabi_memmove(tmp, tmp + 1, 1);
+ __aeabi_memcpy(tmp, tmp + 1, 1);
+ __aeabi_memcmp(tmp, tmp + 1, 1);
+}
diff --git a/lib/libthr/arch/i386/Makefile.inc b/lib/libthr/arch/i386/Makefile.inc
index 24e5dd7c9b03..f8013ea914ed 100644
--- a/lib/libthr/arch/i386/Makefile.inc
+++ b/lib/libthr/arch/i386/Makefile.inc
@@ -1,6 +1,3 @@
-
-SRCS+= _umtx_op_err.S
-
# With the current compiler and libthr code, using SSE in libthr
# does not provide enough performance improvement to outweigh
# the extra context switch cost. This can measurably impact
diff --git a/lib/libthr/arch/i386/i386/_umtx_op_err.S b/lib/libthr/arch/i386/i386/_umtx_op_err.S
deleted file mode 100644
index 460bd72604aa..000000000000
--- a/lib/libthr/arch/i386/i386/_umtx_op_err.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * Copyright (C) 2008 David Xu <davidxu@freebsd.org>
- * All rights reserved.
- *
- * 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. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 <machine/asm.h>
-#include <sys/syscall.h>
-
-#define SYSCALL_ERR(x) \
- ENTRY(__CONCAT(x, _err)); \
- mov __CONCAT($SYS_,x),%eax; \
- int $0x80; \
- ret; \
- END(__CONCAT(x, _err))
-
-SYSCALL_ERR(_umtx_op)
-
- .section .note.GNU-stack,"",%progbits
diff --git a/lib/libthr/arch/i386/include/pthread_md.h b/lib/libthr/arch/i386/include/pthread_md.h
index 2a396abe3824..43f84c3d0393 100644
--- a/lib/libthr/arch/i386/include/pthread_md.h
+++ b/lib/libthr/arch/i386/include/pthread_md.h
@@ -47,11 +47,16 @@ _get_curthread(void)
{
struct pthread *thr;
- __asm __volatile("movl %%gs:%1, %0" : "=r" (thr)
- : "m" (*(volatile u_int *)offsetof(struct tcb, tcb_thread)));
+ __asm __volatile("movl %%gs:%c1, %0" : "=r" (thr)
+ : "i" (offsetof(struct tcb, tcb_thread)));
return (thr);
}
-#define HAS__UMTX_OP_ERR 1
+static __inline void
+_thr_resolve_machdep(void)
+{
+}
+
+#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb)
#endif
diff --git a/lib/libthr/arch/i386/include/pthread_tls.h b/lib/libthr/arch/i386/include/pthread_tls.h
deleted file mode 100644
index b2d0f2dbe845..000000000000
--- a/lib/libthr/arch/i386/include/pthread_tls.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 The FreeBSD Foundation
- *
- * This software was 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
- */
-
-#ifndef _ARCH_I386_PTHREAD_TLS_H
-#define _ARCH_I386_PTHREAD_TLS_H
-
-static __inline uintptr_t
-_get_static_tls_base(struct pthread *thr, size_t offset)
-{
- uintptr_t tlsbase;
-
- tlsbase = (uintptr_t)thr->tcb;
- tlsbase -= offset;
- return (tlsbase);
-}
-
-#endif
diff --git a/lib/libthr/arch/powerpc/Makefile.inc b/lib/libthr/arch/powerpc/Makefile.inc
deleted file mode 100644
index 663706b1b364..000000000000
--- a/lib/libthr/arch/powerpc/Makefile.inc
+++ /dev/null
@@ -1,2 +0,0 @@
-
-SRCS+= _umtx_op_err.S
diff --git a/lib/libthr/arch/powerpc/include/pthread_md.h b/lib/libthr/arch/powerpc/include/pthread_md.h
index 14f1703b5460..291f2d9350d9 100644
--- a/lib/libthr/arch/powerpc/include/pthread_md.h
+++ b/lib/libthr/arch/powerpc/include/pthread_md.h
@@ -49,6 +49,11 @@ _get_curthread(void)
return (NULL);
}
-#define HAS__UMTX_OP_ERR 1
+static __inline void
+_thr_resolve_machdep(void)
+{
+}
+
+#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb)
#endif /* _PTHREAD_MD_H_ */
diff --git a/lib/libthr/arch/powerpc/include/pthread_tls.h b/lib/libthr/arch/powerpc/include/pthread_tls.h
deleted file mode 100644
index e53164436018..000000000000
--- a/lib/libthr/arch/powerpc/include/pthread_tls.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 The FreeBSD Foundation
- *
- * This software was 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
- */
-
-#ifndef _ARCH_POWERPC_PTHREAD_TLS_H
-#define _ARCH_POWERPC_PTHREAD_TLS_H
-
-static __inline uintptr_t
-_get_static_tls_base(struct pthread *thr, size_t offset)
-{
- uintptr_t tlsbase;
-
- tlsbase = (uintptr_t)thr->tcb;
- tlsbase += offset;
- return (tlsbase);
-}
-
-#endif
diff --git a/lib/libthr/arch/powerpc/powerpc/_umtx_op_err.S b/lib/libthr/arch/powerpc/powerpc/_umtx_op_err.S
deleted file mode 100644
index a954962515f6..000000000000
--- a/lib/libthr/arch/powerpc/powerpc/_umtx_op_err.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 Brandon Bergren <bdragon@FreeBSD.org>
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 <machine/asm.h>
-#include <sys/syscall.h>
-
- .text
- .align 2
-ENTRY(_umtx_op_err)
- li %r0, SYS__umtx_op
- sc
- blr
-END(_umtx_op_err)
-
- .section .note.GNU-stack,"",%progbits
diff --git a/lib/libthr/arch/riscv/include/pthread_md.h b/lib/libthr/arch/riscv/include/pthread_md.h
index 343f4cae8486..01dcc9c02b8c 100644
--- a/lib/libthr/arch/riscv/include/pthread_md.h
+++ b/lib/libthr/arch/riscv/include/pthread_md.h
@@ -56,4 +56,11 @@ _get_curthread(void)
return (NULL);
}
+static __inline void
+_thr_resolve_machdep(void)
+{
+}
+
+#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb)
+
#endif /* _PTHREAD_MD_H_ */
diff --git a/lib/libthr/arch/riscv/include/pthread_tls.h b/lib/libthr/arch/riscv/include/pthread_tls.h
deleted file mode 100644
index 0af1ddd4cfaf..000000000000
--- a/lib/libthr/arch/riscv/include/pthread_tls.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause
- *
- * Copyright (c) 2019 The FreeBSD Foundation
- *
- * This software was 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
- */
-
-#ifndef _ARCH_RISCV_PTHREAD_TLS_H
-#define _ARCH_RISCV_PTHREAD_TLS_H
-
-static __inline uintptr_t
-_get_static_tls_base(struct pthread *thr, size_t offset)
-{
- uintptr_t tlsbase;
-
- tlsbase = (uintptr_t)thr->tcb;
- tlsbase += offset;
- return (tlsbase);
-}
-
-#endif
diff --git a/lib/libthr/libthr.3 b/lib/libthr/libthr.3
index 7d0c7669654a..b84176abcd32 100644
--- a/lib/libthr/libthr.3
+++ b/lib/libthr/libthr.3
@@ -1,5 +1,5 @@
.\" Copyright (c) 2005 Robert N. M. Watson
-.\" Copyright (c) 2014,2015,2021 The FreeBSD Foundation, Inc.
+.\" Copyright (c) 2014,2015,2021 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" Part of this documentation was written by
@@ -217,7 +217,7 @@ recycle it at any moment, making this sysctl less useful than it sounds.
.It Dv kern.ipc.umtx_max_robust
The maximal number of robust mutexes allowed for one thread.
The kernel will not unlock more mutexes than specified, see
-.Xr _umtx_op
+.Xr _umtx_op 2
for more details.
The default value is large enough for most useful applications.
.It Dv debug.umtx.robust_faults_verbose
@@ -325,15 +325,15 @@ anyway.
.Sh SEE ALSO
.Xr ktrace 1 ,
.Xr ld-elf.so.1 1 ,
-.Xr getrlimit 2 ,
+.Xr _umtx_op 2 ,
.Xr errno 2 ,
+.Xr getrlimit 2 ,
.Xr thr_exit 2 ,
.Xr thr_kill 2 ,
.Xr thr_kill2 2 ,
.Xr thr_new 2 ,
.Xr thr_self 2 ,
.Xr thr_set_name 2 ,
-.Xr _umtx_op 2 ,
.Xr dlclose 3 ,
.Xr dlopen 3 ,
.Xr getenv 3 ,
diff --git a/lib/libthr/plockstat.d b/lib/libthr/plockstat.d
index de620d893651..39d8946f33d3 100644
--- a/lib/libthr/plockstat.d
+++ b/lib/libthr/plockstat.d
@@ -1,6 +1,5 @@
/*
* Copyright (c) 2010 The FreeBSD Foundation
- * All rights reserved.
*
* This software was developed by Rui Paulo under sponsorship from the
* FreeBSD Foundation.
diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map
index 348fd48df398..3a5353a32dc3 100644
--- a/lib/libthr/pthread.map
+++ b/lib/libthr/pthread.map
@@ -136,7 +136,6 @@ FBSDprivate_1.0 {
__pthread_mutex_lock;
__pthread_mutex_timedlock;
__pthread_mutex_trylock;
- __pthread_distribute_static_tls;
_pthread_atfork;
_pthread_barrier_destroy;
_pthread_barrier_init;
@@ -298,6 +297,9 @@ FBSDprivate_1.0 {
/* ABI bug workaround, indicate that pli->rtli_version is valid */
_pli_rtli_version;
+
+ /* Expose stub for libsys filter */
+ _umtx_op_err;
};
FBSD_1.1 {
@@ -334,3 +336,9 @@ FBSD_1.6 {
pthread_peekjoin_np;
pthread_setname_np;
};
+
+FBSD_1.8 {
+ pthread_signals_block_np;
+ pthread_signals_unblock_np;
+ pthread_sigqueue;
+};
diff --git a/lib/libthr/sys/Makefile.inc b/lib/libthr/sys/Makefile.inc
index 7043b2e7c62d..98d7b2ac7bd3 100644
--- a/lib/libthr/sys/Makefile.inc
+++ b/lib/libthr/sys/Makefile.inc
@@ -1,4 +1,3 @@
-
.PATH: ${.CURDIR}/sys
SRCS+= thr_error.c
diff --git a/lib/libthr/sys/thr_error.c b/lib/libthr/sys/thr_error.c
index 7ce3a84fab6b..ec7a57bf6610 100644
--- a/lib/libthr/sys/thr_error.c
+++ b/lib/libthr/sys/thr_error.c
@@ -39,8 +39,7 @@
#include "libc_private.h"
#include "thr_private.h"
-#undef errno
-extern int errno;
+extern int __libsys_errno;
__weak_reference(__error_threaded, __error);
int *
@@ -53,5 +52,5 @@ __error_threaded(void)
if (curthread != NULL && curthread != _thr_initial)
return (&curthread->error);
}
- return (&errno);
+ return (&__libsys_errno);
}
diff --git a/lib/libthr/tests/Makefile b/lib/libthr/tests/Makefile
index 8b7850b94265..017b740157dc 100644
--- a/lib/libthr/tests/Makefile
+++ b/lib/libthr/tests/Makefile
@@ -1,4 +1,3 @@
-
PACKAGE= tests
WARNS?= 3
@@ -34,7 +33,9 @@ NETBSD_ATF_TESTS_SH+= cancel_test
NETBSD_ATF_TESTS_SH+= exit_test
NETBSD_ATF_TESTS_SH+= resolv_test
+ATF_TESTS_C+= atfork_test
ATF_TESTS_C+= umtx_op_test
+ATF_TESTS_C+= pthread_sigqueue_test
LIBADD+= pthread
LIBADD.fpu_test+= m
diff --git a/lib/libthr/tests/atfork_test.c b/lib/libthr/tests/atfork_test.c
new file mode 100644
index 000000000000..cb0fcb7e62db
--- /dev/null
+++ b/lib/libthr/tests/atfork_test.c
@@ -0,0 +1,280 @@
+/*-
+ *
+ * Copyright (C) 2024 Kyle Evans <kevans@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ */
+
+#include <sys/wait.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#define EXIT_NOPREPARE 1
+#define EXIT_CALLEDPARENT 2
+#define EXIT_NOCHILD 3
+#define EXIT_BADORDER 4
+
+static int child;
+static int forked;
+static int parent;
+
+/*
+ * We'll disable prefork unless we're specifically running the preinit test to
+ * be sure that we don't mess up any other tests' results.
+ */
+static bool prefork_enabled;
+
+static void
+prefork(void)
+{
+ if (prefork_enabled)
+ forked++;
+}
+
+static void
+registrar(void)
+{
+ pthread_atfork(prefork, NULL, NULL);
+}
+
+static __attribute__((section(".preinit_array"), used))
+void (*preinitfn)(void) = &registrar;
+
+/*
+ * preinit_atfork() just enables the prepare handler that we registered in a
+ * .preinit_array entry and checks that forking actually invoked that callback.
+ * We don't bother testing all three callbacks here because the implementation
+ * doesn't really lend itself to the kind of error where we only have a partial
+ * set of callbacks registered.
+ */
+ATF_TC(preinit_atfork);
+ATF_TC_HEAD(preinit_atfork, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that atfork callbacks may be registered in .preinit_array functions");
+}
+ATF_TC_BODY(preinit_atfork, tc)
+{
+ pid_t p;
+
+ (void)signal(SIGCHLD, SIG_IGN);
+ prefork_enabled = true;
+ p = fork();
+
+ ATF_REQUIRE(p >= 0);
+ if (p == 0)
+ _exit(0);
+
+ prefork_enabled = false;
+
+ ATF_REQUIRE(forked != 0);
+}
+
+static void
+basic_prepare(void)
+{
+ ATF_REQUIRE(parent == 0);
+ forked++;
+}
+
+static void
+basic_parent(void)
+{
+ ATF_REQUIRE(forked != 0);
+ parent++;
+}
+
+static void
+basic_child(void)
+{
+ if (!forked)
+ _exit(EXIT_NOPREPARE);
+ if (parent != 0)
+ _exit(EXIT_CALLEDPARENT);
+ child++;
+}
+
+/*
+ * In the basic test, we'll register just once and set some globals to confirm
+ * that the prepare/parent callbacks were executed as expected. The child will
+ * use its exit status to communicate to us if the callback was not executed
+ * properly since we cannot assert there. This is a subset of the
+ * multi-callback test, but separated out so that it's more obvious from running
+ * the atfork_test if pthread_atfork() is completely broken or just
+ * out-of-order.
+ */
+ATF_TC(basic_atfork);
+ATF_TC_HEAD(basic_atfork, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks invocation of all three atfork callbacks");
+}
+ATF_TC_BODY(basic_atfork, tc)
+{
+ pid_t p, wpid;
+ int status;
+
+ pthread_atfork(basic_prepare, basic_parent, basic_child);
+
+ p = fork();
+
+ ATF_REQUIRE(p >= 0);
+ if (p == 0)
+ _exit(child != 0 ? 0 : EXIT_NOCHILD);
+
+ /*
+ * The child can't use any of our standard atf-c(3) macros, so we have
+ * to rely on the exit status to convey any shenanigans.
+ */
+ while ((wpid = waitpid(p, &status, 0)) != p) {
+ ATF_REQUIRE_ERRNO(EINTR, wpid == -1);
+ if (wpid == -1)
+ continue;
+ }
+
+ ATF_REQUIRE_MSG(WIFEXITED(status),
+ "child did not exit cleanly, status %x", status);
+
+ status = WEXITSTATUS(status);
+ ATF_REQUIRE_MSG(status == 0, "atfork in child %s",
+ status == EXIT_NOPREPARE ? "did not see `prepare` execute" :
+ (status == EXIT_CALLEDPARENT ? "observed `parent` executing" :
+ (status == EXIT_NOCHILD ? "did not see `child` execute" :
+ "mystery")));
+
+ ATF_REQUIRE(forked != 0);
+ ATF_REQUIRE(parent != 0);
+ ATF_REQUIRE(child == 0);
+}
+
+static void
+multi_assert(bool cond, bool can_assert)
+{
+ if (can_assert)
+ ATF_REQUIRE((cond));
+ else if (!(cond))
+ _exit(EXIT_BADORDER);
+}
+
+static void
+multi_bump(int *var, int bit, bool can_assert)
+{
+ int mask, val;
+
+ mask = (1 << (bit - 1));
+ val = *var;
+
+ /*
+ * Every bit below this one must be set, and none of the upper bits
+ * should be set.
+ */
+ multi_assert((val & mask) == 0, can_assert);
+ if (bit == 1)
+ multi_assert(val == 0, can_assert);
+ else
+ multi_assert((val & ~mask) == (mask - 1), can_assert);
+
+ *var |= mask;
+}
+
+static void
+multi_prepare1(void)
+{
+ /*
+ * The bits are flipped for prepare because it's supposed to be called
+ * in the reverse order of registration.
+ */
+ multi_bump(&forked, 2, true);
+}
+static void
+multi_prepare2(void)
+{
+ multi_bump(&forked, 1, true);
+}
+
+static void
+multi_parent1(void)
+{
+ multi_bump(&parent, 1, true);
+}
+static void
+multi_parent2(void)
+{
+ multi_bump(&parent, 2, true);
+}
+
+static void
+multi_child1(void)
+{
+ multi_bump(&child, 1, false);
+}
+static void
+multi_child2(void)
+{
+ multi_bump(&child, 2, false);
+}
+
+/*
+ * The multi-atfork test works much like the basic one, but it registers
+ * multiple times and enforces an order. The child still does just as strict
+ * of tests as the parent and continues to communicate the results of those
+ * tests back via its exit status.
+ */
+ATF_TC(multi_atfork);
+ATF_TC_HEAD(multi_atfork, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that multiple callbacks are called in the documented order");
+}
+ATF_TC_BODY(multi_atfork, tc)
+{
+ pid_t p, wpid;
+ int status;
+
+ pthread_atfork(multi_prepare1, multi_parent1, multi_child1);
+ pthread_atfork(multi_prepare2, multi_parent2, multi_child2);
+
+ p = fork();
+
+ ATF_REQUIRE(p >= 0);
+ if (p == 0)
+ _exit(child != 0 ? 0 : EXIT_NOCHILD);
+
+ /*
+ * The child can't use any of our standard atf-c(3) macros, so we have
+ * to rely on the exit status to convey any shenanigans.
+ */
+ while ((wpid = waitpid(p, &status, 0)) != p) {
+ ATF_REQUIRE_ERRNO(EINTR, wpid == -1);
+ if (wpid == -1)
+ continue;
+ }
+
+ ATF_REQUIRE_MSG(WIFEXITED(status),
+ "child did not exit cleanly, status %x", status);
+
+ status = WEXITSTATUS(status);
+ ATF_REQUIRE_MSG(status == 0, "atfork in child %s",
+ status == EXIT_BADORDER ? "called in wrong order" :
+ (status == EXIT_NOCHILD ? "did not see `child` execute" :
+ "mystery"));
+
+ ATF_REQUIRE(forked != 0);
+ ATF_REQUIRE(parent != 0);
+ ATF_REQUIRE(child == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, preinit_atfork);
+ ATF_TP_ADD_TC(tp, basic_atfork);
+ ATF_TP_ADD_TC(tp, multi_atfork);
+ return (atf_no_error());
+}
diff --git a/lib/libthr/tests/dlopen/Makefile b/lib/libthr/tests/dlopen/Makefile
index acc565056f4a..3427f67025b2 100644
--- a/lib/libthr/tests/dlopen/Makefile
+++ b/lib/libthr/tests/dlopen/Makefile
@@ -1,4 +1,3 @@
-
TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libpthread/dlopen
WARNS?= 2
diff --git a/lib/libthr/tests/dlopen/dso/Makefile b/lib/libthr/tests/dlopen/dso/Makefile
index c2052e82c0ed..74d8ada35ff1 100644
--- a/lib/libthr/tests/dlopen/dso/Makefile
+++ b/lib/libthr/tests/dlopen/dso/Makefile
@@ -1,7 +1,7 @@
-
TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libpthread/dlopen/dso
WARNS?= 3
+PACKAGE= tests
SHLIB= h_pthread_dlopen
SHLIB_MAJOR= 1
SHLIB_NAME= h_pthread_dlopen.so.${SHLIB_MAJOR}
diff --git a/lib/libthr/tests/pthread_sigqueue_test.c b/lib/libthr/tests/pthread_sigqueue_test.c
new file mode 100644
index 000000000000..053a8dac4039
--- /dev/null
+++ b/lib/libthr/tests/pthread_sigqueue_test.c
@@ -0,0 +1,120 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2024 The FreeBSD Foundation
+ *
+ * This software was 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 <atf-c.h>
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#define NTHREADS 330
+static int value[NTHREADS];
+static pthread_t thr[NTHREADS];
+static pthread_barrier_t barrier;
+
+static void
+handler(int signo __unused, siginfo_t *info, void *data __unused)
+{
+ pthread_t self;
+ int i;
+
+ /*
+ * Formally this is thread-unsafe but we know context from
+ * where the signal is sent.
+ */
+ self = pthread_self();
+ for (i = 0; i < NTHREADS; i++) {
+ if (pthread_equal(self, thr[i])) {
+ value[i] = info->si_value.sival_int;
+ pthread_exit(NULL);
+ }
+ }
+}
+
+static void *
+threadfunc(void *arg __unused)
+{
+ pthread_barrier_wait(&barrier);
+ for (;;)
+ pause();
+}
+
+ATF_TC(pthread_sigqueue);
+ATF_TC_HEAD(pthread_sigqueue, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks pthread_sigqueue(3) sigval delivery");
+}
+
+ATF_TC_BODY(pthread_sigqueue, tc)
+{
+ struct sigaction sa;
+ union sigval sv;
+ int error, i;
+
+ error = pthread_barrier_init(&barrier, NULL, NTHREADS + 1);
+ ATF_REQUIRE_EQ(0, error);
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGUSR1, &sa, NULL) != 0)
+ atf_tc_fail("sigaction failed");
+
+ memset(&sv, 0, sizeof(sv));
+
+ for (i = 0; i < NTHREADS; i++) {
+ error = pthread_create(&thr[i], NULL, threadfunc, NULL);
+ ATF_REQUIRE_EQ(0, error);
+ }
+ error = pthread_barrier_wait(&barrier);
+ ATF_REQUIRE(error == 0 || error == PTHREAD_BARRIER_SERIAL_THREAD);
+
+ for (i = 0; i < NTHREADS; i++) {
+ sv.sival_int = i + 1000;
+ error = pthread_sigqueue(thr[i], SIGUSR1, sv);
+ ATF_REQUIRE_EQ(0, error);
+ error = pthread_join(thr[i], NULL);
+ ATF_REQUIRE_EQ(0, error);
+ }
+ for (i = 0; i < NTHREADS; i++)
+ ATF_REQUIRE_EQ(i + 1000, value[i]);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pthread_sigqueue);
+ return atf_no_error();
+}
diff --git a/lib/libthr/tests/umtx_op_test.c b/lib/libthr/tests/umtx_op_test.c
index 7bffc2d5bfbf..8f964f9a923b 100644
--- a/lib/libthr/tests/umtx_op_test.c
+++ b/lib/libthr/tests/umtx_op_test.c
@@ -25,7 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/umtx.h>
@@ -36,7 +35,7 @@
/*
* This is an implementation detail of _umtx_op(2), pulled from
* sys/kern/kern_umtx.c. The relevant bug observed that requests above the
- * batch side would not function as intended, so it's important that this
+ * batch size would not function as intended, so it's important that this
* reflects the BATCH_SIZE configured there.
*/
#define UMTX_OP_BATCH_SIZE 128
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>