]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libkse/thread/thr_private.h
This commit was generated by cvs2svn to compensate for changes in r131722,
[FreeBSD/FreeBSD.git] / lib / libkse / thread / thr_private.h
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$
35  */
36
37 #ifndef _THR_PRIVATE_H
38 #define _THR_PRIVATE_H
39
40 /*
41  * Include files.
42  */
43 #include <setjmp.h>
44 #include <signal.h>
45 #include <stdio.h>
46 #include <sys/queue.h>
47 #include <sys/types.h>
48 #include <sys/time.h>
49 #include <sys/cdefs.h>
50 #include <sys/kse.h>
51 #include <sched.h>
52 #include <ucontext.h>
53 #include <unistd.h>
54 #include <pthread.h>
55 #include <pthread_np.h>
56
57 #include "lock.h"
58 #include "pthread_md.h"
59
60 /*
61  * Evaluate the storage class specifier.
62  */
63 #ifdef GLOBAL_PTHREAD_PRIVATE
64 #define SCLASS
65 #define SCLASS_PRESET(x...)     = x
66 #else
67 #define SCLASS                  extern
68 #define SCLASS_PRESET(x...)
69 #endif
70
71 /*
72  * Kernel fatal error handler macro.
73  */
74 #define PANIC(string)   _thr_exit(__FILE__,__LINE__,string)
75
76
77 /* Output debug messages like this: */
78 #define stdout_debug(args...)   _thread_printf(STDOUT_FILENO, ##args)
79 #define stderr_debug(args...)   _thread_printf(STDOUT_FILENO, ##args)
80
81 #define DBG_MUTEX       0x0001
82 #define DBG_SIG         0x0002
83
84 #ifdef _PTHREADS_INVARIANTS
85 #define THR_ASSERT(cond, msg) do {      \
86         if (!(cond))                    \
87                 PANIC(msg);             \
88 } while (0)
89 #else
90 #define THR_ASSERT(cond, msg)
91 #endif
92
93 /*
94  * State change macro without scheduling queue change:
95  */
96 #define THR_SET_STATE(thrd, newstate) do {                              \
97         (thrd)->state = newstate;                                       \
98         (thrd)->fname = __FILE__;                                       \
99         (thrd)->lineno = __LINE__;                                      \
100 } while (0)
101
102
103 #define TIMESPEC_ADD(dst, src, val)                             \
104         do {                                                    \
105                 (dst)->tv_sec = (src)->tv_sec + (val)->tv_sec;  \
106                 (dst)->tv_nsec = (src)->tv_nsec + (val)->tv_nsec; \
107                 if ((dst)->tv_nsec > 1000000000) {              \
108                         (dst)->tv_sec++;                        \
109                         (dst)->tv_nsec -= 1000000000;           \
110                 }                                               \
111         } while (0)
112
113 #define TIMESPEC_SUB(dst, src, val)                             \
114         do {                                                    \
115                 (dst)->tv_sec = (src)->tv_sec - (val)->tv_sec;  \
116                 (dst)->tv_nsec = (src)->tv_nsec - (val)->tv_nsec; \
117                 if ((dst)->tv_nsec < 0) {                       \
118                         (dst)->tv_sec--;                        \
119                         (dst)->tv_nsec += 1000000000;           \
120                 }                                               \
121         } while (0)
122
123 /*
124  * Priority queues.
125  *
126  * XXX It'd be nice if these were contained in uthread_priority_queue.[ch].
127  */
128 typedef struct pq_list {
129         TAILQ_HEAD(, pthread)   pl_head; /* list of threads at this priority */
130         TAILQ_ENTRY(pq_list)    pl_link; /* link for queue of priority lists */
131         int                     pl_prio; /* the priority of this list */
132         int                     pl_queued; /* is this in the priority queue */
133 } pq_list_t;
134
135 typedef struct pq_queue {
136         TAILQ_HEAD(, pq_list)    pq_queue; /* queue of priority lists */
137         pq_list_t               *pq_lists; /* array of all priority lists */
138         int                      pq_size;  /* number of priority lists */
139 #define PQF_ACTIVE      0x0001
140         int                      pq_flags;
141         int                      pq_threads;
142 } pq_queue_t;
143
144 /*
145  * Each KSEG has a scheduling queue.  For now, threads that exist in their
146  * own KSEG (system scope) will get a full priority queue.  In the future
147  * this can be optimized for the single thread per KSEG case.
148  */
149 struct sched_queue {
150         pq_queue_t              sq_runq;
151         TAILQ_HEAD(, pthread)   sq_waitq;       /* waiting in userland */
152 };
153
154 typedef struct kse_thr_mailbox *kse_critical_t;
155
156 struct kse_group;
157
158 #define MAX_KSE_LOCKLEVEL       5       
159 struct kse {
160         /* -- location and order specific items for gdb -- */
161         struct kcb              *k_kcb;
162         struct pthread          *k_curthread;   /* current thread */
163         struct kse_group        *k_kseg;        /* parent KSEG */
164         struct sched_queue      *k_schedq;      /* scheduling queue */
165         /* -- end of location and order specific items -- */
166         TAILQ_ENTRY(kse)        k_qe;           /* KSE list link entry */
167         TAILQ_ENTRY(kse)        k_kgqe;         /* KSEG's KSE list entry */
168         /*
169          * Items that are only modified by the kse, or that otherwise
170          * don't need to be locked when accessed
171          */
172         struct lock             k_lock;
173         struct lockuser         k_lockusers[MAX_KSE_LOCKLEVEL];
174         int                     k_locklevel;
175         stack_t                 k_stack;
176         int                     k_flags;
177 #define KF_STARTED                      0x0001  /* kernel kse created */
178 #define KF_INITIALIZED                  0x0002  /* initialized on 1st upcall */
179 #define KF_TERMINATED                   0x0004  /* kse is terminated */
180 #define KF_IDLE                         0x0008  /* kse is idle */
181 #define KF_SWITCH                       0x0010  /* thread switch in UTS */
182         int                     k_error;        /* syscall errno in critical */
183         int                     k_cpu;          /* CPU ID when bound */
184         int                     k_sigseqno;     /* signal buffered count */
185 };
186
187 #define KSE_SET_IDLE(kse)       ((kse)->k_flags |= KF_IDLE)
188 #define KSE_CLEAR_IDLE(kse)     ((kse)->k_flags &= ~KF_IDLE)
189 #define KSE_IS_IDLE(kse)        (((kse)->k_flags & KF_IDLE) != 0)
190 #define KSE_SET_SWITCH(kse)     ((kse)->k_flags |= KF_SWITCH)
191 #define KSE_CLEAR_SWITCH(kse)   ((kse)->k_flags &= ~KF_SWITCH)
192 #define KSE_IS_SWITCH(kse)      (((kse)->k_flags & KF_SWITCH) != 0)
193
194 /*
195  * Each KSE group contains one or more KSEs in which threads can run.
196  * At least for now, there is one scheduling queue per KSE group; KSEs
197  * within the same KSE group compete for threads from the same scheduling
198  * queue.  A scope system thread has one KSE in one KSE group; the group
199  * does not use its scheduling queue.
200  */
201 struct kse_group {
202         TAILQ_HEAD(, kse)       kg_kseq;        /* list of KSEs in group */
203         TAILQ_HEAD(, pthread)   kg_threadq;     /* list of threads in group */
204         TAILQ_ENTRY(kse_group)  kg_qe;          /* link entry */
205         struct sched_queue      kg_schedq;      /* scheduling queue */
206         struct lock             kg_lock;
207         int                     kg_threadcount; /* # of assigned threads */
208         int                     kg_ksecount;    /* # of assigned KSEs */
209         int                     kg_idle_kses;
210         int                     kg_flags;
211 #define KGF_SINGLE_THREAD               0x0001  /* scope system kse group */
212 #define KGF_SCHEDQ_INITED               0x0002  /* has an initialized schedq */
213 };
214
215 /*
216  * Add/remove threads from a KSE's scheduling queue.
217  * For now the scheduling queue is hung off the KSEG.
218  */
219 #define KSEG_THRQ_ADD(kseg, thr)                        \
220 do {                                                    \
221         TAILQ_INSERT_TAIL(&(kseg)->kg_threadq, thr, kle);\
222         (kseg)->kg_threadcount++;                       \
223 } while (0)
224
225 #define KSEG_THRQ_REMOVE(kseg, thr)                     \
226 do {                                                    \
227         TAILQ_REMOVE(&(kseg)->kg_threadq, thr, kle);    \
228         (kseg)->kg_threadcount--;                       \
229 } while (0)
230
231
232 /*
233  * Lock acquire and release for KSEs.
234  */
235 #define KSE_LOCK_ACQUIRE(kse, lck)                                      \
236 do {                                                                    \
237         if ((kse)->k_locklevel < MAX_KSE_LOCKLEVEL) {                   \
238                 (kse)->k_locklevel++;                                   \
239                 _lock_acquire((lck),                                    \
240                     &(kse)->k_lockusers[(kse)->k_locklevel - 1], 0);    \
241         }                                                               \
242         else                                                            \
243                 PANIC("Exceeded maximum lock level");                   \
244 } while (0)
245
246 #define KSE_LOCK_RELEASE(kse, lck)                                      \
247 do {                                                                    \
248         if ((kse)->k_locklevel > 0) {                                   \
249                 _lock_release((lck),                                    \
250                     &(kse)->k_lockusers[(kse)->k_locklevel - 1]);       \
251                 (kse)->k_locklevel--;                                   \
252         }                                                               \
253 } while (0)
254
255 /*
256  * Lock our own KSEG.
257  */
258 #define KSE_LOCK(curkse)                \
259         KSE_LOCK_ACQUIRE(curkse, &(curkse)->k_kseg->kg_lock)
260 #define KSE_UNLOCK(curkse)              \
261         KSE_LOCK_RELEASE(curkse, &(curkse)->k_kseg->kg_lock)
262
263 /*
264  * Lock a potentially different KSEG.
265  */
266 #define KSE_SCHED_LOCK(curkse, kseg)    \
267         KSE_LOCK_ACQUIRE(curkse, &(kseg)->kg_lock)
268 #define KSE_SCHED_UNLOCK(curkse, kseg)  \
269         KSE_LOCK_RELEASE(curkse, &(kseg)->kg_lock)
270
271 /*
272  * Waiting queue manipulation macros (using pqe link):
273  */
274 #define KSE_WAITQ_REMOVE(kse, thrd) \
275 do { \
276         if (((thrd)->flags & THR_FLAGS_IN_WAITQ) != 0) { \
277                 TAILQ_REMOVE(&(kse)->k_schedq->sq_waitq, thrd, pqe); \
278                 (thrd)->flags &= ~THR_FLAGS_IN_WAITQ; \
279         } \
280 } while (0)
281 #define KSE_WAITQ_INSERT(kse, thrd)     kse_waitq_insert(thrd)
282 #define KSE_WAITQ_FIRST(kse)            TAILQ_FIRST(&(kse)->k_schedq->sq_waitq)
283
284 #define KSE_WAKEUP(kse)         kse_wakeup(&(kse)->k_kcb->kcb_kmbx)
285
286 /*
287  * TailQ initialization values.
288  */
289 #define TAILQ_INITIALIZER       { NULL, NULL }
290
291 /*
292  * lock initialization values.
293  */
294 #define LCK_INITIALIZER         { NULL, NULL, LCK_DEFAULT }
295
296 struct pthread_mutex {
297         /*
298          * Lock for accesses to this structure.
299          */
300         struct lock                     m_lock;
301         enum pthread_mutextype          m_type;
302         int                             m_protocol;
303         TAILQ_HEAD(mutex_head, pthread) m_queue;
304         struct pthread                  *m_owner;
305         long                            m_flags;
306         int                             m_count;
307         int                             m_refcount;
308
309         /*
310          * Used for priority inheritence and protection.
311          *
312          *   m_prio       - For priority inheritence, the highest active
313          *                  priority (threads locking the mutex inherit
314          *                  this priority).  For priority protection, the
315          *                  ceiling priority of this mutex.
316          *   m_saved_prio - mutex owners inherited priority before
317          *                  taking the mutex, restored when the owner
318          *                  unlocks the mutex.
319          */
320         int                             m_prio;
321         int                             m_saved_prio;
322
323         /*
324          * Link for list of all mutexes a thread currently owns.
325          */
326         TAILQ_ENTRY(pthread_mutex)      m_qe;
327 };
328
329 /*
330  * Flags for mutexes. 
331  */
332 #define MUTEX_FLAGS_PRIVATE     0x01
333 #define MUTEX_FLAGS_INITED      0x02
334 #define MUTEX_FLAGS_BUSY        0x04
335
336 /*
337  * Static mutex initialization values. 
338  */
339 #define PTHREAD_MUTEX_STATIC_INITIALIZER                                \
340         { LCK_INITIALIZER, PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE,    \
341         TAILQ_INITIALIZER, NULL, MUTEX_FLAGS_PRIVATE, 0, 0, 0, 0,       \
342         TAILQ_INITIALIZER }
343
344 struct pthread_mutex_attr {
345         enum pthread_mutextype  m_type;
346         int                     m_protocol;
347         int                     m_ceiling;
348         long                    m_flags;
349 };
350
351 #define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
352         { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
353
354 /* 
355  * Condition variable definitions.
356  */
357 enum pthread_cond_type {
358         COND_TYPE_FAST,
359         COND_TYPE_MAX
360 };
361
362 struct pthread_cond {
363         /*
364          * Lock for accesses to this structure.
365          */
366         struct lock                     c_lock;
367         enum pthread_cond_type          c_type;
368         TAILQ_HEAD(cond_head, pthread)  c_queue;
369         struct pthread_mutex            *c_mutex;
370         long                            c_flags;
371         long                            c_seqno;
372 };
373
374 struct pthread_cond_attr {
375         enum pthread_cond_type  c_type;
376         long                    c_flags;
377 };
378
379 struct pthread_barrier {
380         pthread_mutex_t b_lock;
381         pthread_cond_t  b_cond;
382         int             b_count;
383         int             b_waiters;
384         int             b_generation;
385 };
386
387 struct pthread_barrierattr {
388         int             pshared;
389 };
390
391 struct pthread_spinlock {
392         volatile int    s_lock;
393         pthread_t       s_owner;
394 };
395
396 /*
397  * Flags for condition variables.
398  */
399 #define COND_FLAGS_PRIVATE      0x01
400 #define COND_FLAGS_INITED       0x02
401 #define COND_FLAGS_BUSY         0x04
402
403 /*
404  * Static cond initialization values. 
405  */
406 #define PTHREAD_COND_STATIC_INITIALIZER                         \
407         { LCK_INITIALIZER, COND_TYPE_FAST, TAILQ_INITIALIZER,   \
408         NULL, NULL, 0, 0 }
409
410 /*
411  * Cleanup definitions.
412  */
413 struct pthread_cleanup {
414         struct pthread_cleanup  *next;
415         void                    (*routine) ();
416         void                    *routine_arg;
417 };
418
419 struct pthread_atfork {
420         TAILQ_ENTRY(pthread_atfork) qe;
421         void (*prepare)(void);
422         void (*parent)(void);
423         void (*child)(void);
424 };
425
426 struct pthread_attr {
427         int     sched_policy;
428         int     sched_inherit;
429         int     sched_interval;
430         int     prio;
431         int     suspend;
432 #define THR_STACK_USER          0x100   /* 0xFF reserved for <pthread.h> */
433         int     flags;
434         void    *arg_attr;
435         void    (*cleanup_attr) ();
436         void    *stackaddr_attr;
437         size_t  stacksize_attr;
438         size_t  guardsize_attr;
439 };
440
441 /*
442  * Thread creation state attributes.
443  */
444 #define THR_CREATE_RUNNING              0
445 #define THR_CREATE_SUSPENDED            1
446
447 /*
448  * Miscellaneous definitions.
449  */
450 #define THR_STACK_DEFAULT                       65536
451
452 /*
453  * Maximum size of initial thread's stack.  This perhaps deserves to be larger
454  * than the stacks of other threads, since many applications are likely to run
455  * almost entirely on this stack.
456  */
457 #define THR_STACK_INITIAL                       0x100000
458
459 /*
460  * Define the different priority ranges.  All applications have thread
461  * priorities constrained within 0-31.  The threads library raises the
462  * priority when delivering signals in order to ensure that signal
463  * delivery happens (from the POSIX spec) "as soon as possible".
464  * In the future, the threads library will also be able to map specific
465  * threads into real-time (cooperating) processes or kernel threads.
466  * The RT and SIGNAL priorities will be used internally and added to
467  * thread base priorities so that the scheduling queue can handle both
468  * normal and RT priority threads with and without signal handling.
469  *
470  * The approach taken is that, within each class, signal delivery
471  * always has priority over thread execution.
472  */
473 #define THR_DEFAULT_PRIORITY                    15
474 #define THR_MIN_PRIORITY                        0
475 #define THR_MAX_PRIORITY                        31      /* 0x1F */
476 #define THR_SIGNAL_PRIORITY                     32      /* 0x20 */
477 #define THR_RT_PRIORITY                         64      /* 0x40 */
478 #define THR_FIRST_PRIORITY                      THR_MIN_PRIORITY
479 #define THR_LAST_PRIORITY       \
480         (THR_MAX_PRIORITY + THR_SIGNAL_PRIORITY + THR_RT_PRIORITY)
481 #define THR_BASE_PRIORITY(prio) ((prio) & THR_MAX_PRIORITY)
482
483 /*
484  * Clock resolution in microseconds.
485  */
486 #define CLOCK_RES_USEC                          10000
487
488 /*
489  * Time slice period in microseconds.
490  */
491 #define TIMESLICE_USEC                          20000
492
493 /*
494  * XXX - Define a thread-safe macro to get the current time of day
495  *       which is updated at regular intervals by something.
496  *
497  * For now, we just make the system call to get the time.
498  */
499 #define KSE_GET_TOD(curkse, tsp) \
500 do {                                                    \
501         *tsp = (curkse)->k_kcb->kcb_kmbx.km_timeofday;  \
502         if ((tsp)->tv_sec == 0)                         \
503                 clock_gettime(CLOCK_REALTIME, tsp);     \
504 } while (0)
505
506 struct pthread_rwlockattr {
507         int             pshared;
508 };
509
510 struct pthread_rwlock {
511         pthread_mutex_t lock;   /* monitor lock */
512         pthread_cond_t  read_signal;
513         pthread_cond_t  write_signal;
514         int             state;  /* 0 = idle  >0 = # of readers  -1 = writer */
515         int             blocked_writers;
516 };
517
518 /*
519  * Thread states.
520  */
521 enum pthread_state {
522         PS_RUNNING,
523         PS_LOCKWAIT,
524         PS_MUTEX_WAIT,
525         PS_COND_WAIT,
526         PS_SLEEP_WAIT,
527         PS_SIGSUSPEND,
528         PS_SIGWAIT,
529         PS_JOIN,
530         PS_SUSPENDED,
531         PS_DEAD,
532         PS_DEADLOCK,
533         PS_STATE_MAX
534 };
535
536 struct sigwait_data {
537         sigset_t        *waitset;
538         siginfo_t       *siginfo;       /* used to save siginfo for sigwaitinfo() */
539 };
540
541 union pthread_wait_data {
542         pthread_mutex_t mutex;
543         pthread_cond_t  cond;
544         struct lock     *lock;
545         struct sigwait_data *sigwait;
546 };
547
548 /*
549  * Define a continuation routine that can be used to perform a
550  * transfer of control:
551  */
552 typedef void    (*thread_continuation_t) (void *);
553
554 /*
555  * This stores a thread's state prior to running a signal handler.
556  * It is used when a signal is delivered to a thread blocked in
557  * userland.  If the signal handler returns normally, the thread's
558  * state is restored from here.
559  */
560 struct pthread_sigframe {
561         int                     psf_valid;
562         int                     psf_flags;
563         int                     psf_interrupted;
564         int                     psf_timeout;
565         int                     psf_signo;
566         enum pthread_state      psf_state;
567         union pthread_wait_data psf_wait_data;
568         struct timespec         psf_wakeup_time;
569         sigset_t                psf_sigset;
570         sigset_t                psf_sigmask;
571         int                     psf_seqno;
572 };
573
574 struct join_status {
575         struct pthread  *thread;
576         void            *ret;
577         int             error;
578 };
579
580 struct pthread_specific_elem {
581         const void      *data;
582         int             seqno;
583 };
584
585
586 #define MAX_THR_LOCKLEVEL       5       
587 /*
588  * Thread structure.
589  */
590 struct pthread {
591         /*
592          * Thread mailbox is first so it cal be aligned properly.
593          */
594         struct tcb              *tcb;
595
596         /*
597          * Magic value to help recognize a valid thread structure
598          * from an invalid one:
599          */
600 #define THR_MAGIC               ((u_int32_t) 0xd09ba115)
601         u_int32_t               magic;
602         char                    *name;
603         u_int64_t               uniqueid; /* for gdb */
604
605         /* Queue entry for list of all threads: */
606         TAILQ_ENTRY(pthread)    tle;    /* link for all threads in process */
607         TAILQ_ENTRY(pthread)    kle;    /* link for all threads in KSE/KSEG */
608
609         /* Queue entry for GC lists: */
610         TAILQ_ENTRY(pthread)    gcle;
611
612         /* Hash queue entry */
613         LIST_ENTRY(pthread)     hle;
614
615         /*
616          * Lock for accesses to this thread structure.
617          */
618         struct lock             lock;
619         struct lockuser         lockusers[MAX_THR_LOCKLEVEL];
620         int                     locklevel;
621         kse_critical_t          critical[MAX_KSE_LOCKLEVEL];
622         struct kse              *kse;
623         struct kse_group        *kseg;
624
625         /*
626          * Thread start routine, argument, stack pointer and thread
627          * attributes.
628          */
629         void                    *(*start_routine)(void *);
630         void                    *arg;
631         struct pthread_attr     attr;
632
633         int                     active;         /* thread running */
634         int                     blocked;        /* thread blocked in kernel */
635         int                     need_switchout;
636
637         /*
638          * Used for tracking delivery of signal handlers.
639          */
640         struct pthread_sigframe *curframe;
641         siginfo_t               *siginfo;
642
643         /*
644          * Cancelability flags - the lower 2 bits are used by cancel
645          * definitions in pthread.h
646          */
647 #define THR_AT_CANCEL_POINT             0x0004
648 #define THR_CANCELLING                  0x0008
649 #define THR_CANCEL_NEEDED               0x0010
650         int                     cancelflags;
651
652         thread_continuation_t   continuation;
653
654         /*
655          * The thread's base and pending signal masks.  The active
656          * signal mask is stored in the thread's context (in mailbox).
657          */
658         sigset_t                sigmask;
659         sigset_t                sigpend;
660         sigset_t                *oldsigmask;
661         volatile int            check_pending;
662         int                     refcount;
663
664         /* Thread state: */
665         enum pthread_state      state;
666         volatile int            lock_switch;
667
668         /*
669          * Number of microseconds accumulated by this thread when
670          * time slicing is active.
671          */
672         long                    slice_usec;
673
674         /*
675          * Time to wake up thread. This is used for sleeping threads and
676          * for any operation which may time out (such as select).
677          */
678         struct timespec         wakeup_time;
679
680         /* TRUE if operation has timed out. */
681         int                     timeout;
682
683         /*
684          * Error variable used instead of errno. The function __error()
685          * returns a pointer to this. 
686          */
687         int                     error;
688
689         /*
690          * The joiner is the thread that is joining to this thread.  The
691          * join status keeps track of a join operation to another thread.
692          */
693         struct pthread          *joiner;
694         struct join_status      join_status;
695
696         /*
697          * The current thread can belong to only one scheduling queue at
698          * a time (ready or waiting queue).  It can also belong to:
699          *
700          *   o A queue of threads waiting for a mutex
701          *   o A queue of threads waiting for a condition variable
702          *
703          * It is possible for a thread to belong to more than one of the
704          * above queues if it is handling a signal.  A thread may only
705          * enter a mutex or condition variable queue when it is not
706          * being called from a signal handler.  If a thread is a member
707          * of one of these queues when a signal handler is invoked, it
708          * must be removed from the queue before invoking the handler
709          * and then added back to the queue after return from the handler.
710          *
711          * Use pqe for the scheduling queue link (both ready and waiting),
712          * sqe for synchronization (mutex, condition variable, and join)
713          * queue links, and qe for all other links.
714          */
715         TAILQ_ENTRY(pthread)    pqe;    /* priority, wait queues link */
716         TAILQ_ENTRY(pthread)    sqe;    /* synchronization queue link */
717
718         /* Wait data. */
719         union pthread_wait_data data;
720
721         /*
722          * Set to TRUE if a blocking operation was
723          * interrupted by a signal:
724          */
725         int                     interrupted;
726
727         /*
728          * Set to non-zero when this thread has entered a critical
729          * region.  We allow for recursive entries into critical regions.
730          */
731         int                     critical_count;
732
733         /*
734          * Set to TRUE if this thread should yield after leaving a
735          * critical region to check for signals, messages, etc.
736          */
737         int                     critical_yield;
738
739         int                     sflags;
740 #define THR_FLAGS_IN_SYNCQ      0x0001
741
742         /* Miscellaneous flags; only set with scheduling lock held. */
743         int                     flags;
744 #define THR_FLAGS_PRIVATE       0x0001
745 #define THR_FLAGS_IN_WAITQ      0x0002  /* in waiting queue using pqe link */
746 #define THR_FLAGS_IN_RUNQ       0x0004  /* in run queue using pqe link */
747 #define THR_FLAGS_EXITING       0x0008  /* thread is exiting */
748 #define THR_FLAGS_SUSPENDED     0x0010  /* thread is suspended */
749 #define THR_FLAGS_GC_SAFE       0x0020  /* thread safe for cleaning */
750 #define THR_FLAGS_IN_TDLIST     0x0040  /* thread in all thread list */
751 #define THR_FLAGS_IN_GCLIST     0x0080  /* thread in gc list */
752         /*
753          * Base priority is the user setable and retrievable priority
754          * of the thread.  It is only affected by explicit calls to
755          * set thread priority and upon thread creation via a thread
756          * attribute or default priority.
757          */
758         char                    base_priority;
759
760         /*
761          * Inherited priority is the priority a thread inherits by
762          * taking a priority inheritence or protection mutex.  It
763          * is not affected by base priority changes.  Inherited
764          * priority defaults to and remains 0 until a mutex is taken
765          * that is being waited on by any other thread whose priority
766          * is non-zero.
767          */
768         char                    inherited_priority;
769
770         /*
771          * Active priority is always the maximum of the threads base
772          * priority and inherited priority.  When there is a change
773          * in either the base or inherited priority, the active
774          * priority must be recalculated.
775          */
776         char                    active_priority;
777
778         /* Number of priority ceiling or protection mutexes owned. */
779         int                     priority_mutex_count;
780
781         /* Number rwlocks rdlocks held. */
782         int                     rdlock_count;
783
784         /*
785          * Queue of currently owned mutexes.
786          */
787         TAILQ_HEAD(, pthread_mutex)     mutexq;
788
789         void                            *ret;
790         struct pthread_specific_elem    *specific;
791         int                             specific_data_count;
792
793         /* Alternative stack for sigaltstack() */
794         stack_t                         sigstk;
795
796         /*
797          * Current locks bitmap for rtld.
798          */
799         int     rtld_bits;
800
801         /* Cleanup handlers Link List */
802         struct pthread_cleanup *cleanup;
803         char                    *fname; /* Ptr to source file name  */
804         int                     lineno; /* Source line number.      */
805 };
806
807 /*
808  * Critical regions can also be detected by looking at the threads
809  * current lock level.  Ensure these macros increment and decrement
810  * the lock levels such that locks can not be held with a lock level
811  * of 0.
812  */
813 #define THR_IN_CRITICAL(thrd)                                   \
814         (((thrd)->locklevel > 0) ||                             \
815         ((thrd)->critical_count > 0))
816
817 #define THR_YIELD_CHECK(thrd)                                   \
818 do {                                                            \
819         if (((thrd)->critical_yield != 0) &&                    \
820             !(THR_IN_CRITICAL(thrd)))                           \
821                 _thr_sched_switch(thrd);                        \
822         else if (((thrd)->check_pending != 0) &&                \
823             !(THR_IN_CRITICAL(thrd)))                           \
824                 _thr_sig_check_pending(thrd);                   \
825 } while (0)
826
827 #define THR_LOCK_ACQUIRE(thrd, lck)                             \
828 do {                                                            \
829         if ((thrd)->locklevel < MAX_THR_LOCKLEVEL) {            \
830                 THR_DEACTIVATE_LAST_LOCK(thrd);                 \
831                 (thrd)->locklevel++;                            \
832                 _lock_acquire((lck),                            \
833                     &(thrd)->lockusers[(thrd)->locklevel - 1],  \
834                     (thrd)->active_priority);                   \
835         } else                                                  \
836                 PANIC("Exceeded maximum lock level");           \
837 } while (0)
838
839 #define THR_LOCK_RELEASE(thrd, lck)                             \
840 do {                                                            \
841         if ((thrd)->locklevel > 0) {                            \
842                 _lock_release((lck),                            \
843                     &(thrd)->lockusers[(thrd)->locklevel - 1]); \
844                 (thrd)->locklevel--;                            \
845                 THR_ACTIVATE_LAST_LOCK(thrd);                   \
846                 if ((thrd)->locklevel == 0)                     \
847                         THR_YIELD_CHECK(thrd);                  \
848         }                                                       \
849 } while (0)
850
851 #define THR_ACTIVATE_LAST_LOCK(thrd)                                    \
852 do {                                                                    \
853         if ((thrd)->locklevel > 0)                                      \
854                 _lockuser_setactive(                                    \
855                     &(thrd)->lockusers[(thrd)->locklevel - 1], 1);      \
856 } while (0)
857
858 #define THR_DEACTIVATE_LAST_LOCK(thrd)                                  \
859 do {                                                                    \
860         if ((thrd)->locklevel > 0)                                      \
861                 _lockuser_setactive(                                    \
862                     &(thrd)->lockusers[(thrd)->locklevel - 1], 0);      \
863 } while (0)
864
865 /*
866  * For now, threads will have their own lock separate from their
867  * KSE scheduling lock.
868  */
869 #define THR_LOCK(thr)                   THR_LOCK_ACQUIRE(thr, &(thr)->lock)
870 #define THR_UNLOCK(thr)                 THR_LOCK_RELEASE(thr, &(thr)->lock)
871 #define THR_THREAD_LOCK(curthrd, thr)   THR_LOCK_ACQUIRE(curthrd, &(thr)->lock)
872 #define THR_THREAD_UNLOCK(curthrd, thr) THR_LOCK_RELEASE(curthrd, &(thr)->lock)
873
874 /*
875  * Priority queue manipulation macros (using pqe link).  We use
876  * the thread's kseg link instead of the kse link because a thread
877  * does not (currently) have a statically assigned kse.
878  */
879 #define THR_RUNQ_INSERT_HEAD(thrd)      \
880         _pq_insert_head(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
881 #define THR_RUNQ_INSERT_TAIL(thrd)      \
882         _pq_insert_tail(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
883 #define THR_RUNQ_REMOVE(thrd)           \
884         _pq_remove(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
885 #define THR_RUNQ_FIRST(thrd)            \
886         _pq_first(&(thrd)->kseg->kg_schedq.sq_runq)
887
888 /*
889  * Macros to insert/remove threads to the all thread list and
890  * the gc list.
891  */
892 #define THR_LIST_ADD(thrd) do {                                 \
893         if (((thrd)->flags & THR_FLAGS_IN_TDLIST) == 0) {       \
894                 TAILQ_INSERT_HEAD(&_thread_list, thrd, tle);    \
895                 _thr_hash_add(thrd);                            \
896                 (thrd)->flags |= THR_FLAGS_IN_TDLIST;           \
897         }                                                       \
898 } while (0)
899 #define THR_LIST_REMOVE(thrd) do {                              \
900         if (((thrd)->flags & THR_FLAGS_IN_TDLIST) != 0) {       \
901                 TAILQ_REMOVE(&_thread_list, thrd, tle);         \
902                 _thr_hash_remove(thrd);                         \
903                 (thrd)->flags &= ~THR_FLAGS_IN_TDLIST;          \
904         }                                                       \
905 } while (0)
906 #define THR_GCLIST_ADD(thrd) do {                               \
907         if (((thrd)->flags & THR_FLAGS_IN_GCLIST) == 0) {       \
908                 TAILQ_INSERT_HEAD(&_thread_gc_list, thrd, gcle);\
909                 (thrd)->flags |= THR_FLAGS_IN_GCLIST;           \
910                 _gc_count++;                                    \
911         }                                                       \
912 } while (0)
913 #define THR_GCLIST_REMOVE(thrd) do {                            \
914         if (((thrd)->flags & THR_FLAGS_IN_GCLIST) != 0) {       \
915                 TAILQ_REMOVE(&_thread_gc_list, thrd, gcle);     \
916                 (thrd)->flags &= ~THR_FLAGS_IN_GCLIST;          \
917                 _gc_count--;                                    \
918         }                                                       \
919 } while (0)
920
921 #define GC_NEEDED()     (atomic_load_acq_int(&_gc_count) >= 5)
922
923 /*
924  * Locking the scheduling queue for another thread uses that thread's
925  * KSEG lock.
926  */
927 #define THR_SCHED_LOCK(curthr, thr) do {                \
928         (curthr)->critical[(curthr)->locklevel] = _kse_critical_enter(); \
929         (curthr)->locklevel++;                          \
930         KSE_SCHED_LOCK((curthr)->kse, (thr)->kseg);     \
931 } while (0)
932
933 #define THR_SCHED_UNLOCK(curthr, thr) do {              \
934         KSE_SCHED_UNLOCK((curthr)->kse, (thr)->kseg);   \
935         (curthr)->locklevel--;                          \
936         _kse_critical_leave((curthr)->critical[(curthr)->locklevel]); \
937 } while (0)
938
939 /* Take the scheduling lock with the intent to call the scheduler. */
940 #define THR_LOCK_SWITCH(curthr) do {                    \
941         (void)_kse_critical_enter();                    \
942         KSE_SCHED_LOCK((curthr)->kse, (curthr)->kseg);  \
943 } while (0)
944 #define THR_UNLOCK_SWITCH(curthr) do {                  \
945         KSE_SCHED_UNLOCK((curthr)->kse, (curthr)->kseg);\
946 } while (0)
947
948 #define THR_CRITICAL_ENTER(thr)         (thr)->critical_count++
949 #define THR_CRITICAL_LEAVE(thr) do {            \
950         (thr)->critical_count--;                \
951         if (((thr)->critical_yield != 0) &&     \
952             ((thr)->critical_count == 0)) {     \
953                 (thr)->critical_yield = 0;      \
954                 _thr_sched_switch(thr);         \
955         }                                       \
956 } while (0)
957
958 #define THR_IS_ACTIVE(thrd) \
959         ((thrd)->kse != NULL) && ((thrd)->kse->k_curthread == (thrd))
960
961 #define THR_IN_SYNCQ(thrd)      (((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0)
962
963 #define THR_IS_SUSPENDED(thrd) \
964         (((thrd)->state == PS_SUSPENDED) || \
965         (((thrd)->flags & THR_FLAGS_SUSPENDED) != 0))
966 #define THR_IS_EXITING(thrd)    (((thrd)->flags & THR_FLAGS_EXITING) != 0)
967
968 extern int __isthreaded;
969
970 static inline int
971 _kse_isthreaded(void)
972 {
973         return (__isthreaded != 0);
974 }
975
976 /*
977  * Global variables for the pthread kernel.
978  */
979
980 SCLASS void             *_usrstack      SCLASS_PRESET(NULL);
981 SCLASS struct kse       *_kse_initial   SCLASS_PRESET(NULL);
982 SCLASS struct pthread   *_thr_initial   SCLASS_PRESET(NULL);
983
984 /* List of all threads: */
985 SCLASS TAILQ_HEAD(, pthread)    _thread_list
986     SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_list));
987
988 /* List of threads needing GC: */
989 SCLASS TAILQ_HEAD(, pthread)    _thread_gc_list
990     SCLASS_PRESET(TAILQ_HEAD_INITIALIZER(_thread_gc_list));
991
992 SCLASS int      _thr_active_threads  SCLASS_PRESET(1);
993
994 SCLASS TAILQ_HEAD(atfork_head, pthread_atfork) _thr_atfork_list;
995 SCLASS pthread_mutex_t          _thr_atfork_mutex;
996
997 /* Default thread attributes: */
998 SCLASS struct pthread_attr _pthread_attr_default
999     SCLASS_PRESET({
1000         SCHED_RR, 0, TIMESLICE_USEC, THR_DEFAULT_PRIORITY,
1001         THR_CREATE_RUNNING,     PTHREAD_CREATE_JOINABLE, NULL,
1002         NULL, NULL, THR_STACK_DEFAULT, /* guardsize */0
1003     });
1004
1005 /* Default mutex attributes: */
1006 SCLASS struct pthread_mutex_attr _pthread_mutexattr_default
1007     SCLASS_PRESET({PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 });
1008
1009 /* Default condition variable attributes: */
1010 SCLASS struct pthread_cond_attr _pthread_condattr_default
1011     SCLASS_PRESET({COND_TYPE_FAST, 0});
1012
1013 /* Clock resolution in usec.    */
1014 SCLASS int              _clock_res_usec         SCLASS_PRESET(CLOCK_RES_USEC);
1015
1016 /* Array of signal actions for this process: */
1017 SCLASS struct sigaction _thread_sigact[_SIG_MAXSIG];
1018
1019 /*
1020  * Lock for above count of dummy handlers and for the process signal
1021  * mask and pending signal sets.
1022  */
1023 SCLASS struct lock      _thread_signal_lock;
1024
1025 /* Pending signals and mask for this process: */
1026 SCLASS sigset_t         _thr_proc_sigpending;
1027 SCLASS siginfo_t        _thr_proc_siginfo[_SIG_MAXSIG];
1028
1029 SCLASS pid_t            _thr_pid                SCLASS_PRESET(0);
1030
1031 /* Garbage collector lock. */
1032 SCLASS struct lock      _gc_lock;
1033 SCLASS int              _gc_check               SCLASS_PRESET(0);
1034 SCLASS int              _gc_count               SCLASS_PRESET(0);
1035
1036 SCLASS struct lock      _mutex_static_lock;
1037 SCLASS struct lock      _rwlock_static_lock;
1038 SCLASS struct lock      _keytable_lock;
1039 SCLASS struct lock      _thread_list_lock;
1040 SCLASS int              _thr_guard_default;
1041 SCLASS int              _thr_page_size;
1042 SCLASS pthread_t        _thr_sig_daemon;
1043 SCLASS int              _thr_debug_flags        SCLASS_PRESET(0);
1044
1045 /* Undefine the storage class and preset specifiers: */
1046 #undef  SCLASS
1047 #undef  SCLASS_PRESET
1048
1049
1050 /*
1051  * Function prototype definitions.
1052  */
1053 __BEGIN_DECLS
1054 int     _cond_reinit(pthread_cond_t *);
1055 void    _cond_wait_backout(struct pthread *);
1056 struct kse *_kse_alloc(struct pthread *, int sys_scope);
1057 kse_critical_t _kse_critical_enter(void);
1058 void    _kse_critical_leave(kse_critical_t);
1059 int     _kse_in_critical(void);
1060 void    _kse_free(struct pthread *, struct kse *);
1061 void    _kse_init();
1062 struct kse_group *_kseg_alloc(struct pthread *);
1063 void    _kse_lock_wait(struct lock *, struct lockuser *lu);
1064 void    _kse_lock_wakeup(struct lock *, struct lockuser *lu);
1065 void    _kse_single_thread(struct pthread *);
1066 int     _kse_setthreaded(int);
1067 void    _kseg_free(struct kse_group *);
1068 int     _mutex_cv_lock(pthread_mutex_t *);
1069 int     _mutex_cv_unlock(pthread_mutex_t *);
1070 void    _mutex_lock_backout(struct pthread *);
1071 void    _mutex_notify_priochange(struct pthread *, struct pthread *, int);
1072 int     _mutex_reinit(struct pthread_mutex *);
1073 void    _mutex_unlock_private(struct pthread *);
1074 void    _libpthread_init(struct pthread *);
1075 int     _pq_alloc(struct pq_queue *, int, int);
1076 void    _pq_free(struct pq_queue *);
1077 int     _pq_init(struct pq_queue *);
1078 void    _pq_remove(struct pq_queue *pq, struct pthread *);
1079 void    _pq_insert_head(struct pq_queue *pq, struct pthread *);
1080 void    _pq_insert_tail(struct pq_queue *pq, struct pthread *);
1081 struct pthread *_pq_first(struct pq_queue *pq);
1082 void    *_pthread_getspecific(pthread_key_t);
1083 int     _pthread_key_create(pthread_key_t *, void (*) (void *));
1084 int     _pthread_key_delete(pthread_key_t);
1085 int     _pthread_mutex_destroy(pthread_mutex_t *);
1086 int     _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
1087 int     _pthread_mutex_lock(pthread_mutex_t *);
1088 int     _pthread_mutex_trylock(pthread_mutex_t *);
1089 int     _pthread_mutex_unlock(pthread_mutex_t *);
1090 int     _pthread_mutexattr_init(pthread_mutexattr_t *);
1091 int     _pthread_mutexattr_destroy(pthread_mutexattr_t *);
1092 int     _pthread_mutexattr_settype(pthread_mutexattr_t *, int);
1093 int     _pthread_once(pthread_once_t *, void (*) (void));
1094 int     _pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *);
1095 int     _pthread_rwlock_destroy (pthread_rwlock_t *);
1096 struct pthread *_pthread_self(void);
1097 int     _pthread_setspecific(pthread_key_t, const void *);
1098 void    _pthread_yield(void);
1099 void    _pthread_cleanup_push(void (*routine) (void *), void *routine_arg);
1100 void    _pthread_cleanup_pop(int execute);
1101 struct pthread *_thr_alloc(struct pthread *);
1102 void    _thr_exit(char *, int, char *);
1103 void    _thr_exit_cleanup(void);
1104 void    _thr_lock_wait(struct lock *lock, struct lockuser *lu);
1105 void    _thr_lock_wakeup(struct lock *lock, struct lockuser *lu);
1106 void    _thr_mutex_reinit(pthread_mutex_t *);
1107 int     _thr_ref_add(struct pthread *, struct pthread *, int);
1108 void    _thr_ref_delete(struct pthread *, struct pthread *);
1109 void    _thr_rtld_init(void);
1110 void    _thr_rtld_fini(void);
1111 int     _thr_schedule_add(struct pthread *, struct pthread *);
1112 void    _thr_schedule_remove(struct pthread *, struct pthread *);
1113 void    _thr_setrunnable(struct pthread *curthread, struct pthread *thread);
1114 struct kse_mailbox *_thr_setrunnable_unlocked(struct pthread *thread);
1115 struct kse_mailbox *_thr_sig_add(struct pthread *, int, siginfo_t *);
1116 void    _thr_sig_dispatch(struct kse *, int, siginfo_t *);
1117 int     _thr_stack_alloc(struct pthread_attr *);
1118 void    _thr_stack_free(struct pthread_attr *);
1119 void    _thr_exit_cleanup(void);
1120 void    _thr_free(struct pthread *, struct pthread *);
1121 void    _thr_gc(struct pthread *);
1122 void    _thr_panic_exit(char *, int, char *);
1123 void    _thread_cleanupspecific(void);
1124 void    _thread_dump_info(void);
1125 void    _thread_printf(int, const char *, ...);
1126 void    _thr_sched_switch(struct pthread *);
1127 void    _thr_sched_switch_unlocked(struct pthread *);
1128 void    _thr_set_timeout(const struct timespec *);
1129 void    _thr_seterrno(struct pthread *, int);
1130 void    _thr_sig_handler(int, siginfo_t *, ucontext_t *);
1131 void    _thr_sig_check_pending(struct pthread *);
1132 void    _thr_sig_rundown(struct pthread *, ucontext_t *,
1133             struct pthread_sigframe *);
1134 void    _thr_sig_send(struct pthread *pthread, int sig);
1135 void    _thr_sigframe_restore(struct pthread *thread, struct pthread_sigframe *psf);
1136 void    _thr_spinlock_init(void);
1137 void    _thr_cancel_enter(struct pthread *);
1138 void    _thr_cancel_leave(struct pthread *, int);
1139 int     _thr_setconcurrency(int new_level);
1140 int     _thr_setmaxconcurrency(void);
1141 void    _thr_critical_enter(struct pthread *);
1142 void    _thr_critical_leave(struct pthread *);
1143 int     _thr_start_sig_daemon(void);
1144 int     _thr_getprocsig(int sig, siginfo_t *siginfo);
1145 int     _thr_getprocsig_unlocked(int sig, siginfo_t *siginfo);
1146 void    _thr_signal_init(void);
1147 void    _thr_signal_deinit(void);
1148 void    _thr_hash_add(struct pthread *);
1149 void    _thr_hash_remove(struct pthread *);
1150 struct pthread *_thr_hash_find(struct pthread *);
1151 void    _thr_finish_cancellation(void *arg);
1152 int     _thr_sigonstack(void *sp);
1153
1154 /*
1155  * Aliases for _pthread functions. Should be called instead of
1156  * originals if PLT replocation is unwanted at runtme.
1157  */
1158 int     _thr_cond_broadcast(pthread_cond_t *);
1159 int     _thr_cond_signal(pthread_cond_t *);
1160 int     _thr_cond_wait(pthread_cond_t *, pthread_mutex_t *);
1161 int     _thr_mutex_lock(pthread_mutex_t *);
1162 int     _thr_mutex_unlock(pthread_mutex_t *);
1163 int     _thr_rwlock_rdlock (pthread_rwlock_t *);
1164 int     _thr_rwlock_wrlock (pthread_rwlock_t *);
1165 int     _thr_rwlock_unlock (pthread_rwlock_t *);
1166
1167 /* #include <sys/aio.h> */
1168 #ifdef _SYS_AIO_H_
1169 int     __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
1170 #endif
1171
1172 /* #include <fcntl.h> */
1173 #ifdef  _SYS_FCNTL_H_
1174 int     __sys_fcntl(int, int, ...);
1175 int     __sys_open(const char *, int, ...);
1176 #endif
1177
1178 /* #include <sys/ioctl.h> */
1179 #ifdef _SYS_IOCTL_H_
1180 int     __sys_ioctl(int, unsigned long, ...);
1181 #endif
1182
1183 /* #inclde <sched.h> */
1184 #ifdef  _SCHED_H_
1185 int     __sys_sched_yield(void);
1186 #endif
1187
1188 /* #include <signal.h> */
1189 #ifdef _SIGNAL_H_
1190 int     __sys_kill(pid_t, int);
1191 int     __sys_sigaction(int, const struct sigaction *, struct sigaction *);
1192 int     __sys_sigpending(sigset_t *);
1193 int     __sys_sigprocmask(int, const sigset_t *, sigset_t *);
1194 int     __sys_sigsuspend(const sigset_t *);
1195 int     __sys_sigreturn(ucontext_t *);
1196 int     __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
1197 #endif
1198
1199 /* #include <sys/socket.h> */
1200 #ifdef _SYS_SOCKET_H_
1201 int     __sys_accept(int, struct sockaddr *, socklen_t *);
1202 int     __sys_connect(int, const struct sockaddr *, socklen_t);
1203 int     __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
1204             off_t *, int);
1205 #endif
1206
1207 /* #include <sys/uio.h> */
1208 #ifdef  _SYS_UIO_H_
1209 ssize_t __sys_readv(int, const struct iovec *, int);
1210 ssize_t __sys_writev(int, const struct iovec *, int);
1211 #endif
1212
1213 /* #include <time.h> */
1214 #ifdef  _TIME_H_
1215 int     __sys_nanosleep(const struct timespec *, struct timespec *);
1216 #endif
1217
1218 /* #include <unistd.h> */
1219 #ifdef  _UNISTD_H_
1220 int     __sys_close(int);
1221 int     __sys_execve(const char *, char * const *, char * const *);
1222 int     __sys_fork(void);
1223 int     __sys_fsync(int);
1224 pid_t   __sys_getpid(void);
1225 int     __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
1226 ssize_t __sys_read(int, void *, size_t);
1227 ssize_t __sys_write(int, const void *, size_t);
1228 void    __sys_exit(int);
1229 int     __sys_sigwait(const sigset_t *, int *);
1230 int     __sys_sigtimedwait(sigset_t *, siginfo_t *, struct timespec *);
1231 #endif
1232
1233 /* #include <poll.h> */
1234 #ifdef _SYS_POLL_H_
1235 int     __sys_poll(struct pollfd *, unsigned, int);
1236 #endif
1237
1238 /* #include <sys/mman.h> */
1239 #ifdef _SYS_MMAN_H_
1240 int     __sys_msync(void *, size_t, int);
1241 #endif
1242
1243 #endif  /* !_THR_PRIVATE_H */