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 * Evaluate the storage class specifier. 42 */ 43 #ifdef GLOBAL_PTHREAD_PRIVATE 44 #define SCLASS 45 #else 46 #define SCLASS extern 47 #endif 48 49 /* 50 * Include files. 51 */ 52 #include <sys/types.h> 53 #include <sys/cdefs.h> 54 #include <sys/errno.h> 55 #include <sys/time.h> 56 #include <sys/queue.h> 57 #include <pthread_np.h> 58 #include <sched.h> 59 #include <signal.h> 60 #include <spinlock.h> 61 #include <stdio.h> 62 #include <ucontext.h> 63 #include <unistd.h> 64 #if defined(_PTHREADS_INVARIANTS) 65 #include <assert.h> 66 #endif 67 68 #include <machine/atomic.h> 69 #include <sys/thr.h> 70 #include <sys/umtx.h> 71 72 #if defined(_PTHREADS_INVARIANTS) 73 /* 74 * Kernel fatal error handler macro. 75 */ 76 #define PANIC(string) \ 77 do { \ 78 _thread_printf(STDOUT_FILENO, (string)); \ 79 _thread_printf(STDOUT_FILENO, \ 80 "\nAbnormal termination, file: %s, line: %d\n", \ 81 __FILE__, __LINE__); \ 82 abort(); \ 83 } while (0) 84 85 #define PTHREAD_ASSERT(cond, msg) do { \ 86 if (!(cond)) \ 87 PANIC(msg); \ 88 } while (0) 89 90 #define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) \ 91 PTHREAD_ASSERT((((thrd)->flags & PTHREAD_FLAGS_IN_SYNCQ) == 0), \ 92 "Illegal call from signal handler"); 93 94 #else /* !_PTHREADS_INVARIANTS */ 95 #define PANIC(string) _thread_exit(__FILE__, __LINE__, (string)) 96 #define PTHREAD_ASSERT(cond, msg) 97 #define PTHREAD_ASSERT_NOT_IN_SYNCQ(thrd) 98 #endif /* _PTHREADS_INVARIANTS */ 99 100 /* Output debug messages like this: */ 101 #define stdout_debug(args...) _thread_printf(STDOUT_FILENO, args) 102 #define stderr_debug(args...) _thread_printf(STDOUT_FILENO, args) 103 104 /* 105 * Currently executing thread. 106 */ 107 #define curthread _get_curthread() 108 109 /* 110 * Locking macros 111 */ 112 #define UMTX_LOCK(m) \ 113 do { \ 114 if (umtx_lock((m), curthread->thr_id) != 0) \ 115 abort(); \ 116 } while (0) 117 118 #define UMTX_TRYLOCK(m, r) \ 119 do { \ 120 (r) = umtx_trylock((m), curthread->thr_id); \ 121 if ((r) != 0 && (r) != EBUSY) \ 122 abort(); \ 123 } while (0) 124 125 #define UMTX_UNLOCK(m) \ 126 do { \ 127 if (umtx_unlock((m), curthread->thr_id) != 0) \ 128 abort(); \ 129 } while (0) 130 131 132 /* 133 * State change macro: 134 */ 135 #define PTHREAD_SET_STATE(thrd, newstate) do { \ 136 (thrd)->state = newstate; \ 137 (thrd)->fname = __FILE__; \ 138 (thrd)->lineno = __LINE__; \ 139 } while (0) 140 141 #define PTHREAD_NEW_STATE(thrd, newstate) do { \ 142 if (newstate == PS_RUNNING) \ 143 thr_wake(thrd->thr_id); \ 144 PTHREAD_SET_STATE(thrd, newstate); \ 145 } while (0) 146 147 /* 148 * TailQ initialization values. 149 */ 150 #define TAILQ_INITIALIZER { NULL, NULL } 151 152 #define UMTX_INITIALIZER { NULL } 153 154 struct pthread_mutex_attr { 155 enum pthread_mutextype m_type; 156 int m_protocol; 157 int m_ceiling; 158 long m_flags; 159 }; 160 161 /* 162 * Static mutex initialization values. 163 */ 164 165 #define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ 166 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } 167 168 #define PTHREAD_MUTEX_STATIC_INITIALIZER \ 169 { PTHREAD_MUTEXATTR_STATIC_INITIALIZER, UMTX_INITIALIZER, NULL, \ 170 0, 0, TAILQ_INITIALIZER } 171 172 union pthread_mutex_data { 173 void *m_ptr; 174 int m_count; 175 }; 176 177 struct pthread_mutex { 178 enum pthread_mutextype m_type; 179 int m_protocol; 180 TAILQ_HEAD(mutex_head, pthread) m_queue; 181 struct pthread *m_owner; 182 union pthread_mutex_data m_data; 183 long m_flags; 184 int m_refcount; 185 186 /* 187 * Used for priority inheritence and protection. 188 * 189 * m_prio - For priority inheritence, the highest active 190 * priority (threads locking the mutex inherit 191 * this priority). For priority protection, the 192 * ceiling priority of this mutex. 193 * m_saved_prio - mutex owners inherited priority before 194 * taking the mutex, restored when the owner 195 * unlocks the mutex. 196 */ 197 int m_prio; 198 int m_saved_prio; 199 200 /* 201 * Link for list of all mutexes a thread currently owns. 202 */ 203 TAILQ_ENTRY(pthread_mutex) m_qe; 204 205 /* 206 * Lock for accesses to this structure. 207 */ 208 spinlock_t lock; 209 }; 210 211 struct pthread_spinlock { 212 void *s_owner; 213 unsigned int s_magic; 214 }; 215 216 /* 217 * Flags for mutexes. 218 */ 219 #define MUTEX_FLAGS_PRIVATE 0x01 220 #define MUTEX_FLAGS_INITED 0x02 221 #define MUTEX_FLAGS_BUSY 0x04 222 223 /* 224 * Condition variable definitions. 225 */ 226 enum pthread_cond_type { 227 COND_TYPE_FAST, 228 COND_TYPE_MAX 229 }; 230 231 struct pthread_cond { 232 enum pthread_cond_type c_type; 233 TAILQ_HEAD(cond_head, pthread) c_queue; 234 pthread_mutex_t c_mutex; 235 void *c_data; 236 long c_flags; 237 int c_seqno; 238 239 /* 240 * Lock for accesses to this structure. 241 */ 242 struct umtx c_lock; 243 }; 244 245 struct pthread_cond_attr { 246 enum pthread_cond_type c_type; 247 long c_flags; 248 }; 249 250 /* 251 * Flags for condition variables. 252 */ 253 #define COND_FLAGS_INITED 0x01 254 255 /* 256 * Static cond initialization values. 257 */ 258 #define PTHREAD_COND_STATIC_INITIALIZER \ 259 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \ 260 0, 0, UMTX_INITIALIZER } 261 262 /* 263 * Semaphore definitions. 264 */ 265 struct sem { 266 #define SEM_MAGIC ((u_int32_t) 0x09fa4012) 267 u_int32_t magic; 268 pthread_mutex_t lock; 269 pthread_cond_t gtzero; 270 u_int32_t count; 271 u_int32_t nwaiters; 272 }; 273 274 /* 275 * Cleanup definitions. 276 */ 277 struct pthread_cleanup { 278 struct pthread_cleanup *next; 279 void (*routine) (); 280 void *routine_arg; 281 }; 282 283 struct pthread_attr { 284 int sched_policy; 285 int sched_inherit; 286 int sched_interval; 287 int prio; 288 int suspend; 289 int flags; 290 void *arg_attr; 291 void (*cleanup_attr) (); 292 void *stackaddr_attr; 293 size_t stacksize_attr; 294 size_t guardsize_attr; 295 }; 296 297 /* 298 * Thread creation state attributes. 299 */ 300 #define PTHREAD_CREATE_RUNNING 0 301 #define PTHREAD_CREATE_SUSPENDED 1 302 303 /* 304 * Miscellaneous definitions. 305 */ 306 #define PTHREAD_STACK_DEFAULT 65536 307 /* 308 * Size of default red zone at the end of each stack. In actuality, this "red 309 * zone" is merely an unmapped region, except in the case of the initial stack. 310 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK 311 * region, an unmapped gap between thread stacks achieves the same effect as 312 * explicitly mapped red zones. 313 * This is declared and initialized in uthread_init.c. 314 */ 315 extern int _pthread_guard_default; 316 317 extern int _pthread_page_size; 318 319 /* 320 * Maximum size of initial thread's stack. This perhaps deserves to be larger 321 * than the stacks of other threads, since many applications are likely to run 322 * almost entirely on this stack. 323 */ 324 #define PTHREAD_STACK_INITIAL 0x100000 325 326 /* 327 * Define the different priority ranges. All applications have thread 328 * priorities constrained within 0-31. The threads library raises the 329 * priority when delivering signals in order to ensure that signal 330 * delivery happens (from the POSIX spec) "as soon as possible". 331 * In the future, the threads library will also be able to map specific 332 * threads into real-time (cooperating) processes or kernel threads. 333 * The RT and SIGNAL priorities will be used internally and added to 334 * thread base priorities so that the scheduling queue can handle both 335 * normal and RT priority threads with and without signal handling. 336 * 337 * The approach taken is that, within each class, signal delivery 338 * always has priority over thread execution. 339 */ 340 #define PTHREAD_DEFAULT_PRIORITY 15 341 #define PTHREAD_MIN_PRIORITY 0 342 #define PTHREAD_MAX_PRIORITY 31 /* 0x1F */ 343 #define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */ 344 #define PTHREAD_RT_PRIORITY 64 /* 0x40 */ 345 #define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY 346 #define PTHREAD_LAST_PRIORITY \ 347 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY) 348 #define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY) 349 350 /* 351 * Clock resolution in microseconds. 352 */ 353 #define CLOCK_RES_USEC 10000 354 #define CLOCK_RES_USEC_MIN 1000 355 356 /* 357 * Time slice period in microseconds. 358 */ 359 #define TIMESLICE_USEC 20000 360 361 /* 362 * XXX Define a thread-safe macro to get the current time of day 363 * which is updated at regular intervals by the scheduling signal 364 * handler. 365 */ 366 #define GET_CURRENT_TOD(tv) gettimeofday(&(tv), NULL) 367 368 struct pthread_barrierattr { 369 int ba_pshared; 370 }; 371 372 /* 373 * POSIX Threads barrier object. 374 * Lock order: 375 * 1. pthread_barrier 376 * 2. pthread 377 */ 378 struct pthread_barrier { 379 TAILQ_HEAD(barrq_head, pthread) b_barrq; 380 struct umtx b_lock; 381 int b_total; 382 int b_subtotal; 383 }; 384 385 struct pthread_rwlockattr { 386 int pshared; 387 }; 388 389 struct pthread_rwlock { 390 pthread_mutex_t lock; /* monitor lock */ 391 int state; /* 0 = idle >0 = # of readers -1 = writer */ 392 pthread_cond_t read_signal; 393 pthread_cond_t write_signal; 394 int blocked_writers; 395 }; 396 397 /* 398 * Thread states. 399 */ 400 enum pthread_state { 401 PS_RUNNING, 402 PS_MUTEX_WAIT, 403 PS_COND_WAIT, 404 PS_BARRIER_WAIT, 405 PS_SLEEP_WAIT, /* XXX We need to wrap syscalls to set this state */ 406 PS_WAIT_WAIT, 407 PS_JOIN, 408 PS_DEAD, 409 PS_DEADLOCK, 410 PS_STATE_MAX 411 }; 412 413 414 /* 415 * File descriptor locking definitions. 416 */ 417 #define FD_READ 0x1 418 #define FD_WRITE 0x2 419 #define FD_RDWR (FD_READ | FD_WRITE) 420 421 union pthread_wait_data { 422 pthread_mutex_t mutex; 423 pthread_cond_t cond; 424 spinlock_t *spinlock; 425 struct pthread *thread; 426 }; 427 428 struct join_status { 429 struct pthread *thread; 430 void *ret; 431 int error; 432 }; 433 434 struct pthread_state_data { 435 union pthread_wait_data psd_wait_data; 436 enum pthread_state psd_state; 437 int psd_flags; 438 }; 439 440 struct pthread_specific_elem { 441 const void *data; 442 int seqno; 443 }; 444 445 struct rwlock_held { 446 LIST_ENTRY(rwlock_held) rh_link; 447 struct pthread_rwlock *rh_rwlock; 448 int rh_rdcount; 449 int rh_wrcount; 450 }; 451 452 LIST_HEAD(rwlock_listhead, rwlock_held); 453 454 /* 455 * Thread structure. 456 */ 457 struct pthread { 458 /* 459 * Magic value to help recognize a valid thread structure 460 * from an invalid one: 461 */ 462 #define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115) 463 u_int32_t magic; 464 char *name; 465 u_int64_t uniqueid; /* for gdb */ 466 thr_id_t thr_id; 467 sigset_t savedsig; 468 int signest; /* blocked signal netsting level */ 469 470 /* 471 * Lock for accesses to this thread structure. 472 */ 473 struct umtx lock; 474 475 /* Queue entry for list of all threads: */ 476 TAILQ_ENTRY(pthread) tle; 477 478 /* Queue entry for list of dead threads: */ 479 TAILQ_ENTRY(pthread) dle; 480 481 /* 482 * Thread start routine, argument, stack pointer and thread 483 * attributes. 484 */ 485 void *(*start_routine)(void *); 486 void *arg; 487 void *stack; 488 struct pthread_attr attr; 489 490 /* 491 * Machine context, including signal state. 492 */ 493 ucontext_t ctx; 494 495 /* 496 * Cancelability flags - the lower 2 bits are used by cancel 497 * definitions in pthread.h 498 */ 499 #define PTHREAD_AT_CANCEL_POINT 0x0004 500 #define PTHREAD_CANCELLING 0x0008 501 502 /* 503 * Protected by Giant. 504 */ 505 int cancelflags; 506 507 /* Thread state: */ 508 enum pthread_state state; 509 510 /* 511 * Error variable used instead of errno. The function __error() 512 * returns a pointer to this. 513 */ 514 int error; 515 516 /* 517 * The joiner is the thread that is joining to this thread. The 518 * join status keeps track of a join operation to another thread. 519 */ 520 struct pthread *joiner; 521 struct join_status join_status; 522 523 /* 524 * A thread can belong to: 525 * 526 * o A queue of threads waiting for a mutex 527 * o A queue of threads waiting for a condition variable 528 * 529 * A thread can also be joining a thread (the joiner field above). 530 * 531 * It must not be possible for a thread to belong to any of the 532 * above queues while it is handling a signal. Signal handlers 533 * may longjmp back to previous stack frames circumventing normal 534 * control flow. This could corrupt queue integrity if the thread 535 * retains membership in the queue. Therefore, if a thread is a 536 * member of one of these queues when a signal handler is invoked, 537 * it must remove itself from the queue before calling the signal 538 * handler and reinsert itself after normal return of the handler. 539 * 540 * Use sqe for synchronization (mutex and condition variable) queue 541 * links. 542 */ 543 TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */ 544 545 /* Wait data. */ 546 union pthread_wait_data data; 547 548 /* Miscellaneous flags; only set with signals deferred. */ 549 int flags; 550 #define PTHREAD_FLAGS_PRIVATE 0x0001 551 #define PTHREAD_EXITING 0x0002 552 #define PTHREAD_FLAGS_BARR_REL 0x0004 /* has been released from barrier */ 553 #define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/ 554 #define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ 555 #define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */ 556 #define PTHREAD_FLAGS_TRACE 0x0400 /* for debugging purposes */ 557 #define PTHREAD_FLAGS_IN_SYNCQ \ 558 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ) 559 560 /* 561 * Base priority is the user setable and retrievable priority 562 * of the thread. It is only affected by explicit calls to 563 * set thread priority and upon thread creation via a thread 564 * attribute or default priority. 565 */ 566 char base_priority; 567 568 /* 569 * Inherited priority is the priority a thread inherits by 570 * taking a priority inheritence or protection mutex. It 571 * is not affected by base priority changes. Inherited 572 * priority defaults to and remains 0 until a mutex is taken 573 * that is being waited on by any other thread whose priority 574 * is non-zero. 575 */ 576 char inherited_priority; 577 578 /* 579 * Active priority is always the maximum of the threads base 580 * priority and inherited priority. When there is a change 581 * in either the base or inherited priority, the active 582 * priority must be recalculated. 583 */ 584 char active_priority; 585 586 /* Number of priority ceiling or protection mutexes owned. */ 587 int prio_inherit_count; 588 int prio_protect_count; 589 590 /* 591 * Queue of currently owned mutexes. 592 */ 593 TAILQ_HEAD(, pthread_mutex) mutexq; 594 595 /* 596 * List of read-write locks owned for reading _OR_ writing. 597 * This is accessed only by the current thread, so there's 598 * no need for mutual exclusion. 599 */ 600 struct rwlock_listhead *rwlockList; 601 602 void *ret; 603 struct pthread_specific_elem *specific; 604 int specific_data_count; 605 606 /* 607 * Architecture specific id field used for _{get, set}_curthread() 608 * interface. 609 */ 610 void *arch_id; 611 612 /* Cleanup handlers Link List */ 613 struct pthread_cleanup *cleanup; 614 char *fname; /* Ptr to source file name */ 615 int lineno; /* Source line number. */ 616 }; 617 618 /* 619 * Global variables for the uthread kernel. 620 */ 621 622 SCLASS void *_usrstack 623 #ifdef GLOBAL_PTHREAD_PRIVATE 624 = (void *) USRSTACK; 625 #else 626 ; 627 #endif 628 629 SCLASS spinlock_t stack_lock 630 #ifdef GLOBAL_PTHREAD_PRIVATE 631 = _SPINLOCK_INITIALIZER 632 #endif 633 ; 634 #define STACK_LOCK _SPINLOCK(&stack_lock); 635 #define STACK_UNLOCK _SPINUNLOCK(&stack_lock); 636 637 /* List of all threads: */ 638 SCLASS TAILQ_HEAD(, pthread) _thread_list 639 #ifdef GLOBAL_PTHREAD_PRIVATE 640 = TAILQ_HEAD_INITIALIZER(_thread_list); 641 #else 642 ; 643 #endif 644 645 /* Dead threads: */ 646 SCLASS TAILQ_HEAD(, pthread) _dead_list 647 #ifdef GLOBAL_PTHREAD_PRIVATE 648 = TAILQ_HEAD_INITIALIZER(_dead_list); 649 #else 650 ; 651 #endif 652 653 /* 654 * These two locks protect the global active threads list and 655 * the global dead threads list, respectively. Combining these 656 * into one lock for both lists doesn't seem wise, since it 657 * would likely increase contention during busy thread creation 658 * and destruction for very little savings in space. 659 * 660 * The lock for the "dead threads list" must be a pthread mutex 661 * because it is used with condition variables to synchronize 662 * the gc thread with active threads in the process of exiting or 663 * dead threads who have just been joined. 664 */ 665 SCLASS spinlock_t thread_list_lock 666 #ifdef GLOBAL_PTHREAD_PRIVATE 667 = _SPINLOCK_INITIALIZER 668 #endif 669 ; 670 SCLASS pthread_mutex_t dead_list_lock 671 #ifdef GLOBAL_PTHREAD_PRIVATE 672 = NULL 673 #endif 674 ; 675 676 #define THREAD_LIST_LOCK _SPINLOCK(&thread_list_lock) 677 #define THREAD_LIST_UNLOCK _SPINUNLOCK(&thread_list_lock) 678 #define DEAD_LIST_LOCK _pthread_mutex_lock(&dead_list_lock) 679 #define DEAD_LIST_UNLOCK _pthread_mutex_unlock(&dead_list_lock) 680 681 /* Initial thread: */ 682 SCLASS struct pthread *_thread_initial 683 #ifdef GLOBAL_PTHREAD_PRIVATE 684 = NULL; 685 #else 686 ; 687 #endif 688 689 /* Default thread attributes: */ 690 SCLASS struct pthread_attr pthread_attr_default 691 #ifdef GLOBAL_PTHREAD_PRIVATE 692 = { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, 693 PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, 694 PTHREAD_STACK_DEFAULT, -1 }; 695 #else 696 ; 697 #endif 698 699 /* Default mutex attributes: */ 700 SCLASS struct pthread_mutex_attr pthread_mutexattr_default 701 #ifdef GLOBAL_PTHREAD_PRIVATE 702 = { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }; 703 #else 704 ; 705 #endif 706 707 /* Default condition variable attributes: */ 708 SCLASS struct pthread_cond_attr pthread_condattr_default 709 #ifdef GLOBAL_PTHREAD_PRIVATE 710 = { COND_TYPE_FAST, 0 }; 711 #else 712 ; 713 #endif 714 715 /* 716 * Array of signal actions for this process. 717 */ 718 SCLASS struct sigaction _thread_sigact[NSIG]; 719 720 /* Precomputed signal set for _thread_suspend. */ 721 SCLASS sigset_t _thread_suspend_sigset; 722 723 /* Tracks the number of threads blocked while waiting for a spinlock. */ 724 SCLASS volatile int _spinblock_count 725 #ifdef GLOBAL_PTHREAD_PRIVATE 726 = 0 727 #endif 728 ; 729 730 /* Undefine the storage class specifier: */ 731 #undef SCLASS 732 733 /* 734 * Function prototype definitions. 735 */ 736 __BEGIN_DECLS 737 char *__ttyname_basic(int); 738 char *__ttyname_r_basic(int, char *, size_t); 739 char *ttyname_r(int, char *, size_t); 740 void _cond_wait_backout(pthread_t); 741 int _find_thread(pthread_t); 742 pthread_t _get_curthread(void); 743 void *_set_curthread(ucontext_t *, struct pthread *, int *); 744 void _retire_thread(void *arch_id); 745 void *_thread_stack_alloc(size_t, size_t); 746 void _thread_stack_free(void *, size_t, size_t); 747 int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t); 748 int _mutex_cv_lock(pthread_mutex_t *); 749 int _mutex_cv_unlock(pthread_mutex_t *); 750 void _mutex_lock_backout(pthread_t); 751 void _mutex_notify_priochange(pthread_t); 752 int _mutex_reinit(pthread_mutex_t *); 753 void _mutex_unlock_private(pthread_t); 754 int _cond_reinit(pthread_cond_t *); 755 void *_pthread_getspecific(pthread_key_t); 756 int _pthread_key_create(pthread_key_t *, void (*) (void *)); 757 int _pthread_key_delete(pthread_key_t); 758 int _pthread_mutex_destroy(pthread_mutex_t *); 759 int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); 760 int _pthread_mutex_lock(pthread_mutex_t *); 761 int _pthread_mutex_trylock(pthread_mutex_t *); 762 int _pthread_mutex_unlock(pthread_mutex_t *); 763 int _pthread_mutexattr_init(pthread_mutexattr_t *); 764 int _pthread_mutexattr_destroy(pthread_mutexattr_t *); 765 int _pthread_mutexattr_settype(pthread_mutexattr_t *, int); 766 int _pthread_once(pthread_once_t *, void (*) (void)); 767 pthread_t _pthread_self(void); 768 int _pthread_setspecific(pthread_key_t, const void *); 769 int _spintrylock(spinlock_t *); 770 void _thread_exit(char *, int, char *); 771 void _thread_exit_cleanup(void); 772 void *_thread_cleanup(pthread_t); 773 void _thread_cleanupspecific(void); 774 void _thread_dump_info(void); 775 void _thread_init(void); 776 void _thread_sig_wrapper(int sig, siginfo_t *info, void *context); 777 void _thread_printf(int fd, const char *, ...); 778 void _thread_start(void); 779 void _thread_seterrno(pthread_t, int); 780 void _thread_enter_cancellation_point(void); 781 void _thread_leave_cancellation_point(void); 782 void _thread_cancellation_point(void); 783 int _thread_suspend(pthread_t thread, const struct timespec *abstime); 784 void _thread_critical_enter(pthread_t); 785 void _thread_critical_exit(pthread_t); 786 void _thread_sigblock(); 787 void _thread_sigunblock(); 788 void adjust_prio_inheritance(struct pthread *); 789 void adjust_prio_protection(struct pthread *); 790 void deadlist_free_onethread(struct pthread *); 791 void init_td_common(struct pthread *, struct pthread_attr *, int); 792 void init_tdlist(struct pthread *, int); 793 void proc_sigact_copyin(int, const struct sigaction *); 794 void proc_sigact_copyout(int, struct sigaction *); 795 void readjust_priorities(struct pthread *, struct pthread_mutex *); 796 struct sigaction *proc_sigact_sigaction(int); 797 798 /* #include <sys/aio.h> */ 799 #ifdef _SYS_AIO_H_ 800 int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); 801 #endif 802 803 /* #include <sys/event.h> */ 804 #ifdef _SYS_EVENT_H_ 805 int __sys_kevent(int, const struct kevent *, int, struct kevent *, 806 int, const struct timespec *); 807 #endif 808 809 /* #include <sys/ioctl.h> */ 810 #ifdef _SYS_IOCTL_H_ 811 int __sys_ioctl(int, unsigned long, ...); 812 #endif 813 814 /* #include <sys/mman.h> */ 815 #ifdef _SYS_MMAN_H_ 816 int __sys_msync(void *, size_t, int); 817 #endif 818 819 /* #include <sys/mount.h> */ 820 #ifdef _SYS_MOUNT_H_ 821 int __sys_fstatfs(int, struct statfs *); 822 #endif 823 824 /* #include <sys/socket.h> */ 825 #ifdef _SYS_SOCKET_H_ 826 int __sys_accept(int, struct sockaddr *, socklen_t *); 827 int __sys_bind(int, const struct sockaddr *, socklen_t); 828 int __sys_connect(int, const struct sockaddr *, socklen_t); 829 int __sys_getpeername(int, struct sockaddr *, socklen_t *); 830 int __sys_getsockname(int, struct sockaddr *, socklen_t *); 831 int __sys_getsockopt(int, int, int, void *, socklen_t *); 832 int __sys_listen(int, int); 833 ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 834 ssize_t __sys_recvmsg(int, struct msghdr *, int); 835 int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int); 836 ssize_t __sys_sendmsg(int, const struct msghdr *, int); 837 ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t); 838 int __sys_setsockopt(int, int, int, const void *, socklen_t); 839 int __sys_shutdown(int, int); 840 int __sys_socket(int, int, int); 841 int __sys_socketpair(int, int, int, int *); 842 #endif 843 844 /* #include <sys/stat.h> */ 845 #ifdef _SYS_STAT_H_ 846 int __sys_fchflags(int, u_long); 847 int __sys_fchmod(int, mode_t); 848 int __sys_fstat(int, struct stat *); 849 #endif 850 851 /* #include <sys/uio.h> */ 852 #ifdef _SYS_UIO_H_ 853 ssize_t __sys_readv(int, const struct iovec *, int); 854 ssize_t __sys_writev(int, const struct iovec *, int); 855 #endif 856 857 /* #include <sys/wait.h> */ 858 #ifdef WNOHANG 859 pid_t __sys_wait4(pid_t, int *, int, struct rusage *); 860 #endif 861 862 /* #include <dirent.h> */ 863 #ifdef _DIRENT_H_ 864 int __sys_getdirentries(int, char *, int, long *); 865 #endif 866 867 /* #include <fcntl.h> */ 868 #ifdef _SYS_FCNTL_H_ 869 int __sys_fcntl(int, int, ...); 870 int __sys_flock(int, int); 871 int __sys_open(const char *, int, ...); 872 #endif 873 874 /* #include <poll.h> */ 875 #ifdef _SYS_POLL_H_ 876 int __sys_poll(struct pollfd *, unsigned, int); 877 #endif 878 879 /* #include <signal.h> */ 880 #ifdef _SIGNAL_H_ 881 int __sys_sigaction(int, const struct sigaction *, struct sigaction *); 882 int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); 883 int __sys_sigprocmask(int, const sigset_t *, sigset_t *); 884 int __sys_sigreturn(ucontext_t *); 885 #endif 886 887 /* #include <unistd.h> */ 888 #ifdef _UNISTD_H_ 889 int __sys_close(int); 890 int __sys_dup(int); 891 int __sys_dup2(int, int); 892 int __sys_execve(const char *, char * const *, char * const *); 893 void __sys_exit(int); 894 int __sys_fchown(int, uid_t, gid_t); 895 pid_t __sys_fork(void); 896 long __sys_fpathconf(int, int); 897 int __sys_fsync(int); 898 int __sys_pipe(int *); 899 ssize_t __sys_read(int, void *, size_t); 900 ssize_t __sys_write(int, const void *, size_t); 901 #endif 902 903 __END_DECLS 904 905 #endif /* !_PTHREAD_PRIVATE_H */ 906