aboutsummaryrefslogtreecommitdiff
path: root/lib/libthr
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/Makefile37
-rw-r--r--lib/libthr/Makefile.depend3
-rw-r--r--lib/libthr/arch/aarch64/Makefile.inc2
-rw-r--r--lib/libthr/arch/aarch64/include/pthread_md.h9
-rw-r--r--lib/libthr/arch/aarch64/include/pthread_tls.h46
-rw-r--r--lib/libthr/arch/amd64/Makefile.inc6
-rw-r--r--lib/libthr/arch/amd64/amd64/_umtx_op_err.S42
-rw-r--r--lib/libthr/arch/amd64/amd64/thr_machdep.c48
-rw-r--r--lib/libthr/arch/amd64/include/pthread_md.h15
-rw-r--r--lib/libthr/arch/amd64/include/pthread_tls.h46
-rw-r--r--lib/libthr/arch/arm/Makefile.inc3
-rw-r--r--lib/libthr/arch/arm/include/pthread_md.h6
-rw-r--r--lib/libthr/arch/arm/include/pthread_tls.h46
-rw-r--r--lib/libthr/arch/arm/thr_rtld_arm.c67
-rw-r--r--lib/libthr/arch/i386/Makefile.inc4
-rw-r--r--lib/libthr/arch/i386/i386/_umtx_op_err.S41
-rw-r--r--lib/libthr/arch/i386/include/pthread_md.h15
-rw-r--r--lib/libthr/arch/i386/include/pthread_tls.h46
-rw-r--r--lib/libthr/arch/powerpc/Makefile.inc3
-rw-r--r--lib/libthr/arch/powerpc/include/pthread_md.h9
-rw-r--r--lib/libthr/arch/powerpc/include/pthread_tls.h46
-rw-r--r--lib/libthr/arch/powerpc/powerpc/_umtx_op_err.S41
-rw-r--r--lib/libthr/arch/riscv/Makefile.inc1
-rw-r--r--lib/libthr/arch/riscv/include/pthread_md.h9
-rw-r--r--lib/libthr/arch/riscv/include/pthread_tls.h46
-rw-r--r--lib/libthr/libthr.316
-rw-r--r--lib/libthr/plockstat.d3
-rw-r--r--lib/libthr/pthread.map11
-rw-r--r--lib/libthr/sys/Makefile.inc2
-rw-r--r--lib/libthr/sys/thr_error.c7
-rw-r--r--lib/libthr/tests/Makefile4
-rw-r--r--lib/libthr/tests/Makefile.depend1
-rw-r--r--lib/libthr/tests/atfork_test.c280
-rw-r--r--lib/libthr/tests/dlopen/Makefile2
-rw-r--r--lib/libthr/tests/dlopen/Makefile.depend1
-rw-r--r--lib/libthr/tests/dlopen/dso/Makefile3
-rw-r--r--lib/libthr/tests/dlopen/dso/Makefile.depend1
-rw-r--r--lib/libthr/tests/pthread_sigqueue_test.c120
-rw-r--r--lib/libthr/tests/umtx_op_test.c5
-rw-r--r--lib/libthr/thread/Makefile.inc3
-rw-r--r--lib/libthr/thread/thr_affinity.c5
-rw-r--r--lib/libthr/thread/thr_attr.c503
-rw-r--r--lib/libthr/thread/thr_autoinit.c5
-rw-r--r--lib/libthr/thread/thr_barrier.c5
-rw-r--r--lib/libthr/thread/thr_barrierattr.c5
-rw-r--r--lib/libthr/thread/thr_cancel.c30
-rw-r--r--lib/libthr/thread/thr_clean.c3
-rw-r--r--lib/libthr/thread/thr_concurrency.c3
-rw-r--r--lib/libthr/thread/thr_cond.c6
-rw-r--r--lib/libthr/thread/thr_condattr.c4
-rw-r--r--lib/libthr/thread/thr_create.c23
-rw-r--r--lib/libthr/thread/thr_ctrdtr.c3
-rw-r--r--lib/libthr/thread/thr_detach.c5
-rw-r--r--lib/libthr/thread/thr_equal.c3
-rw-r--r--lib/libthr/thread/thr_event.c5
-rw-r--r--lib/libthr/thread/thr_exit.c3
-rw-r--r--lib/libthr/thread/thr_fork.c27
-rw-r--r--lib/libthr/thread/thr_getcpuclockid.c5
-rw-r--r--lib/libthr/thread/thr_getprio.c3
-rw-r--r--lib/libthr/thread/thr_getschedparam.c3
-rw-r--r--lib/libthr/thread/thr_getthreadid_np.c7
-rw-r--r--lib/libthr/thread/thr_info.c10
-rw-r--r--lib/libthr/thread/thr_init.c80
-rw-r--r--lib/libthr/thread/thr_join.c5
-rw-r--r--lib/libthr/thread/thr_kern.c5
-rw-r--r--lib/libthr/thread/thr_kill.c3
-rw-r--r--lib/libthr/thread/thr_list.c56
-rw-r--r--lib/libthr/thread/thr_main_np.c5
-rw-r--r--lib/libthr/thread/thr_malloc.c19
-rw-r--r--lib/libthr/thread/thr_multi_np.c3
-rw-r--r--lib/libthr/thread/thr_mutex.c18
-rw-r--r--lib/libthr/thread/thr_mutexattr.c3
-rw-r--r--lib/libthr/thread/thr_once.c5
-rw-r--r--lib/libthr/thread/thr_printf.c5
-rw-r--r--lib/libthr/thread/thr_private.h36
-rw-r--r--lib/libthr/thread/thr_pshared.c35
-rw-r--r--lib/libthr/thread/thr_pspinlock.c8
-rw-r--r--lib/libthr/thread/thr_resume_np.c8
-rw-r--r--lib/libthr/thread/thr_rtld.c60
-rw-r--r--lib/libthr/thread/thr_rwlock.c29
-rw-r--r--lib/libthr/thread/thr_rwlockattr.c5
-rw-r--r--lib/libthr/thread/thr_self.c3
-rw-r--r--lib/libthr/thread/thr_sem.c5
-rw-r--r--lib/libthr/thread/thr_setprio.c3
-rw-r--r--lib/libthr/thread/thr_setschedparam.c3
-rw-r--r--lib/libthr/thread/thr_sig.c66
-rw-r--r--lib/libthr/thread/thr_sigqueue.c79
-rw-r--r--lib/libthr/thread/thr_single_np.c3
-rw-r--r--lib/libthr/thread/thr_sleepq.c9
-rw-r--r--lib/libthr/thread/thr_spec.c3
-rw-r--r--lib/libthr/thread/thr_spinlock.c3
-rw-r--r--lib/libthr/thread/thr_stack.c31
-rw-r--r--lib/libthr/thread/thr_suspend_np.c8
-rw-r--r--lib/libthr/thread/thr_switch_np.c8
-rw-r--r--lib/libthr/thread/thr_symbols.c3
-rw-r--r--lib/libthr/thread/thr_syscalls.c57
-rw-r--r--lib/libthr/thread/thr_umtx.c15
-rw-r--r--lib/libthr/thread/thr_umtx.h5
-rw-r--r--lib/libthr/thread/thr_yield.c3
99 files changed, 1265 insertions, 1192 deletions
diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile
index 062f5eec5d88..c87be9475390 100644
--- a/lib/libthr/Makefile
+++ b/lib/libthr/Makefile
@@ -1,18 +1,22 @@
-# $FreeBSD$
-#
-# 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
@@ -27,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
@@ -45,14 +53,18 @@ 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
MAN= libthr.3
+.if ${MK_PTHREADS_ASSERTIONS} != "no"
# enable extra internal consistency checks
CFLAGS+=-D_PTHREADS_INVARIANTS
+.endif
PRECIOUSLIB=
@@ -66,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 1c1a9bee1d67..e0d18fcef3a4 100644
--- a/lib/libthr/Makefile.depend
+++ b/lib/libthr/Makefile.depend
@@ -1,11 +1,12 @@
-# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
include \
+ include/xlocale \
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 b720e3de68bf..e69de29bb2d1 100644
--- a/lib/libthr/arch/aarch64/Makefile.inc
+++ b/lib/libthr/arch/aarch64/Makefile.inc
@@ -1,2 +0,0 @@
-# $FreeBSD$
-
diff --git a/lib/libthr/arch/aarch64/include/pthread_md.h b/lib/libthr/arch/aarch64/include/pthread_md.h
index 2ae5a0d2e808..4316955f1d3d 100644
--- a/lib/libthr/arch/aarch64/include/pthread_md.h
+++ b/lib/libthr/arch/aarch64/include/pthread_md.h
@@ -26,8 +26,6 @@
* 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.
- *
- * $FreeBSD$
*/
/*
@@ -51,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 bd3a4fbb2024..000000000000
--- a/lib/libthr/arch/aarch64/include/pthread_tls.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#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 43f6e839ff10..fe80e1a73cc9 100644
--- a/lib/libthr/arch/amd64/Makefile.inc
+++ b/lib/libthr/arch/amd64/Makefile.inc
@@ -1,9 +1,7 @@
-#$FreeBSD$
-
-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 1e9f7d607f7a..000000000000
--- a/lib/libthr/arch/amd64/amd64/_umtx_op_err.S
+++ /dev/null
@@ -1,42 +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.
- *
- * $FreeBSD$
- */
-
-#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 acfbd551b3de..02b73d90f006 100644
--- a/lib/libthr/arch/amd64/include/pthread_md.h
+++ b/lib/libthr/arch/amd64/include/pthread_md.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2003 David Xu <davidxu@freebsd.org>
* Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>
@@ -25,8 +25,6 @@
* 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.
- *
- * $FreeBSD$
*/
/*
@@ -49,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 c0ca6201d41c..000000000000
--- a/lib/libthr/arch/amd64/include/pthread_tls.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#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 dfd7e7d951bf..b90568e249ee 100644
--- a/lib/libthr/arch/arm/include/pthread_md.h
+++ b/lib/libthr/arch/arm/include/pthread_md.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>.
* All rights reserved.
@@ -24,8 +24,6 @@
* 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.
- *
- * $FreeBSD$
*/
/*
@@ -50,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 6aef9c22f365..000000000000
--- a/lib/libthr/arch/arm/include/pthread_tls.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#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 23a95498f443..f8013ea914ed 100644
--- a/lib/libthr/arch/i386/Makefile.inc
+++ b/lib/libthr/arch/i386/Makefile.inc
@@ -1,7 +1,3 @@
-# $FreeBSD$
-
-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 dad6495132f7..000000000000
--- a/lib/libthr/arch/i386/i386/_umtx_op_err.S
+++ /dev/null
@@ -1,41 +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.
- *
- * $FreeBSD$
- */
-
-#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 8940acee6fee..43f84c3d0393 100644
--- a/lib/libthr/arch/i386/include/pthread_md.h
+++ b/lib/libthr/arch/i386/include/pthread_md.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2002 Daniel Eischen <deischen@freebsd.org>.
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>.
@@ -25,8 +25,6 @@
* 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.
- *
- * $FreeBSD$
*/
/*
@@ -49,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 f48147fd6455..000000000000
--- a/lib/libthr/arch/i386/include/pthread_tls.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#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 6c0e24fe3883..000000000000
--- a/lib/libthr/arch/powerpc/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-# $FreeBSD$
-
-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 076c43e1ef43..291f2d9350d9 100644
--- a/lib/libthr/arch/powerpc/include/pthread_md.h
+++ b/lib/libthr/arch/powerpc/include/pthread_md.h
@@ -25,8 +25,6 @@
* 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.
- *
- * $FreeBSD$
*/
/*
@@ -51,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 5c8db311f8d8..000000000000
--- a/lib/libthr/arch/powerpc/include/pthread_tls.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#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 a902a7360d7b..000000000000
--- a/lib/libthr/arch/powerpc/powerpc/_umtx_op_err.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#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/Makefile.inc b/lib/libthr/arch/riscv/Makefile.inc
index e8c0da7a1d7e..e69de29bb2d1 100644
--- a/lib/libthr/arch/riscv/Makefile.inc
+++ b/lib/libthr/arch/riscv/Makefile.inc
@@ -1 +0,0 @@
-# $FreeBSD$
diff --git a/lib/libthr/arch/riscv/include/pthread_md.h b/lib/libthr/arch/riscv/include/pthread_md.h
index 7c7b9a787c24..01dcc9c02b8c 100644
--- a/lib/libthr/arch/riscv/include/pthread_md.h
+++ b/lib/libthr/arch/riscv/include/pthread_md.h
@@ -31,8 +31,6 @@
* 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.
- *
- * $FreeBSD$
*/
/*
@@ -58,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 eb3e47b70260..000000000000
--- a/lib/libthr/arch/riscv/include/pthread_tls.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#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 3018a6f20b86..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
@@ -27,8 +27,6 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD$
-.\"
.Dd October 1, 2021
.Dt LIBTHR 3
.Os
@@ -196,6 +194,12 @@ The integer value of the variable specifies how often blocked
threads are inserted at the head of the sleep queue, instead of its tail.
Bigger values reduce the frequency of the FIFO discipline.
The value must be between 0 and 255.
+.It Dv LIBPTHREAD_UMTX_MIN_TIMEOUT
+The minimal amount of time, in nanoseconds, the thread is required to sleep
+for pthread operations specifying a timeout.
+If the operation requests a timeout less than the value provided,
+it is silently increased to the value.
+The value of zero means no minimum (default).
.Pp
.El
The following
@@ -213,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
@@ -321,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 68586cf84fdb..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.
@@ -25,8 +24,6 @@
* 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.
- *
- * $FreeBSD$
*/
provider plockstat {
diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map
index 15195ce0847b..3a5353a32dc3 100644
--- a/lib/libthr/pthread.map
+++ b/lib/libthr/pthread.map
@@ -1,5 +1,4 @@
/*
- * $FreeBSD$
*/
/*
@@ -137,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;
@@ -299,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 {
@@ -335,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 70c6dda60b74..98d7b2ac7bd3 100644
--- a/lib/libthr/sys/Makefile.inc
+++ b/lib/libthr/sys/Makefile.inc
@@ -1,5 +1,3 @@
-# $FreeBSD$
-
.PATH: ${.CURDIR}/sys
SRCS+= thr_error.c
diff --git a/lib/libthr/sys/thr_error.c b/lib/libthr/sys/thr_error.c
index 922d818c3ca8..ec7a57bf6610 100644
--- a/lib/libthr/sys/thr_error.c
+++ b/lib/libthr/sys/thr_error.c
@@ -32,8 +32,6 @@
* 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.
- *
- * $FreeBSD$
*/
#include <pthread.h>
@@ -41,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 *
@@ -55,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 8dd0b8f1dcc0..017b740157dc 100644
--- a/lib/libthr/tests/Makefile
+++ b/lib/libthr/tests/Makefile
@@ -1,5 +1,3 @@
-# $FreeBSD$
-
PACKAGE= tests
WARNS?= 3
@@ -35,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/Makefile.depend b/lib/libthr/tests/Makefile.depend
index c49a59b437ed..c48ed7f958dd 100644
--- a/lib/libthr/tests/Makefile.depend
+++ b/lib/libthr/tests/Makefile.depend
@@ -1,4 +1,3 @@
-# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
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 05f1cb7e6790..3427f67025b2 100644
--- a/lib/libthr/tests/dlopen/Makefile
+++ b/lib/libthr/tests/dlopen/Makefile
@@ -1,5 +1,3 @@
-# $FreeBSD$
-
TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libpthread/dlopen
WARNS?= 2
diff --git a/lib/libthr/tests/dlopen/Makefile.depend b/lib/libthr/tests/dlopen/Makefile.depend
index 22a01a72015a..daaf971bd513 100644
--- a/lib/libthr/tests/dlopen/Makefile.depend
+++ b/lib/libthr/tests/dlopen/Makefile.depend
@@ -1,4 +1,3 @@
-# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
diff --git a/lib/libthr/tests/dlopen/dso/Makefile b/lib/libthr/tests/dlopen/dso/Makefile
index dfd926586c90..74d8ada35ff1 100644
--- a/lib/libthr/tests/dlopen/dso/Makefile
+++ b/lib/libthr/tests/dlopen/dso/Makefile
@@ -1,8 +1,7 @@
-# $FreeBSD$
-
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/dlopen/dso/Makefile.depend b/lib/libthr/tests/dlopen/dso/Makefile.depend
index 8bb1973e0ff5..a6b2561a99a8 100644
--- a/lib/libthr/tests/dlopen/dso/Makefile.depend
+++ b/lib/libthr/tests/dlopen/dso/Makefile.depend
@@ -1,4 +1,3 @@
-# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
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 f7046ab42fc4..8f964f9a923b 100644
--- a/lib/libthr/tests/umtx_op_test.c
+++ b/lib/libthr/tests/umtx_op_test.c
@@ -25,9 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/types.h>
#include <sys/umtx.h>
@@ -38,7 +35,7 @@ __FBSDID("$FreeBSD$");
/*
* 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 34b881a69637..c7442284bd51 100644
--- a/lib/libthr/thread/Makefile.inc
+++ b/lib/libthr/thread/Makefile.inc
@@ -1,5 +1,3 @@
-# $FreeBSD$
-
# thr sources
.PATH: ${.CURDIR}/thread
@@ -48,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 1a820b72b9f3..78c89e146a79 100644
--- a/lib/libthr/thread/thr_affinity.c
+++ b/lib/libthr/thread/thr_affinity.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2008, David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 6ff23aa5a3da..1d0bc8cb7b91 100644
--- a/lib/libthr/thread/thr_attr.c
+++ b/lib/libthr/thread/thr_attr.c
@@ -93,9 +93,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -115,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);
@@ -143,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);
@@ -181,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);
@@ -206,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);
@@ -226,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);
@@ -243,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);
@@ -260,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);
@@ -277,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);
@@ -296,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);
@@ -317,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);
@@ -337,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);
@@ -356,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);
@@ -398,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);
@@ -424,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);
@@ -443,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);
@@ -465,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
@@ -496,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);
@@ -515,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);
@@ -558,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);
@@ -577,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
@@ -599,8 +515,10 @@ _get_kern_cpuset_size(void)
size_t len;
len = sizeof(kern_cpuset_size);
- if (sysctlbyname("kern.sched.cpusetsize", &kern_cpuset_size,
- &len, NULL, 0))
+ if (sysctlbyname("kern.sched.cpusetsizemin", &kern_cpuset_size,
+ &len, NULL, 0) != 0 &&
+ sysctlbyname("kern.sched.cpusetsize", &kern_cpuset_size,
+ &len, NULL, 0) != 0)
PANIC("failed to get sysctl kern.sched.cpusetsize");
}
@@ -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 d741f3cf1af7..b0b4e601eff7 100644
--- a/lib/libthr/thread/thr_autoinit.c
+++ b/lib/libthr/thread/thr_autoinit.c
@@ -33,15 +33,12 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <pthread.h>
#include "thr_private.h"
/*
- * This module uses GCC extentions to initialize the
+ * This module uses GCC extensions to initialize the
* threads package at program start-up time.
*/
diff --git a/lib/libthr/thread/thr_barrier.c b/lib/libthr/thread/thr_barrier.c
index fc42588cb412..13dec864e2f6 100644
--- a/lib/libthr/thread/thr_barrier.c
+++ b/lib/libthr/thread/thr_barrier.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2003 David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 09d8c9cff606..6e5de86973f2 100644
--- a/lib/libthr/thread/thr_barrierattr.c
+++ b/lib/libthr/thread/thr_barrierattr.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2003 David Xu <davidxu@freebsd.org>.
* All rights reserved.
@@ -28,9 +28,6 @@
* DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 7e78fe9163c7..4189a2640d14 100644
--- a/lib/libthr/thread/thr_cancel.c
+++ b/lib/libthr/thread/thr_cancel.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005, David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <pthread.h>
#include "un-namespace.h"
@@ -86,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);
}
@@ -128,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);
}
@@ -169,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 4c73c486eeff..43fd570fd1df 100644
--- a/lib/libthr/thread/thr_clean.c
+++ b/lib/libthr/thread/thr_clean.c
@@ -30,9 +30,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 9f60dca1e445..64c605f7d058 100644
--- a/lib/libthr/thread/thr_concurrency.c
+++ b/lib/libthr/thread/thr_concurrency.c
@@ -32,9 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 925792a92662..0eb3dac068ca 100644
--- a/lib/libthr/thread/thr_cond.c
+++ b/lib/libthr/thread/thr_cond.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
* Copyright (c) 2015 The FreeBSD Foundation
@@ -30,9 +30,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <stdlib.h>
#include <errno.h>
@@ -66,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 0a06d004cef7..dc56363fc084 100644
--- a/lib/libthr/thread/thr_condattr.c
+++ b/lib/libthr/thread/thr_condattr.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <stdlib.h>
#include <string.h>
@@ -97,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 b99e5825f5f5..e56dbcfe30e1 100644
--- a/lib/libthr/thread/thr_create.c
+++ b/lib/libthr/thread/thr_create.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2003 Daniel M. Eischen <deischen@gdeb.com>
* Copyright (c) 2005, David Xu <davidxu@freebsd.org>
@@ -27,13 +27,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
+#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>
@@ -46,9 +45,13 @@ __FBSDID("$FreeBSD$");
#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
@@ -149,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;
@@ -163,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)
@@ -229,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);
}
@@ -288,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 9ce068072524..6fa462a81d86 100644
--- a/lib/libthr/thread/thr_ctrdtr.c
+++ b/lib/libthr/thread/thr_ctrdtr.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 2618f637b5df..c7a60bb26129 100644
--- a/lib/libthr/thread/thr_detach.c
+++ b/lib/libthr/thread/thr_detach.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
* Copyright (C) 2003 Daniel M. Eischen <deischen@freebsd.org>
@@ -27,9 +27,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 69aa6bff8922..e5b2ab881138 100644
--- a/lib/libthr/thread/thr_equal.c
+++ b/lib/libthr/thread/thr_equal.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 977c0dacb7c7..f0b1805894fb 100644
--- a/lib/libthr/thread/thr_event.c
+++ b/lib/libthr/thread/thr_event.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu
* All rights reserved.
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "thr_private.h"
void
diff --git a/lib/libthr/thread/thr_exit.c b/lib/libthr/thread/thr_exit.c
index b9d81787c3bb..5a9dcf99fa21 100644
--- a/lib/libthr/thread/thr_exit.c
+++ b/lib/libthr/thread/thr_exit.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 9861e93c427d..aa54b0444cf4 100644
--- a/lib/libthr/thread/thr_fork.c
+++ b/lib/libthr/thread/thr_fork.c
@@ -57,9 +57,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/syscall.h>
#include "namespace.h"
#include <errno.h>
@@ -78,6 +75,8 @@ __FBSDID("$FreeBSD$");
__weak_reference(_thr_atfork, _pthread_atfork);
__weak_reference(_thr_atfork, pthread_atfork);
+bool _thr_after_fork = false;
+
int
_thr_atfork(void (*prepare)(void), void (*parent)(void),
void (*child)(void))
@@ -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);
}
@@ -243,7 +246,9 @@ thr_fork_impl(const struct thr_fork_args *a)
_thr_signal_postfork_child();
if (was_threaded) {
+ _thr_after_fork = true;
_rtld_atfork_post(rtld_locks);
+ _thr_after_fork = false;
__thr_pshared_atfork_post();
}
_thr_setthreaded(0);
diff --git a/lib/libthr/thread/thr_getcpuclockid.c b/lib/libthr/thread/thr_getcpuclockid.c
index 20f63039ea89..dee3a2a9447a 100644
--- a/lib/libthr/thread/thr_getcpuclockid.c
+++ b/lib/libthr/thread/thr_getcpuclockid.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2008 David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 a8d8d2bfe017..d338287342ac 100644
--- a/lib/libthr/thread/thr_getprio.c
+++ b/lib/libthr/thread/thr_getprio.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 5785438f3085..3abe9be6937b 100644
--- a/lib/libthr/thread/thr_getschedparam.c
+++ b/lib/libthr/thread/thr_getschedparam.c
@@ -32,9 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 9f522b79cb06..ffecd0bc7ea9 100644
--- a/lib/libthr/thread/thr_getthreadid_np.c
+++ b/lib/libthr/thread/thr_getthreadid_np.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2011 Jung-uk Kim <jkim@FreeBSD.org>
*
@@ -25,9 +25,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <pthread.h>
#include <pthread_np.h>
@@ -39,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 117d55c7bc4f..f6bf81203f9c 100644
--- a/lib/libthr/thread/thr_info.c
+++ b/lib/libthr/thread/thr_info.c
@@ -33,9 +33,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <sys/errno.h>
#include <stdlib.h>
@@ -116,9 +113,10 @@ thr_get_name_np(struct pthread *thread, char *buf, size_t len)
buf[0] = '\0';
}
-__weak_reference(_pthread_getname_np, pthread_getname_np);
+__weak_reference(_thr_getname_np, pthread_getname_np);
+__weak_reference(_thr_getname_np, _pthread_getname_np);
int
-_pthread_getname_np(pthread_t thread, char *buf, size_t len)
+_thr_getname_np(pthread_t thread, char *buf, size_t len)
{
struct pthread *curthread;
int res;
@@ -149,5 +147,5 @@ __weak_reference(_pthread_get_name_np, pthread_get_name_np);
void
_pthread_get_name_np(pthread_t thread, char *buf, size_t len)
{
- (void)_pthread_getname_np(thread, buf, len);
+ (void)_thr_getname_np(thread, buf, len);
}
diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c
index 82bde10a153e..0f9e3749d75f 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -33,11 +33,10 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
+#define _WANT_P_OSREL
#include "namespace.h"
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/auxv.h>
#include <sys/signalvar.h>
#include <sys/ioctl.h>
#include <sys/link_elf.h>
@@ -61,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include "libc_private.h"
#include "thr_private.h"
+int __getosreldate(void);
char *_usrstack;
struct pthread *_thr_initial;
int _libthr_debug;
@@ -170,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 +271,9 @@ static pthread_func_t jmp_table[][2] = {
[PJT_MUTEXATTR_SETROBUST] = {DUAL_ENTRY(_thr_mutexattr_setrobust)},
[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,15 +434,50 @@ 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() */
}
-static void
-init_private(void)
+bool
+__thr_get_main_stack_base(char **base)
{
- struct rlimit rlim;
size_t len;
int mib[2];
+
+ if (elf_aux_info(AT_USRSTACKBASE, base, sizeof(*base)) == 0)
+ return (true);
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_USRSTACK;
+ len = sizeof(*base);
+ if (sysctl(mib, nitems(mib), base, &len, NULL, 0) == 0)
+ return (true);
+
+ return (false);
+}
+
+bool
+__thr_get_main_stack_lim(size_t *lim)
+{
+ struct rlimit rlim;
+
+ if (elf_aux_info(AT_USRSTACKLIM, lim, sizeof(*lim)) == 0)
+ return (true);
+
+ if (getrlimit(RLIMIT_STACK, &rlim) == 0) {
+ *lim = rlim.rlim_cur;
+ return (true);
+ }
+
+ return (false);
+}
+
+static void
+init_private(void)
+{
char *env, *env_bigstack, *env_splitstack;
_thr_umutex_init(&_mutex_static_lock);
@@ -462,18 +501,15 @@ init_private(void)
if (init_once == 0) {
__thr_pshared_init();
__thr_malloc_init();
+
/* Find the stack top */
- mib[0] = CTL_KERN;
- mib[1] = KERN_USRSTACK;
- len = sizeof (_usrstack);
- if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
- PANIC("Cannot get kern.usrstack from sysctl");
+ if (!__thr_get_main_stack_base(&_usrstack))
+ PANIC("Cannot get kern.usrstack");
env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN");
env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN");
if (env_bigstack != NULL || env_splitstack == NULL) {
- if (getrlimit(RLIMIT_STACK, &rlim) == -1)
+ if (!__thr_get_main_stack_lim(&_thr_stack_initial))
PANIC("Cannot get stack rlimit");
- _thr_stack_initial = rlim.rlim_cur;
}
_thr_is_smp = sysconf(_SC_NPROCESSORS_CONF);
if (_thr_is_smp == -1)
@@ -492,7 +528,17 @@ 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;
+ long mint;
+
+ mint = strtol(env, &endptr, 0);
+ if (*endptr == '\0' && mint >= 0) {
+ _umtx_op(NULL, UMTX_OP_SET_MIN_TIMEOUT,
+ mint, NULL, NULL);
+ }
+ }
}
init_once = 1;
}
diff --git a/lib/libthr/thread/thr_join.c b/lib/libthr/thread/thr_join.c
index ab3ed68eccaa..53f28daa258d 100644
--- a/lib/libthr/thread/thr_join.c
+++ b/lib/libthr/thread/thr_join.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005, David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 0b83b2dd5ac9..913b0d3ef44c 100644
--- a/lib/libthr/thread/thr_kern.c
+++ b/lib/libthr/thread/thr_kern.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
* Copyright (C) 2003 Daniel M. Eischen <deischen@freebsd.org>
@@ -27,9 +27,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 c96c1b3ecbaa..5fb40b3bc496 100644
--- a/lib/libthr/thread/thr_kill.c
+++ b/lib/libthr/thread/thr_kill.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 f28f059c2909..cbf16179f619 100644
--- a/lib/libthr/thread/thr_list.c
+++ b/lib/libthr/thread/thr_list.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
* Copyright (C) 2003 Daniel M. Eischen <deischen@freebsd.org>
@@ -27,19 +27,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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
@@ -152,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 {
@@ -179,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);
@@ -205,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
@@ -225,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);
}
/*
@@ -363,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 ff28d1d8a5ac..1d34dc21b84c 100644
--- a/lib/libthr/thread/thr_main_np.c
+++ b/lib/libthr/thread/thr_main_np.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2001 Alfred Perlstein
* Author: Alfred Perlstein <alfred@FreeBSD.org>
@@ -27,9 +27,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 b4a627cc55eb..48af9d1ea929 100644
--- a/lib/libthr/thread/thr_malloc.c
+++ b/lib/libthr/thread/thr_malloc.c
@@ -1,8 +1,7 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * 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,9 +28,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/types.h>
#include <sys/mman.h>
#include <rtld_malloc.h>
@@ -124,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 59e782cc59b2..bac58ca85dca 100644
--- a/lib/libthr/thread/thr_multi_np.c
+++ b/lib/libthr/thread/thr_multi_np.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 8dccdf4dfa8c..32bdc4afe65f 100644
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -38,9 +38,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <stdlib.h>
#include <errno.h>
@@ -120,7 +117,7 @@ __weak_reference(_pthread_mutex_getyieldloops_np, pthread_mutex_getyieldloops_np
__weak_reference(_pthread_mutex_isowned_np, pthread_mutex_isowned_np);
static void
-mutex_init_link(struct pthread_mutex *m)
+mutex_init_link(struct pthread_mutex *m __unused)
{
#if defined(_PTHREADS_INVARIANTS)
@@ -291,8 +288,8 @@ mutex_init(pthread_mutex_t *mutex,
if (error != 0)
return (error);
}
- if ((pmutex = (pthread_mutex_t)
- calloc_cb(1, sizeof(struct pthread_mutex))) == NULL)
+ if ((pmutex = (pthread_mutex_t)calloc_cb(1,
+ sizeof(struct pthread_mutex))) == NULL)
return (ENOMEM);
mutex_init_body(pmutex, attr);
*mutex = pmutex;
@@ -596,7 +593,7 @@ check_and_init_mutex(pthread_mutex_t *mutex, struct pthread_mutex **m)
*m = *mutex;
ret = 0;
- if (*m == THR_PSHARED_PTR) {
+ if (__predict_false(*m == THR_PSHARED_PTR)) {
*m = __thr_pshared_offpage(mutex, 0);
if (*m == NULL)
ret = EINVAL;
@@ -622,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);
@@ -714,7 +712,7 @@ done:
return (ret);
}
-static inline int
+static __always_inline int
mutex_lock_common(struct pthread_mutex *m, const struct timespec *abstime,
bool cvattach, bool rb_onlist)
{
@@ -728,7 +726,7 @@ mutex_lock_common(struct pthread_mutex *m, const struct timespec *abstime,
if (!rb_onlist)
robust = _mutex_enter_robust(curthread, m);
ret = _thr_umutex_trylock2(&m->m_lock, TID(curthread));
- if (ret == 0 || ret == EOWNERDEAD) {
+ if (__predict_true(ret == 0) || ret == EOWNERDEAD) {
enqueue_mutex(curthread, m, ret);
if (ret == EOWNERDEAD)
m->m_lock.m_flags |= UMUTEX_NONCONSISTENT;
@@ -951,7 +949,7 @@ mutex_self_lock(struct pthread_mutex *m, const struct timespec *abstime)
return (ret);
}
-static int
+static __always_inline int
mutex_unlock_common(struct pthread_mutex *m, bool cv, int *mtx_defer)
{
struct pthread *curthread;
diff --git a/lib/libthr/thread/thr_mutexattr.c b/lib/libthr/thread/thr_mutexattr.c
index 1f5d3b284af8..d78aad518ee8 100644
--- a/lib/libthr/thread/thr_mutexattr.c
+++ b/lib/libthr/thread/thr_mutexattr.c
@@ -59,9 +59,6 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 6783d8f644f8..89b76ee58c1e 100644
--- a/lib/libthr/thread/thr_once.c
+++ b/lib/libthr/thread/thr_once.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005, David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 dd761783a2a6..e1edffe5acb2 100644
--- a/lib/libthr/thread/thr_printf.c
+++ b/lib/libthr/thread/thr_printf.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2002 Jonathan Mini <mini@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 a5bbc5997d30..d7b889930365 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2005 Daniel M. Eischen <deischen@freebsd.org>
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
@@ -27,8 +27,6 @@
* 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.
- *
- * $FreeBSD$
*/
#ifndef _THR_PRIVATE_H
@@ -39,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>
@@ -263,7 +261,6 @@ struct pthread_atfork {
};
struct pthread_attr {
-#define pthread_attr_start_copy sched_policy
int sched_policy;
int sched_inherit;
int prio;
@@ -273,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;
};
@@ -567,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)
@@ -578,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 +777,10 @@ extern int _suspend_all_waiters __hidden;
extern int _suspend_all_cycle __hidden;
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);
@@ -1073,6 +1076,7 @@ int _thr_cond_wait(pthread_cond_t *, pthread_mutex_t *);
int _thr_detach(pthread_t);
int _thr_equal(pthread_t, pthread_t);
void _Tthr_exit(void *);
+int _thr_getname_np(pthread_t, char *, size_t);
int _thr_key_create(pthread_key_t *, void (*)(void *));
int _thr_key_delete(pthread_key_t);
int _thr_setspecific(pthread_key_t, const void *);
@@ -1102,6 +1106,10 @@ int _thr_mutex_destroy(pthread_mutex_t *);
int _thr_mutex_unlock(pthread_mutex_t *);
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 d0219d0488f4..d20d66e21ea3 100644
--- a/lib/libthr/thread/thr_pshared.c
+++ b/lib/libthr/thread/thr_pshared.c
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/queue.h>
@@ -213,6 +210,17 @@ pshared_clean(void *key, void *val)
_umtx_op(NULL, UMTX_OP_SHM, UMTX_SHM_DESTROY, key, NULL);
}
+static void
+pshared_destroy(struct pthread *curthread, void *key)
+{
+ void *val;
+
+ pshared_wlock(curthread);
+ val = pshared_remove(key);
+ pshared_unlock(curthread);
+ pshared_clean(key, val);
+}
+
void *
__thr_pshared_offpage(void *key, int doalloc)
{
@@ -221,11 +229,16 @@ __thr_pshared_offpage(void *key, int doalloc)
int fd, ins_done;
curthread = _get_curthread();
- pshared_rlock(curthread);
- res = pshared_lookup(key);
- pshared_unlock(curthread);
- if (res != NULL)
- return (res);
+ if (doalloc) {
+ pshared_destroy(curthread, key);
+ res = NULL;
+ } else {
+ pshared_rlock(curthread);
+ res = pshared_lookup(key);
+ pshared_unlock(curthread);
+ if (res != NULL)
+ return (res);
+ }
fd = _umtx_op(NULL, UMTX_OP_SHM, doalloc ? UMTX_SHM_CREAT :
UMTX_SHM_LOOKUP, key, NULL);
if (fd == -1)
@@ -248,13 +261,9 @@ void
__thr_pshared_destroy(void *key)
{
struct pthread *curthread;
- void *val;
curthread = _get_curthread();
- pshared_wlock(curthread);
- val = pshared_remove(key);
- pshared_unlock(curthread);
- pshared_clean(key, val);
+ pshared_destroy(curthread, key);
pshared_gc(curthread);
}
diff --git a/lib/libthr/thread/thr_pspinlock.c b/lib/libthr/thread/thr_pspinlock.c
index d1a53446f654..4820490ab6af 100644
--- a/lib/libthr/thread/thr_pspinlock.c
+++ b/lib/libthr/thread/thr_pspinlock.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2003 David Xu <davidxu@freebsd.org>
* Copyright (c) 2016 The FreeBSD Foundation
@@ -30,9 +30,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <errno.h>
#include <stdlib.h>
@@ -60,7 +57,8 @@ _pthread_spin_init(pthread_spinlock_t *lock, int pshared)
if (lock == NULL)
return (EINVAL);
if (pshared == PTHREAD_PROCESS_PRIVATE) {
- lck = malloc(sizeof(struct pthread_spinlock));
+ lck = aligned_alloc(CACHE_LINE_SIZE,
+ roundup(sizeof(struct pthread_spinlock), CACHE_LINE_SIZE));
if (lck == NULL)
return (ENOMEM);
*lock = lck;
diff --git a/lib/libthr/thread/thr_resume_np.c b/lib/libthr/thread/thr_resume_np.c
index 125d70a595e9..c5669fd4f0ff 100644
--- a/lib/libthr/thread/thr_resume_np.c
+++ b/lib/libthr/thread/thr_resume_np.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -41,7 +38,8 @@ __FBSDID("$FreeBSD$");
#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);
@@ -62,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 1967ea14859d..3cfdfc548cf2 100644
--- a/lib/libthr/thread/thr_rtld.c
+++ b/lib/libthr/thread/thr_rtld.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2006, David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,13 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
/*
* A lockless rwlock for rtld.
*/
-#include <sys/cdefs.h>
#include <sys/mman.h>
#include <sys/syscall.h>
#include <link.h>
@@ -43,8 +39,7 @@ __FBSDID("$FreeBSD$");
#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);
@@ -55,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);
@@ -100,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
@@ -121,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();
}
@@ -142,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();
}
@@ -158,6 +161,25 @@ _thr_rtld_lock_release(void *lock)
l = (struct rtld_lock *)lock;
state = l->lock.rw_state;
+ if (__predict_false(_thr_after_fork)) {
+ /*
+ * After fork, only this thread is running, there is no
+ * waiters. Keeping waiters recorded in rwlock breaks
+ * wake logic.
+ */
+ atomic_clear_int(&l->lock.rw_state,
+ URWLOCK_WRITE_WAITERS | URWLOCK_READ_WAITERS);
+ 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--;
@@ -213,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;
@@ -268,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 1d110a7bf285..084181ba922a 100644
--- a/lib/libthr/thread/thr_rwlock.c
+++ b/lib/libthr/thread/thr_rwlock.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 1998 Alex Nash
* All rights reserved.
@@ -26,12 +26,10 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
+#include <string.h>
#include "namespace.h"
#include <pthread.h>
@@ -61,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 ||
@@ -102,9 +100,11 @@ rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
if (attr == NULL || *attr == NULL ||
(*attr)->pshared == PTHREAD_PROCESS_PRIVATE) {
- prwlock = calloc(1, sizeof(struct pthread_rwlock));
+ prwlock = aligned_alloc(CACHE_LINE_SIZE,
+ roundup(sizeof(struct pthread_rwlock), CACHE_LINE_SIZE));
if (prwlock == NULL)
return (ENOMEM);
+ memset(prwlock, 0, sizeof(struct pthread_rwlock));
*rwlock = prwlock;
} else {
prwlock = __thr_pshared_offpage(rwlock, 1);
@@ -160,6 +160,7 @@ int
_thr_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
+ _thr_check_init();
*rwlock = NULL;
return (rwlock_init(rwlock, attr));
}
@@ -228,6 +229,7 @@ rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime)
int
_Tthr_rwlock_rdlock(pthread_rwlock_t *rwlock)
{
+ _thr_check_init();
return (rwlock_rdlock_common(rwlock, NULL));
}
@@ -235,21 +237,24 @@ int
_pthread_rwlock_timedrdlock(pthread_rwlock_t * __restrict rwlock,
const struct timespec * __restrict abstime)
{
+ _thr_check_init();
return (rwlock_rdlock_common(rwlock, abstime));
}
int
_Tthr_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
pthread_rwlock_t prwlock;
int flags;
int ret;
+ _thr_check_init();
ret = check_and_init_rwlock(rwlock, &prwlock);
if (ret != 0)
return (ret);
+ curthread = _get_curthread();
if (curthread->rdlock_count) {
/*
* To avoid having to track all the rdlocks held by
@@ -277,14 +282,16 @@ _Tthr_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
int
_Tthr_rwlock_trywrlock(pthread_rwlock_t *rwlock)
{
- struct pthread *curthread = _get_curthread();
+ struct pthread *curthread;
pthread_rwlock_t prwlock;
int ret;
+ _thr_check_init();
ret = check_and_init_rwlock(rwlock, &prwlock);
if (ret != 0)
return (ret);
+ curthread = _get_curthread();
ret = _thr_rwlock_trywrlock(&prwlock->lock);
if (ret == 0)
prwlock->owner = TID(curthread);
@@ -340,14 +347,16 @@ rwlock_wrlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime)
int
_Tthr_rwlock_wrlock(pthread_rwlock_t *rwlock)
{
- return (rwlock_wrlock_common (rwlock, NULL));
+ _thr_check_init();
+ return (rwlock_wrlock_common(rwlock, NULL));
}
int
_pthread_rwlock_timedwrlock(pthread_rwlock_t * __restrict rwlock,
const struct timespec * __restrict abstime)
{
- return (rwlock_wrlock_common (rwlock, abstime));
+ _thr_check_init();
+ return (rwlock_wrlock_common(rwlock, abstime));
}
int
diff --git a/lib/libthr/thread/thr_rwlockattr.c b/lib/libthr/thread/thr_rwlockattr.c
index b0b8e70a44c4..34bbbb20e611 100644
--- a/lib/libthr/thread/thr_rwlockattr.c
+++ b/lib/libthr/thread/thr_rwlockattr.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 1998 Alex Nash
* All rights reserved.
@@ -26,9 +26,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 68bf5bc39312..cbdadb13ccc4 100644
--- a/lib/libthr/thread/thr_self.c
+++ b/lib/libthr/thread/thr_self.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 66386764666a..76180604c183 100644
--- a/lib/libthr/thread/thr_sem.c
+++ b/lib/libthr/thread/thr_sem.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (C) 2005 David Xu <davidxu@freebsd.org>.
* Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
@@ -30,9 +30,6 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 537b9b89f201..fddf664457bd 100644
--- a/lib/libthr/thread/thr_setprio.c
+++ b/lib/libthr/thread/thr_setprio.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 cf2c1f919e12..49ec2ae7a7fd 100644
--- a/lib/libthr/thread/thr_setschedparam.c
+++ b/lib/libthr/thread/thr_setschedparam.c
@@ -32,9 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 20f62dad99c9..4bff5497a804 100644
--- a/lib/libthr/thread/thr_sig.c
+++ b/lib/libthr/thread/thr_sig.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005, David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <sys/param.h>
#include <sys/auxv.h>
@@ -40,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include <pthread_np.h>
#include "un-namespace.h"
#include "libc_private.h"
@@ -166,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)
{
@@ -188,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;
@@ -250,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;
@@ -310,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
@@ -360,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);
@@ -371,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);
}
}
@@ -403,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
@@ -410,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;
@@ -669,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;
@@ -703,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;
@@ -718,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 7aecfc93b3e3..3aa7adba954d 100644
--- a/lib/libthr/thread/thr_single_np.c
+++ b/lib/libthr/thread/thr_single_np.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 05145a739681..9c680acd0ac0 100644
--- a/lib/libthr/thread/thr_sleepq.c
+++ b/lib/libthr/thread/thr_sleepq.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2010 David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,9 +26,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include <stdlib.h>
#include "thr_private.h"
@@ -65,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);
@@ -74,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 bce3d1fa2507..44a124785085 100644
--- a/lib/libthr/thread/thr_spec.c
+++ b/lib/libthr/thread/thr_spec.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 42077ce5d447..bf3401c92780 100644
--- a/lib/libthr/thread/thr_spinlock.c
+++ b/lib/libthr/thread/thr_spinlock.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 b08bafdd9417..d249bb5606fd 100644
--- a/lib/libthr/thread/thr_stack.c
+++ b/lib/libthr/thread/thr_stack.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>
* Copyright (c) 2000-2001 Jason Evans <jasone@freebsd.org>
@@ -27,10 +27,8 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/queue.h>
#include <sys/resource.h>
@@ -128,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
@@ -147,21 +142,13 @@ _thr_stack_fix_protection(struct pthread *thrd)
static void
singlethread_map_stacks_exec(void)
{
- int mib[2];
- struct rlimit rlim;
- u_long usrstack;
- size_t len;
+ char *usrstack;
+ size_t stacksz;
- mib[0] = CTL_KERN;
- mib[1] = KERN_USRSTACK;
- len = sizeof(usrstack);
- if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0)
- == -1)
- return;
- if (getrlimit(RLIMIT_STACK, &rlim) == -1)
+ if (!__thr_get_main_stack_base(&usrstack) ||
+ !__thr_get_main_stack_lim(&stacksz))
return;
- mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur),
- rlim.rlim_cur, _rtld_get_stack_prot());
+ mprotect(usrstack - stacksz, stacksz, _rtld_get_stack_prot());
}
void
diff --git a/lib/libthr/thread/thr_suspend_np.c b/lib/libthr/thread/thr_suspend_np.c
index 2d68582623dd..cf4e9e8a96b1 100644
--- a/lib/libthr/thread/thr_suspend_np.c
+++ b/lib/libthr/thread/thr_suspend_np.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -44,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
@@ -104,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 aad8641e4806..59a9a4c7e1a3 100644
--- a/lib/libthr/thread/thr_switch_np.c
+++ b/lib/libthr/thread/thr_switch_np.c
@@ -32,9 +32,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <errno.h>
#include <pthread.h>
@@ -43,10 +40,13 @@ __FBSDID("$FreeBSD$");
#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 71737392c62f..f2de1f777558 100644
--- a/lib/libthr/thread/thr_symbols.c
+++ b/lib/libthr/thread/thr_symbols.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 c60308fcd1d2..188374a30070 100644
--- a/lib/libthr/thread/thr_syscalls.c
+++ b/lib/libthr/thread/thr_syscalls.c
@@ -65,13 +65,10 @@
*
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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>
@@ -191,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);
}
@@ -297,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);
@@ -638,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)
{
@@ -646,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);
@@ -674,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 86e5a1f13780..bbc68d0e30c6 100644
--- a/lib/libthr/thread/thr_umtx.c
+++ b/lib/libthr/thread/thr_umtx.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -26,22 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#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 1017214adb5c..89f70e4ab14f 100644
--- a/lib/libthr/thread/thr_umtx.h
+++ b/lib/libthr/thread/thr_umtx.h
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2005 David Xu <davidxu@freebsd.org>
* All rights reserved.
@@ -24,8 +24,6 @@
* 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.
- *
- * $FreeBSD$
*/
#ifndef _THR_FBSD_UMTX_H_
@@ -41,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 0d666d52a554..057fc789de02 100644
--- a/lib/libthr/thread/thr_yield.c
+++ b/lib/libthr/thread/thr_yield.c
@@ -29,9 +29,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
#include "namespace.h"
#include <pthread.h>
#include <sched.h>