thr_private.h revision 61681
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: head/lib/libkse/thread/thr_private.h 61681 2000-06-14 17:17:41Z jasone $ 35 */ 36 37#ifndef _PTHREAD_PRIVATE_H 38#define _PTHREAD_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 <setjmp.h> 53#include <signal.h> 54#include <sys/queue.h> 55#include <sys/types.h> 56#include <sys/time.h> 57#include <sys/cdefs.h> 58#include <sched.h> 59#include <spinlock.h> 60#include <pthread_np.h> 61 62/* 63 * Kernel fatal error handler macro. 64 */ 65#define PANIC(string) _thread_exit(__FILE__,__LINE__,string) 66 67/* Output debug messages like this: */ 68#define stdout_debug(_x) _thread_sys_write(1,_x,strlen(_x)); 69#define stderr_debug(_x) _thread_sys_write(2,_x,strlen(_x)); 70 71 72/* 73 * Priority queue manipulation macros (using pqe link): 74 */ 75#define PTHREAD_PRIOQ_INSERT_HEAD(thrd) _pq_insert_head(&_readyq,thrd) 76#define PTHREAD_PRIOQ_INSERT_TAIL(thrd) _pq_insert_tail(&_readyq,thrd) 77#define PTHREAD_PRIOQ_REMOVE(thrd) _pq_remove(&_readyq,thrd) 78#define PTHREAD_PRIOQ_FIRST() _pq_first(&_readyq) 79 80/* 81 * Waiting queue manipulation macros (using pqe link): 82 */ 83#if defined(_PTHREADS_INVARIANTS) 84#define PTHREAD_WAITQ_REMOVE(thrd) _waitq_remove(thrd) 85#define PTHREAD_WAITQ_INSERT(thrd) _waitq_insert(thrd) 86#define PTHREAD_WAITQ_CLEARACTIVE() _waitq_clearactive() 87#define PTHREAD_WAITQ_SETACTIVE() _waitq_setactive() 88#else 89#define PTHREAD_WAITQ_REMOVE(thrd) do { \ 90 TAILQ_REMOVE(&_waitingq,thrd,pqe); \ 91 (thrd)->flags &= ~PTHREAD_FLAGS_IN_WAITQ; \ 92} while (0) 93 94#define PTHREAD_WAITQ_INSERT(thrd) do { \ 95 if ((thrd)->wakeup_time.tv_sec == -1) \ 96 TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \ 97 else { \ 98 pthread_t tid = TAILQ_FIRST(&_waitingq); \ 99 while ((tid != NULL) && (tid->wakeup_time.tv_sec != -1) && \ 100 ((tid->wakeup_time.tv_sec < (thrd)->wakeup_time.tv_sec) || \ 101 ((tid->wakeup_time.tv_sec == (thrd)->wakeup_time.tv_sec) && \ 102 (tid->wakeup_time.tv_nsec <= (thrd)->wakeup_time.tv_nsec)))) \ 103 tid = TAILQ_NEXT(tid, pqe); \ 104 if (tid == NULL) \ 105 TAILQ_INSERT_TAIL(&_waitingq,thrd,pqe); \ 106 else \ 107 TAILQ_INSERT_BEFORE(tid,thrd,pqe); \ 108 } \ 109 (thrd)->flags |= PTHREAD_FLAGS_IN_WAITQ; \ 110} while (0) 111#define PTHREAD_WAITQ_CLEARACTIVE() 112#define PTHREAD_WAITQ_SETACTIVE() 113#endif 114 115/* 116 * Work queue manipulation macros (using qe link): 117 */ 118#define PTHREAD_WORKQ_INSERT(thrd) do { \ 119 TAILQ_INSERT_TAIL(&_workq,thrd,qe); \ 120 (thrd)->flags |= PTHREAD_FLAGS_IN_WORKQ; \ 121} while (0) 122#define PTHREAD_WORKQ_REMOVE(thrd) do { \ 123 TAILQ_REMOVE(&_workq,thrd,qe); \ 124 (thrd)->flags &= ~PTHREAD_FLAGS_IN_WORKQ; \ 125} while (0) 126 127 128/* 129 * State change macro without scheduling queue change: 130 */ 131#define PTHREAD_SET_STATE(thrd, newstate) do { \ 132 (thrd)->state = newstate; \ 133 (thrd)->fname = __FILE__; \ 134 (thrd)->lineno = __LINE__; \ 135} while (0) 136 137/* 138 * State change macro with scheduling queue change - This must be 139 * called with preemption deferred (see thread_kern_sched_[un]defer). 140 */ 141#if defined(_PTHREADS_INVARIANTS) 142#define PTHREAD_NEW_STATE(thrd, newstate) do { \ 143 if (_thread_kern_new_state != 0) \ 144 PANIC("Recursive PTHREAD_NEW_STATE"); \ 145 _thread_kern_new_state = 1; \ 146 if ((thrd)->state != newstate) { \ 147 if ((thrd)->state == PS_RUNNING) { \ 148 PTHREAD_PRIOQ_REMOVE(thrd); \ 149 PTHREAD_WAITQ_INSERT(thrd); \ 150 } else if (newstate == PS_RUNNING) { \ 151 PTHREAD_WAITQ_REMOVE(thrd); \ 152 PTHREAD_PRIOQ_INSERT_TAIL(thrd); \ 153 } \ 154 } \ 155 _thread_kern_new_state = 0; \ 156 PTHREAD_SET_STATE(thrd, newstate); \ 157} while (0) 158#else 159#define PTHREAD_NEW_STATE(thrd, newstate) do { \ 160 if ((thrd)->state != newstate) { \ 161 if ((thrd)->state == PS_RUNNING) { \ 162 PTHREAD_PRIOQ_REMOVE(thrd); \ 163 PTHREAD_WAITQ_INSERT(thrd); \ 164 } else if (newstate == PS_RUNNING) { \ 165 PTHREAD_WAITQ_REMOVE(thrd); \ 166 PTHREAD_PRIOQ_INSERT_TAIL(thrd); \ 167 } \ 168 } \ 169 PTHREAD_SET_STATE(thrd, newstate); \ 170} while (0) 171#endif 172 173/* 174 * Define the signals to be used for scheduling. 175 */ 176#if defined(_PTHREADS_COMPAT_SCHED) 177#define _ITIMER_SCHED_TIMER ITIMER_VIRTUAL 178#define _SCHED_SIGNAL SIGVTALRM 179#else 180#define _ITIMER_SCHED_TIMER ITIMER_PROF 181#define _SCHED_SIGNAL SIGPROF 182#endif 183 184/* 185 * Priority queues. 186 * 187 * XXX It'd be nice if these were contained in uthread_priority_queue.[ch]. 188 */ 189typedef struct pq_list { 190 TAILQ_HEAD(, pthread) pl_head; /* list of threads at this priority */ 191 TAILQ_ENTRY(pq_list) pl_link; /* link for queue of priority lists */ 192 int pl_prio; /* the priority of this list */ 193 int pl_queued; /* is this in the priority queue */ 194} pq_list_t; 195 196typedef struct pq_queue { 197 TAILQ_HEAD(, pq_list) pq_queue; /* queue of priority lists */ 198 pq_list_t *pq_lists; /* array of all priority lists */ 199 int pq_size; /* number of priority lists */ 200} pq_queue_t; 201 202 203/* 204 * TailQ initialization values. 205 */ 206#define TAILQ_INITIALIZER { NULL, NULL } 207 208/* 209 * Mutex definitions. 210 */ 211union pthread_mutex_data { 212 void *m_ptr; 213 int m_count; 214}; 215 216struct pthread_mutex { 217 enum pthread_mutextype m_type; 218 int m_protocol; 219 TAILQ_HEAD(mutex_head, pthread) m_queue; 220 struct pthread *m_owner; 221 union pthread_mutex_data m_data; 222 long m_flags; 223 int m_refcount; 224 225 /* 226 * Used for priority inheritence and protection. 227 * 228 * m_prio - For priority inheritence, the highest active 229 * priority (threads locking the mutex inherit 230 * this priority). For priority protection, the 231 * ceiling priority of this mutex. 232 * m_saved_prio - mutex owners inherited priority before 233 * taking the mutex, restored when the owner 234 * unlocks the mutex. 235 */ 236 int m_prio; 237 int m_saved_prio; 238 239 /* 240 * Link for list of all mutexes a thread currently owns. 241 */ 242 TAILQ_ENTRY(pthread_mutex) m_qe; 243 244 /* 245 * Lock for accesses to this structure. 246 */ 247 spinlock_t lock; 248}; 249 250/* 251 * Flags for mutexes. 252 */ 253#define MUTEX_FLAGS_PRIVATE 0x01 254#define MUTEX_FLAGS_INITED 0x02 255#define MUTEX_FLAGS_BUSY 0x04 256 257/* 258 * Static mutex initialization values. 259 */ 260#define PTHREAD_MUTEX_STATIC_INITIALIZER \ 261 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, TAILQ_INITIALIZER, \ 262 NULL, { NULL }, MUTEX_FLAGS_PRIVATE, 0, 0, 0, TAILQ_INITIALIZER, \ 263 _SPINLOCK_INITIALIZER } 264 265struct pthread_mutex_attr { 266 enum pthread_mutextype m_type; 267 int m_protocol; 268 int m_ceiling; 269 long m_flags; 270}; 271 272/* 273 * Condition variable definitions. 274 */ 275enum pthread_cond_type { 276 COND_TYPE_FAST, 277 COND_TYPE_MAX 278}; 279 280struct pthread_cond { 281 enum pthread_cond_type c_type; 282 TAILQ_HEAD(cond_head, pthread) c_queue; 283 pthread_mutex_t c_mutex; 284 void *c_data; 285 long c_flags; 286 287 /* 288 * Lock for accesses to this structure. 289 */ 290 spinlock_t lock; 291}; 292 293struct pthread_cond_attr { 294 enum pthread_cond_type c_type; 295 long c_flags; 296}; 297 298/* 299 * Flags for condition variables. 300 */ 301#define COND_FLAGS_PRIVATE 0x01 302#define COND_FLAGS_INITED 0x02 303#define COND_FLAGS_BUSY 0x04 304 305/* 306 * Static cond initialization values. 307 */ 308#define PTHREAD_COND_STATIC_INITIALIZER \ 309 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \ 310 0, _SPINLOCK_INITIALIZER } 311 312/* 313 * Semaphore definitions. 314 */ 315struct sem { 316#define SEM_MAGIC ((u_int32_t) 0x09fa4012) 317 u_int32_t magic; 318 pthread_mutex_t lock; 319 pthread_cond_t gtzero; 320 u_int32_t count; 321 u_int32_t nwaiters; 322}; 323 324/* 325 * Cleanup definitions. 326 */ 327struct pthread_cleanup { 328 struct pthread_cleanup *next; 329 void (*routine) (); 330 void *routine_arg; 331}; 332 333struct pthread_attr { 334 int sched_policy; 335 int sched_inherit; 336 int sched_interval; 337 int prio; 338 int suspend; 339 int flags; 340 void *arg_attr; 341 void (*cleanup_attr) (); 342 void *stackaddr_attr; 343 size_t stacksize_attr; 344}; 345 346/* 347 * Thread creation state attributes. 348 */ 349#define PTHREAD_CREATE_RUNNING 0 350#define PTHREAD_CREATE_SUSPENDED 1 351 352/* 353 * Additional state for a thread suspended with pthread_suspend_np(). 354 */ 355enum pthread_susp { 356 SUSP_NO, /* Not suspended. */ 357 SUSP_YES, /* Suspended. */ 358 SUSP_NOWAIT, /* Suspended, was in a mutex or condition queue. */ 359 SUSP_MUTEX_WAIT,/* Suspended, still in a mutex queue. */ 360 SUSP_COND_WAIT /* Suspended, still in a condition queue. */ 361}; 362 363/* 364 * Miscellaneous definitions. 365 */ 366#define PTHREAD_STACK_DEFAULT 65536 367/* 368 * Size of red zone at the end of each stack. In actuality, this "red zone" is 369 * merely an unmapped region, except in the case of the initial stack. Since 370 * mmap() makes it possible to specify the maximum growth of a MAP_STACK region, 371 * an unmapped gap between thread stacks achieves the same effect as explicitly 372 * mapped red zones. 373 */ 374#define PTHREAD_STACK_GUARD PAGE_SIZE 375 376/* 377 * Maximum size of initial thread's stack. This perhaps deserves to be larger 378 * than the stacks of other threads, since many applications are likely to run 379 * almost entirely on this stack. 380 */ 381#define PTHREAD_STACK_INITIAL 0x100000 382/* Address immediately beyond the beginning of the initial thread stack. */ 383#define PTHREAD_DEFAULT_PRIORITY 64 384#define PTHREAD_MAX_PRIORITY 126 385#define PTHREAD_MIN_PRIORITY 0 386#define _POSIX_THREAD_ATTR_STACKSIZE 387 388/* 389 * Clock resolution in nanoseconds. 390 */ 391#define CLOCK_RES_NSEC 10000000 392 393/* 394 * Time slice period in microseconds. 395 */ 396#define TIMESLICE_USEC 100000 397 398struct pthread_key { 399 spinlock_t lock; 400 volatile int allocated; 401 volatile int count; 402 void (*destructor) (); 403}; 404 405struct pthread_rwlockattr { 406 int pshared; 407}; 408 409struct pthread_rwlock { 410 pthread_mutex_t lock; /* monitor lock */ 411 int state; /* 0 = idle >0 = # of readers -1 = writer */ 412 pthread_cond_t read_signal; 413 pthread_cond_t write_signal; 414 int blocked_writers; 415}; 416 417/* 418 * Thread states. 419 */ 420enum pthread_state { 421 PS_RUNNING, 422 PS_SIGTHREAD, 423 PS_MUTEX_WAIT, 424 PS_COND_WAIT, 425 PS_FDLR_WAIT, 426 PS_FDLW_WAIT, 427 PS_FDR_WAIT, 428 PS_FDW_WAIT, 429 PS_FILE_WAIT, 430 PS_POLL_WAIT, 431 PS_SELECT_WAIT, 432 PS_SLEEP_WAIT, 433 PS_WAIT_WAIT, 434 PS_SIGSUSPEND, 435 PS_SIGWAIT, 436 PS_SPINBLOCK, 437 PS_JOIN, 438 PS_SUSPENDED, 439 PS_DEAD, 440 PS_DEADLOCK, 441 PS_STATE_MAX 442}; 443 444 445/* 446 * File descriptor locking definitions. 447 */ 448#define FD_READ 0x1 449#define FD_WRITE 0x2 450#define FD_RDWR (FD_READ | FD_WRITE) 451 452/* 453 * File descriptor table structure. 454 */ 455struct fd_table_entry { 456 /* 457 * Lock for accesses to this file descriptor table 458 * entry. This is passed to _spinlock() to provide atomic 459 * access to this structure. It does *not* represent the 460 * state of the lock on the file descriptor. 461 */ 462 spinlock_t lock; 463 TAILQ_HEAD(, pthread) r_queue; /* Read queue. */ 464 TAILQ_HEAD(, pthread) w_queue; /* Write queue. */ 465 struct pthread *r_owner; /* Ptr to thread owning read lock. */ 466 struct pthread *w_owner; /* Ptr to thread owning write lock. */ 467 char *r_fname; /* Ptr to read lock source file name */ 468 int r_lineno; /* Read lock source line number. */ 469 char *w_fname; /* Ptr to write lock source file name */ 470 int w_lineno; /* Write lock source line number. */ 471 int r_lockcount; /* Count for FILE read locks. */ 472 int w_lockcount; /* Count for FILE write locks. */ 473 int flags; /* Flags used in open. */ 474}; 475 476struct pthread_poll_data { 477 int nfds; 478 struct pollfd *fds; 479}; 480 481union pthread_wait_data { 482 pthread_mutex_t mutex; 483 pthread_cond_t cond; 484 const sigset_t *sigwait; /* Waiting on a signal in sigwait */ 485 struct { 486 short fd; /* Used when thread waiting on fd */ 487 short branch; /* Line number, for debugging. */ 488 char *fname; /* Source file name for debugging.*/ 489 } fd; 490 struct pthread_poll_data * poll_data; 491 spinlock_t *spinlock; 492}; 493 494/* 495 * Define a continuation routine that can be used to perform a 496 * transfer of control: 497 */ 498typedef void (*thread_continuation_t) (void *); 499 500/* 501 * Thread structure. 502 */ 503struct pthread { 504 /* 505 * Magic value to help recognize a valid thread structure 506 * from an invalid one: 507 */ 508#define PTHREAD_MAGIC ((u_int32_t) 0xd09ba115) 509 u_int32_t magic; 510 char *name; 511 u_int64_t uniqueid; /* for gdb */ 512 513 /* 514 * Lock for accesses to this thread structure. 515 */ 516 spinlock_t lock; 517 518 /* Queue entry for list of all threads: */ 519 TAILQ_ENTRY(pthread) tle; 520 521 /* Queue entry for list of dead threads: */ 522 TAILQ_ENTRY(pthread) dle; 523 524 /* 525 * Thread start routine, argument, stack pointer and thread 526 * attributes. 527 */ 528 void *(*start_routine)(void *); 529 void *arg; 530 void *stack; 531 struct pthread_attr attr; 532 533#if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(__i386__) 534 /* 535 * Saved floating point registers on systems where they are not 536 * saved in the signal context. 537 */ 538 char saved_fp[108]; 539#endif 540 541 /* 542 * Saved signal context used in call to sigreturn by 543 * _thread_kern_sched if sig_saved is TRUE. 544 */ 545 ucontext_t saved_sigcontext; 546 547 /* 548 * Saved jump buffer used in call to longjmp by _thread_kern_sched 549 * if sig_saved is FALSE. 550 */ 551 jmp_buf saved_jmp_buf; 552 jmp_buf *sighandler_jmp_buf; 553 554 /* 555 * Saved jump buffers for use when doing nested [sig|_]longjmp()s, as 556 * when doing signal delivery. 557 */ 558 union { 559 jmp_buf jmp; 560 sigjmp_buf sigjmp; 561 } nested_jmp; 562 int longjmp_val; 563 564#define JMPFLAGS_NONE 0x00 565#define JMPFLAGS_LONGJMP 0x01 566#define JMPFLAGS__LONGJMP 0x02 567#define JMPFLAGS_SIGLONGJMP 0x04 568#define JMPFLAGS_DEFERRED 0x08 569 int jmpflags; 570 571 /* 572 * TRUE if the last state saved was a signal context. FALSE if the 573 * last state saved was a jump buffer. 574 */ 575 int sig_saved; 576 577 /* 578 * Used for tracking delivery of nested signal handlers. 579 */ 580 int signal_nest_level; 581 582 /* 583 * Cancelability flags - the lower 2 bits are used by cancel 584 * definitions in pthread.h 585 */ 586#define PTHREAD_AT_CANCEL_POINT 0x0004 587#define PTHREAD_CANCELLING 0x0008 588#define PTHREAD_CANCEL_NEEDED 0x0010 589 int cancelflags; 590 591 enum pthread_susp suspended; 592 593 thread_continuation_t continuation; 594 595 /* 596 * Current signal mask and pending signals. 597 */ 598 sigset_t sigmask; 599 sigset_t sigpend; 600 601 /* Thread state: */ 602 enum pthread_state state; 603 enum pthread_state oldstate; 604 605 /* Time that this thread was last made active. */ 606 struct timeval last_active; 607 608 /* Time that this thread was last made inactive. */ 609 struct timeval last_inactive; 610 611 /* 612 * Number of microseconds accumulated by this thread when 613 * time slicing is active. 614 */ 615 long slice_usec; 616 617 /* 618 * Incremental priority accumulated by thread while it is ready to 619 * run but is denied being run. 620 */ 621 int inc_prio; 622 623 /* 624 * Time to wake up thread. This is used for sleeping threads and 625 * for any operation which may time out (such as select). 626 */ 627 struct timespec wakeup_time; 628 629 /* TRUE if operation has timed out. */ 630 int timeout; 631 632 /* 633 * Error variable used instead of errno. The function __error() 634 * returns a pointer to this. 635 */ 636 int error; 637 638 /* Join queue head and link for waiting threads: */ 639 TAILQ_HEAD(join_head, pthread) join_queue; 640 641 /* 642 * The current thread can belong to only one scheduling queue at 643 * a time (ready or waiting queue). It can also belong to (only) 644 * one of: 645 * 646 * o A queue of threads waiting for a mutex 647 * o A queue of threads waiting for a condition variable 648 * o A queue of threads waiting for another thread to terminate 649 * (the join queue above) 650 * o A queue of threads waiting for a file descriptor lock 651 * o A queue of threads needing work done by the kernel thread 652 * (waiting for a spinlock or file I/O) 653 * 654 * Use pqe for the scheduling queue link (both ready and waiting), 655 * and qe for other links. 656 */ 657 658 /* Priority queue entry for this thread: */ 659 TAILQ_ENTRY(pthread) pqe; 660 661 /* Queue entry for this thread: */ 662 TAILQ_ENTRY(pthread) qe; 663 664 /* Wait data. */ 665 union pthread_wait_data data; 666 667 /* 668 * Allocated for converting select into poll. 669 */ 670 struct pthread_poll_data poll_data; 671 672 /* 673 * Set to TRUE if a blocking operation was 674 * interrupted by a signal: 675 */ 676 int interrupted; 677 678 /* Signal number when in state PS_SIGWAIT: */ 679 int signo; 680 681 /* 682 * Set to non-zero when this thread has deferred signals. 683 * We allow for recursive deferral. 684 */ 685 int sig_defer_count; 686 687 /* 688 * Set to TRUE if this thread should yield after undeferring 689 * signals. 690 */ 691 int yield_on_sig_undefer; 692 693 /* Miscellaneous flags; only set with signals deferred. */ 694 int flags; 695#define PTHREAD_FLAGS_PRIVATE 0x0001 696#define PTHREAD_EXITING 0x0002 697#define PTHREAD_FLAGS_IN_CONDQ 0x0004 /* in condition queue using qe link*/ 698#define PTHREAD_FLAGS_IN_WORKQ 0x0008 /* in work queue using qe link */ 699#define PTHREAD_FLAGS_IN_WAITQ 0x0010 /* in waiting queue using pqe link */ 700#define PTHREAD_FLAGS_IN_PRIOQ 0x0020 /* in priority queue using pqe link */ 701#define PTHREAD_FLAGS_IN_MUTEXQ 0x0040 /* in mutex queue using qe link */ 702#define PTHREAD_FLAGS_IN_FILEQ 0x0080 /* in file lock queue using qe link */ 703#define PTHREAD_FLAGS_IN_FDQ 0x0100 /* in fd lock queue using qe link */ 704#define PTHREAD_FLAGS_TRACE 0x0200 /* for debugging purposes */ 705 706 /* 707 * Base priority is the user setable and retrievable priority 708 * of the thread. It is only affected by explicit calls to 709 * set thread priority and upon thread creation via a thread 710 * attribute or default priority. 711 */ 712 char base_priority; 713 714 /* 715 * Inherited priority is the priority a thread inherits by 716 * taking a priority inheritence or protection mutex. It 717 * is not affected by base priority changes. Inherited 718 * priority defaults to and remains 0 until a mutex is taken 719 * that is being waited on by any other thread whose priority 720 * is non-zero. 721 */ 722 char inherited_priority; 723 724 /* 725 * Active priority is always the maximum of the threads base 726 * priority and inherited priority. When there is a change 727 * in either the base or inherited priority, the active 728 * priority must be recalculated. 729 */ 730 char active_priority; 731 732 /* Number of priority ceiling or protection mutexes owned. */ 733 int priority_mutex_count; 734 735 /* 736 * Queue of currently owned mutexes. 737 */ 738 TAILQ_HEAD(, pthread_mutex) mutexq; 739 740 void *ret; 741 const void **specific_data; 742 int specific_data_count; 743 744 /* Cleanup handlers Link List */ 745 struct pthread_cleanup *cleanup; 746 char *fname; /* Ptr to source file name */ 747 int lineno; /* Source line number. */ 748}; 749 750/* Spare thread stack. */ 751struct stack { 752 SLIST_ENTRY(stack) qe; /* Queue entry for this stack. */ 753}; 754 755/* 756 * Global variables for the uthread kernel. 757 */ 758 759/* Kernel thread structure used when there are no running threads: */ 760SCLASS struct pthread _thread_kern_thread; 761 762/* Ptr to the thread structure for the running thread: */ 763SCLASS struct pthread * volatile _thread_run 764#ifdef GLOBAL_PTHREAD_PRIVATE 765= &_thread_kern_thread; 766#else 767; 768#endif 769 770/* Ptr to the thread structure for the last user thread to run: */ 771SCLASS struct pthread * volatile _last_user_thread 772#ifdef GLOBAL_PTHREAD_PRIVATE 773= &_thread_kern_thread; 774#else 775; 776#endif 777 778/* 779 * Ptr to the thread running in single-threaded mode or NULL if 780 * running multi-threaded (default POSIX behaviour). 781 */ 782SCLASS struct pthread * volatile _thread_single 783#ifdef GLOBAL_PTHREAD_PRIVATE 784= NULL; 785#else 786; 787#endif 788 789/* List of all threads: */ 790SCLASS TAILQ_HEAD(, pthread) _thread_list 791#ifdef GLOBAL_PTHREAD_PRIVATE 792= TAILQ_HEAD_INITIALIZER(_thread_list); 793#else 794; 795#endif 796 797/* 798 * Array of kernel pipe file descriptors that are used to ensure that 799 * no signals are missed in calls to _select. 800 */ 801SCLASS int _thread_kern_pipe[2] 802#ifdef GLOBAL_PTHREAD_PRIVATE 803= { 804 -1, 805 -1 806}; 807#else 808; 809#endif 810SCLASS int volatile _queue_signals 811#ifdef GLOBAL_PTHREAD_PRIVATE 812= 0; 813#else 814; 815#endif 816SCLASS int _thread_kern_in_sched 817#ifdef GLOBAL_PTHREAD_PRIVATE 818= 0; 819#else 820; 821#endif 822 823/* Last time that an incremental priority update was performed: */ 824SCLASS struct timeval kern_inc_prio_time 825#ifdef GLOBAL_PTHREAD_PRIVATE 826= { 0, 0 }; 827#else 828; 829#endif 830 831/* Dead threads: */ 832SCLASS TAILQ_HEAD(, pthread) _dead_list 833#ifdef GLOBAL_PTHREAD_PRIVATE 834= TAILQ_HEAD_INITIALIZER(_dead_list); 835#else 836; 837#endif 838 839/* Initial thread: */ 840SCLASS struct pthread *_thread_initial 841#ifdef GLOBAL_PTHREAD_PRIVATE 842= NULL; 843#else 844; 845#endif 846 847/* Default thread attributes: */ 848SCLASS struct pthread_attr pthread_attr_default 849#ifdef GLOBAL_PTHREAD_PRIVATE 850= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, PTHREAD_CREATE_RUNNING, 851 PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, PTHREAD_STACK_DEFAULT }; 852#else 853; 854#endif 855 856/* Default mutex attributes: */ 857SCLASS struct pthread_mutex_attr pthread_mutexattr_default 858#ifdef GLOBAL_PTHREAD_PRIVATE 859= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }; 860#else 861; 862#endif 863 864/* Default condition variable attributes: */ 865SCLASS struct pthread_cond_attr pthread_condattr_default 866#ifdef GLOBAL_PTHREAD_PRIVATE 867= { COND_TYPE_FAST, 0 }; 868#else 869; 870#endif 871 872/* 873 * Standard I/O file descriptors need special flag treatment since 874 * setting one to non-blocking does all on *BSD. Sigh. This array 875 * is used to store the initial flag settings. 876 */ 877SCLASS int _pthread_stdio_flags[3]; 878 879/* File table information: */ 880SCLASS struct fd_table_entry **_thread_fd_table 881#ifdef GLOBAL_PTHREAD_PRIVATE 882= NULL; 883#else 884; 885#endif 886 887/* Table for polling file descriptors: */ 888SCLASS struct pollfd *_thread_pfd_table 889#ifdef GLOBAL_PTHREAD_PRIVATE 890= NULL; 891#else 892; 893#endif 894 895SCLASS const int dtablecount 896#ifdef GLOBAL_PTHREAD_PRIVATE 897= 4096/sizeof(struct fd_table_entry); 898#else 899; 900#endif 901SCLASS int _thread_dtablesize /* Descriptor table size. */ 902#ifdef GLOBAL_PTHREAD_PRIVATE 903= 0; 904#else 905; 906#endif 907 908SCLASS int _clock_res_nsec /* Clock resolution in nsec. */ 909#ifdef GLOBAL_PTHREAD_PRIVATE 910= CLOCK_RES_NSEC; 911#else 912; 913#endif 914 915/* Garbage collector mutex and condition variable. */ 916SCLASS pthread_mutex_t _gc_mutex 917#ifdef GLOBAL_PTHREAD_PRIVATE 918= NULL 919#endif 920; 921SCLASS pthread_cond_t _gc_cond 922#ifdef GLOBAL_PTHREAD_PRIVATE 923= NULL 924#endif 925; 926 927/* 928 * Array of signal actions for this process. 929 */ 930SCLASS struct sigaction _thread_sigact[NSIG]; 931 932/* 933 * Pending signals for this process. 934 */ 935SCLASS sigset_t _process_sigpending; 936 937/* 938 * Scheduling queues: 939 */ 940SCLASS pq_queue_t _readyq; 941SCLASS TAILQ_HEAD(, pthread) _waitingq; 942 943/* 944 * Work queue: 945 */ 946SCLASS TAILQ_HEAD(, pthread) _workq; 947 948/* Tracks the number of threads blocked while waiting for a spinlock. */ 949SCLASS volatile int _spinblock_count 950#ifdef GLOBAL_PTHREAD_PRIVATE 951= 0 952#endif 953; 954 955/* Indicates that the signal queue needs to be checked. */ 956SCLASS volatile int _sigq_check_reqd 957#ifdef GLOBAL_PTHREAD_PRIVATE 958= 0 959#endif 960; 961 962/* Thread switch hook. */ 963SCLASS pthread_switch_routine_t _sched_switch_hook 964#ifdef GLOBAL_PTHREAD_PRIVATE 965= NULL 966#endif 967; 968 969/* 970 * Spare stack queue. Stacks of default size are cached in order to reduce 971 * thread creation time. Spare stacks are used in LIFO order to increase cache 972 * locality. 973 */ 974SCLASS SLIST_HEAD(, stack) _stackq; 975 976/* 977 * Base address of next unallocated default-size {stack, red zone}. Stacks are 978 * allocated contiguously, starting below the bottom of the main stack. When a 979 * new stack is created, a red zone is created (actually, the red zone is simply 980 * left unmapped) below the bottom of the stack, such that the stack will not be 981 * able to grow all the way to the top of the next stack. This isn't 982 * fool-proof. It is possible for a stack to grow by a large amount, such that 983 * it grows into the next stack, and as long as the memory within the red zone 984 * is never accessed, nothing will prevent one thread stack from trouncing all 985 * over the next. 986 */ 987SCLASS void * _next_stack 988#ifdef GLOBAL_PTHREAD_PRIVATE 989/* main stack top - main stack size - stack size - (red zone + main stack red zone) */ 990= (void *) USRSTACK - PTHREAD_STACK_INITIAL - PTHREAD_STACK_DEFAULT - (2 * PTHREAD_STACK_GUARD) 991#endif 992; 993 994/* Used for _PTHREADS_INVARIANTS checking. */ 995SCLASS int _thread_kern_new_state 996#ifdef GLOBAL_PTHREAD_PRIVATE 997= 0 998#endif 999; 1000 1001/* Undefine the storage class specifier: */ 1002#undef SCLASS 1003 1004#ifdef _LOCK_DEBUG 1005#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock_debug(_fd, _type, \ 1006 _ts, __FILE__, __LINE__) 1007#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock_debug(_fd, _type, \ 1008 __FILE__, __LINE__) 1009#else 1010#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts) 1011#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type) 1012#endif 1013 1014/* 1015 * Function prototype definitions. 1016 */ 1017__BEGIN_DECLS 1018char *__ttyname_basic(int); 1019char *__ttyname_r_basic(int, char *, size_t); 1020char *ttyname_r(int, char *, size_t); 1021int _find_dead_thread(pthread_t); 1022int _find_thread(pthread_t); 1023void _funlock_owned(pthread_t); 1024int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t); 1025int _thread_fd_lock(int, int, struct timespec *); 1026int _thread_fd_lock_debug(int, int, struct timespec *,char *fname,int lineno); 1027void _dispatch_signals(void); 1028int _mutex_cv_lock(pthread_mutex_t *); 1029int _mutex_cv_unlock(pthread_mutex_t *); 1030void _mutex_notify_priochange(pthread_t); 1031int _mutex_reinit(pthread_mutex_t *); 1032void _mutex_unlock_private(pthread_t); 1033int _cond_reinit(pthread_cond_t *); 1034int _pq_alloc(struct pq_queue *, int, int); 1035int _pq_init(struct pq_queue *); 1036void _pq_remove(struct pq_queue *pq, struct pthread *); 1037void _pq_insert_head(struct pq_queue *pq, struct pthread *); 1038void _pq_insert_tail(struct pq_queue *pq, struct pthread *); 1039struct pthread *_pq_first(struct pq_queue *pq); 1040#if defined(_PTHREADS_INVARIANTS) 1041void _waitq_insert(pthread_t pthread); 1042void _waitq_remove(pthread_t pthread); 1043void _waitq_setactive(void); 1044void _waitq_clearactive(void); 1045#endif 1046void _thread_exit(char *, int, char *); 1047void _thread_exit_cleanup(void); 1048void _thread_fd_unlock(int, int); 1049void _thread_fd_unlock_debug(int, int, char *, int); 1050void _thread_fd_unlock_owned(pthread_t); 1051void *_thread_cleanup(pthread_t); 1052void _thread_cleanupspecific(void); 1053void _thread_dump_info(void); 1054void _thread_init(void); 1055void _thread_kern_sched(ucontext_t *); 1056void _thread_kern_sched_state(enum pthread_state,char *fname,int lineno); 1057void _thread_kern_sched_state_unlock(enum pthread_state state, 1058 spinlock_t *lock, char *fname, int lineno); 1059void _thread_kern_set_timeout(struct timespec *); 1060void _thread_kern_sig_defer(void); 1061void _thread_kern_sig_undefer(void); 1062void _thread_sig_handler(int, int, ucontext_t *); 1063pthread_t _thread_sig_handle(int, ucontext_t *); 1064void _thread_sig_init(void); 1065void _thread_sig_send(pthread_t pthread, int sig); 1066void _thread_sig_deliver(pthread_t pthread, int sig); 1067void _thread_start(void); 1068void _thread_start_sig_handler(void); 1069void _thread_seterrno(pthread_t,int); 1070int _thread_fd_table_init(int fd); 1071pthread_addr_t _thread_gc(pthread_addr_t); 1072void _thread_enter_cancellation_point(void); 1073void _thread_leave_cancellation_point(void); 1074void _thread_cancellation_point(void); 1075 1076/* #include <signal.h> */ 1077int _thread_sys_sigaction(int, const struct sigaction *, struct sigaction *); 1078int _thread_sys_sigpending(sigset_t *); 1079int _thread_sys_sigprocmask(int, const sigset_t *, sigset_t *); 1080int _thread_sys_sigsuspend(const sigset_t *); 1081int _thread_sys_siginterrupt(int, int); 1082int _thread_sys_sigpause(int); 1083int _thread_sys_sigreturn(ucontext_t *); 1084int _thread_sys_sigstack(const struct sigstack *, struct sigstack *); 1085int _thread_sys_sigvec(int, struct sigvec *, struct sigvec *); 1086void _thread_sys_psignal(unsigned int, const char *); 1087void (*_thread_sys_signal(int, void (*)(int)))(int); 1088 1089/* #include <sys/stat.h> */ 1090#ifdef _SYS_STAT_H_ 1091int _thread_sys_fchmod(int, mode_t); 1092int _thread_sys_fstat(int, struct stat *); 1093int _thread_sys_fchflags(int, u_long); 1094#endif 1095 1096/* #include <sys/mount.h> */ 1097#ifdef _SYS_MOUNT_H_ 1098int _thread_sys_fstatfs(int, struct statfs *); 1099#endif 1100int _thread_sys_pipe(int *); 1101 1102/* #include <sys/socket.h> */ 1103#ifdef _SYS_SOCKET_H_ 1104int _thread_sys_accept(int, struct sockaddr *, int *); 1105int _thread_sys_bind(int, const struct sockaddr *, int); 1106int _thread_sys_connect(int, const struct sockaddr *, int); 1107int _thread_sys_getpeername(int, struct sockaddr *, int *); 1108int _thread_sys_getsockname(int, struct sockaddr *, int *); 1109int _thread_sys_getsockopt(int, int, int, void *, int *); 1110int _thread_sys_listen(int, int); 1111int _thread_sys_setsockopt(int, int, int, const void *, int); 1112int _thread_sys_shutdown(int, int); 1113int _thread_sys_socket(int, int, int); 1114int _thread_sys_socketpair(int, int, int, int *); 1115ssize_t _thread_sys_recv(int, void *, size_t, int); 1116ssize_t _thread_sys_recvfrom(int, void *, size_t, int, struct sockaddr *, int *); 1117ssize_t _thread_sys_recvmsg(int, struct msghdr *, int); 1118ssize_t _thread_sys_send(int, const void *, size_t, int); 1119ssize_t _thread_sys_sendmsg(int, const struct msghdr *, int); 1120ssize_t _thread_sys_sendto(int, const void *,size_t, int, const struct sockaddr *, int); 1121#endif 1122 1123/* #include <stdio.h> */ 1124#ifdef _STDIO_H_ 1125FILE *_thread_sys_fdopen(int, const char *); 1126FILE *_thread_sys_fopen(const char *, const char *); 1127FILE *_thread_sys_freopen(const char *, const char *, FILE *); 1128FILE *_thread_sys_popen(const char *, const char *); 1129FILE *_thread_sys_tmpfile(void); 1130char *_thread_sys_ctermid(char *); 1131char *_thread_sys_cuserid(char *); 1132char *_thread_sys_fgetln(FILE *, size_t *); 1133char *_thread_sys_fgets(char *, int, FILE *); 1134char *_thread_sys_gets(char *); 1135char *_thread_sys_tempnam(const char *, const char *); 1136char *_thread_sys_tmpnam(char *); 1137int _thread_sys_fclose(FILE *); 1138int _thread_sys_feof(FILE *); 1139int _thread_sys_ferror(FILE *); 1140int _thread_sys_fflush(FILE *); 1141int _thread_sys_fgetc(FILE *); 1142int _thread_sys_fgetpos(FILE *, fpos_t *); 1143int _thread_sys_fileno(FILE *); 1144int _thread_sys_fprintf(FILE *, const char *, ...); 1145int _thread_sys_fpurge(FILE *); 1146int _thread_sys_fputc(int, FILE *); 1147int _thread_sys_fputs(const char *, FILE *); 1148int _thread_sys_fscanf(FILE *, const char *, ...); 1149int _thread_sys_fseek(FILE *, long, int); 1150int _thread_sys_fsetpos(FILE *, const fpos_t *); 1151int _thread_sys_getc(FILE *); 1152int _thread_sys_getchar(void); 1153int _thread_sys_getw(FILE *); 1154int _thread_sys_pclose(FILE *); 1155int _thread_sys_printf(const char *, ...); 1156int _thread_sys_putc(int, FILE *); 1157int _thread_sys_putchar(int); 1158int _thread_sys_puts(const char *); 1159int _thread_sys_putw(int, FILE *); 1160int _thread_sys_remove(const char *); 1161int _thread_sys_rename (const char *, const char *); 1162int _thread_sys_scanf(const char *, ...); 1163int _thread_sys_setlinebuf(FILE *); 1164int _thread_sys_setvbuf(FILE *, char *, int, size_t); 1165int _thread_sys_snprintf(char *, size_t, const char *, ...); 1166int _thread_sys_sprintf(char *, const char *, ...); 1167int _thread_sys_sscanf(const char *, const char *, ...); 1168int _thread_sys_ungetc(int, FILE *); 1169int _thread_sys_vfprintf(FILE *, const char *, _BSD_VA_LIST_); 1170int _thread_sys_vprintf(const char *, _BSD_VA_LIST_); 1171int _thread_sys_vscanf(const char *, _BSD_VA_LIST_); 1172int _thread_sys_vsnprintf(char *, size_t, const char *, _BSD_VA_LIST_); 1173int _thread_sys_vsprintf(char *, const char *, _BSD_VA_LIST_); 1174int _thread_sys_vsscanf(const char *, const char *, _BSD_VA_LIST_); 1175long _thread_sys_ftell(FILE *); 1176size_t _thread_sys_fread(void *, size_t, size_t, FILE *); 1177size_t _thread_sys_fwrite(const void *, size_t, size_t, FILE *); 1178void _thread_sys_clearerr(FILE *); 1179void _thread_sys_perror(const char *); 1180void _thread_sys_rewind(FILE *); 1181void _thread_sys_setbuf(FILE *, char *); 1182void _thread_sys_setbuffer(FILE *, char *, int); 1183#endif 1184 1185/* #include <unistd.h> */ 1186#ifdef _UNISTD_H_ 1187char *_thread_sys_ttyname(int); 1188int _thread_sys_close(int); 1189int _thread_sys_dup(int); 1190int _thread_sys_dup2(int, int); 1191int _thread_sys_exect(const char *, char * const *, char * const *); 1192int _thread_sys_execve(const char *, char * const *, char * const *); 1193int _thread_sys_fchdir(int); 1194int _thread_sys_fchown(int, uid_t, gid_t); 1195int _thread_sys_fsync(int); 1196int _thread_sys_ftruncate(int, off_t); 1197int _thread_sys_pause(void); 1198int _thread_sys_pipe(int *); 1199int _thread_sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 1200off_t _thread_sys_lseek(int, off_t, int); 1201pid_t _thread_sys_fork(void); 1202pid_t _thread_sys_tcgetpgrp(int); 1203ssize_t _thread_sys_read(int, void *, size_t); 1204ssize_t _thread_sys_write(int, const void *, size_t); 1205void _thread_sys__exit(int); 1206#endif 1207 1208/* #include <fcntl.h> */ 1209#ifdef _SYS_FCNTL_H_ 1210int _thread_sys_creat(const char *, mode_t); 1211int _thread_sys_fcntl(int, int, ...); 1212int _thread_sys_flock(int, int); 1213int _thread_sys_open(const char *, int, ...); 1214#endif 1215 1216/* #include <sys/ioctl.h> */ 1217#ifdef _SYS_IOCTL_H_ 1218int _thread_sys_ioctl(int, unsigned long, ...); 1219#endif 1220 1221/* #include <dirent.h> */ 1222#ifdef _DIRENT_H_ 1223DIR *___thread_sys_opendir2(const char *, int); 1224DIR *_thread_sys_opendir(const char *); 1225int _thread_sys_alphasort(const void *, const void *); 1226int _thread_sys_scandir(const char *, struct dirent ***, 1227 int (*)(struct dirent *), int (*)(const void *, const void *)); 1228int _thread_sys_closedir(DIR *); 1229int _thread_sys_getdirentries(int, char *, int, long *); 1230long _thread_sys_telldir(const DIR *); 1231struct dirent *_thread_sys_readdir(DIR *); 1232void _thread_sys_rewinddir(DIR *); 1233void _thread_sys_seekdir(DIR *, long); 1234#endif 1235 1236/* #include <sys/uio.h> */ 1237#ifdef _SYS_UIO_H_ 1238ssize_t _thread_sys_readv(int, const struct iovec *, int); 1239ssize_t _thread_sys_writev(int, const struct iovec *, int); 1240#endif 1241 1242/* #include <sys/wait.h> */ 1243#ifdef WNOHANG 1244pid_t _thread_sys_wait(int *); 1245pid_t _thread_sys_waitpid(pid_t, int *, int); 1246pid_t _thread_sys_wait3(int *, int, struct rusage *); 1247pid_t _thread_sys_wait4(pid_t, int *, int, struct rusage *); 1248#endif 1249 1250/* #include <poll.h> */ 1251#ifdef _SYS_POLL_H_ 1252int _thread_sys_poll(struct pollfd *, unsigned, int); 1253#endif 1254 1255/* #include <sys/mman.h> */ 1256#ifdef _SYS_MMAN_H_ 1257int _thread_sys_msync(void *, size_t, int); 1258#endif 1259 1260/* #include <setjmp.h> */ 1261#ifdef _SETJMP_H_ 1262extern void __siglongjmp(sigjmp_buf, int) __dead2; 1263extern void __longjmp(jmp_buf, int) __dead2; 1264extern void ___longjmp(jmp_buf, int) __dead2; 1265#endif 1266__END_DECLS 1267 1268#endif /* !_PTHREAD_PRIVATE_H */ 1269