1 /* $OpenBSD: pthread_private.h,v 1.53 2004/06/07 21:11:23 marc Exp $ */ 2 /* 3 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by John Birrell. 17 * 4. Neither the name of the author nor the names of any co-contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Private thread definitions for the uthread kernel. 34 * 35 * $FreeBSD: pthread_private.h,v 1.27 1999/09/29 15:18:38 marcel Exp $ 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 <signal.h> 54 #include <stdio.h> 55 #include <sys/queue.h> 56 #include <sys/types.h> 57 #include <sys/time.h> 58 #include <sched.h> 59 #include <spinlock.h> 60 #include <pthread_np.h> 61 #include "thread_private.h" 62 #include "uthread_machdep.h" 63 64 /* 65 * Workaround until we have ENOTSUP in errno.h 66 */ 67 #define ENOTSUP EOPNOTSUPP 68 69 /* 70 * Kernel fatal error handler macro. 71 */ 72 #define PANIC(string) _thread_exit(__FILE__,__LINE__,string) 73 74 /* Output debug messages like this: */ 75 #define stdout_debug(_x) _thread_sys_write(1,_x,strlen(_x)); 76 #define stderr_debug(_x) _thread_sys_write(2,_x,strlen(_x)); 77 78 79 /* 80 * Priority queue manipulation macros (using pqe link): 81 */ 82 #define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd) 83 #define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd) 84 #define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd) 85 #define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq) 86 87 /* 88 * Waiting queue manipulation macros (using pqe link): 89 */ 90 #define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd) 91 #define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd) 92 93 #if defined(_PTHREADS_INVARIANTS) 94 #define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive() 95 #define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive() 96 #else 97 #define PTHREAD_WAITQ_CLEARACTIVE() 98 #define PTHREAD_WAITQ_SETACTIVE() 99 #endif 100 101 /* 102 * Work queue manipulation macros (using qe link): 103 */ 104 #define PTHREAD_WORKQ_INSERT(thrd) do { \ 105 TAILQ_INSERT_TAIL(&_workq,thrd,qe); \ 106 (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \ 107 } while (0) 108 #define PTHREAD_WORKQ_REMOVE(thrd) do { \ 109 TAILQ_REMOVE(&_workq,thrd,qe); \ 110 (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \ 111 } while (0) 112 113 114 /* 115 * State change macro without scheduling queue change: 116 */ 117 #define PTHREAD_SET_STATE(thrd, newstate) do { \ 118 (thrd)->state = newstate; \ 119 (thrd)->fname = __FILE__; \ 120 (thrd)->lineno = __LINE__; \ 121 } while (0) 122 123 /* 124 * State change macro with scheduling queue change - This must be 125 * called with preemption deferred (see thread_kern_sched_[un]defer). 126 */ 127 #if defined(_PTHREADS_INVARIANTS) 128 #include <assert.h> 129 #define PTHREAD_ASSERT(cond, msg) do { \ 130 if (!(cond)) \ 131 PANIC(msg); \ 132 } while (0) 133 #define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \ 134 PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \ 135 "Illegal call from signal handler"); 136 #define PTHREAD_NEW_STATE(thrd, newstate) do { \ 137 if (_thread_kern_new_state != 0) \ 138 PANIC("Recursive PTHREAD_NEW_STATE"); \ 139 _thread_kern_new_state = 1; \ 140 if ((thrd)->state != newstate) { \ 141 if ((thrd)->state == PS_RUNNING) { \ 142 PTHREAD_PRIOQ_REMOVE(thrd); \ 143 PTHREAD_WAITQ_INSERT(thrd); \ 144 } else if (newstate == PS_RUNNING) { \ 145 PTHREAD_WAITQ_REMOVE(thrd); \ 146 PTHREAD_PRIOQ_INSERT_TAIL(thrd); \ 147 } \ 148 } \ 149 _thread_kern_new_state = 0; \ 150 PTHREAD_SET_STATE(thrd, newstate); \ 151 } while (0) 152 #else 153 #define PTHREAD_ASSERT(cond, msg) 154 #define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) 155 #define PTHREAD_NEW_STATE(thrd, newstate) do { \ 156 if ((thrd)->state != newstate) { \ 157 if ((thrd)->state == PS_RUNNING) { \ 158 PTHREAD_PRIOQ_REMOVE(thrd); \ 159 PTHREAD_WAITQ_INSERT(thrd); \ 160 } else if (newstate == PS_RUNNING) { \ 161 PTHREAD_WAITQ_REMOVE(thrd); \ 162 PTHREAD_PRIOQ_INSERT_TAIL(thrd); \ 163 } \ 164 } \ 165 PTHREAD_SET_STATE(thrd, newstate); \ 166 } while (0) 167 #endif 168 169 /* 170 * Define the signals to be used for scheduling. 171 */ 172 #if defined(_PTHREADS_COMPAT_SCHED) || defined(PROF) 173 #define _ITIMER_SCHED_TIMER ITIMER_VIRTUAL 174 #define _SCHED_SIGNAL SIGVTALRM 175 #else 176 #define _ITIMER_SCHED_TIMER ITIMER_PROF 177 #define _SCHED_SIGNAL SIGPROF 178 #endif 179 180 /* Lists with volatile elements */ 181 #define V_TAILQ_HEAD(name, type) \ 182 volatile struct name { \ 183 struct type * tqh_first; \ 184 struct type * volatile * tqh_last; \ 185 } 186 187 #define V_TAILQ_ENTRY(type) \ 188 volatile struct { \ 189 struct type * tqe_next; \ 190 struct type * volatile * tqe_prev; \ 191 } 192 193 /* List of all threads: */ 194 typedef V_TAILQ_HEAD(, pthread) _thread_list_t; 195 196 /* 197 * Priority queues. 198 * 199 * XXX It'd be nice if these were contained in uthread_priority_queue.[ch]. 200 */ 201 typedef struct pq_list { 202 _thread_list_t pl_head; /* list of threads at this priority */ 203 TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */ 204 int pl_prio; /* the priority of this list */ 205 int pl_queued; /* is this in the priority queue */ 206 } pq_list_t; 207 208 typedef struct pq_queue { 209 TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */ 210 pq_list_t *pq_lists; /* array of all priority lists */ 211 int pq_size; /* number of priority lists */ 212 } pq_queue_t; 213 214 215 /* 216 * TailQ initialization values. 217 */ 218 #define TAILQ_INITIALIZER { NULL, NULL } 219 220 /* 221 * Mutex definitions. 222 */ 223 union pthread_mutex_data { 224 void *m_ptr; 225 int m_count; 226 }; 227 228 struct pthread_mutex { 229 enum pthread_mutextype m_type; 230 int m_protocol; 231 V_TAILQ_HEAD(mutex_head, pthread) m_queue; 232 struct pthread *m_owner; 233 union pthread_mutex_data m_data; 234 long m_flags; 235 int m_refcount; 236 237 /* 238 * Used for priority inheritence and protection. 239 * 240 * m_prio - For priority inheritence, the highest active 241 * priority (threads locking the mutex inherit 242 * this priority). For priority protection, the 243 * ceiling priority of this mutex. 244 * m_saved_prio - mutex owners inherited priority before 245 * taking the mutex, restored when the owner 246 * unlocks the mutex. 247 */ 248 int m_prio; 249 int m_saved_prio; 250 251 /* 252 * Link for list of all mutexes a thread currently owns. 253 */ 254 V_TAILQ_ENTRY(pthread_mutex volatile) m_qe; 255 256 /* 257 * Lock for accesses to this structure. 258 */ 259 spinlock_t lock; 260 }; 261 262 /* 263 * Flags for mutexes. 264 */ 265 #define MUTEX_FLAGS_PRIVATE 0x01 266 #define MUTEX_FLAGS_INITED 0x02 267 #define MUTEX_FLAGS_BUSY 0x04 268 269 /* 270 * Static mutex initialization values. 271 */ 272 #define PTHREAD_MUTEX_STATIC_INITIALIZER \ 273 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \ 274 NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \ 275 _SPINLOCK_INITIALIZER } 276 277 struct pthread_mutex_attr { 278 enum pthread_mutextype m_type; 279 int m_protocol; 280 int m_ceiling; 281 long m_flags; 282 }; 283 284 #define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ 285 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } 286 287 /* 288 * Condition variable definitions. 289 */ 290 enum pthread_cond_type { 291 COND_TYPE_FAST, 292 COND_TYPE_MAX 293 }; 294 295 struct pthread_cond { 296 enum pthread_cond_type c_type; 297 V_TAILQ_HEAD(cond_head, pthread) c_queue; 298 pthread_mutex_t c_mutex; 299 long c_flags; 300 int c_seqno; 301 302 /* 303 * Lock for accesses to this structure. 304 */ 305 spinlock_t lock; 306 }; 307 308 struct pthread_cond_attr { 309 enum pthread_cond_type c_type; 310 long c_flags; 311 }; 312 313 /* 314 * Flags for condition variables. 315 */ 316 #define COND_FLAGS_PRIVATE 0x01 317 #define COND_FLAGS_INITED 0x02 318 #define COND_FLAGS_BUSY 0x04 319 320 /* 321 * Static cond initialization values. 322 */ 323 #define PTHREAD_COND_STATIC_INITIALIZER \ 324 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \ 325 0, 0, _SPINLOCK_INITIALIZER } 326 327 /* 328 * Semaphore definitions. 329 */ 330 struct sem { 331 #define SEM_MAGIC ((u_int32_t) 0x09fa4012) 332 u_int32_t magic; 333 pthread_mutex_t lock; 334 pthread_cond_t gtzero; 335 u_int32_t count; 336 u_int32_t nwaiters; 337 }; 338 339 /* 340 * Cleanup definitions. 341 */ 342 struct pthread_cleanup { 343 struct pthread_cleanup *next; 344 void (*routine)(void*); 345 void *routine_arg; 346 }; 347 348 struct pthread_attr { 349 int sched_policy; 350 int sched_inherit; 351 int sched_interval; 352 int prio; 353 int suspend; 354 int flags; 355 void *arg_attr; 356 void (*cleanup_attr)(void*); 357 void *stackaddr_attr; 358 size_t stacksize_attr; 359 size_t guardsize_attr; 360 }; 361 362 /* 363 * Thread creation state attributes. 364 */ 365 #define PTHREAD_CREATE_RUNNING 0 366 #define PTHREAD_CREATE_SUSPENDED 1 367 368 /* 369 * Additional state for a thread suspended with pthread_suspend_np(). 370 */ 371 enum pthread_susp { 372 SUSP_NO, /* Not suspended. */ 373 SUSP_YES, /* Suspended. */ 374 SUSP_JOIN, /* Suspended, joining. */ 375 SUSP_NOWAIT, /* Suspended, was in a mutex or condition queue. */ 376 SUSP_MUTEX_WAIT,/* Suspended, still in a mutex queue. */ 377 SUSP_COND_WAIT /* Suspended, still in a condition queue. */ 378 }; 379 380 /* 381 * Miscellaneous definitions. 382 */ 383 #define PTHREAD_STACK_DEFAULT 65536 384 /* 385 * Maximum size of initial thread's stack. This perhaps deserves to be larger 386 * than the stacks of other threads, since many applications are likely to run 387 * almost entirely on this stack. 388 */ 389 #define PTHREAD_STACK_INITIAL 0x100000 390 391 /* Address immediately beyond the beginning of the initial thread stack. */ 392 #define _POSIX_THREAD_ATTR_STACKSIZE 393 394 /* 395 * Define the different priority ranges. All applications have thread 396 * priorities constrained within 0-31. The threads library raises the 397 * priority when delivering signals in order to ensure that signal 398 * delivery happens (from the POSIX spec) "as soon as possible". 399 * In the future, the threads library will also be able to map specific 400 * threads into real-time (cooperating) processes or kernel threads. 401 * The RT and SIGNAL priorities will be used internally and added to 402 * thread base priorities so that the scheduling queue can handle both 403 * normal and RT priority threads with and without signal handling. 404 * 405 * The approach taken is that, within each class, signal delivery 406 * always has priority over thread execution. 407 */ 408 #define PTHREAD_DEFAULT_PRIORITY 15 409 #define PTHREAD_MIN_PRIORITY 0 410 #define PTHREAD_MAX_PRIORITY 31 /* 0x1F */ 411 #define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */ 412 #define PTHREAD_RT_PRIORITY 64 /* 0x40 */ 413 #define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY 414 #define PTHREAD_LAST_PRIORITY \ 415 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY) 416 #define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY) 417 418 /* 419 * Clock resolution in microseconds. 420 */ 421 #define CLOCK_RES_USEC 10000 422 #define CLOCK_RES_USEC_MIN 1000 423 424 /* 425 * Time slice period in microseconds. 426 */ 427 #define TIMESLICE_USEC 20000 428 429 /* 430 * Define a thread-safe macro to get the current time of day 431 * which is updated at regular intervals by the scheduling signal 432 * handler. 433 */ 434 #define GET_CURRENT_TOD(tv) \ 435 do { \ 436 tv.tv_sec = _sched_tod.tv_sec; \ 437 tv.tv_usec = _sched_tod.tv_usec; \ 438 } while (tv.tv_sec != _sched_tod.tv_sec) 439 440 441 struct pthread_key { 442 spinlock_t lock; 443 volatile int allocated; 444 volatile int count; 445 void (*destructor)(void*); 446 }; 447 448 struct pthread_rwlockattr { 449 int pshared; 450 }; 451 452 struct pthread_rwlock { 453 pthread_mutex_t lock; /* monitor lock */ 454 int state; /* 0 = idle >0 = # of readers -1 = writer */ 455 pthread_cond_t read_signal; 456 pthread_cond_t write_signal; 457 int blocked_writers; 458 }; 459 460 /* 461 * Thread states. 462 */ 463 enum pthread_state { 464 PS_RUNNING, 465 PS_SIGTHREAD, 466 PS_MUTEX_WAIT, 467 PS_COND_WAIT, 468 PS_FDLR_WAIT, 469 PS_FDLW_WAIT, 470 PS_FDR_WAIT, 471 PS_FDW_WAIT, 472 PS_FILE_WAIT, 473 PS_POLL_WAIT, 474 PS_SELECT_WAIT, 475 PS_SLEEP_WAIT, 476 PS_WAIT_WAIT, 477 PS_SIGSUSPEND, 478 PS_SIGWAIT, 479 PS_SPINBLOCK, 480 PS_JOIN, 481 PS_SUSPENDED, 482 PS_DEAD, 483 PS_DEADLOCK, 484 PS_STATE_MAX 485 }; 486 487 488 /* 489 * File descriptor locking definitions are defined in "thread_private.h" 490 */ 491 492 /* 493 * File descriptor table structure. 494 */ 495 struct fd_table_entry { 496 /* 497 * Lock for accesses to this file descriptor table 498 * entry. This is passed to _spinlock() to provide atomic 499 * access to this structure. It does *not* represent the 500 * state of the lock on the file descriptor. 501 */ 502 spinlock_t lock; 503 _thread_list_t r_queue; /* Read queue. */ 504 _thread_list_t w_queue; /* Write queue. */ 505 struct pthread *r_owner; /* thread owning read lock. */ 506 struct pthread *w_owner; /* thread owning write lock. */ 507 const char *r_fname; /* read lock source file name */ 508 int r_lineno; /* Read lock source line no. */ 509 const char *w_fname; /* write lock src file name */ 510 int w_lineno; /* Write lock src line no. */ 511 int r_lockcount; /* Count for FILE read locks. */ 512 int w_lockcount; /* Count for FILE write locks.*/ 513 int flags; /* Flags used in open. */ 514 int refcnt; /* how many fds use this entry*/ 515 }; 516 517 struct pthread_poll_data { 518 int nfds; 519 struct pollfd *fds; 520 }; 521 522 union pthread_wait_data { 523 pthread_mutex_t mutex; 524 pthread_cond_t cond; 525 const sigset_t *sigwait; /* Waiting on a signal in sigwait */ 526 struct { 527 short fd; /* Used when thread waiting on fd */ 528 short branch; /* Line number, for debugging. */ 529 const char *fname; /* Source file name for debugging.*/ 530 } fd; 531 FILE *fp; 532 struct pthread_poll_data *poll_data; 533 spinlock_t *spinlock; 534 struct pthread *thread; 535 }; 536 537 /* Spare thread stack. */ 538 struct stack { 539 SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */ 540 void *base; /* Bottom of useful stack */ 541 size_t size; /* Size of useful stack */ 542 void *redzone; /* Red zone location */ 543 void *storage; /* allocated storage */ 544 }; 545 546 /* 547 * Define a continuation routine that can be used to perform a 548 * transfer of control: 549 */ 550 typedef void (*thread_continuation_t) (void *); 551 552 typedef V_TAILQ_ENTRY(pthread) pthread_entry_t; 553 554 struct join_status { 555 struct pthread *thread; 556 void *ret; 557 int error; 558 }; 559 560 /* 561 * Thread structure. 562 */ 563 struct pthread { 564 /* 565 * Magic value to help recognize a valid thread structure 566 * from an invalid one: 567 */ 568 #define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115) 569 u_int32_t magic; 570 char *name; 571 572 /* 573 * Lock for accesses to this thread structure. 574 */ 575 spinlock_t lock; 576 577 /* Queue entry for list of all threads: */ 578 pthread_entry_t tle; 579 580 /* Queue entry for list of dead threads: */ 581 pthread_entry_t dle; 582 583 /* 584 * Thread start routine, argument, stack pointer and thread 585 * attributes. 586 */ 587 void *(*start_routine)(void *); 588 void *arg; 589 struct stack *stack; 590 struct pthread_attr attr; 591 592 /* 593 * Saved signal context used in call to sigreturn by 594 * _thread_kern_sched if sig_saved is TRUE. 595 */ 596 struct sigcontext saved_sigcontext; 597 598 /* 599 * Machine-dependent context, valid if sig_saved is FALSE. 600 */ 601 struct _machdep_state _machdep; 602 603 /* 604 * TRUE if the last state saved was a signal context. FALSE if the 605 * last state saved was a jump buffer. 606 */ 607 int sig_saved; 608 609 /* 610 * Cancelability flags - the lower 2 bits are used by cancel 611 * definitions in pthread.h 612 */ 613 #define PTHREAD_AT_CANCEL_POINT 0x0004 614 #define PTHREAD_CANCELLING 0x0008 615 #define PTHREAD_CANCEL_NEEDED 0x0010 616 int cancelflags; 617 618 enum pthread_susp suspended; 619 620 thread_continuation_t continuation; 621 622 /* 623 * Current signal mask and pending signals. 624 */ 625 sigset_t sigmask; 626 sigset_t sigpend; 627 628 /* Thread state: */ 629 enum pthread_state state; 630 631 /* Scheduling clock when this thread was last made active. */ 632 long last_active; 633 634 /* Scheduling clock when this thread was last made inactive. */ 635 long last_inactive; 636 637 /* 638 * Number of microseconds accumulated by this thread when 639 * time slicing is active. 640 */ 641 long slice_usec; 642 643 /* 644 * Time to wake up thread. This is used for sleeping threads and 645 * for any operation which may time out (such as select). 646 */ 647 struct timespec wakeup_time; 648 649 /* TRUE if operation has timed out. */ 650 int timeout; 651 652 /* 653 * Error variable used instead of errno. The function __error() 654 * returns a pointer to this. 655 */ 656 int error; 657 658 /* 659 * The joiner is the thread that is joining to this thread. The 660 * join status keeps track of a join operation to another thread. 661 */ 662 struct pthread *joiner; 663 struct join_status join_status; 664 665 /* 666 * The current thread can belong to only one scheduling queue at 667 * a time (ready or waiting queue). It can also belong to: 668 * 669 * o A queue of threads waiting for a mutex 670 * o A queue of threads waiting for a condition variable 671 * o A queue of threads waiting for a file descriptor lock 672 * o A queue of threads needing work done by the kernel thread 673 * (waiting for a spinlock or file I/O) 674 * 675 * A thread can also be joining a thread (the joiner field above). 676 * 677 * It must not be possible for a thread to belong to any of the 678 * above queues while it is handling a signal. Signal handlers 679 * may longjmp back to previous stack frames circumventing normal 680 * control flow. This could corrupt queue integrity if the thread 681 * retains membership in the queue. Therefore, if a thread is a 682 * member of one of these queues when a signal handler is invoked, 683 * it must remove itself from the queue before calling the signal 684 * handler and reinsert itself after normal return of the handler. 685 * 686 * Use pqe for the scheduling queue link (both ready and waiting), 687 * sqe for synchronization (mutex and condition variable) queue 688 * links, and qe for all other links. 689 */ 690 691 pthread_entry_t pqe; /* priority queue link */ 692 pthread_entry_t sqe; /* synchronization queue link */ 693 pthread_entry_t qe; /* all other queues link */ 694 695 /* Wait data. */ 696 union pthread_wait_data data; 697 698 /* 699 * Allocated for converting select into poll. 700 */ 701 struct pthread_poll_data poll_data; 702 703 /* 704 * Set to TRUE if a blocking operation was 705 * interrupted by a signal: 706 */ 707 int interrupted; 708 709 /* Signal number when in state PS_SIGWAIT: */ 710 int signo; 711 712 /* 713 * Set to non-zero when this thread has deferred signals. 714 * We allow for recursive deferral. 715 */ 716 int sig_defer_count; 717 718 /* 719 * Set to TRUE if this thread should yield after undeferring 720 * signals. 721 */ 722 int yield_on_sig_undefer; 723 724 /* Miscellaneous flags; only set with signals deferred. */ 725 int flags; 726 #define PTHREAD_FLAGS_PRIVATE 0x0001 727 #define PTHREAD_EXITING 0x0002 728 #define PTHREAD_FLAGS_IN_WAITQ 0x0004 /* in waiting queue using pqe link */ 729 #define PTHREAD_FLAGS_IN_PRIOQ 0x0008 /* in priority queue using pqe link */ 730 #define PTHREAD_FLAGS_IN_WORKQ 0x0010 /* in work queue using qe link */ 731 #define PTHREAD_FLAGS_IN_FILEQ 0x0020 /* in file lock queue using qe link */ 732 #define PTHREAD_FLAGS_IN_FDQ 0x0040 /* in fd lock queue using qe link */ 733 #define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link */ 734 #define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ 735 #define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */ 736 #define PTHREAD_FLAGS_IN_SYNCQ \ 737 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ) 738 739 /* 740 * Base priority is the user setable and retrievable priority 741 * of the thread. It is only affected by explicit calls to 742 * set thread priority and upon thread creation via a thread 743 * attribute or default priority. 744 */ 745 char base_priority; 746 747 /* 748 * Inherited priority is the priority a thread inherits by 749 * taking a priority inheritence or protection mutex. It 750 * is not affected by base priority changes. Inherited 751 * priority defaults to and remains 0 until a mutex is taken 752 * that is being waited on by any other thread whose priority 753 * is non-zero. 754 */ 755 char inherited_priority; 756 757 /* 758 * Active priority is always the maximum of the threads base 759 * priority and inherited priority. When there is a change 760 * in either the base or inherited priority, the active 761 * priority must be recalculated. 762 */ 763 char active_priority; 764 765 /* Number of priority ceiling or protection mutexes owned. */ 766 int priority_mutex_count; 767 768 /* Number rwlocks rdlocks held. */ 769 int rdlock_count; 770 771 /* 772 * Queue of currently owned mutexes. 773 */ 774 V_TAILQ_HEAD(, pthread_mutex volatile) mutexq; 775 776 void *ret; 777 const void **specific_data; 778 int specific_data_count; 779 780 /* Cleanup handlers Link List */ 781 struct pthread_cleanup *cleanup; 782 const char *fname; /* Ptr to source file name */ 783 int lineno; /* Source line number. */ 784 }; 785 786 /* 787 * Flags and prototypes for the machine dependent layer 788 */ 789 void _thread_machdep_switch(struct _machdep_state *newstate, 790 struct _machdep_state *savestate); 791 void _thread_machdep_init(struct _machdep_state *state, void *stackbase, 792 int stacksize, void (*entry)(void)); 793 void _thread_machdep_save_float_state(struct _machdep_state* statep); 794 void _thread_machdep_restore_float_state(struct _machdep_state* statep); 795 796 /* 797 * Global variables for the uthread kernel. 798 */ 799 800 /* Kernel thread structure used when there are no running threads: */ 801 SCLASS struct pthread _thread_kern_thread; 802 803 /* Ptr to the thread structure for the running thread: */ 804 SCLASS struct pthread * volatile _thread_run 805 #ifdef GLOBAL_PTHREAD_PRIVATE 806 = &_thread_kern_thread; 807 #else 808 ; 809 #endif 810 811 /* Ptr to the thread structure for the last user thread to run: */ 812 SCLASS struct pthread * volatile _last_user_thread 813 #ifdef GLOBAL_PTHREAD_PRIVATE 814 = &_thread_kern_thread; 815 #else 816 ; 817 #endif 818 819 /* 820 * Ptr to the thread running in single-threaded mode or NULL if 821 * running multi-threaded (default POSIX behaviour). 822 */ 823 SCLASS struct pthread * volatile _thread_single 824 #ifdef GLOBAL_PTHREAD_PRIVATE 825 = NULL; 826 #else 827 ; 828 #endif 829 830 SCLASS _thread_list_t _thread_list 831 #ifdef GLOBAL_PTHREAD_PRIVATE 832 = TAILQ_HEAD_INITIALIZER(_thread_list); 833 #else 834 ; 835 #endif 836 837 /* 838 * Array of kernel pipe file descriptors that are used to ensure that 839 * no signals are missed in calls to _select. 840 */ 841 SCLASS int _thread_kern_pipe[2] 842 #ifdef GLOBAL_PTHREAD_PRIVATE 843 = { 844 -1, 845 -1 846 }; 847 #else 848 ; 849 #endif 850 SCLASS int volatile _queue_signals 851 #ifdef GLOBAL_PTHREAD_PRIVATE 852 = 0; 853 #else 854 ; 855 #endif 856 SCLASS int volatile _thread_kern_in_sched 857 #ifdef GLOBAL_PTHREAD_PRIVATE 858 = 0; 859 #else 860 ; 861 #endif 862 863 SCLASS int _sig_in_handler 864 #ifdef GLOBAL_PTHREAD_PRIVATE 865 = 0; 866 #else 867 ; 868 #endif 869 870 /* Time of day at last scheduling timer signal: */ 871 SCLASS struct timeval volatile _sched_tod 872 #ifdef GLOBAL_PTHREAD_PRIVATE 873 = { 0, 0 }; 874 #else 875 ; 876 #endif 877 878 /* 879 * Current scheduling timer ticks; used as resource usage. 880 */ 881 SCLASS unsigned int volatile _sched_ticks 882 #ifdef GLOBAL_PTHREAD_PRIVATE 883 = 0; 884 #else 885 ; 886 #endif 887 888 /* Dead threads: */ 889 SCLASS _thread_list_t _dead_list 890 #ifdef GLOBAL_PTHREAD_PRIVATE 891 = TAILQ_HEAD_INITIALIZER(_dead_list); 892 #else 893 ; 894 #endif 895 896 /* Initial thread: */ 897 SCLASS struct pthread *_thread_initial 898 #ifdef GLOBAL_PTHREAD_PRIVATE 899 = NULL; 900 #else 901 ; 902 #endif 903 904 /* Default thread attributes: */ 905 SCLASS struct pthread_attr pthread_attr_default 906 #ifdef GLOBAL_PTHREAD_PRIVATE 907 = { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, 908 PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, 909 PTHREAD_STACK_DEFAULT }; 910 #else 911 ; 912 #endif 913 914 /* Default mutex attributes: */ 915 SCLASS struct pthread_mutex_attr pthread_mutexattr_default 916 #ifdef GLOBAL_PTHREAD_PRIVATE 917 = { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }; 918 #else 919 ; 920 #endif 921 922 /* Default condition variable attributes: */ 923 SCLASS struct pthread_cond_attr pthread_condattr_default 924 #ifdef GLOBAL_PTHREAD_PRIVATE 925 = { COND_TYPE_FAST, 0 }; 926 #else 927 ; 928 #endif 929 930 /* File table information: */ 931 SCLASS struct fd_table_entry **_thread_fd_table 932 #ifdef GLOBAL_PTHREAD_PRIVATE 933 = NULL; 934 #else 935 ; 936 #endif 937 938 /* Table for polling file descriptors: */ 939 SCLASS struct pollfd *_thread_pfd_table 940 #ifdef GLOBAL_PTHREAD_PRIVATE 941 = NULL; 942 #else 943 ; 944 #endif 945 946 SCLASS const int dtablecount 947 #ifdef GLOBAL_PTHREAD_PRIVATE 948 = 4096/sizeof(struct fd_table_entry); 949 #else 950 ; 951 #endif 952 SCLASS int _thread_dtablesize /* Descriptor table size. */ 953 #ifdef GLOBAL_PTHREAD_PRIVATE 954 = 0; 955 #else 956 ; 957 #endif 958 959 SCLASS int _clock_res_usec /* Clock resolution in usec. */ 960 #ifdef GLOBAL_PTHREAD_PRIVATE 961 = CLOCK_RES_USEC; 962 #else 963 ; 964 #endif 965 966 /* Garbage collector mutex and condition variable. */ 967 SCLASS pthread_mutex_t _gc_mutex 968 #ifdef GLOBAL_PTHREAD_PRIVATE 969 = NULL 970 #endif 971 ; 972 SCLASS pthread_cond_t _gc_cond 973 #ifdef GLOBAL_PTHREAD_PRIVATE 974 = NULL 975 #endif 976 ; 977 978 /* 979 * Array of signal actions for this process. 980 */ 981 SCLASS struct sigaction _thread_sigact[NSIG]; 982 983 /* 984 * Array of counts of dummy handlers for SIG_DFL signals. This is used to 985 * assure that there is always a dummy signal handler installed while there is a 986 * thread sigwait()ing on the corresponding signal. 987 */ 988 SCLASS int _thread_dfl_count[NSIG]; 989 990 /* 991 * Pending signals and mask for this process: 992 */ 993 SCLASS sigset_t _process_sigpending; 994 SCLASS sigset_t _process_sigmask 995 #ifdef GLOBAL_PTHREAD_PRIVATE 996 = 0 997 #endif 998 ; 999 1000 /* 1001 * Scheduling queues: 1002 */ 1003 SCLASS pq_queue_t _readyq; 1004 SCLASS _thread_list_t _waitingq; 1005 1006 /* 1007 * Work queue: 1008 */ 1009 SCLASS _thread_list_t _workq; 1010 1011 /* Tracks the number of threads blocked while waiting for a spinlock. */ 1012 SCLASS volatile int _spinblock_count 1013 #ifdef GLOBAL_PTHREAD_PRIVATE 1014 = 0 1015 #endif 1016 ; 1017 1018 /* Used to maintain pending and active signals: */ 1019 struct sigstatus { 1020 spinlock_t lock; /* structure access lock */ 1021 int pending; /* Is this a pending signal? */ 1022 siginfo_t siginfo; /* arg 2 to signal handler */ 1023 }; 1024 1025 SCLASS struct sigstatus _thread_sigq[NSIG]; 1026 1027 /* Indicates that the signal queue needs to be checked. */ 1028 SCLASS volatile int _sigq_check_reqd 1029 #ifdef GLOBAL_PTHREAD_PRIVATE 1030 = 0 1031 #endif 1032 ; 1033 1034 /* The signal stack. */ 1035 SCLASS struct sigaltstack _thread_sigstack; 1036 1037 /* Thread switch hook. */ 1038 SCLASS pthread_switch_routine_t _sched_switch_hook 1039 #ifdef GLOBAL_PTHREAD_PRIVATE 1040 = NULL 1041 #endif 1042 ; 1043 1044 /* 1045 * Spare stack queue. Stacks of default size are cached in order to reduce 1046 * thread creation time. Spare stacks are used in LIFO order to increase cache 1047 * locality. 1048 */ 1049 typedef SLIST_HEAD(, stack) _stack_list_t; 1050 extern _stack_list_t _stackq; 1051 1052 /* Used for _PTHREADS_INVARIANTS checking. */ 1053 SCLASS int _thread_kern_new_state 1054 #ifdef GLOBAL_PTHREAD_PRIVATE 1055 = 0; 1056 #else 1057 ; 1058 #endif 1059 1060 /* Undefine the storage class specifier: */ 1061 #undef SCLASS 1062 1063 /* 1064 * Function prototype definitions. 1065 */ 1066 __BEGIN_DECLS 1067 int *__error(void); 1068 int _find_thread(pthread_t); 1069 struct pthread *_get_curthread(void); 1070 void _set_curthread(struct pthread *); 1071 int _thread_create(pthread_t *, const pthread_attr_t *, 1072 void *(*start_routine)(void *), void *,pthread_t); 1073 void _dispatch_signal(int, struct sigcontext *); 1074 void _dispatch_signals(struct sigcontext *); 1075 void _thread_signal(pthread_t, int); 1076 int _mutex_cv_lock(pthread_mutex_t *); 1077 int _mutex_cv_unlock(pthread_mutex_t *); 1078 int _mutex_reinit(pthread_mutex_t *); 1079 void _mutex_notify_priochange(struct pthread *); 1080 int _cond_reinit(pthread_cond_t *); 1081 int _pq_alloc(struct pq_queue *, int, int); 1082 int _pq_init(struct pq_queue *); 1083 void _pq_remove(struct pq_queue *pq, struct pthread *); 1084 void _pq_insert_head(struct pq_queue *pq, struct pthread *); 1085 void _pq_insert_tail(struct pq_queue *pq, struct pthread *); 1086 struct pthread *_pq_first(struct pq_queue *pq); 1087 void _waitq_insert(pthread_t pthread); 1088 void _waitq_remove(pthread_t pthread); 1089 #if defined(_PTHREADS_INVARIANTS) 1090 void _waitq_setactive(void); 1091 void _waitq_clearactive(void); 1092 #endif 1093 __dead void _thread_exit(const char *, int, const char *) __attribute__((__noreturn__)); 1094 void *_thread_cleanup(pthread_t); 1095 void _thread_cleanupspecific(void); 1096 void _thread_clear_pending(int, pthread_t); 1097 void _thread_dump_data(const void *, int); 1098 void _thread_dump_info(void); 1099 void _thread_init(void); 1100 void _thread_kern_lock(int); 1101 void _thread_kern_sched(struct sigcontext *); 1102 void _thread_kern_sched_state(enum pthread_state, const char *, int); 1103 void _thread_kern_sched_state_unlock(enum pthread_state, spinlock_t *, 1104 const char *, int); 1105 void _thread_kern_set_timeout(const struct timespec *); 1106 void _thread_kern_sig_defer(void); 1107 void _thread_kern_sig_undefer(void); 1108 void _thread_kill_siginfo(int); 1109 void _thread_sig_handler(int, siginfo_t *, struct sigcontext *); 1110 int _thread_sig_handle(int, struct sigcontext *); 1111 void _thread_sig_init(void); 1112 void _thread_start(void); 1113 void _thread_start_sig_handler(void); 1114 void _thread_seterrno(pthread_t,int); 1115 void _thread_fd_init(void); 1116 int _thread_fd_table_init(int); 1117 int _thread_fd_table_dup(int, int); 1118 void _thread_fd_table_remove(int); 1119 void _thread_fd_unlock_owned(pthread_t); 1120 void _thread_fd_unlock_thread(struct pthread *, int, int); 1121 pthread_addr_t _thread_gc(pthread_addr_t); 1122 void _thread_enter_cancellation_point(void); 1123 void _thread_leave_cancellation_point(void); 1124 void _thread_cancellation_point(void); 1125 int _thread_slow_atomic_lock(volatile _spinlock_lock_t *); 1126 int _thread_slow_atomic_is_locked(volatile _spinlock_lock_t *); 1127 struct stack * _thread_stack_alloc(void *, size_t); 1128 void _thread_stack_free(struct stack *); 1129 1130 1131 /* #include <signal.h> */ 1132 #ifdef _USER_SIGNAL_H 1133 int _thread_sys_kill(pid_t, int); 1134 int _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *); 1135 int _thread_sys_sigblock(int); 1136 int _thread_sys_sigsetmask(int); 1137 int _thread_sys_sigpending(sigset_t *); 1138 int _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *); 1139 int _thread_sys_sigsuspend(const sigset_t *); 1140 int _thread_sys_siginterrupt(int, int); 1141 int _thread_sys_sigpause(int); 1142 int _thread_sys_sigreturn(struct sigcontext *); 1143 int _thread_sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); 1144 int _thread_sys_sigvec(int, struct sigvec *, struct sigvec *); 1145 void _thread_sys_psignal(unsigned int, const char *); 1146 void (*_thread_sys_signal(int, void (*)(int)))(int); 1147 #endif 1148 1149 /* #include <sys/stat.h> */ 1150 #ifdef _SYS_STAT_H_ 1151 int _thread_sys_fchmod(int, mode_t); 1152 int _thread_sys_fstat(int, struct stat *); 1153 int _thread_sys_fchflags(int, unsigned int); 1154 #endif 1155 1156 /* #include <sys/mount.h> */ 1157 #ifdef _SYS_MOUNT_H_ 1158 int _thread_sys_fstatfs(int, struct statfs *); 1159 #endif 1160 int _thread_sys_pipe(int *); 1161 1162 /* #include <sys/socket.h> */ 1163 #ifdef _SYS_SOCKET_H_ 1164 int _thread_sys_accept(int, struct sockaddr *, socklen_t *); 1165 int _thread_sys_bind(int, const struct sockaddr *, socklen_t); 1166 int _thread_sys_connect(int, const struct sockaddr *, socklen_t); 1167 int _thread_sys_getpeername(int, struct sockaddr *, socklen_t *); 1168 int _thread_sys_getsockname(int, struct sockaddr *, socklen_t *); 1169 int _thread_sys_getsockopt(int, int, int, void *, socklen_t *); 1170 int _thread_sys_listen(int, int); 1171 int _thread_sys_setsockopt(int, int, int, const void *, socklen_t); 1172 int _thread_sys_shutdown(int, int); 1173 int _thread_sys_socket(int, int, int); 1174 int _thread_sys_socketpair(int, int, int, int *); 1175 ssize_t _thread_sys_recv(int, void *, size_t, int); 1176 ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 1177 ssize_t _thread_sys_recvmsg(int, struct msghdr *, int); 1178 ssize_t _thread_sys_send(int, const void *, size_t, int); 1179 ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int); 1180 ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t); 1181 #endif 1182 1183 /* #include <stdio.h> */ 1184 #ifdef _STDIO_H_ 1185 FILE *_thread_sys_fdopen(int, const char *); 1186 FILE *_thread_sys_fopen(const char *, const char *); 1187 FILE *_thread_sys_freopen(const char *, const char *, FILE *); 1188 FILE *_thread_sys_popen(const char *, const char *); 1189 FILE *_thread_sys_tmpfile(void); 1190 char *_thread_sys_ctermid(char *); 1191 char *_thread_sys_cuserid(char *); 1192 char *_thread_sys_fgetln(FILE *, size_t *); 1193 char *_thread_sys_fgets(char *, int, FILE *); 1194 char *_thread_sys_gets(char *); 1195 char *_thread_sys_tempnam(const char *, const char *); 1196 char *_thread_sys_tmpnam(char *); 1197 int _thread_sys_fclose(FILE *); 1198 int _thread_sys_feof(FILE *); 1199 int _thread_sys_ferror(FILE *); 1200 int _thread_sys_fflush(FILE *); 1201 int _thread_sys_fgetc(FILE *); 1202 int _thread_sys_fgetpos(FILE *, fpos_t *); 1203 int _thread_sys_fileno(FILE *); 1204 int _thread_sys_fprintf(FILE *, const char *, ...); 1205 int _thread_sys_fpurge(FILE *); 1206 int _thread_sys_fputc(int, FILE *); 1207 int _thread_sys_fputs(const char *, FILE *); 1208 int _thread_sys_fscanf(FILE *, const char *, ...); 1209 int _thread_sys_fseek(FILE *, long, int); 1210 int _thread_sys_fsetpos(FILE *, const fpos_t *); 1211 int _thread_sys_getc(FILE *); 1212 int _thread_sys_getchar(void); 1213 int _thread_sys_getw(FILE *); 1214 int _thread_sys_pclose(FILE *); 1215 int _thread_sys_printf(const char *, ...); 1216 int _thread_sys_putc(int, FILE *); 1217 int _thread_sys_putchar(int); 1218 int _thread_sys_puts(const char *); 1219 int _thread_sys_putw(int, FILE *); 1220 int _thread_sys_remove(const char *); 1221 int _thread_sys_rename (const char *, const char *); 1222 int _thread_sys_scanf(const char *, ...); 1223 int _thread_sys_setlinebuf(FILE *); 1224 int _thread_sys_setvbuf(FILE *, char *, int, size_t); 1225 int _thread_sys_snprintf(char *, size_t, const char *, ...); 1226 int _thread_sys_sprintf(char *, const char *, ...); 1227 int _thread_sys_sscanf(const char *, const char *, ...); 1228 int _thread_sys_ungetc(int, FILE *); 1229 int _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_); 1230 int _thread_sys_vprintf(const char *, _BSD_VA_LIST_); 1231 int _thread_sys_vscanf(const char *, _BSD_VA_LIST_); 1232 int _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_); 1233 int _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_); 1234 int _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_); 1235 long _thread_sys_ftell(FILE *); 1236 size_t _thread_sys_fread(void *, size_t, size_t, FILE *); 1237 size_t _thread_sys_fwrite(const void *, size_t, size_t, FILE *); 1238 void _thread_sys_clearerr(FILE *); 1239 void _thread_sys_perror(const char *); 1240 void _thread_sys_rewind(FILE *); 1241 void _thread_sys_setbuf(FILE *, char *); 1242 void _thread_sys_setbuffer(FILE *, char *, int); 1243 #endif 1244 1245 /* #include <unistd.h> */ 1246 #ifdef _UNISTD_H_ 1247 char *_thread_sys_ttyname(int); 1248 int _thread_sys_close(int); 1249 int _thread_sys_closefrom(int); 1250 int _thread_sys_dup(int); 1251 int _thread_sys_dup2(int, int); 1252 int _thread_sys_exect(const char *, char * const *, char * const *); 1253 int _thread_sys_execve(const char *, char * const *, char * const *); 1254 int _thread_sys_fchdir(int); 1255 int _thread_sys_fchown(int, uid_t, gid_t); 1256 int _thread_sys_fsync(int); 1257 int _thread_sys_ftruncate(int, off_t); 1258 long _thread_sys_fpathconf(int, int); 1259 pid_t _thread_sys_getpid(void); 1260 int _thread_sys_pipe(int *); 1261 int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 1262 off_t _thread_sys_lseek(int, off_t, int); 1263 pid_t _thread_sys_fork(void); 1264 pid_t _thread_sys_tcgetpgrp(int); 1265 ssize_t _thread_sys_read(int, void *, size_t); 1266 ssize_t _thread_sys_write(int, const void *, size_t); 1267 __dead void _thread_sys__exit(int) __attribute__((__noreturn__)); 1268 #endif 1269 1270 /* #include <fcntl.h> */ 1271 #ifdef _SYS_FCNTL_H_ 1272 int _thread_sys_creat(const char *, mode_t); 1273 int _thread_sys_fcntl(int, int, ...); 1274 int _thread_sys_flock(int, int); 1275 int _thread_sys_open(const char *, int, ...); 1276 #endif 1277 1278 /* #include <sys/ioctl.h> */ 1279 #ifdef _SYS_IOCTL_H_ 1280 int _thread_sys_ioctl(int, unsigned long, ...); 1281 #endif 1282 1283 /* #include <dirent.h> */ 1284 #ifdef _DIRENT_H_ 1285 DIR *___thread_sys_opendir2(const char *, int); 1286 DIR *_thread_sys_opendir(const char *); 1287 int _thread_sys_alphasort(const void *, const void *); 1288 int _thread_sys_scandir(const char *, struct dirent ***, 1289 int (*)(struct dirent *), int (*)(const void *, const void *)); 1290 int _thread_sys_closedir(DIR *); 1291 int _thread_sys_getdirentries(int, char *, int, long *); 1292 long _thread_sys_telldir(const DIR *); 1293 struct dirent *_thread_sys_readdir(DIR *); 1294 void _thread_sys_rewinddir(DIR *); 1295 void _thread_sys_seekdir(DIR *, long); 1296 #endif 1297 1298 /* #include <sys/uio.h> */ 1299 #ifdef _SYS_UIO_H_ 1300 ssize_t _thread_sys_readv(int, const struct iovec *, int); 1301 ssize_t _thread_sys_writev(int, const struct iovec *, int); 1302 #endif 1303 1304 /* #include <sys/wait.h> */ 1305 #ifdef _SYS_WAIT_H_ 1306 pid_t _thread_sys_wait(int *); 1307 pid_t _thread_sys_waitpid(pid_t, int *, int); 1308 pid_t _thread_sys_wait3(int *, int, struct rusage *); 1309 pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *); 1310 #endif 1311 1312 /* #include <poll.h> */ 1313 #ifdef _SYS_POLL_H_ 1314 int _thread_sys_poll(struct pollfd *, unsigned, int); 1315 #endif 1316 1317 /* #include <sys/event.h> */ 1318 #ifdef _SYS_EVENT_H_ 1319 int _thread_sys_kqueue(void); 1320 int _thread_sys_kevent(int, const struct kevent *, int, struct kevent *, 1321 int, const struct timespec *); 1322 #endif 1323 1324 /* #include <sys/mman.h> */ 1325 int _thread_sys_msync(void *, size_t, int); 1326 1327 __END_DECLS 1328 1329 #endif /* !_PTHREAD_PRIVATE_H */ 1330