diff options
Diffstat (limited to '')
| -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_ */ |
