summaryrefslogtreecommitdiff
path: root/src/lib/libc/include/thread_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/include/thread_private.h')
-rw-r--r--src/lib/libc/include/thread_private.h427
1 files changed, 0 insertions, 427 deletions
diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h
deleted file mode 100644
index 1ec1071161..0000000000
--- a/src/lib/libc/include/thread_private.h
+++ /dev/null
@@ -1,427 +0,0 @@
1/* $OpenBSD: thread_private.h,v 1.37 2024/08/18 02:25:51 guenther Exp $ */
2
3/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
4
5#ifndef _THREAD_PRIVATE_H_
6#define _THREAD_PRIVATE_H_
7
8extern int __isthreaded;
9
10#define _MALLOC_MUTEXES 32
11void _malloc_init(int);
12#ifdef __LIBC__
13PROTO_NORMAL(_malloc_init);
14#endif /* __LIBC__ */
15
16/*
17 * The callbacks needed by libc to handle the threaded case.
18 * NOTE: Bump the version when you change the struct contents!
19 *
20 * tc_canceled:
21 * If not NULL, what to do when canceled (otherwise _exit(0))
22 *
23 * tc_flockfile, tc_ftrylockfile, and tc_funlockfile:
24 * If not NULL, these implement the flockfile() family.
25 * XXX In theory, you should be able to lock a FILE before
26 * XXX loading libpthread and have that be a real lock on it,
27 * XXX but that doesn't work without the libc base version
28 * XXX tracking the recursion count.
29 *
30 * tc_malloc_lock and tc_malloc_unlock:
31 * tc_atexit_lock and tc_atexit_unlock:
32 * tc_atfork_lock and tc_atfork_unlock:
33 * tc_arc4_lock and tc_arc4_unlock:
34 * The locks used by the malloc, atexit, atfork, and arc4 subsystems.
35 * These have to be ordered specially in the fork/vfork wrappers
36 * and may be implemented differently than the general mutexes
37 * in the callbacks below.
38 *
39 * tc_mutex_lock and tc_mutex_unlock:
40 * Lock and unlock the given mutex. If the given mutex is NULL
41 * a mutex is allocated and initialized automatically.
42 *
43 * tc_mutex_destroy:
44 * Destroy/deallocate the given mutex.
45 *
46 * tc_tag_lock and tc_tag_unlock:
47 * Lock and unlock the mutex associated with the given tag.
48 * If the given tag is NULL a tag is allocated and initialized
49 * automatically.
50 *
51 * tc_tag_storage:
52 * Returns a pointer to per-thread instance of data associated
53 * with the given tag. If the given tag is NULL a tag is
54 * allocated and initialized automatically.
55 *
56 * tc_fork, tc_vfork:
57 * If not NULL, they are called instead of the syscall stub, so that
58 * the thread library can do necessary locking and reinitialization.
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.
63 *
64 * tc_thread_key_zero:
65 * For each thread, zero out the key data associated with the given key.
66
67 * If <machine/tcb.h> doesn't define TCB_GET(), then locating the TCB in a
68 * threaded process requires a syscall (__get_tcb(2)) which is too much
69 * overhead for single-threaded processes. For those archs, there are two
70 * additional callbacks, though they are placed first in the struct for
71 * convenience in ASM:
72 *
73 * tc_errnoptr:
74 * Returns the address of the thread's errno.
75 *
76 * tc_tcb:
77 * Returns the address of the thread's TCB.
78 */
79
80struct __sFILE;
81struct pthread;
82struct thread_callbacks {
83 int *(*tc_errnoptr)(void); /* MUST BE FIRST */
84 void *(*tc_tcb)(void);
85 __dead void (*tc_canceled)(void);
86 void (*tc_flockfile)(struct __sFILE *);
87 int (*tc_ftrylockfile)(struct __sFILE *);
88 void (*tc_funlockfile)(struct __sFILE *);
89 void (*tc_malloc_lock)(int);
90 void (*tc_malloc_unlock)(int);
91 void (*tc_atexit_lock)(void);
92 void (*tc_atexit_unlock)(void);
93 void (*tc_atfork_lock)(void);
94 void (*tc_atfork_unlock)(void);
95 void (*tc_arc4_lock)(void);
96 void (*tc_arc4_unlock)(void);
97 void (*tc_mutex_lock)(void **);
98 void (*tc_mutex_unlock)(void **);
99 void (*tc_mutex_destroy)(void **);
100 void (*tc_tag_lock)(void **);
101 void (*tc_tag_unlock)(void **);
102 void *(*tc_tag_storage)(void **, void *, size_t, void (*)(void *),
103 void *);
104 __pid_t (*tc_fork)(void);
105 __pid_t (*tc_vfork)(void);
106 void (*tc_thread_release)(struct pthread *);
107 void (*tc_thread_key_zero)(int);
108};
109
110__BEGIN_PUBLIC_DECLS
111/*
112 * Set the callbacks used by libc
113 */
114void _thread_set_callbacks(const struct thread_callbacks *_cb, size_t _len);
115__END_PUBLIC_DECLS
116
117#ifdef __LIBC__
118__BEGIN_HIDDEN_DECLS
119/* the current set */
120extern struct thread_callbacks _thread_cb;
121__END_HIDDEN_DECLS
122#endif /* __LIBC__ */
123
124/*
125 * helper macro to make unique names in the thread namespace
126 */
127#define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name)
128
129/*
130 * Macros used in libc to access thread mutex, keys, and per thread storage.
131 * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for
132 * historical reasons. They do the same thing, define a static variable
133 * keyed by 'name' that identifies a mutex and a key to identify per thread
134 * data.
135 */
136#define _THREAD_PRIVATE_KEY(name) \
137 static void *__THREAD_NAME(name)
138#define _THREAD_PRIVATE_MUTEX(name) \
139 static void *__THREAD_NAME(name)
140
141
142#ifndef __LIBC__ /* building some sort of reach around */
143
144#define _THREAD_PRIVATE_MUTEX_LOCK(name) do {} while (0)
145#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) do {} while (0)
146#define _THREAD_PRIVATE(keyname, storage, error) &(storage)
147#define _THREAD_PRIVATE_DT(keyname, storage, dt, error) &(storage)
148#define _MUTEX_LOCK(mutex) do {} while (0)
149#define _MUTEX_UNLOCK(mutex) do {} while (0)
150#define _MUTEX_DESTROY(mutex) do {} while (0)
151#define _MALLOC_LOCK(n) do {} while (0)
152#define _MALLOC_UNLOCK(n) do {} while (0)
153#define _ATEXIT_LOCK() do {} while (0)
154#define _ATEXIT_UNLOCK() do {} while (0)
155#define _ATFORK_LOCK() do {} while (0)
156#define _ATFORK_UNLOCK() do {} while (0)
157#define _ARC4_LOCK() do {} while (0)
158#define _ARC4_UNLOCK() do {} while (0)
159
160#else /* building libc */
161#define _THREAD_PRIVATE_MUTEX_LOCK(name) \
162 do { \
163 if (_thread_cb.tc_tag_lock != NULL) \
164 _thread_cb.tc_tag_lock(&(__THREAD_NAME(name))); \
165 } while (0)
166#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \
167 do { \
168 if (_thread_cb.tc_tag_unlock != NULL) \
169 _thread_cb.tc_tag_unlock(&(__THREAD_NAME(name))); \
170 } while (0)
171#define _THREAD_PRIVATE(keyname, storage, error) \
172 (_thread_cb.tc_tag_storage == NULL ? &(storage) : \
173 _thread_cb.tc_tag_storage(&(__THREAD_NAME(keyname)), \
174 &(storage), sizeof(storage), NULL, (error)))
175
176#define _THREAD_PRIVATE_DT(keyname, storage, dt, error) \
177 (_thread_cb.tc_tag_storage == NULL ? &(storage) : \
178 _thread_cb.tc_tag_storage(&(__THREAD_NAME(keyname)), \
179 &(storage), sizeof(storage), (dt), (error)))
180
181/*
182 * Macros used in libc to access mutexes.
183 */
184#define _MUTEX_LOCK(mutex) \
185 do { \
186 if (__isthreaded) \
187 _thread_cb.tc_mutex_lock(mutex); \
188 } while (0)
189#define _MUTEX_UNLOCK(mutex) \
190 do { \
191 if (__isthreaded) \
192 _thread_cb.tc_mutex_unlock(mutex); \
193 } while (0)
194#define _MUTEX_DESTROY(mutex) \
195 do { \
196 if (__isthreaded) \
197 _thread_cb.tc_mutex_destroy(mutex); \
198 } while (0)
199
200/*
201 * malloc lock/unlock prototypes and definitions
202 */
203#define _MALLOC_LOCK(n) \
204 do { \
205 if (__isthreaded) \
206 _thread_cb.tc_malloc_lock(n); \
207 } while (0)
208#define _MALLOC_UNLOCK(n) \
209 do { \
210 if (__isthreaded) \
211 _thread_cb.tc_malloc_unlock(n); \
212 } while (0)
213
214#define _ATEXIT_LOCK() \
215 do { \
216 if (__isthreaded) \
217 _thread_cb.tc_atexit_lock(); \
218 } while (0)
219#define _ATEXIT_UNLOCK() \
220 do { \
221 if (__isthreaded) \
222 _thread_cb.tc_atexit_unlock(); \
223 } while (0)
224
225#define _ATFORK_LOCK() \
226 do { \
227 if (__isthreaded) \
228 _thread_cb.tc_atfork_lock(); \
229 } while (0)
230#define _ATFORK_UNLOCK() \
231 do { \
232 if (__isthreaded) \
233 _thread_cb.tc_atfork_unlock(); \
234 } while (0)
235
236#define _ARC4_LOCK() \
237 do { \
238 if (__isthreaded) \
239 _thread_cb.tc_arc4_lock(); \
240 } while (0)
241#define _ARC4_UNLOCK() \
242 do { \
243 if (__isthreaded) \
244 _thread_cb.tc_arc4_unlock(); \
245 } while (0)
246#endif /* __LIBC__ */
247
248
249/*
250 * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
251 * All Rights Reserved.
252 *
253 * Permission to use, copy, modify, and distribute this software for any
254 * purpose with or without fee is hereby granted, provided that the above
255 * copyright notice and this permission notice appear in all copies.
256 *
257 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
258 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
259 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
260 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
261 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
262 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
263 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
264 */
265/*
266 * Private data structures that back up the typedefs in pthread.h.
267 * Since only the thread library cares about their size or arrangement,
268 * it should be possible to switch libraries without relinking.
269 *
270 * Do not reorder _atomic_lock_t and sem_t variables in the structs.
271 * This is due to alignment requirements of certain arches like hppa.
272 * The current requirement is 16 bytes.
273 *
274 * THE MACHINE DEPENDENT CERROR CODE HAS HARD CODED OFFSETS INTO PTHREAD_T!
275 */
276
277#include <sys/queue.h>
278#include <pthread.h>
279#include <semaphore.h>
280#include <machine/spinlock.h>
281
282#define _SPINLOCK_UNLOCKED _ATOMIC_LOCK_UNLOCKED
283
284struct __sem {
285 _atomic_lock_t lock;
286 volatile int waitcount;
287 volatile int value;
288 int shared;
289};
290
291TAILQ_HEAD(pthread_queue, pthread);
292
293#ifdef FUTEX
294
295struct pthread_mutex {
296 volatile unsigned int lock;
297 int type;
298 pthread_t owner;
299 int count;
300 int prioceiling;
301};
302
303struct pthread_cond {
304 volatile unsigned int seq;
305 clockid_t clock;
306 struct pthread_mutex *mutex;
307};
308
309struct pthread_rwlock {
310 volatile unsigned int value;
311};
312
313#else
314
315struct pthread_mutex {
316 _atomic_lock_t lock;
317 struct pthread_queue lockers;
318 int type;
319 pthread_t owner;
320 int count;
321 int prioceiling;
322};
323
324struct pthread_cond {
325 _atomic_lock_t lock;
326 struct pthread_queue waiters;
327 struct pthread_mutex *mutex;
328 clockid_t clock;
329};
330
331struct pthread_rwlock {
332 _atomic_lock_t lock;
333 pthread_t owner;
334 struct pthread_queue writers;
335 int readers;
336};
337#endif /* FUTEX */
338
339struct pthread_mutex_attr {
340 int ma_type;
341 int ma_protocol;
342 int ma_prioceiling;
343};
344
345struct pthread_cond_attr {
346 clockid_t ca_clock;
347};
348
349struct pthread_attr {
350 void *stack_addr;
351 size_t stack_size;
352 size_t guard_size;
353 int detach_state;
354 int contention_scope;
355 int sched_policy;
356 struct sched_param sched_param;
357 int sched_inherit;
358};
359
360struct rthread_storage {
361 int keyid;
362 struct rthread_storage *next;
363 void *data;
364};
365
366struct rthread_cleanup_fn {
367 void (*fn)(void *);
368 void *arg;
369 struct rthread_cleanup_fn *next;
370};
371
372struct tib;
373struct stack;
374struct pthread {
375 struct __sem donesem;
376 unsigned int flags;
377 _atomic_lock_t flags_lock;
378 struct tib *tib;
379 void *retval;
380 void *(*fn)(void *);
381 void *arg;
382 char name[32];
383 struct stack *stack;
384 LIST_ENTRY(pthread) threads;
385 TAILQ_ENTRY(pthread) waiting;
386 pthread_cond_t blocking_cond;
387 struct pthread_attr attr;
388 struct rthread_storage *local_storage;
389 struct rthread_cleanup_fn *cleanup_fns;
390
391 /* cancel received in a delayed cancel block? */
392 int delayed_cancel;
393};
394/* flags in pthread->flags */
395#define THREAD_DONE 0x001
396#define THREAD_DETACHED 0x002
397
398/* flags in tib->tib_thread_flags */
399#define TIB_THREAD_ASYNC_CANCEL 0x001
400#define TIB_THREAD_INITIAL_STACK 0x002 /* has stack from exec */
401
402#define ENTER_DELAYED_CANCEL_POINT(tib, self) \
403 (self)->delayed_cancel = 0; \
404 ENTER_CANCEL_POINT_INNER(tib, 1, 1)
405
406/*
407 * Internal functions exported from libc's thread bits for use by libpthread
408 */
409void _spinlock(volatile _atomic_lock_t *);
410int _spinlocktry(volatile _atomic_lock_t *);
411void _spinunlock(volatile _atomic_lock_t *);
412
413void _rthread_debug(int, const char *, ...)
414 __attribute__((__format__ (printf, 2, 3)));
415pid_t _thread_dofork(pid_t (*_sys_fork)(void));
416void _thread_finalize(void);
417
418/*
419 * Threading syscalls not declared in system headers
420 */
421__dead void __threxit(pid_t *);
422int __thrsleep(const volatile void *, clockid_t,
423 const struct timespec *, volatile void *, const int *);
424int __thrwakeup(const volatile void *, int n);
425int __thrsigdivert(sigset_t, siginfo_t *, const struct timespec *);
426
427#endif /* _THREAD_PRIVATE_H_ */