summaryrefslogtreecommitdiff
path: root/lib/libpthread/uthread/pthread_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpthread/uthread/pthread_private.h')
-rw-r--r--lib/libpthread/uthread/pthread_private.h348
1 files changed, 209 insertions, 139 deletions
diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h
index 69a36e13477..f49d0eb257e 100644
--- a/lib/libpthread/uthread/pthread_private.h
+++ b/lib/libpthread/uthread/pthread_private.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: pthread_private.h,v 1.18 1999/11/25 07:01:30 d Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -20,7 +21,7 @@
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -31,15 +32,12 @@
*
* Private thread definitions for the uthread kernel.
*
- * $OpenBSD: pthread_private.h,v 1.17 1999/09/08 08:21:47 espie Exp $
- *
+ * $FreeBSD: pthread_private.h,v 1.27 1999/09/29 15:18:38 marcel Exp $
*/
#ifndef _PTHREAD_PRIVATE_H
#define _PTHREAD_PRIVATE_H
-#include <paths.h>
-
/*
* Include files.
*/
@@ -51,9 +49,7 @@
#include <sched.h>
#include <spinlock.h>
#include <pthread_np.h>
-#ifndef _NO_UTHREAD_MACHDEP
#include "uthread_machdep.h"
-#endif
/*
* Kernel fatal error handler macro.
@@ -66,33 +62,88 @@
/*
- * Priority queue manipulation macros:
+ * Priority queue manipulation macros (using pqe link):
*/
#define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd)
#define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd)
#define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd)
-#define PTHREAD_PRIOQ_FIRST _pq_first(&_readyq)
+#define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq)
/*
- * Waiting queue manipulation macros:
+ * Waiting queue manipulation macros (using pqe link):
*/
-#define PTHREAD_WAITQ_INSERT(thrd) TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe)
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd)
+#define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd)
+#define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive()
+#define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive()
+#else
#define PTHREAD_WAITQ_REMOVE(thrd) TAILQ_REMOVE(&_waitingq,thrd,pqe)
+#define PTHREAD_WAITQ_INSERT(thrd) do { \
+ if ((thrd)->wakeup_time.tv_sec == -1) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else { \
+ pthread_t tid = TAILQ_FIRST(&_waitingq); \
+ while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) && \
+ ((tid->wakeup_time.tv_sec < (thrd)->wakeup_time.tv_sec) || \
+ ((tid->wakeup_time.tv_sec == (thrd)->wakeup_time.tv_sec) && \
+ (tid->wakeup_time.tv_nsec <= (thrd)->wakeup_time.tv_nsec)))) \
+ tid = TAILQ_NEXT(tid, pqe); \
+ if (tid == NULL) \
+ TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \
+ else \
+ TAILQ_INSERT_BEFORE(tid,thrd,pqe); \
+ } \
+} while (0)
+#define PTHREAD_WAITQ_CLEARACTIVE()
+#define PTHREAD_WAITQ_SETACTIVE()
+#endif
+
+/*
+ * Work queue manipulation macros (using qe link):
+ */
+#define PTHREAD_WORKQ_INSERT(thrd) do { \
+ TAILQ_INSERT_TAIL(&_workq,thrd,qe); \
+ (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+#define PTHREAD_WORKQ_REMOVE(thrd) do { \
+ TAILQ_REMOVE(&_workq,thrd,qe); \
+ (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \
+} while (0)
+
/*
* State change macro without scheduling queue change:
*/
-#define PTHREAD_SET_STATE(thrd, newstate) { \
+#define PTHREAD_SET_STATE(thrd, newstate) do { \
(thrd)->state = newstate; \
(thrd)->fname = __FILE__; \
(thrd)->lineno = __LINE__; \
-}
+} while (0)
/*
* State change macro with scheduling queue change - This must be
* called with preemption deferred (see thread_kern_sched_[un]defer).
*/
-#define PTHREAD_NEW_STATE(thrd, newstate) { \
+#if defined(_PTHREADS_INVARIANTS)
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
+ if (_thread_kern_new_state != 0) \
+ PANIC("Recursive PTHREAD_NEW_STATE"); \
+ _thread_kern_new_state = 1; \
+ if ((thrd)->state != newstate) { \
+ if ((thrd)->state == PS_RUNNING) { \
+ PTHREAD_PRIOQ_REMOVE(thrd); \
+ PTHREAD_WAITQ_INSERT(thrd); \
+ } else if (newstate == PS_RUNNING) { \
+ PTHREAD_WAITQ_REMOVE(thrd); \
+ PTHREAD_PRIOQ_INSERT_TAIL(thrd); \
+ } \
+ } \
+ _thread_kern_new_state = 0; \
+ PTHREAD_SET_STATE(thrd, newstate); \
+} while (0)
+#else
+#define PTHREAD_NEW_STATE(thrd, newstate) do { \
if ((thrd)->state != newstate) { \
if ((thrd)->state == PS_RUNNING) { \
PTHREAD_PRIOQ_REMOVE(thrd); \
@@ -103,7 +154,8 @@
} \
} \
PTHREAD_SET_STATE(thrd, newstate); \
-}
+} while (0)
+#endif
/*
* Define the signals to be used for scheduling.
@@ -117,15 +169,6 @@
#endif
/*
- * Queue definitions.
- */
-struct pthread_queue {
- struct pthread *q_next;
- struct pthread *q_last;
- void *q_data;
-};
-
-/*
* Priority queues.
*
* XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
@@ -145,14 +188,9 @@ typedef struct pq_queue {
/*
- * Static queue initialization values.
- */
-#define PTHREAD_QUEUE_INITIALIZER { NULL, NULL, NULL }
-
-/*
* TailQ initialization values.
*/
-#define TAILQ_INITIALIZER { NULL, NULL }
+#define TAILQ_INITIALIZER { NULL, NULL }
/*
* Mutex definitions.
@@ -223,7 +261,7 @@ struct pthread_mutex_attr {
*/
enum pthread_cond_type {
COND_TYPE_FAST,
- COND_TYPE_MAX
+#define COND_TYPE_MAX ((int)COND_TYPE_FAST + 1)
};
struct pthread_cond {
@@ -255,8 +293,8 @@ struct pthread_cond_attr {
* Static cond initialization values.
*/
#define PTHREAD_COND_STATIC_INITIALIZER \
- { COND_TYPE_FAST, PTHREAD_QUEUE_INITIALIZER, NULL, NULL, \
- 0, _SPINLOCK_INITIALIZER }
+ { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \
+ 0, _SPINLOCK_INITIALIZER }
/*
* Cleanup definitions.
@@ -290,6 +328,13 @@ struct pthread_attr {
* Miscellaneous definitions.
*/
#define PTHREAD_STACK_DEFAULT 65536
+/*
+ * Maximum size of initial thread's stack. This perhaps deserves to be larger
+ * than the stacks of other threads, since many applications are likely to run
+ * almost entirely on this stack.
+ */
+#define PTHREAD_STACK_INITIAL 0x100000
+/* Address immediately beyond the beginning of the initial thread stack. */
#define PTHREAD_DEFAULT_PRIORITY 64
#define PTHREAD_MAX_PRIORITY 126
#define PTHREAD_MIN_PRIORITY 0
@@ -301,12 +346,6 @@ struct pthread_attr {
#define CLOCK_RES_NSEC 10000000
/*
- * Number of microseconds between incremental priority updates for
- * threads that are ready to run, but denied being run.
- */
-#define INC_PRIO_USEC 500000
-
-/*
* Time slice period in microseconds.
*/
#define TIMESLICE_USEC 100000
@@ -343,6 +382,7 @@ enum pthread_state {
PS_FDR_WAIT,
PS_FDW_WAIT,
PS_FILE_WAIT,
+ PS_POLL_WAIT,
PS_SELECT_WAIT,
PS_SLEEP_WAIT,
PS_WAIT_WAIT,
@@ -352,8 +392,8 @@ enum pthread_state {
PS_JOIN,
PS_SUSPENDED,
PS_DEAD,
- PS_DEADLOCK,
- PS_STATE_MAX
+ PS_DEADLOCK
+#define PS_STATE_MAX ((int)PS_DEADLOCK + 1)
};
@@ -375,8 +415,8 @@ struct fd_table_entry {
* state of the lock on the file descriptor.
*/
spinlock_t lock;
- struct pthread_queue r_queue; /* Read queue. */
- struct pthread_queue w_queue; /* Write queue. */
+ TAILQ_HEAD(, pthread) r_queue; /* Read queue. */
+ TAILQ_HEAD(, pthread) w_queue; /* Write queue. */
struct pthread *r_owner; /* Ptr to thread owning read lock. */
struct pthread *w_owner; /* Ptr to thread owning write lock. */
const char *r_fname; /* Ptr to read lock source file name */
@@ -388,11 +428,9 @@ struct fd_table_entry {
int flags; /* Flags used in open. */
};
-struct pthread_select_data {
+struct pthread_poll_data {
int nfds;
- fd_set readfds;
- fd_set writefds;
- fd_set exceptfds;
+ struct pollfd *fds;
};
union pthread_wait_data {
@@ -404,10 +442,21 @@ union pthread_wait_data {
short branch; /* Line number, for debugging. */
const char *fname; /* Source file name for debugging.*/
} fd;
- struct pthread_select_data * select_data;
+ struct pthread_poll_data * poll_data;
spinlock_t *spinlock;
};
+/* Spare thread stack. */
+struct stack {
+ SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */
+ void *base; /* Bottom of useful stack */
+ size_t size; /* Size of useful stack */
+ void *redzone; /* Red zone location */
+ void *storage; /* allocated storage */
+};
+
+typedef TAILQ_ENTRY(pthread) pthread_entry_t;
+
/*
* Thread structure.
*/
@@ -425,15 +474,11 @@ struct pthread {
*/
spinlock_t lock;
- /*
- * Pointer to the next thread in the thread linked list.
- */
- struct pthread *nxt;
+ /* Queue entry for list of all threads: */
+ pthread_entry_t tle;
- /*
- * Pointer to the next thread in the dead thread linked list.
- */
- struct pthread *nxt_dead;
+ /* Queue entry for list of dead threads: */
+ pthread_entry_t dle;
/*
* Thread start routine, argument, stack pointer and thread
@@ -441,7 +486,7 @@ struct pthread {
*/
void *(*start_routine)(void *);
void *arg;
- void *stack;
+ struct stack *stack;
struct pthread_attr attr;
/*
@@ -450,6 +495,17 @@ struct pthread {
*/
struct sigcontext saved_sigcontext;
+ /*
+ * Saved jump buffer used in call to longjmp by _thread_kern_sched
+ * if sig_saved is FALSE.
+ */
+ _machdep_jmp_buf saved_jmp_buf;
+
+ /*
+ * Further machine-dependent context, valid if sig_saved is FALSE.
+ */
+ struct _machdep_struct _machdep;
+
/*
* TRUE if the last state saved was a signal context. FALSE if the
* last state saved was a jump buffer.
@@ -484,12 +540,6 @@ struct pthread {
long slice_usec;
/*
- * Cumulative times spent in thread
- */
- struct timeval ru_utime;
- struct timeval ru_stime;
-
- /*
* Incremental priority accumulated by thread while it is ready to
* run but is denied being run.
*/
@@ -510,36 +560,41 @@ struct pthread {
*/
int error;
- /* Join queue for waiting threads: */
- struct pthread_queue join_queue;
+ /* Join queue head and link for waiting threads: */
+ TAILQ_HEAD(join_head, pthread) join_queue;
/*
- * The current thread can belong to only one scheduling queue
- * at a time (ready or waiting queue). It can also belong to
- * a queue of threads waiting on mutexes or condition variables.
- * Use pqe for the scheduling queue link (both ready and waiting),
- * and qe for other links (mutexes and condition variables).
+ * The current thread can belong to only one scheduling queue at
+ * a time (ready or waiting queue). It can also belong to (only)
+ * one of:
*
- * Pointer to queue (if any) on which the current thread is waiting.
+ * o A queue of threads waiting for a mutex
+ * o A queue of threads waiting for a condition variable
+ * o A queue of threads waiting for another thread to terminate
+ * (the join queue above)
+ * o A queue of threads waiting for a file descriptor lock
+ * o A queue of threads needing work done by the kernel thread
+ * (waiting for a spinlock or file I/O)
*
- * XXX The queuing should be changed to use the TAILQ entry below.
- * XXX For the time being, it's hybrid.
+ * Use pqe for the scheduling queue link (both ready and waiting),
+ * and qe for other links.
*/
- struct pthread_queue *queue;
-
- /* Pointer to next element in queue. */
- struct pthread *qnxt;
/* Priority queue entry for this thread: */
- TAILQ_ENTRY(pthread) pqe;
+ pthread_entry_t pqe;
/* Queue entry for this thread: */
- TAILQ_ENTRY(pthread) qe;
+ pthread_entry_t qe;
/* Wait data. */
union pthread_wait_data data;
/*
+ * Allocated for converting select into poll.
+ */
+ struct pthread_poll_data poll_data;
+
+ /*
* Set to TRUE if a blocking operation was
* interrupted by a signal:
*/
@@ -549,25 +604,28 @@ struct pthread {
int signo;
/*
- * Set to non-zero when this thread has deferred thread
- * scheduling. We allow for recursive deferral.
+ * Set to non-zero when this thread has deferred signals.
+ * We allow for recursive deferral.
*/
- int sched_defer_count;
+ int sig_defer_count;
/*
* Set to TRUE if this thread should yield after undeferring
- * thread scheduling.
+ * signals.
*/
- int yield_on_sched_undefer;
+ int yield_on_sig_undefer;
/* Miscellaneous data. */
int flags;
#define PTHREAD_FLAGS_PRIVATE 0x0001
#define PTHREAD_EXITING 0x0002
-#define PTHREAD_FLAGS_QUEUED 0x0004 /* in queue (qe is used) */
-#define PTHREAD_FLAGS_TRACE 0x0008
-#define PTHREAD_CANCELLING 0x0010 /* thread has been cancelled */
-#define PTHREAD_AT_CANCEL_POINT 0x0020 /* thread at cancel point */
+#define PTHREAD_FLAGS_IN_CONDQ 0x0004 /* in condition queue using qe link*/
+#define PTHREAD_FLAGS_IN_WORKQ 0x0008 /* in work queue using qe link */
+#define PTHREAD_FLAGS_IN_WAITQ 0x0010 /* in waiting queue using pqe link*/
+#define PTHREAD_FLAGS_IN_PRIOQ 0x0020 /* in priority queue using pqe link*/
+#define PTHREAD_FLAGS_TRACE 0x0040 /* for debugging purposes */
+#define PTHREAD_FLAGS_CANCELED 0x1000 /* thread has been cancelled */
+#define PTHREAD_FLAGS_CANCELPT 0x2000 /* thread at cancel point */
/*
* Base priority is the user setable and retrievable priority
@@ -590,7 +648,7 @@ struct pthread {
/*
* Active priority is always the maximum of the threads base
* priority and inherited priority. When there is a change
- * in either the real or inherited priority, the active
+ * in either the base or inherited priority, the active
* priority must be recalculated.
*/
char active_priority;
@@ -611,17 +669,6 @@ struct pthread {
struct pthread_cleanup *cleanup;
const char *fname; /* Ptr to source file name */
int lineno; /* Source line number. */
-
- /*
- * Saved jump buffer used in call to longjmp by _thread_kern_sched
- * if sig_saved is FALSE.
- */
- _machdep_jmp_buf saved_jmp_buf;
-
-#ifndef _UTHREAD_MACHDEP
- /* Machine dependent information */
- struct _machdep_struct _machdep;
-#endif
};
/*
@@ -629,14 +676,13 @@ struct pthread {
*/
/* Kernel thread structure used when there are no running threads: */
-extern struct pthread volatile _thread_kern_thread;
-extern struct pthread * volatile _thread_kern_threadp;
+extern struct pthread _thread_kern_thread;
/* Ptr to the thread structure for the running thread: */
extern struct pthread * volatile _thread_run;
/* Ptr to the thread structure for the last user thread to run: */
-extern struct pthread * volatile _last_user_thread;
+extern struct pthread * volatile _last_user_thread;
/*
* Ptr to the thread running in single-threaded mode or NULL if
@@ -644,22 +690,23 @@ extern struct pthread * volatile _last_user_thread;
*/
extern struct pthread * volatile _thread_single;
-/* Ptr to the first thread in the thread linked list: */
-extern struct pthread * volatile _thread_link_list;
+/* List of all threads: */
+typedef TAILQ_HEAD(, pthread) _thread_list_t;
+extern _thread_list_t _thread_list;
/*
* Array of kernel pipe file descriptors that are used to ensure that
* no signals are missed in calls to _select.
*/
-extern int _thread_kern_pipe[2];
-extern int _thread_kern_in_select;
+extern int _thread_kern_pipe[2];
+extern int volatile _queue_signals;
extern int _thread_kern_in_sched;
/* Last time that an incremental priority update was performed: */
extern struct timeval kern_inc_prio_time;
/* Dead threads: */
-extern struct pthread * volatile _thread_dead;
+extern _thread_list_t _dead_list;
/* Initial thread: */
extern struct pthread *_thread_initial;
@@ -682,12 +729,18 @@ extern int _pthread_stdio_flags[3];
/* File table information: */
extern struct fd_table_entry **_thread_fd_table;
+
+/* Table for polling file descriptors: */
+extern struct pollfd *_thread_pfd_table;
+
extern const int dtablecount;
-extern int _thread_dtablesize;
+extern int _thread_dtablesize; /* Descriptor table size. */
+
+extern int _clock_res_nsec; /* Clock resolution in nsec. */
/* Garbage collector mutex and condition variable. */
-extern pthread_mutex_t _gc_mutex;
-extern pthread_cond_t _gc_cond;
+extern pthread_mutex_t _gc_mutex;
+extern pthread_cond_t _gc_cond;
/*
* Array of signal actions for this process.
@@ -698,19 +751,32 @@ extern struct sigaction _thread_sigact[NSIG];
* Scheduling queues:
*/
extern pq_queue_t _readyq;
-typedef TAILQ_HEAD(, pthread) _waitingq_t;
-extern _waitingq_t _waitingq;
+extern _thread_list_t _waitingq;
+
+/*
+ * Work queue:
+ */
+extern _thread_list_t _workq;
-/* Indicates that the waitingq now has threads ready to run. */
-extern volatile int _waitingq_check_reqd;
+/* Tracks the number of threads blocked while waiting for a spinlock. */
+extern volatile int _spinblock_count;
+
+/* Indicates that the signal queue needs to be checked. */
+extern volatile int _sigq_check_reqd;
/* Thread switch hook. */
extern pthread_switch_routine_t _sched_switch_hook;
/*
- * Where SIGINFO writes thread states when /dev/tty cannot be opened
+ * Spare stack queue. Stacks of default size are cached in order to reduce
+ * thread creation time. Spare stacks are used in LIFO order to increase cache
+ * locality.
*/
-#define INFO_DUMP_FILE "/tmp/uthread.dump"
+typedef SLIST_HEAD(, stack) _stack_list_t;
+extern _stack_list_t _stackq;
+
+/* Used for _PTHREADS_INVARIANTS checking. */
+extern int _thread_kern_new_state;
#ifdef _LOCK_DEBUG
#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \
@@ -722,6 +788,8 @@ extern pthread_switch_routine_t _sched_switch_hook;
#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
#endif
+extern int __isthreaded;
+
/*
* Function prototype definitions.
*/
@@ -733,49 +801,52 @@ int _thread_fd_lock(int, int, struct timespec *);
int _thread_fd_lock_debug(int, int, struct timespec *,const char *fname,int lineno);
void _dispatch_signals(void);
void _thread_signal(pthread_t, int);
-void _lock_thread(void);
-void _lock_thread_list(void);
-void _unlock_thread(void);
-void _unlock_thread_list(void);
int _mutex_cv_lock(pthread_mutex_t *);
int _mutex_cv_unlock(pthread_mutex_t *);
+int _mutex_reinit(pthread_mutex_t *);
void _mutex_notify_priochange(struct pthread *);
-int _pq_init(struct pq_queue *pq, int, int);
+int _cond_reinit(pthread_cond_t *);
+int _pq_alloc(struct pq_queue *, int, int);
+int _pq_init(struct pq_queue *);
void _pq_remove(struct pq_queue *pq, struct pthread *);
void _pq_insert_head(struct pq_queue *pq, struct pthread *);
void _pq_insert_tail(struct pq_queue *pq, struct pthread *);
struct pthread *_pq_first(struct pq_queue *pq);
-void _thread_exit(const char *, int, const char *)
- __attribute__((noreturn));
+#if defined(_PTHREADS_INVARIANTS)
+void _waitq_insert(pthread_t pthread);
+void _waitq_remove(pthread_t pthread);
+void _waitq_setactive(void);
+void _waitq_clearactive(void);
+#endif
+__dead void _thread_exit(const char *, int, const char *) __attribute__((noreturn));
void _thread_fd_unlock(int, int);
-void _thread_fd_unlock_debug(int, int, char *, int);
+void _thread_fd_unlock_debug(int, int, const char *, int);
void *_thread_cleanup(pthread_t);
void _thread_cleanupspecific(void);
void _thread_dump_info(void);
void _thread_init(void);
void _thread_kern_sched(struct sigcontext *);
-void _thread_kern_sched_state(enum pthread_state, const char *, int);
+void _thread_kern_sched_state(enum pthread_state,const char *fname,int lineno);
void _thread_kern_sched_state_unlock(enum pthread_state state,
spinlock_t *lock, char *fname, int lineno);
void _thread_kern_set_timeout(struct timespec *);
-void _thread_kern_sched_defer(void);
-void _thread_kern_sched_undefer(void);
+void _thread_kern_sig_defer(void);
+void _thread_kern_sig_undefer(void);
void _thread_sig_handler(int, int, struct sigcontext *);
+void _thread_sig_handle(int, struct sigcontext *);
+void _thread_sig_init(void);
void _thread_start(void);
void _thread_start_sig_handler(void);
void _thread_seterrno(pthread_t,int);
-void _thread_queue_init(struct pthread_queue *);
-void _thread_queue_enq(struct pthread_queue *, struct pthread *);
-int _thread_queue_remove(struct pthread_queue *, struct pthread *);
int _thread_fd_table_init(int fd);
-struct pthread *_thread_queue_get(struct pthread_queue *);
-struct pthread *_thread_queue_deq(struct pthread_queue *);
pthread_addr_t _thread_gc(pthread_addr_t);
void _thread_enter_cancellation_point(void);
void _thread_leave_cancellation_point(void);
void _thread_cancellation_point(void);
int _thread_slow_atomic_lock(volatile _spinlock_lock_t *);
int _thread_slow_atomic_is_locked(volatile _spinlock_lock_t *);
+struct stack * _thread_stack_alloc(void *, size_t);
+void _thread_stack_free(struct stack *);
/* #include <signal.h> */
#ifdef _USER_SIGNAL_H
@@ -900,7 +971,7 @@ int _thread_sys_fchdir(int);
int _thread_sys_fchown(int, uid_t, gid_t);
int _thread_sys_fsync(int);
int _thread_sys_ftruncate(int, off_t);
-long _thread_sys_fpathconf(int, int);
+long _thread_sys_fpathconf(int, int);
int _thread_sys_pause(void);
int _thread_sys_pipe(int *);
int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
@@ -909,8 +980,7 @@ pid_t _thread_sys_fork(void);
pid_t _thread_sys_tcgetpgrp(int);
ssize_t _thread_sys_read(int, void *, size_t);
ssize_t _thread_sys_write(int, const void *, size_t);
-void _thread_sys__exit(int)
- __attribute__((noreturn));
+__dead void _thread_sys__exit(int) __attribute__((noreturn));
#endif
/* #include <fcntl.h> */
@@ -948,16 +1018,16 @@ ssize_t _thread_sys_writev(int, const struct iovec *, int);
#endif
/* #include <sys/wait.h> */
-#ifdef _SYS_WAIT_H_
+#ifdef _SYS_WAIT_H_
pid_t _thread_sys_wait(int *);
pid_t _thread_sys_waitpid(pid_t, int *, int);
pid_t _thread_sys_wait3(int *, int, struct rusage *);
pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *);
#endif
-/* #include <sys/poll.h> */
+/* #include <poll.h> */
#ifdef _SYS_POLL_H_
-int _thread_sys_poll(struct pollfd[], int, int);
+int _thread_sys_poll(struct pollfd *, unsigned, int);
#endif
/* #include <sys/mman.h> */