diff options
author | guenther <> | 2017-09-05 02:40:54 +0000 |
---|---|---|
committer | guenther <> | 2017-09-05 02:40:54 +0000 |
commit | c1d0fec9b838e4df93e396d54f1e4b9a41f7401a (patch) | |
tree | 32e0f60be3ce027e6df050bdc53fc50cad03781e /src/lib | |
parent | ec1b9739d1881112264d7fe9aac0d7924e149b28 (diff) | |
download | openbsd-c1d0fec9b838e4df93e396d54f1e4b9a41f7401a.tar.gz openbsd-c1d0fec9b838e4df93e396d54f1e4b9a41f7401a.tar.bz2 openbsd-c1d0fec9b838e4df93e396d54f1e4b9a41f7401a.zip |
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@
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libc/include/cancel.h | 8 | ||||
-rw-r--r-- | src/lib/libc/include/thread_private.h | 185 |
2 files changed, 182 insertions, 11 deletions
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 @@ | |||
1 | /* $OpenBSD: cancel.h,v 1.4 2017/04/20 17:16:32 visa Exp $ */ | 1 | /* $OpenBSD: cancel.h,v 1.5 2017/09/05 02:40:54 guenther Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org> | 3 | * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org> |
4 | * | 4 | * |
@@ -21,10 +21,12 @@ | |||
21 | #include <tib.h> | 21 | #include <tib.h> |
22 | #include "thread_private.h" | 22 | #include "thread_private.h" |
23 | 23 | ||
24 | __BEGIN_HIDDEN_DECLS | ||
25 | /* process a cancel request at a cancel point */ | 24 | /* process a cancel request at a cancel point */ |
26 | __dead void _thread_canceled(void); | 25 | __dead void _thread_canceled(void); |
27 | __END_HIDDEN_DECLS | 26 | |
27 | #ifdef __LIBC__ | ||
28 | PROTO_NORMAL(_thread_canceled); | ||
29 | #endif | ||
28 | 30 | ||
29 | #if defined(__LIBC__) && !defined(TCB_HAVE_MD_GET) | 31 | #if defined(__LIBC__) && !defined(TCB_HAVE_MD_GET) |
30 | /* | 32 | /* |
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 @@ | |||
1 | /* $OpenBSD: thread_private.h,v 1.29 2016/10/15 18:24:40 guenther Exp $ */ | 1 | /* $OpenBSD: thread_private.h,v 1.30 2017/09/05 02:40:54 guenther Exp $ */ |
2 | 2 | ||
3 | /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ | 3 | /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ |
4 | 4 | ||
@@ -57,7 +57,13 @@ PROTO_NORMAL(_malloc_init); | |||
57 | * If not NULL, they are called instead of the syscall stub, so that | 57 | * If not NULL, they are called instead of the syscall stub, so that |
58 | * the thread library can do necessary locking and reinitialization. | 58 | * the thread library can do necessary locking and reinitialization. |
59 | * | 59 | * |
60 | * tc_thread_release: | ||
61 | * Handles the release of a thread's TIB and struct pthread and the | ||
62 | * notification of other threads...when there are other threads. | ||
60 | * | 63 | * |
64 | * tc_thread_key_zero: | ||
65 | * For each thread, zero out the key data associated with the given key. | ||
66 | |||
61 | * If <machine/tcb.h> doesn't define TCB_GET(), then locating the TCB in a | 67 | * If <machine/tcb.h> doesn't define TCB_GET(), then locating the TCB in a |
62 | * threaded process requires a syscall (__get_tcb(2)) which is too much | 68 | * threaded process requires a syscall (__get_tcb(2)) which is too much |
63 | * overhead for single-threaded processes. For those archs, there are two | 69 | * overhead for single-threaded processes. For those archs, there are two |
@@ -71,6 +77,7 @@ PROTO_NORMAL(_malloc_init); | |||
71 | * Returns the address of the thread's TCB. | 77 | * Returns the address of the thread's TCB. |
72 | */ | 78 | */ |
73 | 79 | ||
80 | struct pthread; | ||
74 | struct thread_callbacks { | 81 | struct thread_callbacks { |
75 | int *(*tc_errnoptr)(void); /* MUST BE FIRST */ | 82 | int *(*tc_errnoptr)(void); /* MUST BE FIRST */ |
76 | void *(*tc_tcb)(void); | 83 | void *(*tc_tcb)(void); |
@@ -94,6 +101,8 @@ struct thread_callbacks { | |||
94 | void *(*tc_tag_storage)(void **, void *, size_t, void *); | 101 | void *(*tc_tag_storage)(void **, void *, size_t, void *); |
95 | __pid_t (*tc_fork)(void); | 102 | __pid_t (*tc_fork)(void); |
96 | __pid_t (*tc_vfork)(void); | 103 | __pid_t (*tc_vfork)(void); |
104 | void (*tc_thread_release)(struct pthread *); | ||
105 | void (*tc_thread_key_zero)(int); | ||
97 | }; | 106 | }; |
98 | 107 | ||
99 | __BEGIN_PUBLIC_DECLS | 108 | __BEGIN_PUBLIC_DECLS |
@@ -116,13 +125,6 @@ __END_HIDDEN_DECLS | |||
116 | #define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name) | 125 | #define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name) |
117 | 126 | ||
118 | /* | 127 | /* |
119 | * Resolver code is special cased in that it uses global keys. | ||
120 | */ | ||
121 | extern void *__THREAD_NAME(_res); | ||
122 | extern void *__THREAD_NAME(_res_ext); | ||
123 | extern void *__THREAD_NAME(serv_mutex); | ||
124 | |||
125 | /* | ||
126 | * Macros used in libc to access thread mutex, keys, and per thread storage. | 128 | * Macros used in libc to access thread mutex, keys, and per thread storage. |
127 | * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for | 129 | * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for |
128 | * historical reasons. They do the same thing, define a static variable | 130 | * historical reasons. They do the same thing, define a static variable |
@@ -235,4 +237,171 @@ extern void *__THREAD_NAME(serv_mutex); | |||
235 | } while (0) | 237 | } while (0) |
236 | #endif /* __LIBC__ */ | 238 | #endif /* __LIBC__ */ |
237 | 239 | ||
240 | |||
241 | /* | ||
242 | * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> | ||
243 | * All Rights Reserved. | ||
244 | * | ||
245 | * Permission to use, copy, modify, and distribute this software for any | ||
246 | * purpose with or without fee is hereby granted, provided that the above | ||
247 | * copyright notice and this permission notice appear in all copies. | ||
248 | * | ||
249 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
250 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
251 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
252 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
253 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
254 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
255 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
256 | */ | ||
257 | /* | ||
258 | * Private data structures that back up the typedefs in pthread.h. | ||
259 | * Since only the thread library cares about their size or arrangement, | ||
260 | * it should be possible to switch libraries without relinking. | ||
261 | * | ||
262 | * Do not reorder _atomic_lock_t and sem_t variables in the structs. | ||
263 | * This is due to alignment requirements of certain arches like hppa. | ||
264 | * The current requirement is 16 bytes. | ||
265 | * | ||
266 | * THE MACHINE DEPENDENT CERROR CODE HAS HARD CODED OFFSETS INTO PTHREAD_T! | ||
267 | */ | ||
268 | |||
269 | #include <sys/queue.h> | ||
270 | #include <pthread.h> | ||
271 | #include <semaphore.h> | ||
272 | #include <machine/spinlock.h> | ||
273 | |||
274 | #define _SPINLOCK_UNLOCKED _ATOMIC_LOCK_UNLOCKED | ||
275 | |||
276 | struct __sem { | ||
277 | _atomic_lock_t lock; | ||
278 | volatile int waitcount; | ||
279 | volatile int value; | ||
280 | int shared; | ||
281 | }; | ||
282 | |||
283 | TAILQ_HEAD(pthread_queue, pthread); | ||
284 | |||
285 | #ifdef FUTEX | ||
286 | |||
287 | struct pthread_mutex { | ||
288 | volatile unsigned int lock; | ||
289 | int type; | ||
290 | pthread_t owner; | ||
291 | int count; | ||
292 | int prioceiling; | ||
293 | }; | ||
294 | |||
295 | struct pthread_cond { | ||
296 | volatile unsigned int seq; | ||
297 | clockid_t clock; | ||
298 | struct pthread_mutex *mutex; | ||
299 | }; | ||
300 | |||
301 | #else | ||
302 | |||
303 | struct pthread_mutex { | ||
304 | _atomic_lock_t lock; | ||
305 | struct pthread_queue lockers; | ||
306 | int type; | ||
307 | pthread_t owner; | ||
308 | int count; | ||
309 | int prioceiling; | ||
310 | }; | ||
311 | |||
312 | struct pthread_cond { | ||
313 | _atomic_lock_t lock; | ||
314 | struct pthread_queue waiters; | ||
315 | struct pthread_mutex *mutex; | ||
316 | clockid_t clock; | ||
317 | }; | ||
318 | #endif /* FUTEX */ | ||
319 | |||
320 | struct pthread_mutex_attr { | ||
321 | int ma_type; | ||
322 | int ma_protocol; | ||
323 | int ma_prioceiling; | ||
324 | }; | ||
325 | |||
326 | struct pthread_cond_attr { | ||
327 | clockid_t ca_clock; | ||
328 | }; | ||
329 | |||
330 | struct pthread_attr { | ||
331 | void *stack_addr; | ||
332 | size_t stack_size; | ||
333 | size_t guard_size; | ||
334 | int detach_state; | ||
335 | int contention_scope; | ||
336 | int sched_policy; | ||
337 | struct sched_param sched_param; | ||
338 | int sched_inherit; | ||
339 | }; | ||
340 | |||
341 | struct rthread_storage { | ||
342 | int keyid; | ||
343 | struct rthread_storage *next; | ||
344 | void *data; | ||
345 | }; | ||
346 | |||
347 | struct rthread_cleanup_fn { | ||
348 | void (*fn)(void *); | ||
349 | void *arg; | ||
350 | struct rthread_cleanup_fn *next; | ||
351 | }; | ||
352 | |||
353 | struct tib; | ||
354 | struct stack; | ||
355 | struct pthread { | ||
356 | struct __sem donesem; | ||
357 | unsigned int flags; | ||
358 | _atomic_lock_t flags_lock; | ||
359 | struct tib *tib; | ||
360 | void *retval; | ||
361 | void *(*fn)(void *); | ||
362 | void *arg; | ||
363 | char name[32]; | ||
364 | struct stack *stack; | ||
365 | LIST_ENTRY(pthread) threads; | ||
366 | TAILQ_ENTRY(pthread) waiting; | ||
367 | pthread_cond_t blocking_cond; | ||
368 | struct pthread_attr attr; | ||
369 | struct rthread_storage *local_storage; | ||
370 | struct rthread_cleanup_fn *cleanup_fns; | ||
371 | |||
372 | /* cancel received in a delayed cancel block? */ | ||
373 | int delayed_cancel; | ||
374 | }; | ||
375 | /* flags in pthread->flags */ | ||
376 | #define THREAD_DONE 0x001 | ||
377 | #define THREAD_DETACHED 0x002 | ||
378 | |||
379 | /* flags in tib->tib_thread_flags */ | ||
380 | #define TIB_THREAD_ASYNC_CANCEL 0x001 | ||
381 | #define TIB_THREAD_INITIAL_STACK 0x002 /* has stack from exec */ | ||
382 | |||
383 | #define ENTER_DELAYED_CANCEL_POINT(tib, self) \ | ||
384 | (self)->delayed_cancel = 0; \ | ||
385 | ENTER_CANCEL_POINT_INNER(tib, 1, 1) | ||
386 | |||
387 | /* | ||
388 | * Internal functions exported from libc's thread bits for use by libpthread | ||
389 | */ | ||
390 | void _spinlock(volatile _atomic_lock_t *); | ||
391 | int _spinlocktry(volatile _atomic_lock_t *); | ||
392 | void _spinunlock(volatile _atomic_lock_t *); | ||
393 | |||
394 | void _rthread_debug(int, const char *, ...) | ||
395 | __attribute__((__format__ (printf, 2, 3))); | ||
396 | pid_t _thread_dofork(pid_t (*_sys_fork)(void)); | ||
397 | |||
398 | /* | ||
399 | * Threading syscalls not declared in system headers | ||
400 | */ | ||
401 | __dead void __threxit(pid_t *); | ||
402 | int __thrsleep(const volatile void *, clockid_t, | ||
403 | const struct timespec *, volatile void *, const int *); | ||
404 | int __thrwakeup(const volatile void *, int n); | ||
405 | int __thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); | ||
406 | |||
238 | #endif /* _THREAD_PRIVATE_H_ */ | 407 | #endif /* _THREAD_PRIVATE_H_ */ |