thr_private.h revision 129484
1227753Stheraven/* 2232498Stheraven * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>. 3227753Stheraven * All rights reserved. 4227753Stheraven * 5227753Stheraven * Redistribution and use in source and binary forms, with or without 6227753Stheraven * modification, are permitted provided that the following conditions 7227753Stheraven * are met: 8227753Stheraven * 1. Redistributions of source code must retain the above copyright 9227753Stheraven * notice, this list of conditions and the following disclaimer. 10227753Stheraven * 2. Redistributions in binary form must reproduce the above copyright 11232498Stheraven * notice, this list of conditions and the following disclaimer in the 12232498Stheraven * documentation and/or other materials provided with the distribution. 13232498Stheraven * 3. All advertising materials mentioning features or use of this software 14232498Stheraven * must display the following acknowledgement: 15232498Stheraven * This product includes software developed by John Birrell. 16227753Stheraven * 4. Neither the name of the author nor the names of any co-contributors 17227753Stheraven * may be used to endorse or promote products derived from this software 18227753Stheraven * without specific prior written permission. 19227753Stheraven * 20232498Stheraven * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 21227753Stheraven * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22227753Stheraven * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23227753Stheraven * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24227753Stheraven * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25227753Stheraven * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26227753Stheraven * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27227753Stheraven * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28227753Stheraven * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29227753Stheraven * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30227753Stheraven * SUCH DAMAGE. 31227753Stheraven * 32227753Stheraven * Private thread definitions for the uthread kernel. 33227753Stheraven * 34227753Stheraven * $FreeBSD: head/lib/libthr/thread/thr_private.h 129484 2004-05-20 12:06:16Z mtm $ 35227753Stheraven */ 36227753Stheraven 37232498Stheraven#ifndef _THR_PRIVATE_H 38227753Stheraven#define _THR_PRIVATE_H 39227753Stheraven 40232498Stheraven/* 41227753Stheraven * Evaluate the storage class specifier. 42232498Stheraven */ 43227753Stheraven#ifdef GLOBAL_PTHREAD_PRIVATE 44232498Stheraven#define SCLASS 45227753Stheraven#else 46232498Stheraven#define SCLASS extern 47227753Stheraven#endif 48232498Stheraven 49227753Stheraven/* 50227753Stheraven * Include files. 51227753Stheraven */ 52232498Stheraven#include <sys/types.h> 53232498Stheraven#include <sys/cdefs.h> 54231714Sdim#include <sys/errno.h> 55227753Stheraven#include <sys/time.h> 56232498Stheraven#include <sys/queue.h> 57227753Stheraven#include <pthread_np.h> 58232498Stheraven#include <sched.h> 59227753Stheraven#include <signal.h> 60232498Stheraven#include <spinlock.h> 61227753Stheraven#include <stdio.h> 62232498Stheraven#include <ucontext.h> 63227753Stheraven#include <unistd.h> 64232498Stheraven#if defined(_PTHREADS_INVARIANTS) 65227753Stheraven#include <assert.h> 66232498Stheraven#endif 67227753Stheraven 68232498Stheraven#include <machine/atomic.h> 69232498Stheraven#include <sys/thr.h> 70227753Stheraven#include <sys/umtx.h> 71227753Stheraven 72227753Stheraven#if defined(_PTHREADS_INVARIANTS) 73232498Stheraven/* 74232498Stheraven * Kernel fatal error handler macro. 75231714Sdim */ 76232498Stheraven#define PANIC(string) \ 77232498Stheraven do { \ 78231673Stheraven _thread_printf(STDOUT_FILENO, (string)); \ 79227753Stheraven _thread_printf(STDOUT_FILENO, \ 80227753Stheraven "\nAbnormal termination, file: %s, line: %d\n", \ 81227753Stheraven __FILE__, __LINE__); \ 82227753Stheraven abort(); \ 83227753Stheraven } while (0) 84227753Stheraven 85227753Stheraven#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 143struct 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 161union pthread_mutex_data { 162 void *m_ptr; 163 int m_count; 164}; 165 166struct 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 200struct 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 */ 215enum pthread_cond_type { 216 COND_TYPE_FAST, 217 COND_TYPE_MAX 218}; 219 220struct 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 234struct 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 */ 254struct 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 */ 266struct pthread_cleanup { 267 struct pthread_cleanup *next; 268 void (*routine) (); 269 void *routine_arg; 270}; 271 272struct pthread_attr { 273 int sched_policy; 274 int sched_inherit; 275 int sched_interval; 276 int prio; 277 int suspend; 278 int flags; 279 void *arg_attr; 280 void (*cleanup_attr) (); 281 void *stackaddr_attr; 282 size_t stacksize_attr; 283 size_t guardsize_attr; 284}; 285 286/* 287 * Thread creation state attributes. 288 */ 289#define PTHREAD_CREATE_RUNNING 0 290#define PTHREAD_CREATE_SUSPENDED 1 291 292/* 293 * Miscellaneous definitions. 294 */ 295#define PTHREAD_STACK_DEFAULT 65536 296/* 297 * Size of default red zone at the end of each stack. In actuality, this "red 298 * zone" is merely an unmapped region, except in the case of the initial stack. 299 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK 300 * region, an unmapped gap between thread stacks achieves the same effect as 301 * explicitly mapped red zones. 302 * This is declared and initialized in uthread_init.c. 303 */ 304extern int _pthread_guard_default; 305 306extern int _pthread_page_size; 307 308/* 309 * Maximum size of initial thread's stack. This perhaps deserves to be larger 310 * than the stacks of other threads, since many applications are likely to run 311 * almost entirely on this stack. 312 */ 313#define PTHREAD_STACK_INITIAL 0x100000 314 315/* 316 * Define the different priority ranges. All applications have thread 317 * priorities constrained within 0-31. The threads library raises the 318 * priority when delivering signals in order to ensure that signal 319 * delivery happens (from the POSIX spec) "as soon as possible". 320 * In the future, the threads library will also be able to map specific 321 * threads into real-time (cooperating) processes or kernel threads. 322 * The RT and SIGNAL priorities will be used internally and added to 323 * thread base priorities so that the scheduling queue can handle both 324 * normal and RT priority threads with and without signal handling. 325 * 326 * The approach taken is that, within each class, signal delivery 327 * always has priority over thread execution. 328 */ 329#define PTHREAD_DEFAULT_PRIORITY 15 330#define PTHREAD_MIN_PRIORITY 0 331#define PTHREAD_MAX_PRIORITY 31 /* 0x1F */ 332#define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */ 333#define PTHREAD_RT_PRIORITY 64 /* 0x40 */ 334#define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY 335#define PTHREAD_LAST_PRIORITY \ 336 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY) 337#define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY) 338 339/* 340 * Clock resolution in microseconds. 341 */ 342#define CLOCK_RES_USEC 10000 343#define CLOCK_RES_USEC_MIN 1000 344 345/* 346 * Time slice period in microseconds. 347 */ 348#define TIMESLICE_USEC 20000 349 350/* 351 * XXX Define a thread-safe macro to get the current time of day 352 * which is updated at regular intervals by the scheduling signal 353 * handler. 354 */ 355#define GET_CURRENT_TOD(tv) gettimeofday(&(tv), NULL) 356 357struct pthread_barrierattr { 358 int ba_pshared; 359}; 360 361/* 362 * POSIX Threads barrier object. 363 * Lock order: 364 * 1. pthread_barrier 365 * 2. pthread 366 */ 367struct pthread_barrier { 368 TAILQ_HEAD(barrq_head, pthread) b_barrq; 369 struct umtx b_lock; 370 int b_total; 371 int b_subtotal; 372}; 373 374struct pthread_rwlockattr { 375 int pshared; 376}; 377 378struct pthread_rwlock { 379 pthread_mutex_t lock; /* monitor lock */ 380 int state; /* 0 = idle >0 = # of readers -1 = writer */ 381 pthread_cond_t read_signal; 382 pthread_cond_t write_signal; 383 int blocked_writers; 384}; 385 386/* 387 * Thread states. 388 */ 389enum pthread_state { 390 PS_RUNNING, 391 PS_MUTEX_WAIT, 392 PS_COND_WAIT, 393 PS_BARRIER_WAIT, 394 PS_SLEEP_WAIT, /* XXX We need to wrap syscalls to set this state */ 395 PS_WAIT_WAIT, 396 PS_JOIN, 397 PS_DEAD, 398 PS_DEADLOCK, 399 PS_STATE_MAX 400}; 401 402 403/* 404 * File descriptor locking definitions. 405 */ 406#define FD_READ 0x1 407#define FD_WRITE 0x2 408#define FD_RDWR (FD_READ | FD_WRITE) 409 410union pthread_wait_data { 411 pthread_mutex_t mutex; 412 pthread_cond_t cond; 413 spinlock_t *spinlock; 414 struct pthread *thread; 415}; 416 417struct join_status { 418 struct pthread *thread; 419 void *ret; 420 int error; 421}; 422 423struct pthread_state_data { 424 union pthread_wait_data psd_wait_data; 425 enum pthread_state psd_state; 426 int psd_flags; 427}; 428 429struct pthread_specific_elem { 430 const void *data; 431 int seqno; 432}; 433 434struct rwlock_held { 435 LIST_ENTRY(rwlock_held) rh_link; 436 struct pthread_rwlock *rh_rwlock; 437 int rh_rdcount; 438 int rh_wrcount; 439}; 440 441LIST_HEAD(rwlock_listhead, rwlock_held); 442 443/* 444 * The cancel mode a thread is in is determined by the 445 * the cancel type and state it is set in. The two values 446 * are combined into one mode: 447 * Mode State Type 448 * ---- ----- ---- 449 * off disabled deferred 450 * off disabled async 451 * deferred enabled deferred 452 * async enabled async 453 */ 454enum cancel_mode { M_OFF, M_DEFERRED, M_ASYNC }; 455 456/* 457 * A thread's cancellation is pending until the cancel 458 * mode has been tested to determine if the thread can be 459 * cancelled immediately. 460 */ 461enum cancellation_state { CS_NULL, CS_PENDING, CS_SET }; 462 463/* 464 * Thread structure. 465 */ 466struct pthread { 467 /* 468 * Magic value to help recognize a valid thread structure 469 * from an invalid one: 470 */ 471#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115) 472 u_int32_t magic; 473 char *name; 474 u_int64_t uniqueid; /* for gdb */ 475 thr_id_t thr_id; 476 sigset_t savedsig; 477 int signest; /* blocked signal netsting level */ 478 int ptdflags; /* used by other other threads 479 to signal this thread */ 480 int isdead; 481 int isdeadlocked; 482 int exiting; 483 int cancellationpoint; 484 485 /* 486 * Lock for accesses to this thread structure. 487 */ 488 struct umtx lock; 489 490 /* Queue entry for list of all threads: */ 491 TAILQ_ENTRY(pthread) tle; 492 493 /* Queue entry for list of dead threads: */ 494 TAILQ_ENTRY(pthread) dle; 495 496 /* 497 * Thread start routine, argument, stack pointer and thread 498 * attributes. 499 */ 500 void *(*start_routine)(void *); 501 void *arg; 502 void *stack; 503 struct pthread_attr attr; 504 505 /* 506 * Machine context, including signal state. 507 */ 508 ucontext_t ctx; 509 510 /* 511 * The primary method of obtaining a thread's cancel state 512 * and type is through cancelmode. The cancelstate field is 513 * only so we don't loose the cancel state when the mode is 514 * turned off. 515 */ 516 enum cancel_mode cancelmode; 517 enum cancel_mode cancelstate; 518 519 /* Specifies if cancellation is pending, acted upon, or neither. */ 520 enum cancellation_state cancellation; 521 522 /* 523 * Error variable used instead of errno. The function __error() 524 * returns a pointer to this. 525 */ 526 int error; 527 528 /* 529 * The joiner is the thread that is joining to this thread. The 530 * join status keeps track of a join operation to another thread. 531 */ 532 struct pthread *joiner; 533 struct join_status join_status; 534 535 /* 536 * A thread can belong to: 537 * 538 * o A queue of threads waiting for a mutex 539 * o A queue of threads waiting for a condition variable 540 * 541 * A thread can also be joining a thread (the joiner field above). 542 * 543 * Use sqe for synchronization (mutex and condition variable) queue 544 * links. 545 */ 546 TAILQ_ENTRY(pthread) sqe; /* synchronization queue link */ 547 548 /* Wait data. */ 549 union pthread_wait_data data; 550 551 /* Miscellaneous flags; only set with signals deferred. */ 552 int flags; 553#define PTHREAD_FLAGS_PRIVATE 0x0001 554#define PTHREAD_FLAGS_BARR_REL 0x0004 /* has been released from barrier */ 555#define PTHREAD_FLAGS_IN_BARRQ 0x0008 /* in barrier queue using sqe link */ 556#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/ 557#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ 558#define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */ 559#define PTHREAD_FLAGS_TRACE 0x0400 /* for debugging purposes */ 560#define PTHREAD_FLAGS_IN_SYNCQ \ 561 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ | PTHREAD_FLAGS_IN_BARRQ) 562#define PTHREAD_FLAGS_NOT_RUNNING \ 563 (PTHREAD_FLAGS_IN_SYNCQ | PTHREAD_FLAGS_SUSPENDED) 564 565 /* 566 * Base priority is the user setable and retrievable priority 567 * of the thread. It is only affected by explicit calls to 568 * set thread priority and upon thread creation via a thread 569 * attribute or default priority. 570 */ 571 char base_priority; 572 573 /* 574 * Inherited priority is the priority a thread inherits by 575 * taking a priority inheritence or protection mutex. It 576 * is not affected by base priority changes. Inherited 577 * priority defaults to and remains 0 until a mutex is taken 578 * that is being waited on by any other thread whose priority 579 * is non-zero. 580 */ 581 char inherited_priority; 582 583 /* 584 * Active priority is always the maximum of the threads base 585 * priority and inherited priority. When there is a change 586 * in either the base or inherited priority, the active 587 * priority must be recalculated. 588 */ 589 char active_priority; 590 591 /* Number of priority ceiling or protection mutexes owned. */ 592 int prio_inherit_count; 593 int prio_protect_count; 594 595 /* 596 * Queue of currently owned mutexes. 597 */ 598 TAILQ_HEAD(, pthread_mutex) mutexq; 599 600 /* 601 * List of read-write locks owned for reading _OR_ writing. 602 * This is accessed only by the current thread, so there's 603 * no need for mutual exclusion. 604 */ 605 struct rwlock_listhead *rwlockList; 606 607 void *ret; 608 struct pthread_specific_elem *specific; 609 int specific_data_count; 610 611 /* 612 * Architecture specific id field used for _{get, set}_curthread() 613 * interface. 614 */ 615 void *arch_id; 616 617 /* Cleanup handlers Link List */ 618 struct pthread_cleanup *cleanup; 619 char *fname; /* Ptr to source file name */ 620 int lineno; /* Source line number. */ 621}; 622 623/* 624 * Global variables for the uthread kernel. 625 */ 626 627SCLASS void *_usrstack 628#ifdef GLOBAL_PTHREAD_PRIVATE 629= (void *) USRSTACK; 630#else 631; 632#endif 633 634SCLASS spinlock_t stack_lock 635#ifdef GLOBAL_PTHREAD_PRIVATE 636= _SPINLOCK_INITIALIZER 637#endif 638; 639#define STACK_LOCK _SPINLOCK(&stack_lock); 640#define STACK_UNLOCK _SPINUNLOCK(&stack_lock); 641 642/* List of all threads: */ 643SCLASS TAILQ_HEAD(, pthread) _thread_list 644#ifdef GLOBAL_PTHREAD_PRIVATE 645= TAILQ_HEAD_INITIALIZER(_thread_list); 646#else 647; 648#endif 649 650/* Dead threads: */ 651SCLASS TAILQ_HEAD(, pthread) _dead_list 652#ifdef GLOBAL_PTHREAD_PRIVATE 653= TAILQ_HEAD_INITIALIZER(_dead_list); 654#else 655; 656#endif 657 658/* 659 * These two locks protect the global active threads list and 660 * the global dead threads list, respectively. Combining these 661 * into one lock for both lists doesn't seem wise, since it 662 * would likely increase contention during busy thread creation 663 * and destruction for very little savings in space. 664 * 665 * The lock for the "dead threads list" must be a pthread mutex 666 * because it is used with condition variables to synchronize 667 * the gc thread with active threads in the process of exiting or 668 * dead threads who have just been joined. 669 */ 670SCLASS spinlock_t thread_list_lock 671#ifdef GLOBAL_PTHREAD_PRIVATE 672= _SPINLOCK_INITIALIZER 673#endif 674; 675SCLASS pthread_mutex_t dead_list_lock 676#ifdef GLOBAL_PTHREAD_PRIVATE 677= NULL 678#endif 679; 680 681#define THREAD_LIST_LOCK _SPINLOCK(&thread_list_lock) 682#define THREAD_LIST_UNLOCK _SPINUNLOCK(&thread_list_lock) 683#define DEAD_LIST_LOCK _pthread_mutex_lock(&dead_list_lock) 684#define DEAD_LIST_UNLOCK _pthread_mutex_unlock(&dead_list_lock) 685 686/* Initial thread: */ 687SCLASS struct pthread *_thread_initial 688#ifdef GLOBAL_PTHREAD_PRIVATE 689= NULL; 690#else 691; 692#endif 693 694/* Default thread attributes: */ 695SCLASS struct pthread_attr pthread_attr_default 696#ifdef GLOBAL_PTHREAD_PRIVATE 697= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, 698 PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, 699 PTHREAD_STACK_DEFAULT, -1 }; 700#else 701; 702#endif 703 704/* Default mutex attributes: */ 705SCLASS struct pthread_mutex_attr pthread_mutexattr_default 706#ifdef GLOBAL_PTHREAD_PRIVATE 707= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }; 708#else 709; 710#endif 711 712/* Default condition variable attributes: */ 713SCLASS struct pthread_cond_attr pthread_condattr_default 714#ifdef GLOBAL_PTHREAD_PRIVATE 715= { COND_TYPE_FAST, 0 }; 716#else 717; 718#endif 719 720/* 721 * Array of signal actions for this process. 722 */ 723SCLASS struct sigaction _thread_sigact[NSIG]; 724 725/* Precomputed signal set for _thread_suspend. */ 726SCLASS sigset_t _thread_suspend_sigset; 727 728/* Tracks the number of threads blocked while waiting for a spinlock. */ 729SCLASS volatile int _spinblock_count 730#ifdef GLOBAL_PTHREAD_PRIVATE 731= 0 732#endif 733; 734 735/* Undefine the storage class specifier: */ 736#undef SCLASS 737 738/* 739 * Function prototype definitions. 740 */ 741__BEGIN_DECLS 742char *__ttyname_basic(int); 743char *__ttyname_r_basic(int, char *, size_t); 744char *ttyname_r(int, char *, size_t); 745void _cond_wait_backout(pthread_t); 746int _find_thread(pthread_t); 747pthread_t _get_curthread(void); 748void *_set_curthread(ucontext_t *, struct pthread *, int *); 749void _retire_thread(void *arch_id); 750void *_thread_stack_alloc(size_t, size_t); 751void _thread_stack_free(void *, size_t, size_t); 752int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t); 753int _mutex_cv_lock(pthread_mutex_t *); 754int _mutex_cv_unlock(pthread_mutex_t *); 755void _mutex_lock_backout(pthread_t); 756void _mutex_notify_priochange(pthread_t); 757int _mutex_reinit(pthread_mutex_t *); 758void _mutex_unlock_private(pthread_t); 759int _cond_reinit(pthread_cond_t *); 760void *_pthread_getspecific(pthread_key_t); 761int _pthread_key_create(pthread_key_t *, void (*) (void *)); 762int _pthread_key_delete(pthread_key_t); 763int _pthread_mutex_destroy(pthread_mutex_t *); 764int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); 765int _pthread_mutex_lock(pthread_mutex_t *); 766int _pthread_mutex_trylock(pthread_mutex_t *); 767int _pthread_mutex_unlock(pthread_mutex_t *); 768int _pthread_mutexattr_init(pthread_mutexattr_t *); 769int _pthread_mutexattr_destroy(pthread_mutexattr_t *); 770int _pthread_mutexattr_settype(pthread_mutexattr_t *, int); 771int _pthread_once(pthread_once_t *, void (*) (void)); 772pthread_t _pthread_self(void); 773int _pthread_setspecific(pthread_key_t, const void *); 774int _spintrylock(spinlock_t *); 775void _thread_exit(char *, int, char *); 776void _thread_exit_cleanup(void); 777void *_thread_cleanup(pthread_t); 778void _thread_cleanupspecific(void); 779void _thread_dump_info(void); 780void _thread_init(void); 781void _thread_printf(int fd, const char *, ...); 782void _thread_start(void); 783void _thread_seterrno(pthread_t, int); 784void _thread_enter_cancellation_point(void); 785void _thread_leave_cancellation_point(void); 786void _thread_cancellation_point(void); 787int _thread_suspend(pthread_t thread, const struct timespec *abstime); 788void _thread_critical_enter(pthread_t); 789void _thread_critical_exit(pthread_t); 790void _thread_sigblock(); 791void _thread_sigunblock(); 792void adjust_prio_inheritance(struct pthread *); 793void adjust_prio_protection(struct pthread *); 794void deadlist_free_onethread(struct pthread *); 795void init_td_common(struct pthread *, struct pthread_attr *, int); 796void init_tdlist(struct pthread *, int); 797void proc_sigact_copyin(int, const struct sigaction *); 798void proc_sigact_copyout(int, struct sigaction *); 799void readjust_priorities(struct pthread *, struct pthread_mutex *); 800struct sigaction *proc_sigact_sigaction(int); 801 802/* #include <sys/aio.h> */ 803#ifdef _SYS_AIO_H_ 804int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); 805#endif 806 807/* #include <sys/event.h> */ 808#ifdef _SYS_EVENT_H_ 809int __sys_kevent(int, const struct kevent *, int, struct kevent *, 810 int, const struct timespec *); 811#endif 812 813/* #include <sys/ioctl.h> */ 814#ifdef _SYS_IOCTL_H_ 815int __sys_ioctl(int, unsigned long, ...); 816#endif 817 818/* #include <sys/mman.h> */ 819#ifdef _SYS_MMAN_H_ 820int __sys_msync(void *, size_t, int); 821#endif 822 823/* #include <sys/mount.h> */ 824#ifdef _SYS_MOUNT_H_ 825int __sys_fstatfs(int, struct statfs *); 826#endif 827 828/* #include <sys/socket.h> */ 829#ifdef _SYS_SOCKET_H_ 830int __sys_accept(int, struct sockaddr *, socklen_t *); 831int __sys_bind(int, const struct sockaddr *, socklen_t); 832int __sys_connect(int, const struct sockaddr *, socklen_t); 833int __sys_getpeername(int, struct sockaddr *, socklen_t *); 834int __sys_getsockname(int, struct sockaddr *, socklen_t *); 835int __sys_getsockopt(int, int, int, void *, socklen_t *); 836int __sys_listen(int, int); 837ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 838ssize_t __sys_recvmsg(int, struct msghdr *, int); 839int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int); 840ssize_t __sys_sendmsg(int, const struct msghdr *, int); 841ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t); 842int __sys_setsockopt(int, int, int, const void *, socklen_t); 843int __sys_shutdown(int, int); 844int __sys_socket(int, int, int); 845int __sys_socketpair(int, int, int, int *); 846#endif 847 848/* #include <sys/stat.h> */ 849#ifdef _SYS_STAT_H_ 850int __sys_fchflags(int, u_long); 851int __sys_fchmod(int, mode_t); 852int __sys_fstat(int, struct stat *); 853#endif 854 855/* #include <sys/uio.h> */ 856#ifdef _SYS_UIO_H_ 857ssize_t __sys_readv(int, const struct iovec *, int); 858ssize_t __sys_writev(int, const struct iovec *, int); 859#endif 860 861/* #include <sys/wait.h> */ 862#ifdef WNOHANG 863pid_t __sys_wait4(pid_t, int *, int, struct rusage *); 864#endif 865 866/* #include <dirent.h> */ 867#ifdef _DIRENT_H_ 868int __sys_getdirentries(int, char *, int, long *); 869#endif 870 871/* #include <fcntl.h> */ 872#ifdef _SYS_FCNTL_H_ 873int __sys_fcntl(int, int, ...); 874int __sys_flock(int, int); 875int __sys_open(const char *, int, ...); 876#endif 877 878/* #include <poll.h> */ 879#ifdef _SYS_POLL_H_ 880int __sys_poll(struct pollfd *, unsigned, int); 881#endif 882 883/* #include <signal.h> */ 884#ifdef _SIGNAL_H_ 885int __sys_sigaction(int, const struct sigaction *, struct sigaction *); 886int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); 887int __sys_sigprocmask(int, const sigset_t *, sigset_t *); 888int __sys_sigreturn(ucontext_t *); 889#endif 890 891/* #include <unistd.h> */ 892#ifdef _UNISTD_H_ 893int __sys_close(int); 894int __sys_dup(int); 895int __sys_dup2(int, int); 896int __sys_execve(const char *, char * const *, char * const *); 897void __sys_exit(int); 898int __sys_fchown(int, uid_t, gid_t); 899pid_t __sys_fork(void); 900long __sys_fpathconf(int, int); 901int __sys_fsync(int); 902int __sys_pipe(int *); 903ssize_t __sys_read(int, void *, size_t); 904ssize_t __sys_write(int, const void *, size_t); 905#endif 906 907__END_DECLS 908 909#endif /* !_PTHREAD_PRIVATE_H */ 910