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