rename amd64 architecture to x86_64
[dragonfly.git] / lib / libc_r / uthread / pthread_private.h
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by John Birrell.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * Private thread definitions for the uthread kernel.
33 *
34 * $FreeBSD: src/lib/libc_r/uthread/pthread_private.h,v 1.36.2.21 2002/10/22 14:44:02 fjoe Exp $
808851ae 35 * $DragonFly: src/lib/libc_r/uthread/pthread_private.h,v 1.16 2008/05/25 21:34:49 hasso Exp $
984263bc
MD
36 */
37
38#ifndef _PTHREAD_PRIVATE_H
39#define _PTHREAD_PRIVATE_H
40
41/*
42 * Evaluate the storage class specifier.
43 */
44#ifdef GLOBAL_PTHREAD_PRIVATE
45#define SCLASS
46#else
47#define SCLASS extern
48#endif
49
50/*
51 * Include files.
52 */
53#include <setjmp.h>
54#include <signal.h>
55#include <stdio.h>
56#include <sys/queue.h>
57#include <sys/types.h>
58#include <sys/time.h>
59#include <sys/cdefs.h>
c4dd4100 60#include <sys/sched.h>
984263bc
MD
61#include <spinlock.h>
62#include <pthread_np.h>
63
40b6c3c5
JS
64#include <machine/tls.h>
65
984263bc
MD
66/*
67 * Define machine dependent macros to get and set the stack pointer
68 * from the supported contexts. Also define a macro to set the return
69 * address in a jmp_buf context.
70 *
71 * XXX - These need to be moved into architecture dependent support files.
72 */
73#if defined(__i386__)
74#define GET_STACK_JB(jb) ((unsigned long)((jb)[0]._jb[2]))
75#define GET_STACK_SJB(sjb) ((unsigned long)((sjb)[0]._sjb[2]))
76#define GET_STACK_UC(ucp) ((unsigned long)((ucp)->uc_mcontext.mc_esp))
77#define SET_STACK_JB(jb, stk) (jb)[0]._jb[2] = (int)(stk)
78#define SET_STACK_SJB(sjb, stk) (sjb)[0]._sjb[2] = (int)(stk)
79#define SET_STACK_UC(ucp, stk) (ucp)->uc_mcontext.mc_esp = (int)(stk)
984263bc 80#define SET_RETURN_ADDR_JB(jb, ra) (jb)[0]._jb[0] = (int)(ra)
c1543a89 81#elif defined(__x86_64__)
64c2a074
SS
82#define GET_STACK_JB(jb) ((unsigned long)((jb)[0]._jb[2]))
83#define GET_STACK_SJB(sjb) ((unsigned long)((sjb)[0]._sjb[2]))
84#define GET_STACK_UC(ucp) ((unsigned long)((ucp)->uc_mcontext.mc_rsp))
85#define SET_STACK_JB(jb, stk) (jb)[0]._jb[2] = (long)(stk)
86#define SET_STACK_SJB(sjb, stk) (sjb)[0]._sjb[2] = (long)(stk)
87#define SET_STACK_UC(ucp, stk) (ucp)->uc_mcontext.mc_rsp = (long)(stk)
88#define FP_SAVE_UC(ucp) do { \
89 char *fdata; \
90 fdata = (char *) (ucp)->uc_mcontext.mc_fpstate; \
91 __asm__("fxsave %0": :"m"(*fdata)); \
92} while (0)
93#define FP_RESTORE_UC(ucp) do { \
94 char *fdata; \
95 fdata = (char *) (ucp)->uc_mcontext.mc_fpstate; \
96 __asm__("fxrstor %0": :"m"(*fdata)); \
97} while (0)
98#define SET_RETURN_ADDR_JB(jb, ra) (jb)[0]._jb[0] = (long)(ra)
984263bc
MD
99#else
100#error "Don't recognize this architecture!"
101#endif
102
103/*
104 * Kernel fatal error handler macro.
105 */
106#define PANIC(string) _thread_exit(__FILE__,__LINE__,string)
107
108
109/* Output debug messages like this: */
110#define stdout_debug(args...) do { \
111 char buf[128]; \
112 snprintf(buf, sizeof(buf), ##args); \
b09fd398 113 __sys_extpwrite(1, buf, strlen(buf), O_FBLOCKING, -1); \
984263bc
MD
114} while (0)
115#define stderr_debug(args...) do { \
116 char buf[128]; \
117 snprintf(buf, sizeof(buf), ##args); \
b09fd398 118 __sys_extpwrite(2, buf, strlen(buf), O_FBLOCKING, -1); \
984263bc
MD
119} while (0)
120
121
122
123/*
124 * Priority queue manipulation macros (using pqe link):
125 */
126#define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd)
127#define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd)
128#define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd)
129#define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq)
130
131/*
132 * Waiting queue manipulation macros (using pqe link):
133 */
134#define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd)
135#define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd)
136
137#if defined(_PTHREADS_INVARIANTS)
138#define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive()
139#define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive()
140#else
141#define PTHREAD_WAITQ_CLEARACTIVE()
142#define PTHREAD_WAITQ_SETACTIVE()
143#endif
144
145/*
146 * Work queue manipulation macros (using qe link):
147 */
148#define PTHREAD_WORKQ_INSERT(thrd) do { \
149 TAILQ_INSERT_TAIL(&_workq,thrd,qe); \
150 (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \
151} while (0)
152#define PTHREAD_WORKQ_REMOVE(thrd) do { \
153 TAILQ_REMOVE(&_workq,thrd,qe); \
154 (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \
155} while (0)
156
157
158/*
159 * State change macro without scheduling queue change:
160 */
161#define PTHREAD_SET_STATE(thrd, newstate) do { \
162 (thrd)->state = newstate; \
163 (thrd)->fname = __FILE__; \
164 (thrd)->lineno = __LINE__; \
165} while (0)
166
167/*
168 * State change macro with scheduling queue change - This must be
169 * called with preemption deferred (see thread_kern_sched_[un]defer).
170 */
171#if defined(_PTHREADS_INVARIANTS)
172#include <assert.h>
173#define PTHREAD_ASSERT(cond, msg) do { \
174 if (!(cond)) \
175 PANIC(msg); \
176} while (0)
177#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \
178 PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \
179 "Illegal call from signal handler");
180#define PTHREAD_NEW_STATE(thrd, newstate) do { \
181 if (_thread_kern_new_state != 0) \
182 PANIC("Recursive PTHREAD_NEW_STATE"); \
183 _thread_kern_new_state = 1; \
184 if ((thrd)->state != newstate) { \
185 if ((thrd)->state == PS_RUNNING) { \
186 PTHREAD_PRIOQ_REMOVE(thrd); \
187 PTHREAD_SET_STATE(thrd, newstate); \
188 PTHREAD_WAITQ_INSERT(thrd); \
189 } else if (newstate == PS_RUNNING) { \
190 PTHREAD_WAITQ_REMOVE(thrd); \
191 PTHREAD_SET_STATE(thrd, newstate); \
192 PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
193 } \
194 } \
195 _thread_kern_new_state = 0; \
196} while (0)
197#else
198#define PTHREAD_ASSERT(cond, msg)
199#define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd)
200#define PTHREAD_NEW_STATE(thrd, newstate) do { \
201 if ((thrd)->state != newstate) { \
202 if ((thrd)->state == PS_RUNNING) { \
203 PTHREAD_PRIOQ_REMOVE(thrd); \
204 PTHREAD_WAITQ_INSERT(thrd); \
205 } else if (newstate == PS_RUNNING) { \
206 PTHREAD_WAITQ_REMOVE(thrd); \
207 PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
208 } \
209 } \
210 PTHREAD_SET_STATE(thrd, newstate); \
211} while (0)
212#endif
213
214/*
215 * Define the signals to be used for scheduling.
216 */
217#if defined(_PTHREADS_COMPAT_SCHED)
218#define _ITIMER_SCHED_TIMER ITIMER_VIRTUAL
219#define _SCHED_SIGNAL SIGVTALRM
220#else
221#define _ITIMER_SCHED_TIMER ITIMER_PROF
222#define _SCHED_SIGNAL SIGPROF
223#endif
224
225/*
226 * Priority queues.
227 *
228 * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
229 */
230typedef struct pq_list {
231 TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */
232 TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */
233 int pl_prio; /* the priority of this list */
234 int pl_queued; /* is this in the priority queue */
235} pq_list_t;
236
237typedef struct pq_queue {
238 TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */
239 pq_list_t *pq_lists; /* array of all priority lists */
240 int pq_size; /* number of priority lists */
241} pq_queue_t;
242
243
244/*
245 * TailQ initialization values.
246 */
247#define TAILQ_INITIALIZER { NULL, NULL }
248
249/*
250 * Mutex definitions.
251 */
252union pthread_mutex_data {
253 void *m_ptr;
254 int m_count;
255};
256
257struct pthread_mutex {
258 enum pthread_mutextype m_type;
259 int m_protocol;
260 TAILQ_HEAD(mutex_head, pthread) m_queue;
261 struct pthread *m_owner;
262 union pthread_mutex_data m_data;
263 long m_flags;
264 int m_refcount;
265
266 /*
267 * Used for priority inheritence and protection.
268 *
269 * m_prio - For priority inheritence, the highest active
270 * priority (threads locking the mutex inherit
271 * this priority). For priority protection, the
272 * ceiling priority of this mutex.
273 * m_saved_prio - mutex owners inherited priority before
274 * taking the mutex, restored when the owner
275 * unlocks the mutex.
276 */
277 int m_prio;
278 int m_saved_prio;
279
280 /*
281 * Link for list of all mutexes a thread currently owns.
282 */
283 TAILQ_ENTRY(pthread_mutex) m_qe;
284
285 /*
286 * Lock for accesses to this structure.
287 */
288 spinlock_t lock;
289};
290
291/*
292 * Flags for mutexes.
293 */
294#define MUTEX_FLAGS_PRIVATE 0x01
295#define MUTEX_FLAGS_INITED 0x02
296#define MUTEX_FLAGS_BUSY 0x04
297
298/*
299 * Static mutex initialization values.
300 */
301#define PTHREAD_MUTEX_STATIC_INITIALIZER \
302 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \
303 NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \
304 _SPINLOCK_INITIALIZER }
305
306struct pthread_mutex_attr {
307 enum pthread_mutextype m_type;
308 int m_protocol;
309 int m_ceiling;
310 long m_flags;
311};
312
313/*
314 * Condition variable definitions.
315 */
316enum pthread_cond_type {
317 COND_TYPE_FAST,
318 COND_TYPE_MAX
319};
320
321struct pthread_cond {
322 enum pthread_cond_type c_type;
323 TAILQ_HEAD(cond_head, pthread) c_queue;
324 pthread_mutex_t c_mutex;
325 void *c_data;
326 long c_flags;
327 int c_seqno;
328
329 /*
330 * Lock for accesses to this structure.
331 */
332 spinlock_t lock;
333};
334
335struct pthread_cond_attr {
336 enum pthread_cond_type c_type;
337 long c_flags;
338};
339
340/*
341 * Flags for condition variables.
342 */
343#define COND_FLAGS_PRIVATE 0x01
344#define COND_FLAGS_INITED 0x02
345#define COND_FLAGS_BUSY 0x04
346
347/*
348 * Static cond initialization values.
349 */
350#define PTHREAD_COND_STATIC_INITIALIZER \
351 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
352 0, 0, _SPINLOCK_INITIALIZER }
353
354/*
355 * Semaphore definitions.
356 */
357struct sem {
358#define SEM_MAGIC ((u_int32_t) 0x09fa4012)
359 u_int32_t magic;
360 pthread_mutex_t lock;
361 pthread_cond_t gtzero;
362 u_int32_t count;
363 u_int32_t nwaiters;
364};
365
366/*
367 * Cleanup definitions.
368 */
369struct pthread_cleanup {
370 struct pthread_cleanup *next;
ed298f34 371 void (*routine)(void *);
984263bc
MD
372 void *routine_arg;
373};
374
808851ae
HT
375struct pthread_atfork {
376 TAILQ_ENTRY(pthread_atfork) qe;
377 void (*prepare)(void);
378 void (*parent)(void);
379 void (*child)(void);
380};
381
984263bc
MD
382struct pthread_attr {
383 int sched_policy;
384 int sched_inherit;
385 int sched_interval;
386 int prio;
387 int suspend;
388 int flags;
389 void *arg_attr;
ed298f34 390 void (*cleanup_attr)(void *);
984263bc
MD
391 void *stackaddr_attr;
392 size_t stacksize_attr;
393};
394
395/*
396 * Thread creation state attributes.
397 */
398#define PTHREAD_CREATE_RUNNING 0
399#define PTHREAD_CREATE_SUSPENDED 1
400
401/*
402 * Miscellaneous definitions.
403 */
404#define PTHREAD_STACK_DEFAULT 65536
405/*
406 * Size of red zone at the end of each stack. In actuality, this "red zone" is
407 * merely an unmapped region, except in the case of the initial stack. Since
408 * mmap() makes it possible to specify the maximum growth of a MAP_STACK region,
409 * an unmapped gap between thread stacks achieves the same effect as explicitly
410 * mapped red zones.
411 */
412#define PTHREAD_STACK_GUARD PAGE_SIZE
413
414/*
415 * Maximum size of initial thread's stack. This perhaps deserves to be larger
416 * than the stacks of other threads, since many applications are likely to run
417 * almost entirely on this stack.
418 */
419#define PTHREAD_STACK_INITIAL 0x100000
420
421/* Size of the scheduler stack: */
422#define SCHED_STACK_SIZE PAGE_SIZE
423
424/*
425 * Define the different priority ranges. All applications have thread
426 * priorities constrained within 0-31. The threads library raises the
427 * priority when delivering signals in order to ensure that signal
428 * delivery happens (from the POSIX spec) "as soon as possible".
429 * In the future, the threads library will also be able to map specific
430 * threads into real-time (cooperating) processes or kernel threads.
431 * The RT and SIGNAL priorities will be used internally and added to
432 * thread base priorities so that the scheduling queue can handle both
433 * normal and RT priority threads with and without signal handling.
434 *
435 * The approach taken is that, within each class, signal delivery
436 * always has priority over thread execution.
437 */
438#define PTHREAD_DEFAULT_PRIORITY 15
439#define PTHREAD_MIN_PRIORITY 0
440#define PTHREAD_MAX_PRIORITY 31 /* 0x1F */
441#define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */
442#define PTHREAD_RT_PRIORITY 64 /* 0x40 */
443#define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY
444#define PTHREAD_LAST_PRIORITY \
445 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY)
446#define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY)
447
448/*
449 * Clock resolution in microseconds.
450 */
451#define CLOCK_RES_USEC 10000
452#define CLOCK_RES_USEC_MIN 1000
453
454/*
455 * Time slice period in microseconds.
456 */
457#define TIMESLICE_USEC 20000
458
459/*
460 * Define a thread-safe macro to get the current time of day
461 * which is updated at regular intervals by the scheduling signal
462 * handler.
463 */
464#define GET_CURRENT_TOD(tv) \
465 do { \
466 tv.tv_sec = _sched_tod.tv_sec; \
467 tv.tv_usec = _sched_tod.tv_usec; \
468 } while (tv.tv_sec != _sched_tod.tv_sec)
469
470
471struct pthread_key {
472 spinlock_t lock;
473 volatile int allocated;
474 volatile int count;
ed298f34 475 void (*destructor)(void *);
984263bc
MD
476};
477
478struct pthread_rwlockattr {
479 int pshared;
480};
481
482struct pthread_rwlock {
483 pthread_mutex_t lock; /* monitor lock */
484 int state; /* 0 = idle >0 = # of readers -1 = writer */
485 pthread_cond_t read_signal;
486 pthread_cond_t write_signal;
487 int blocked_writers;
488};
489
490/*
491 * Thread states.
492 */
493enum pthread_state {
494 PS_RUNNING,
495 PS_SIGTHREAD,
496 PS_MUTEX_WAIT,
497 PS_COND_WAIT,
498 PS_FDLR_WAIT,
499 PS_FDLW_WAIT,
500 PS_FDR_WAIT,
501 PS_FDW_WAIT,
984263bc
MD
502 PS_POLL_WAIT,
503 PS_SELECT_WAIT,
504 PS_SLEEP_WAIT,
505 PS_WAIT_WAIT,
506 PS_SIGSUSPEND,
507 PS_SIGWAIT,
508 PS_SPINBLOCK,
509 PS_JOIN,
510 PS_SUSPENDED,
511 PS_DEAD,
512 PS_DEADLOCK,
513 PS_STATE_MAX
514};
515
516
517/*
518 * File descriptor locking definitions.
519 */
520#define FD_READ 0x1
521#define FD_WRITE 0x2
522#define FD_RDWR (FD_READ | FD_WRITE)
523
524/*
525 * File descriptor table structure.
526 */
527struct fd_table_entry {
528 /*
529 * Lock for accesses to this file descriptor table
530 * entry. This is passed to _spinlock() to provide atomic
531 * access to this structure. It does *not* represent the
532 * state of the lock on the file descriptor.
533 */
534 spinlock_t lock;
535 TAILQ_HEAD(, pthread) r_queue; /* Read queue. */
536 TAILQ_HEAD(, pthread) w_queue; /* Write queue. */
537 struct pthread *r_owner; /* Ptr to thread owning read lock. */
538 struct pthread *w_owner; /* Ptr to thread owning write lock. */
539 char *r_fname; /* Ptr to read lock source file name */
540 int r_lineno; /* Read lock source line number. */
541 char *w_fname; /* Ptr to write lock source file name */
542 int w_lineno; /* Write lock source line number. */
543 int r_lockcount; /* Count for FILE read locks. */
544 int w_lockcount; /* Count for FILE write locks. */
545 int flags; /* Flags used in open. */
546};
547
548struct pthread_poll_data {
549 int nfds;
550 struct pollfd *fds;
551};
552
553union pthread_wait_data {
554 pthread_mutex_t mutex;
555 pthread_cond_t cond;
556 const sigset_t *sigwait; /* Waiting on a signal in sigwait */
557 struct {
558 short fd; /* Used when thread waiting on fd */
559 short branch; /* Line number, for debugging. */
560 char *fname; /* Source file name for debugging.*/
561 } fd;
562 FILE *fp;
563 struct pthread_poll_data *poll_data;
564 spinlock_t *spinlock;
565 struct pthread *thread;
566};
567
568/*
569 * Define a continuation routine that can be used to perform a
570 * transfer of control:
571 */
572typedef void (*thread_continuation_t) (void *);
573
574struct pthread_signal_frame;
575
576struct pthread_state_data {
577 struct pthread_signal_frame *psd_curframe;
578 sigset_t psd_sigmask;
579 struct timespec psd_wakeup_time;
580 union pthread_wait_data psd_wait_data;
581 enum pthread_state psd_state;
582 int psd_flags;
583 int psd_interrupted;
584 int psd_longjmp_val;
585 int psd_sigmask_seqno;
586 int psd_signo;
587 int psd_sig_defer_count;
588 /* XXX - What about thread->timeout and/or thread->error? */
589};
590
591struct join_status {
592 struct pthread *thread;
593 void *ret;
594 int error;
595};
596
597/*
598 * The frame that is added to the top of a threads stack when setting up
599 * up the thread to run a signal handler.
600 */
601struct pthread_signal_frame {
602 /*
603 * This stores the threads state before the signal.
604 */
605 struct pthread_state_data saved_state;
606
607 /*
608 * Threads return context; we use only jmp_buf's for now.
609 */
610 union {
611 jmp_buf jb;
612 ucontext_t uc;
613 } ctx;
614 int signo; /* signal, arg 1 to sighandler */
615 int sig_has_args; /* use signal args if true */
616 ucontext_t uc;
617 siginfo_t siginfo;
618};
619
620/*
621 * Thread structure.
622 */
623struct pthread {
624 /*
625 * Magic value to help recognize a valid thread structure
626 * from an invalid one:
627 */
628#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115)
629 u_int32_t magic;
630 char *name;
631 u_int64_t uniqueid; /* for gdb */
40b6c3c5 632 struct tls_tcb *tcb;
984263bc
MD
633
634 /*
635 * Lock for accesses to this thread structure.
636 */
637 spinlock_t lock;
638
639 /* Queue entry for list of all threads: */
640 TAILQ_ENTRY(pthread) tle;
641
642 /* Queue entry for list of dead threads: */
643 TAILQ_ENTRY(pthread) dle;
644
645 /*
646 * Thread start routine, argument, stack pointer and thread
647 * attributes.
648 */
649 void *(*start_routine)(void *);
650 void *arg;
651 void *stack;
652 struct pthread_attr attr;
653
654 /*
655 * Threads return context; we use only jmp_buf's for now.
656 */
657 union {
658 jmp_buf jb;
659 ucontext_t uc;
660 } ctx;
661
662 /*
663 * Used for tracking delivery of signal handlers.
664 */
665 struct pthread_signal_frame *curframe;
666
667 /*
668 * Cancelability flags - the lower 2 bits are used by cancel
669 * definitions in pthread.h
670 */
671#define PTHREAD_AT_CANCEL_POINT 0x0004
672#define PTHREAD_CANCELLING 0x0008
673#define PTHREAD_CANCEL_NEEDED 0x0010
674 int cancelflags;
675
676 thread_continuation_t continuation;
677
678 /*
679 * Current signal mask and pending signals.
680 */
681 sigset_t sigmask;
682 sigset_t sigpend;
683 int sigmask_seqno;
684 int check_pending;
685
686 /* Thread state: */
687 enum pthread_state state;
688
689 /* Scheduling clock when this thread was last made active. */
690 long last_active;
691
692 /* Scheduling clock when this thread was last made inactive. */
693 long last_inactive;
694
695 /*
696 * Number of microseconds accumulated by this thread when
697 * time slicing is active.
698 */
699 long slice_usec;
700
701 /*
702 * Time to wake up thread. This is used for sleeping threads and
703 * for any operation which may time out (such as select).
704 */
705 struct timespec wakeup_time;
706
707 /* TRUE if operation has timed out. */
708 int timeout;
709
710 /*
984263bc
MD
711 * The joiner is the thread that is joining to this thread. The
712 * join status keeps track of a join operation to another thread.
713 */
714 struct pthread *joiner;
715 struct join_status join_status;
716
717 /*
718 * The current thread can belong to only one scheduling queue at
719 * a time (ready or waiting queue). It can also belong to:
720 *
721 * o A queue of threads waiting for a mutex
722 * o A queue of threads waiting for a condition variable
723 * o A queue of threads waiting for a file descriptor lock
724 * o A queue of threads needing work done by the kernel thread
725 * (waiting for a spinlock or file I/O)
726 *
727 * A thread can also be joining a thread (the joiner field above).
728 *
729 * It must not be possible for a thread to belong to any of the
730 * above queues while it is handling a signal. Signal handlers
731 * may longjmp back to previous stack frames circumventing normal
732 * control flow. This could corrupt queue integrity if the thread
733 * retains membership in the queue. Therefore, if a thread is a
734 * member of one of these queues when a signal handler is invoked,
735 * it must remove itself from the queue before calling the signal
736 * handler and reinsert itself after normal return of the handler.
737 *
738 * Use pqe for the scheduling queue link (both ready and waiting),
739 * sqe for synchronization (mutex and condition variable) queue
740 * links, and qe for all other links.
741 */
742 TAILQ_ENTRY(pthread) pqe; /* priority queue link */
743 TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */
744 TAILQ_ENTRY(pthread) qe; /* all other queues link */
745
746 /* Wait data. */
747 union pthread_wait_data data;
748
749 /*
750 * Allocated for converting select into poll.
751 */
752 struct pthread_poll_data poll_data;
753
754 /*
755 * Set to TRUE if a blocking operation was
756 * interrupted by a signal:
757 */
758 int interrupted;
759
760 /* Signal number when in state PS_SIGWAIT: */
761 int signo;
762
763 /*
764 * Set to non-zero when this thread has deferred signals.
765 * We allow for recursive deferral.
766 */
767 int sig_defer_count;
768
769 /*
770 * Set to TRUE if this thread should yield after undeferring
771 * signals.
772 */
773 int yield_on_sig_undefer;
774
775 /* Miscellaneous flags; only set with signals deferred. */
776 int flags;
777#define PTHREAD_FLAGS_PRIVATE 0x0001
778#define PTHREAD_EXITING 0x0002
779#define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link */
780#define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link */
781#define PTHREAD_FLAGS_IN_WORKQ 0x0010 /* in work queue using qe link */
782#define PTHREAD_FLAGS_IN_FILEQ 0x0020 /* in file lock queue using qe link */
783#define PTHREAD_FLAGS_IN_FDQ 0x0040 /* in fd lock queue using qe link */
784#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/
785#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */
786#define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */
787#define PTHREAD_FLAGS_TRACE 0x0400 /* for debugging purposes */
788#define PTHREAD_FLAGS_IN_SYNCQ \
789 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ)
790
791 /*
792 * Base priority is the user setable and retrievable priority
793 * of the thread. It is only affected by explicit calls to
794 * set thread priority and upon thread creation via a thread
795 * attribute or default priority.
796 */
797 char base_priority;
798
799 /*
800 * Inherited priority is the priority a thread inherits by
801 * taking a priority inheritence or protection mutex. It
802 * is not affected by base priority changes. Inherited
803 * priority defaults to and remains 0 until a mutex is taken
804 * that is being waited on by any other thread whose priority
805 * is non-zero.
806 */
807 char inherited_priority;
808
809 /*
810 * Active priority is always the maximum of the threads base
811 * priority and inherited priority. When there is a change
812 * in either the base or inherited priority, the active
813 * priority must be recalculated.
814 */
815 char active_priority;
816
817 /* Number of priority ceiling or protection mutexes owned. */
818 int priority_mutex_count;
819
820 /*
821 * Queue of currently owned mutexes.
822 */
823 TAILQ_HEAD(, pthread_mutex) mutexq;
824
825 void *ret;
826 const void **specific_data;
827 int specific_data_count;
828
829 /* Cleanup handlers Link List */
830 struct pthread_cleanup *cleanup;
831 char *fname; /* Ptr to source file name */
832 int lineno; /* Source line number. */
833};
834
835/* Spare thread stack. */
836struct stack {
837 SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */
838};
839
840/*
841 * Global variables for the uthread kernel.
842 */
843
844SCLASS void *_usrstack
845#ifdef GLOBAL_PTHREAD_PRIVATE
846= (void *) USRSTACK;
847#else
848;
849#endif
850
851/* Kernel thread structure used when there are no running threads: */
852SCLASS struct pthread _thread_kern_thread;
853
854/* Ptr to the thread structure for the running thread: */
855SCLASS struct pthread * volatile _thread_run
856#ifdef GLOBAL_PTHREAD_PRIVATE
857= &_thread_kern_thread;
858#else
859;
860#endif
861
862/* Ptr to the thread structure for the last user thread to run: */
863SCLASS struct pthread * volatile _last_user_thread
864#ifdef GLOBAL_PTHREAD_PRIVATE
865= &_thread_kern_thread;
866#else
867;
868#endif
869
870/* List of all threads: */
871SCLASS TAILQ_HEAD(, pthread) _thread_list
872#ifdef GLOBAL_PTHREAD_PRIVATE
873= TAILQ_HEAD_INITIALIZER(_thread_list);
874#else
875;
876#endif
877
878/*
879 * Array of kernel pipe file descriptors that are used to ensure that
880 * no signals are missed in calls to _select.
881 */
882SCLASS int _thread_kern_pipe[2]
883#ifdef GLOBAL_PTHREAD_PRIVATE
884= {
885 -1,
886 -1
887};
888#else
889;
890#endif
891SCLASS int volatile _queue_signals
892#ifdef GLOBAL_PTHREAD_PRIVATE
893= 0;
894#else
895;
896#endif
897SCLASS int _thread_kern_in_sched
898#ifdef GLOBAL_PTHREAD_PRIVATE
899= 0;
900#else
901;
902#endif
903
904SCLASS int _sig_in_handler
905#ifdef GLOBAL_PTHREAD_PRIVATE
906= 0;
907#else
908;
909#endif
910
911/* Time of day at last scheduling timer signal: */
912SCLASS struct timeval volatile _sched_tod
913#ifdef GLOBAL_PTHREAD_PRIVATE
914= { 0, 0 };
915#else
916;
917#endif
918
919/*
920 * Current scheduling timer ticks; used as resource usage.
921 */
922SCLASS unsigned int volatile _sched_ticks
923#ifdef GLOBAL_PTHREAD_PRIVATE
924= 0;
925#else
926;
927#endif
928
929/* Dead threads: */
930SCLASS TAILQ_HEAD(, pthread) _dead_list
931#ifdef GLOBAL_PTHREAD_PRIVATE
932= TAILQ_HEAD_INITIALIZER(_dead_list);
933#else
934;
935#endif
936
937/* Initial thread: */
938SCLASS struct pthread *_thread_initial
939#ifdef GLOBAL_PTHREAD_PRIVATE
940= NULL;
941#else
942;
943#endif
944
808851ae
HT
945SCLASS TAILQ_HEAD(atfork_head, pthread_atfork) _atfork_list;
946SCLASS pthread_mutex_t _atfork_mutex;
947
984263bc
MD
948/* Default thread attributes: */
949SCLASS struct pthread_attr pthread_attr_default
950#ifdef GLOBAL_PTHREAD_PRIVATE
951= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, PTHREAD_CREATE_RUNNING,
952 PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT };
953#else
954;
955#endif
956
957/* Default mutex attributes: */
958SCLASS struct pthread_mutex_attr pthread_mutexattr_default
959#ifdef GLOBAL_PTHREAD_PRIVATE
960= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 };
961#else
962;
963#endif
964
965/* Default condition variable attributes: */
966SCLASS struct pthread_cond_attr pthread_condattr_default
967#ifdef GLOBAL_PTHREAD_PRIVATE
968= { COND_TYPE_FAST, 0 };
969#else
970;
971#endif
972
973/*
974 * Standard I/O file descriptors need special flag treatment since
975 * setting one to non-blocking does all on *BSD. Sigh. This array
976 * is used to store the initial flag settings.
977 */
978SCLASS int _pthread_stdio_flags[3];
979
980/* File table information: */
981SCLASS struct fd_table_entry **_thread_fd_table
982#ifdef GLOBAL_PTHREAD_PRIVATE
983= NULL;
984#else
985;
986#endif
987
988/* Table for polling file descriptors: */
989SCLASS struct pollfd *_thread_pfd_table
990#ifdef GLOBAL_PTHREAD_PRIVATE
991= NULL;
992#else
993;
994#endif
995
996SCLASS const int dtablecount
997#ifdef GLOBAL_PTHREAD_PRIVATE
998= 4096/sizeof(struct fd_table_entry);
999#else
1000;
1001#endif
1002SCLASS int _thread_dtablesize /* Descriptor table size. */
1003#ifdef GLOBAL_PTHREAD_PRIVATE
1004= 0;
1005#else
1006;
1007#endif
1008
1009SCLASS int _clock_res_usec /* Clock resolution in usec. */
1010#ifdef GLOBAL_PTHREAD_PRIVATE
1011= CLOCK_RES_USEC;
1012#else
1013;
1014#endif
1015
1016/* Garbage collector mutex and condition variable. */
1017SCLASS pthread_mutex_t _gc_mutex
1018#ifdef GLOBAL_PTHREAD_PRIVATE
1019= NULL
1020#endif
1021;
1022SCLASS pthread_cond_t _gc_cond
1023#ifdef GLOBAL_PTHREAD_PRIVATE
1024= NULL
1025#endif
1026;
1027
1028/*
1029 * Array of signal actions for this process.
1030 */
1031SCLASS struct sigaction _thread_sigact[NSIG];
1032
1033/*
1034 * Array of counts of dummy handlers for SIG_DFL signals. This is used to
1035 * assure that there is always a dummy signal handler installed while there is a
1036 * thread sigwait()ing on the corresponding signal.
1037 */
1038SCLASS int _thread_dfl_count[NSIG];
1039
1040/*
1041 * Pending signals and mask for this process:
1042 */
1043SCLASS sigset_t _process_sigpending;
1044SCLASS sigset_t _process_sigmask
1045#ifdef GLOBAL_PTHREAD_PRIVATE
1046= { {0, 0, 0, 0} }
1047#endif
1048;
1049
1050/*
1051 * Scheduling queues:
1052 */
1053SCLASS pq_queue_t _readyq;
1054SCLASS TAILQ_HEAD(, pthread) _waitingq;
1055
1056/*
1057 * Work queue:
1058 */
1059SCLASS TAILQ_HEAD(, pthread) _workq;
1060
1061/* Tracks the number of threads blocked while waiting for a spinlock. */
1062SCLASS volatile int _spinblock_count
1063#ifdef GLOBAL_PTHREAD_PRIVATE
1064= 0
1065#endif
1066;
1067
1068/* Used to maintain pending and active signals: */
1069struct sigstatus {
1070 int pending; /* Is this a pending signal? */
1071 int blocked; /*
1072 * A handler is currently active for
1073 * this signal; ignore subsequent
1074 * signals until the handler is done.
1075 */
1076 int signo; /* arg 1 to signal handler */
1077 siginfo_t siginfo; /* arg 2 to signal handler */
1078 ucontext_t uc; /* arg 3 to signal handler */
1079};
1080
1081SCLASS struct sigstatus _thread_sigq[NSIG];
1082
1083/* Indicates that the signal queue needs to be checked. */
1084SCLASS volatile int _sigq_check_reqd
1085#ifdef GLOBAL_PTHREAD_PRIVATE
1086= 0
1087#endif
1088;
1089
1090/* Thread switch hook. */
1091SCLASS pthread_switch_routine_t _sched_switch_hook
1092#ifdef GLOBAL_PTHREAD_PRIVATE
1093= NULL
1094#endif
1095;
1096
1097/*
1098 * Spare stack queue. Stacks of default size are cached in order to reduce
1099 * thread creation time. Spare stacks are used in LIFO order to increase cache
1100 * locality.
1101 */
1102SCLASS SLIST_HEAD(, stack) _stackq;
1103
1104/*
1105 * Base address of next unallocated default-size {stack, red zone}. Stacks are
1106 * allocated contiguously, starting below the bottom of the main stack. When a
1107 * new stack is created, a red zone is created (actually, the red zone is simply
1108 * left unmapped) below the bottom of the stack, such that the stack will not be
1109 * able to grow all the way to the top of the next stack. This isn't
1110 * fool-proof. It is possible for a stack to grow by a large amount, such that
1111 * it grows into the next stack, and as long as the memory within the red zone
1112 * is never accessed, nothing will prevent one thread stack from trouncing all
1113 * over the next.
1114 */
1115SCLASS void * _next_stack
1116#ifdef GLOBAL_PTHREAD_PRIVATE
1117/* main stack top - main stack size - stack size - (red zone + main stack red zone) */
1118= (void *) USRSTACK - PTHREAD_STACK_INITIAL - PTHREAD_STACK_DEFAULT - (2 * PTHREAD_STACK_GUARD)
1119#endif
1120;
1121
1122/*
1123 * Declare the kernel scheduler jump buffer and stack:
1124 */
1125SCLASS jmp_buf _thread_kern_sched_jb;
1126
1127SCLASS void * _thread_kern_sched_stack
1128#ifdef GLOBAL_PTHREAD_PRIVATE
1129= NULL
1130#endif
1131;
1132
1133
1134/* Used for _PTHREADS_INVARIANTS checking. */
1135SCLASS int _thread_kern_new_state
1136#ifdef GLOBAL_PTHREAD_PRIVATE
1137= 0
1138#endif
1139;
1140
1141/* Undefine the storage class specifier: */
1142#undef SCLASS
1143
1144#ifdef _LOCK_DEBUG
1145#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
1146 _ts, __FILE__, __LINE__)
1147#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock_debug(_fd, _type, \
1148 __FILE__, __LINE__)
1149#else
1150#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts)
1151#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
1152#endif
1153
1154/*
1155 * Function prototype definitions.
1156 */
1157__BEGIN_DECLS
1158char *__ttyname_basic(int);
984263bc
MD
1159void _cond_wait_backout(pthread_t);
1160void _fd_lock_backout(pthread_t);
1161int _find_thread(pthread_t);
1162struct pthread *_get_curthread(void);
1163void _set_curthread(struct pthread *);
1164void _flockfile_backout(struct pthread *);
1165void _funlock_owned(struct pthread *);
1166int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t);
1167int _mutex_cv_lock(pthread_mutex_t *);
1168int _mutex_cv_unlock(pthread_mutex_t *);
1169void _mutex_lock_backout(pthread_t);
1170void _mutex_notify_priochange(pthread_t);
1171int _mutex_reinit(pthread_mutex_t *);
1172void _mutex_unlock_private(pthread_t);
1173int _cond_reinit(pthread_cond_t *);
1174int _pq_alloc(struct pq_queue *, int, int);
1175int _pq_init(struct pq_queue *);
1176void _pq_remove(struct pq_queue *pq, struct pthread *);
1177void _pq_insert_head(struct pq_queue *pq, struct pthread *);
1178void _pq_insert_tail(struct pq_queue *pq, struct pthread *);
1179struct pthread *_pq_first(struct pq_queue *pq);
1180void *_pthread_getspecific(pthread_key_t);
1181int _pthread_key_create(pthread_key_t *, void (*) (void *));
1182int _pthread_key_delete(pthread_key_t);
1183int _pthread_mutex_destroy(pthread_mutex_t *);
1184int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
1185int _pthread_mutex_lock(pthread_mutex_t *);
1186int _pthread_mutex_trylock(pthread_mutex_t *);
1187int _pthread_mutex_unlock(pthread_mutex_t *);
1188int _pthread_once(pthread_once_t *, void (*) (void));
1189int _pthread_setspecific(pthread_key_t, const void *);
1190int _pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
1191int _pthread_cond_destroy(pthread_cond_t *);
1192int _pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
1193int _pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *,
1194 const struct timespec *);
1195int _pthread_cond_signal(pthread_cond_t *);
1196int _pthread_cond_broadcast(pthread_cond_t *);
1197void _waitq_insert(pthread_t pthread);
1198void _waitq_remove(pthread_t pthread);
1199#if defined(_PTHREADS_INVARIANTS)
1200void _waitq_setactive(void);
1201void _waitq_clearactive(void);
1202#endif
1203void _thread_exit(char *, int, char *);
1204void _thread_exit_cleanup(void);
1205int _thread_fd_getflags(int);
1206int _thread_fd_lock(int, int, struct timespec *);
1207int _thread_fd_lock_debug(int, int, struct timespec *,char *fname,int lineno);
1208void _thread_fd_setflags(int, int);
1209int _thread_fd_table_init(int fd);
1210void _thread_fd_unlock(int, int);
1211void _thread_fd_unlock_debug(int, int, char *, int);
1212void _thread_fd_unlock_owned(pthread_t);
1213void *_thread_cleanup(pthread_t);
1214void _thread_cleanupspecific(void);
1215void _thread_dump_info(void);
1216void _thread_init(void);
1217void _thread_kern_sched(ucontext_t *);
1218void _thread_kern_scheduler(void);
1219void _thread_kern_sched_frame(struct pthread_signal_frame *psf);
1220void _thread_kern_sched_sig(void);
1221void _thread_kern_sched_state(enum pthread_state, char *fname, int lineno);
1222void _thread_kern_sched_state_unlock(enum pthread_state state,
1223 spinlock_t *lock, char *fname, int lineno);
1224void _thread_kern_set_timeout(const struct timespec *);
1225void _thread_kern_sig_defer(void);
1226void _thread_kern_sig_undefer(void);
c07c16ed 1227void _thread_mksigpipe(void);
984263bc
MD
1228void _thread_sig_handler(int, siginfo_t *, ucontext_t *);
1229void _thread_sig_check_pending(struct pthread *pthread);
1230void _thread_sig_handle_pending(void);
1231void _thread_sig_send(struct pthread *pthread, int sig);
1232void _thread_sig_wrapper(void);
1233void _thread_sigframe_restore(struct pthread *thread,
1234 struct pthread_signal_frame *psf);
1235void _thread_start(void);
984263bc
MD
1236pthread_addr_t _thread_gc(pthread_addr_t);
1237void _thread_enter_cancellation_point(void);
1238void _thread_leave_cancellation_point(void);
1239void _thread_cancellation_point(void);
1240
1241/* #include <aio.h> */
1242#ifdef _SYS_AIO_H_
1243int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
1244#endif
1245
1246/* #include <sys/event.h> */
1247#ifdef _SYS_EVENT_H_
1248int __sys_kevent(int, const struct kevent *, int, struct kevent *,
1249 int, const struct timespec *);
1250#endif
1251
1252/* #include <sys/ioctl.h> */
1253#ifdef _SYS_IOCTL_H_
1254int __sys_ioctl(int, unsigned long, ...);
1255#endif
1256
1257/* #include <sys/mman.h> */
1258#ifdef _SYS_MMAN_H_
1259int __sys_msync(void *, size_t, int);
1260#endif
1261
1262/* #include <sys/mount.h> */
1263#ifdef _SYS_MOUNT_H_
1264int __sys_fstatfs(int, struct statfs *);
1265#endif
1266
1267/* #include <sys/socket.h> */
1268#ifdef _SYS_SOCKET_H_
1269int __sys_accept(int, struct sockaddr *, socklen_t *);
b09fd398 1270int __sys_extaccept(int, int, struct sockaddr *, socklen_t *);
984263bc
MD
1271int __sys_bind(int, const struct sockaddr *, socklen_t);
1272int __sys_connect(int, const struct sockaddr *, socklen_t);
b09fd398 1273int __sys_extconnect(int, int, const struct sockaddr *, socklen_t);
984263bc
MD
1274int __sys_getpeername(int, struct sockaddr *, socklen_t *);
1275int __sys_getsockname(int, struct sockaddr *, socklen_t *);
1276int __sys_getsockopt(int, int, int, void *, socklen_t *);
1277int __sys_listen(int, int);
1278ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
1279ssize_t __sys_recvmsg(int, struct msghdr *, int);
1280int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int);
1281ssize_t __sys_sendmsg(int, const struct msghdr *, int);
1282ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
1283int __sys_setsockopt(int, int, int, const void *, socklen_t);
1284int __sys_shutdown(int, int);
1285int __sys_socket(int, int, int);
1286int __sys_socketpair(int, int, int, int *);
1287#endif
1288
1289/* #include <sys/stat.h> */
1290#ifdef _SYS_STAT_H_
1291int __sys_fchflags(int, u_long);
1292int __sys_fchmod(int, mode_t);
1293int __sys_fstat(int, struct stat *);
1294#endif
1295
1296/* #include <sys/uio.h> */
1297#ifdef _SYS_UIO_H_
1298ssize_t __sys_readv(int, const struct iovec *, int);
1299ssize_t __sys_writev(int, const struct iovec *, int);
b09fd398
MD
1300ssize_t __sys_extpreadv(int, const struct iovec *, int, int, off_t);
1301ssize_t __sys_extpwritev(int, const struct iovec *, int, int, off_t);
984263bc
MD
1302#endif
1303
1304/* #include <sys/wait.h> */
1305#ifdef WNOHANG
1306pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
1307#endif
1308
1309/* #include <dirent.h> */
1310#ifdef _DIRENT_H_
1311int __sys_getdirentries(int, char *, int, long *);
1312#endif
1313
1314/* #include <fcntl.h> */
1315#ifdef _SYS_FCNTL_H_
1316int __sys_fcntl(int, int, ...);
1317int __sys_flock(int, int);
1318int __sys_open(const char *, int, ...);
1319#endif
1320
1321/* #include <poll.h> */
1322#ifdef _SYS_POLL_H_
1323int __sys_poll(struct pollfd *, unsigned, int);
1324#endif
1325
1326/* #include <signal.h> */
1327#ifdef _SIGNAL_H_
1328int __sys_sigaction(int, const struct sigaction *, struct sigaction *);
1329int __sys_sigprocmask(int, const sigset_t *, sigset_t *);
1330int __sys_sigreturn(ucontext_t *);
1331#endif
1332
1333/* #include <unistd.h> */
1334#ifdef _UNISTD_H_
6028d5c3 1335void __sys_exit(int);
984263bc 1336int __sys_close(int);
9d315dd3 1337int __sys_closefrom(int);
984263bc
MD
1338int __sys_dup(int);
1339int __sys_dup2(int, int);
1340int __sys_execve(const char *, char * const *, char * const *);
1341int __sys_fchown(int, uid_t, gid_t);
1342pid_t __sys_fork(void);
1343long __sys_fpathconf(int, int);
1344int __sys_fsync(int);
1345int __sys_pipe(int *);
1346ssize_t __sys_read(int, void *, size_t);
b09fd398 1347ssize_t __sys_extpread(int, void *, size_t, int, off_t);
984263bc 1348ssize_t __sys_write(int, const void *, size_t);
b09fd398 1349ssize_t __sys_extpwrite(int, const void *, size_t, int, off_t);
984263bc
MD
1350#endif
1351
1352/* #include <setjmp.h> */
1353#ifdef _SETJMP_H_
1354extern void __siglongjmp(sigjmp_buf, int) __dead2;
1355extern void __longjmp(jmp_buf, int) __dead2;
1356extern void ___longjmp(jmp_buf, int) __dead2;
1357#endif
1358__END_DECLS
1359
1360#endif /* !_PTHREAD_PRIVATE_H */