diff options
-rw-r--r-- | include/stdio.h | 3 | ||||
-rw-r--r-- | lib/libc/include/libc_private.h | 3 | ||||
-rw-r--r-- | lib/libthr/Makefile | 7 | ||||
-rw-r--r-- | lib/libthr/arch/aarch64/include/pthread_md.h | 2 | ||||
-rw-r--r-- | lib/libthr/arch/arm/include/pthread_md.h | 2 | ||||
-rw-r--r-- | lib/libthr/arch/mips/include/pthread_md.h | 2 | ||||
-rw-r--r-- | lib/libthr/arch/powerpc/include/pthread_md.h | 2 | ||||
-rw-r--r-- | lib/libthr/arch/riscv/include/pthread_md.h | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_attr.c | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_exit.c | 19 | ||||
-rw-r--r-- | lib/libthr/thread/thr_kern.c | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_list.c | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_mutex.c | 3 | ||||
-rw-r--r-- | lib/libthr/thread/thr_private.h | 41 | ||||
-rw-r--r-- | lib/libthr/thread/thr_rwlock.c | 71 | ||||
-rw-r--r-- | lib/libthr/thread/thr_sig.c | 6 | ||||
-rw-r--r-- | lib/libthr/thread/thr_spec.c | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_umtx.c | 2 | ||||
-rw-r--r-- | lib/libthr/thread/thr_umtx.h | 4 |
19 files changed, 109 insertions, 68 deletions
diff --git a/include/stdio.h b/include/stdio.h index 4c82f90..1ff9aca 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -499,7 +499,10 @@ static __inline int __sputc(int _c, FILE *_p) { (*(p)->_p = (c), (int)*(p)->_p++)) #endif +#ifndef __LIBC_ISTHREADED_DECLARED +#define __LIBC_ISTHREADED_DECLARED extern int __isthreaded; +#endif #ifndef __cplusplus diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 384f61f..2134f34 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -42,7 +42,10 @@ * or more threads. It is used to avoid calling locking functions * when they are not required. */ +#ifndef __LIBC_ISTHREADED_DECLARED +#define __LIBC_ISTHREADED_DECLARED extern int __isthreaded; +#endif /* * Elf_Auxinfo *__elf_aux_vector, the pointer to the ELF aux vector diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile index 5b3e3bf..60cb420 100644 --- a/lib/libthr/Makefile +++ b/lib/libthr/Makefile @@ -17,6 +17,7 @@ MK_SSP= no LIB=thr SHLIB_MAJOR= 3 WARNS?= 3 +NO_WTHREAD_SAFETY=1 CFLAGS+=-DPTHREAD_KERNEL CFLAGS+=-I${SRCTOP}/lib/libc/include -I${.CURDIR}/thread \ -I${SRCTOP}/include @@ -27,6 +28,12 @@ CFLAGS+=-I${SRCTOP}/libexec/rtld-elf/${MACHINE_CPUARCH} CFLAGS+=-I${SRCTOP}/lib/libthread_db CFLAGS+=-Winline +CFLAGS.thr_stack.c+= -Wno-cast-align +.include <bsd.compiler.mk> +.if !(${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} < 40300) +CFLAGS.thr_symbols.c+= -Wno-missing-variable-declarations +.endif + .ifndef NO_THREAD_UNWIND_STACK CFLAGS+=-fexceptions CFLAGS+=-D_PTHREAD_FORCED_UNWIND diff --git a/lib/libthr/arch/aarch64/include/pthread_md.h b/lib/libthr/arch/aarch64/include/pthread_md.h index 14c1893..d14bce2 100644 --- a/lib/libthr/arch/aarch64/include/pthread_md.h +++ b/lib/libthr/arch/aarch64/include/pthread_md.h @@ -72,8 +72,6 @@ _tcb_get(void) return (tcb); } -extern struct pthread *_thr_initial; - static __inline struct pthread * _get_curthread(void) { diff --git a/lib/libthr/arch/arm/include/pthread_md.h b/lib/libthr/arch/arm/include/pthread_md.h index 9a6b523..4ae7971 100644 --- a/lib/libthr/arch/arm/include/pthread_md.h +++ b/lib/libthr/arch/arm/include/pthread_md.h @@ -75,8 +75,6 @@ _tcb_get(void) #endif } -extern struct pthread *_thr_initial; - static __inline struct pthread * _get_curthread(void) { diff --git a/lib/libthr/arch/mips/include/pthread_md.h b/lib/libthr/arch/mips/include/pthread_md.h index 32af964..22aa3db 100644 --- a/lib/libthr/arch/mips/include/pthread_md.h +++ b/lib/libthr/arch/mips/include/pthread_md.h @@ -70,8 +70,6 @@ _tcb_get(void) return tcb; } -extern struct pthread *_thr_initial; - static __inline struct pthread * _get_curthread(void) { diff --git a/lib/libthr/arch/powerpc/include/pthread_md.h b/lib/libthr/arch/powerpc/include/pthread_md.h index 544ee1c..699233e 100644 --- a/lib/libthr/arch/powerpc/include/pthread_md.h +++ b/lib/libthr/arch/powerpc/include/pthread_md.h @@ -80,8 +80,6 @@ _tcb_get(void) return ((struct tcb *)(_tp - TP_OFFSET)); } -extern struct pthread *_thr_initial; - static __inline struct pthread * _get_curthread(void) { diff --git a/lib/libthr/arch/riscv/include/pthread_md.h b/lib/libthr/arch/riscv/include/pthread_md.h index 3f51078..499da5f 100644 --- a/lib/libthr/arch/riscv/include/pthread_md.h +++ b/lib/libthr/arch/riscv/include/pthread_md.h @@ -78,8 +78,6 @@ _tcb_get(void) return ((struct tcb *)(_tp - TP_OFFSET)); } -extern struct pthread *_thr_initial; - static __inline struct pthread * _get_curthread(void) { diff --git a/lib/libthr/thread/thr_attr.c b/lib/libthr/thread/thr_attr.c index ff9eb2d5..a790483 100644 --- a/lib/libthr/thread/thr_attr.c +++ b/lib/libthr/thread/thr_attr.c @@ -607,7 +607,7 @@ _pthread_attr_setaffinity_np(pthread_attr_t *pattr, size_t cpusetsize, /* Kernel checks invalid bits, we check it here too. */ size_t i; for (i = kern_size; i < cpusetsize; ++i) { - if (((char *)cpusetp)[i]) + if (((const char *)cpusetp)[i]) return (EINVAL); } } diff --git a/lib/libthr/thread/thr_exit.c b/lib/libthr/thread/thr_exit.c index a2d67de..1a34394 100644 --- a/lib/libthr/thread/thr_exit.c +++ b/lib/libthr/thread/thr_exit.c @@ -46,8 +46,6 @@ __FBSDID("$FreeBSD$"); #include "libc_private.h" #include "thr_private.h" -void _pthread_exit(void *status); - static void exit_thread(void) __dead2; __weak_reference(_pthread_exit, pthread_exit); @@ -72,7 +70,7 @@ static void thread_uw_init(void) { static int inited = 0; - Dl_info dlinfo; + Dl_info dli; void *handle; void *forcedunwind, *getcfa; @@ -80,12 +78,12 @@ thread_uw_init(void) return; handle = RTLD_DEFAULT; if ((forcedunwind = dlsym(handle, "_Unwind_ForcedUnwind")) != NULL) { - if (dladdr(forcedunwind, &dlinfo)) { + if (dladdr(forcedunwind, &dli)) { /* * Make sure the address is always valid by holding the library, * also assume functions are in same library. */ - if ((handle = dlopen(dlinfo.dli_fname, RTLD_LAZY)) != NULL) { + if ((handle = dlopen(dli.dli_fname, RTLD_LAZY)) != NULL) { forcedunwind = dlsym(handle, "_Unwind_ForcedUnwind"); getcfa = dlsym(handle, "_Unwind_GetCFA"); if (forcedunwind != NULL && getcfa != NULL) { @@ -119,7 +117,8 @@ _Unwind_GetCFA(struct _Unwind_Context *context) #endif /* PIC */ static void -thread_unwind_cleanup(_Unwind_Reason_Code code, struct _Unwind_Exception *e) +thread_unwind_cleanup(_Unwind_Reason_Code code __unused, + struct _Unwind_Exception *e __unused) { /* * Specification said that _Unwind_Resume should not be used here, @@ -130,10 +129,10 @@ thread_unwind_cleanup(_Unwind_Reason_Code code, struct _Unwind_Exception *e) } static _Unwind_Reason_Code -thread_unwind_stop(int version, _Unwind_Action actions, - int64_t exc_class, - struct _Unwind_Exception *exc_obj, - struct _Unwind_Context *context, void *stop_parameter) +thread_unwind_stop(int version __unused, _Unwind_Action actions, + int64_t exc_class __unused, + struct _Unwind_Exception *exc_obj __unused, + struct _Unwind_Context *context, void *stop_parameter __unused) { struct pthread *curthread = _get_curthread(); struct pthread_cleanup *cur; diff --git a/lib/libthr/thread/thr_kern.c b/lib/libthr/thread/thr_kern.c index 6463f1d..64128b4 100644 --- a/lib/libthr/thread/thr_kern.c +++ b/lib/libthr/thread/thr_kern.c @@ -62,7 +62,7 @@ _thr_setthreaded(int threaded) } void -_thr_assert_lock_level() +_thr_assert_lock_level(void) { PANIC("locklevel <= 0"); } diff --git a/lib/libthr/thread/thr_list.c b/lib/libthr/thread/thr_list.c index ae1f124..70b85bc 100644 --- a/lib/libthr/thread/thr_list.c +++ b/lib/libthr/thread/thr_list.c @@ -35,8 +35,8 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <pthread.h> -#include "thr_private.h" #include "libc_private.h" +#include "thr_private.h" /*#define DEBUG_THREAD_LIST */ #ifdef DEBUG_THREAD_LIST diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c index 877bd37..4ab7720 100644 --- a/lib/libthr/thread/thr_mutex.c +++ b/lib/libthr/thread/thr_mutex.c @@ -70,8 +70,6 @@ int __pthread_mutex_trylock(pthread_mutex_t *mutex); int __pthread_mutex_lock(pthread_mutex_t *mutex); int __pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime); -int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, - void *(calloc_cb)(size_t, size_t)); int _pthread_mutex_getspinloops_np(pthread_mutex_t *mutex, int *count); int _pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count); int __pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count); @@ -712,6 +710,7 @@ mutex_lock_common(struct pthread_mutex *m, const struct timespec *abstime, struct pthread *curthread; int ret, robust; + robust = 0; /* pacify gcc */ curthread = _get_curthread(); if (!cvattach && m->m_flags & PMUTEX_FLAG_PRIVATE) THR_CRITICAL_ENTER(curthread); diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index 56ecdb4..4c9245e 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -69,6 +69,9 @@ __NULLABILITY_PRAGMA_PUSH WEAK_REF(func, SYM_FBP10(sym)); \ SYM_DEFAULT(sym, SYM_FBP10(sym), FBSDprivate_1.0) +struct pthread; +extern struct pthread *_thr_initial __hidden; + #include "pthread_md.h" #include "thr_umtx.h" #include "thread_db.h" @@ -701,14 +704,16 @@ do { \ (curthr->report_events && \ (((curthr)->event_mask | _thread_event_mask ) & e) != 0) +#ifndef __LIBC_ISTHREADED_DECLARED +#define __LIBC_ISTHREADED_DECLARED extern int __isthreaded; +#endif /* * Global variables for the pthread kernel. */ extern char *_usrstack __hidden; -extern struct pthread *_thr_initial __hidden; /* For debugger */ extern int _libthr_debug; @@ -835,8 +840,10 @@ int _sched_yield(void); void _pthread_cleanup_push(void (*)(void *), void *); void _pthread_cleanup_pop(int); void _pthread_exit_mask(void *status, sigset_t *mask) __dead2 __hidden; +#ifndef _LIBC_PRIVATE_H_ void _pthread_cancel_enter(int maycancel); void _pthread_cancel_leave(int maycancel); +#endif int _pthread_mutex_consistent(pthread_mutex_t * _Nonnull); int _pthread_mutexattr_getrobust(pthread_mutexattr_t * _Nonnull __restrict, int * _Nonnull __restrict); @@ -844,46 +851,56 @@ 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, ...); -#endif +#endif /* _LIBC_PRIVATE_H_ */ +#endif /* _SYS_FCNTL_H_ */ /* #include <signal.h> */ #ifdef _SIGNAL_H_ int __sys_kill(pid_t, int); -int __sys_sigaction(int, const struct sigaction *, struct sigaction *); +int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); int __sys_sigpending(sigset_t *); +int __sys_sigreturn(const ucontext_t *); +#ifndef _LIBC_PRIVATE_H_ +int __sys_sigaction(int, const struct sigaction *, struct sigaction *); int __sys_sigprocmask(int, const sigset_t *, sigset_t *); int __sys_sigsuspend(const sigset_t *); -int __sys_sigreturn(const ucontext_t *); -int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); -int __sys_sigwait(const sigset_t *, int *); int __sys_sigtimedwait(const sigset_t *, siginfo_t *, const struct timespec *); +int __sys_sigwait(const sigset_t *, int *); int __sys_sigwaitinfo(const sigset_t *set, siginfo_t *info); -#endif +#endif /* _LIBC_PRIVATE_H_ */ +#endif /* _SYS_FCNTL_H_ */ /* #include <time.h> */ #ifdef _TIME_H_ +#ifndef _LIBC_PRIVATE_H_ int __sys_clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *); int __sys_nanosleep(const struct timespec *, struct timespec *); -#endif +#endif /* _LIBC_PRIVATE_H_ */ +#endif /* _SYS_FCNTL_H_ */ /* #include <sys/ucontext.h> */ #ifdef _SYS_UCONTEXT_H_ +#ifndef _LIBC_PRIVATE_H_ int __sys_setcontext(const ucontext_t *ucp); int __sys_swapcontext(ucontext_t *oucp, const ucontext_t *ucp); -#endif +#endif /* _LIBC_PRIVATE_H_ */ +#endif /* _SYS_FCNTL_H_ */ /* #include <unistd.h> */ #ifdef _UNISTD_H_ +void __sys_exit(int); +pid_t __sys_getpid(void); +#ifndef _LIBC_PRIVATE_H_ int __sys_close(int); int __sys_fork(void); -pid_t __sys_getpid(void); ssize_t __sys_read(int, void *, size_t); -void __sys_exit(int); -#endif +#endif /* _LIBC_PRIVATE_H_ */ +#endif /* _SYS_FCNTL_H_ */ static inline int _thr_isthreaded(void) diff --git a/lib/libthr/thread/thr_rwlock.c b/lib/libthr/thread/thr_rwlock.c index 748eb52..105b35c 100644 --- a/lib/libthr/thread/thr_rwlock.c +++ b/lib/libthr/thread/thr_rwlock.c @@ -49,27 +49,42 @@ __weak_reference(_pthread_rwlock_unlock, pthread_rwlock_unlock); __weak_reference(_pthread_rwlock_wrlock, pthread_rwlock_wrlock); __weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock); -#define CHECK_AND_INIT_RWLOCK \ - if (*rwlock == THR_PSHARED_PTR) { \ - prwlock = __thr_pshared_offpage(rwlock, 0); \ - if (prwlock == NULL) \ - return (EINVAL); \ - } else if (__predict_false((prwlock = (*rwlock)) <= \ - THR_RWLOCK_DESTROYED)) { \ - if (prwlock == THR_RWLOCK_INITIALIZER) { \ - int ret; \ - ret = init_static(_get_curthread(), rwlock); \ - if (ret) \ - return (ret); \ - } else if (prwlock == THR_RWLOCK_DESTROYED) { \ - return (EINVAL); \ - } \ - prwlock = *rwlock; \ - } +static int init_static(struct pthread *thread, pthread_rwlock_t *rwlock); +static int init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out); -/* - * Prototypes - */ +static int __always_inline +check_and_init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out) +{ + if (__predict_false(*rwlock == THR_PSHARED_PTR || + *rwlock <= THR_RWLOCK_DESTROYED)) + return (init_rwlock(rwlock, rwlock_out)); + *rwlock_out = *rwlock; + return (0); +} + +static int __noinline +init_rwlock(pthread_rwlock_t *rwlock, pthread_rwlock_t *rwlock_out) +{ + pthread_rwlock_t prwlock; + int ret; + + if (*rwlock == THR_PSHARED_PTR) { + prwlock = __thr_pshared_offpage(rwlock, 0); + if (prwlock == NULL) + return (EINVAL); + } else if ((prwlock = *rwlock) <= THR_RWLOCK_DESTROYED) { + if (prwlock == THR_RWLOCK_INITIALIZER) { + ret = init_static(_get_curthread(), rwlock); + if (ret != 0) + return (ret); + } else if (prwlock == THR_RWLOCK_DESTROYED) { + return (EINVAL); + } + prwlock = *rwlock; + } + *rwlock_out = prwlock; + return (0); +} static int rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) @@ -148,7 +163,9 @@ rwlock_rdlock_common(pthread_rwlock_t *rwlock, const struct timespec *abstime) int flags; int ret; - CHECK_AND_INIT_RWLOCK + ret = check_and_init_rwlock(rwlock, &prwlock); + if (ret != 0) + return (ret); if (curthread->rdlock_count) { /* @@ -220,7 +237,9 @@ _pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock) int flags; int ret; - CHECK_AND_INIT_RWLOCK + ret = check_and_init_rwlock(rwlock, &prwlock); + if (ret != 0) + return (ret); if (curthread->rdlock_count) { /* @@ -253,7 +272,9 @@ _pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) pthread_rwlock_t prwlock; int ret; - CHECK_AND_INIT_RWLOCK + ret = check_and_init_rwlock(rwlock, &prwlock); + if (ret != 0) + return (ret); ret = _thr_rwlock_trywrlock(&prwlock->lock); if (ret == 0) @@ -268,7 +289,9 @@ rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime) pthread_rwlock_t prwlock; int ret; - CHECK_AND_INIT_RWLOCK + ret = check_and_init_rwlock(rwlock, &prwlock); + if (ret != 0) + return (ret); /* * POSIX said the validity of the abstimeout parameter need diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c index 8241539..978ae61 100644 --- a/lib/libthr/thread/thr_sig.c +++ b/lib/libthr/thread/thr_sig.c @@ -441,7 +441,7 @@ _thr_signal_init(int dlopened) } void -_thr_sigact_unload(struct dl_phdr_info *phdr_info) +_thr_sigact_unload(struct dl_phdr_info *phdr_info __unused) { #if 0 struct pthread *curthread = _get_curthread(); @@ -736,8 +736,8 @@ __thr_setcontext(const ucontext_t *ucp) errno = EINVAL; return (-1); } - if (!SIGISMEMBER(uc.uc_sigmask, SIGCANCEL)) - return __sys_setcontext(ucp); + if (!SIGISMEMBER(ucp->uc_sigmask, SIGCANCEL)) + return (__sys_setcontext(ucp)); (void) memcpy(&uc, ucp, sizeof(uc)); SIGDELSET(uc.uc_sigmask, SIGCANCEL); return (__sys_setcontext(&uc)); diff --git a/lib/libthr/thread/thr_spec.c b/lib/libthr/thread/thr_spec.c index 46d4ddf..303e34e 100644 --- a/lib/libthr/thread/thr_spec.c +++ b/lib/libthr/thread/thr_spec.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); #include "thr_private.h" -struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX]; +static struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX]; __weak_reference(_pthread_key_create, pthread_key_create); __weak_reference(_pthread_key_delete, pthread_key_delete); diff --git a/lib/libthr/thread/thr_umtx.c b/lib/libthr/thread/thr_umtx.c index cd2b101..085e04e 100644 --- a/lib/libthr/thread/thr_umtx.c +++ b/lib/libthr/thread/thr_umtx.c @@ -168,7 +168,7 @@ __thr_umutex_timedlock(struct umutex *mtx, uint32_t id, } int -__thr_umutex_unlock(struct umutex *mtx, uint32_t id) +__thr_umutex_unlock(struct umutex *mtx) { return (_umtx_op_err(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0)); diff --git a/lib/libthr/thread/thr_umtx.h b/lib/libthr/thread/thr_umtx.h index fff8729..5dae304 100644 --- a/lib/libthr/thread/thr_umtx.h +++ b/lib/libthr/thread/thr_umtx.h @@ -44,7 +44,7 @@ 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, const struct timespec *timeout) __hidden; -int __thr_umutex_unlock(struct umutex *mtx, uint32_t id) __hidden; +int __thr_umutex_unlock(struct umutex *mtx) __hidden; int __thr_umutex_trylock(struct umutex *mtx) __hidden; int __thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling, uint32_t *oldceiling) __hidden; @@ -155,7 +155,7 @@ _thr_umutex_unlock2(struct umutex *mtx, uint32_t id, int *defer) if (atomic_cmpset_rel_32(&mtx->m_owner, id, noncst ? UMUTEX_RB_NOTRECOV : UMUTEX_UNOWNED)) return (0); - return (__thr_umutex_unlock(mtx, id)); + return (__thr_umutex_unlock(mtx)); } do { |