From c1d0fec9b838e4df93e396d54f1e4b9a41f7401a Mon Sep 17 00:00:00 2001 From: guenther <> Date: Tue, 5 Sep 2017 02:40:54 +0000 Subject: Move mutex, condvar, and thread-specific data routes, pthread_once, and pthread_exit from libpthread to libc, along with low-level bits to support them. Major bump to both libc and libpthread. Requested by libressl team. Ports testing by naddy@ ok kettenis@ --- src/lib/libc/include/cancel.h | 8 +- src/lib/libc/include/thread_private.h | 185 ++++++++++++++++++++++++++++++++-- 2 files changed, 182 insertions(+), 11 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libc/include/cancel.h b/src/lib/libc/include/cancel.h index 2c87be39e3..c452bf3d4c 100644 --- a/src/lib/libc/include/cancel.h +++ b/src/lib/libc/include/cancel.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cancel.h,v 1.4 2017/04/20 17:16:32 visa Exp $ */ +/* $OpenBSD: cancel.h,v 1.5 2017/09/05 02:40:54 guenther Exp $ */ /* * Copyright (c) 2015 Philip Guenther * @@ -21,10 +21,12 @@ #include #include "thread_private.h" -__BEGIN_HIDDEN_DECLS /* process a cancel request at a cancel point */ __dead void _thread_canceled(void); -__END_HIDDEN_DECLS + +#ifdef __LIBC__ +PROTO_NORMAL(_thread_canceled); +#endif #if defined(__LIBC__) && !defined(TCB_HAVE_MD_GET) /* diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h index b443e32e83..23faa73faa 100644 --- a/src/lib/libc/include/thread_private.h +++ b/src/lib/libc/include/thread_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: thread_private.h,v 1.29 2016/10/15 18:24:40 guenther Exp $ */ +/* $OpenBSD: thread_private.h,v 1.30 2017/09/05 02:40:54 guenther Exp $ */ /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman */ @@ -57,7 +57,13 @@ PROTO_NORMAL(_malloc_init); * If not NULL, they are called instead of the syscall stub, so that * the thread library can do necessary locking and reinitialization. * + * tc_thread_release: + * Handles the release of a thread's TIB and struct pthread and the + * notification of other threads...when there are other threads. * + * tc_thread_key_zero: + * For each thread, zero out the key data associated with the given key. + * If doesn't define TCB_GET(), then locating the TCB in a * threaded process requires a syscall (__get_tcb(2)) which is too much * overhead for single-threaded processes. For those archs, there are two @@ -71,6 +77,7 @@ PROTO_NORMAL(_malloc_init); * Returns the address of the thread's TCB. */ +struct pthread; struct thread_callbacks { int *(*tc_errnoptr)(void); /* MUST BE FIRST */ void *(*tc_tcb)(void); @@ -94,6 +101,8 @@ struct thread_callbacks { void *(*tc_tag_storage)(void **, void *, size_t, void *); __pid_t (*tc_fork)(void); __pid_t (*tc_vfork)(void); + void (*tc_thread_release)(struct pthread *); + void (*tc_thread_key_zero)(int); }; __BEGIN_PUBLIC_DECLS @@ -115,13 +124,6 @@ __END_HIDDEN_DECLS */ #define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name) -/* - * Resolver code is special cased in that it uses global keys. - */ -extern void *__THREAD_NAME(_res); -extern void *__THREAD_NAME(_res_ext); -extern void *__THREAD_NAME(serv_mutex); - /* * Macros used in libc to access thread mutex, keys, and per thread storage. * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for @@ -235,4 +237,171 @@ extern void *__THREAD_NAME(serv_mutex); } while (0) #endif /* __LIBC__ */ + +/* + * Copyright (c) 2004,2005 Ted Unangst + * All Rights Reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Private data structures that back up the typedefs in pthread.h. + * Since only the thread library cares about their size or arrangement, + * it should be possible to switch libraries without relinking. + * + * Do not reorder _atomic_lock_t and sem_t variables in the structs. + * This is due to alignment requirements of certain arches like hppa. + * The current requirement is 16 bytes. + * + * THE MACHINE DEPENDENT CERROR CODE HAS HARD CODED OFFSETS INTO PTHREAD_T! + */ + +#include +#include +#include +#include + +#define _SPINLOCK_UNLOCKED _ATOMIC_LOCK_UNLOCKED + +struct __sem { + _atomic_lock_t lock; + volatile int waitcount; + volatile int value; + int shared; +}; + +TAILQ_HEAD(pthread_queue, pthread); + +#ifdef FUTEX + +struct pthread_mutex { + volatile unsigned int lock; + int type; + pthread_t owner; + int count; + int prioceiling; +}; + +struct pthread_cond { + volatile unsigned int seq; + clockid_t clock; + struct pthread_mutex *mutex; +}; + +#else + +struct pthread_mutex { + _atomic_lock_t lock; + struct pthread_queue lockers; + int type; + pthread_t owner; + int count; + int prioceiling; +}; + +struct pthread_cond { + _atomic_lock_t lock; + struct pthread_queue waiters; + struct pthread_mutex *mutex; + clockid_t clock; +}; +#endif /* FUTEX */ + +struct pthread_mutex_attr { + int ma_type; + int ma_protocol; + int ma_prioceiling; +}; + +struct pthread_cond_attr { + clockid_t ca_clock; +}; + +struct pthread_attr { + void *stack_addr; + size_t stack_size; + size_t guard_size; + int detach_state; + int contention_scope; + int sched_policy; + struct sched_param sched_param; + int sched_inherit; +}; + +struct rthread_storage { + int keyid; + struct rthread_storage *next; + void *data; +}; + +struct rthread_cleanup_fn { + void (*fn)(void *); + void *arg; + struct rthread_cleanup_fn *next; +}; + +struct tib; +struct stack; +struct pthread { + struct __sem donesem; + unsigned int flags; + _atomic_lock_t flags_lock; + struct tib *tib; + void *retval; + void *(*fn)(void *); + void *arg; + char name[32]; + struct stack *stack; + LIST_ENTRY(pthread) threads; + TAILQ_ENTRY(pthread) waiting; + pthread_cond_t blocking_cond; + struct pthread_attr attr; + struct rthread_storage *local_storage; + struct rthread_cleanup_fn *cleanup_fns; + + /* cancel received in a delayed cancel block? */ + int delayed_cancel; +}; +/* flags in pthread->flags */ +#define THREAD_DONE 0x001 +#define THREAD_DETACHED 0x002 + +/* flags in tib->tib_thread_flags */ +#define TIB_THREAD_ASYNC_CANCEL 0x001 +#define TIB_THREAD_INITIAL_STACK 0x002 /* has stack from exec */ + +#define ENTER_DELAYED_CANCEL_POINT(tib, self) \ + (self)->delayed_cancel = 0; \ + ENTER_CANCEL_POINT_INNER(tib, 1, 1) + +/* + * Internal functions exported from libc's thread bits for use by libpthread + */ +void _spinlock(volatile _atomic_lock_t *); +int _spinlocktry(volatile _atomic_lock_t *); +void _spinunlock(volatile _atomic_lock_t *); + +void _rthread_debug(int, const char *, ...) + __attribute__((__format__ (printf, 2, 3))); +pid_t _thread_dofork(pid_t (*_sys_fork)(void)); + +/* + * Threading syscalls not declared in system headers + */ +__dead void __threxit(pid_t *); +int __thrsleep(const volatile void *, clockid_t, + const struct timespec *, volatile void *, const int *); +int __thrwakeup(const volatile void *, int n); +int __thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); + #endif /* _THREAD_PRIVATE_H_ */ -- cgit v1.2.3-55-g6feb