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