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