150/* 151 * TailQ initialization values. 152 */ 153#define TAILQ_INITIALIZER { NULL, NULL } 154 155#define UMTX_INITIALIZER { NULL } 156 157struct pthread_mutex_attr { 158 enum pthread_mutextype m_type; 159 int m_protocol; 160 int m_ceiling; 161 long m_flags; 162}; 163 164/* 165 * Static mutex initialization values. 166 */ 167 168#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ 169 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } 170 171#define PTHREAD_MUTEX_STATIC_INITIALIZER \ 172 { PTHREAD_MUTEXATTR_STATIC_INITIALIZER, UMTX_INITIALIZER, NULL, \ 173 0, 0, TAILQ_INITIALIZER } 174 175union pthread_mutex_data { 176 void *m_ptr; 177 int m_count; 178}; 179 180struct pthread_mutex { 181 enum pthread_mutextype m_type; 182 int m_protocol; 183 TAILQ_HEAD(mutex_head, pthread) m_queue; 184 struct pthread *m_owner; 185 union pthread_mutex_data m_data; 186 long m_flags; 187 int m_refcount; 188 189 /* 190 * Used for priority inheritence and protection. 191 * 192 * m_prio - For priority inheritence, the highest active 193 * priority (threads locking the mutex inherit 194 * this priority). For priority protection, the 195 * ceiling priority of this mutex. 196 * m_saved_prio - mutex owners inherited priority before 197 * taking the mutex, restored when the owner 198 * unlocks the mutex. 199 */ 200 int m_prio; 201 int m_saved_prio; 202 203 /* 204 * Link for list of all mutexes a thread currently owns. 205 */ 206 TAILQ_ENTRY(pthread_mutex) m_qe; 207 208 /* 209 * Lock for accesses to this structure. 210 */ 211 spinlock_t lock; 212}; 213 214struct pthread_spinlock { 215 void *s_owner; 216 unsigned int s_magic; 217}; 218 219/* 220 * Flags for mutexes. 221 */ 222#define MUTEX_FLAGS_PRIVATE 0x01 223#define MUTEX_FLAGS_INITED 0x02 224#define MUTEX_FLAGS_BUSY 0x04 225 226/* 227 * Condition variable definitions. 228 */ 229enum pthread_cond_type { 230 COND_TYPE_FAST, 231 COND_TYPE_MAX 232}; 233 234struct pthread_cond { 235 enum pthread_cond_type c_type; 236 TAILQ_HEAD(cond_head, pthread) c_queue; 237 pthread_mutex_t c_mutex; 238 void *c_data; 239 long c_flags; 240 int c_seqno; 241 242 /* 243 * Lock for accesses to this structure. 244 */ 245 struct umtx c_lock; 246}; 247 248struct pthread_cond_attr { 249 enum pthread_cond_type c_type; 250 long c_flags; 251}; 252 253/* 254 * Flags for condition variables. 255 */ 256#define COND_FLAGS_INITED 0x01 257 258/* 259 * Static cond initialization values. 260 */ 261#define PTHREAD_COND_STATIC_INITIALIZER \ 262 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \ 263 0, 0, UMTX_INITIALIZER } 264 265/* 266 * Semaphore definitions. 267 */ 268struct sem { 269#define SEM_MAGIC ((u_int32_t) 0x09fa4012) 270 u_int32_t magic; 271 pthread_mutex_t lock; 272 pthread_cond_t gtzero; 273 u_int32_t count; 274 u_int32_t nwaiters; 275}; 276 277/* 278 * Cleanup definitions. 279 */ 280struct pthread_cleanup { 281 struct pthread_cleanup *next; 282 void (*routine) (); 283 void *routine_arg; 284}; 285 286struct pthread_attr { 287 int sched_policy; 288 int sched_inherit; 289 int sched_interval; 290 int prio; 291 int suspend; 292 int flags; 293 void *arg_attr; 294 void (*cleanup_attr) (); 295 void *stackaddr_attr; 296 size_t stacksize_attr; 297 size_t guardsize_attr; 298}; 299 300/* 301 * Thread creation state attributes. 302 */ 303#define PTHREAD_CREATE_RUNNING 0 304#define PTHREAD_CREATE_SUSPENDED 1 305 306/* 307 * Miscellaneous definitions. 308 */ 309#define PTHREAD_STACK_DEFAULT 65536 310/* 311 * Size of default red zone at the end of each stack. In actuality, this "red 312 * zone" is merely an unmapped region, except in the case of the initial stack. 313 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK 314 * region, an unmapped gap between thread stacks achieves the same effect as 315 * explicitly mapped red zones. 316 * This is declared and initialized in uthread_init.c. 317 */ 318extern int _pthread_guard_default; 319 320extern int _pthread_page_size; 321 322/* 323 * Maximum size of initial thread's stack. This perhaps deserves to be larger 324 * than the stacks of other threads, since many applications are likely to run 325 * almost entirely on this stack. 326 */ 327#define PTHREAD_STACK_INITIAL 0x100000 328 329/* 330 * Define the different priority ranges. All applications have thread 331 * priorities constrained within 0-31. The threads library raises the 332 * priority when delivering signals in order to ensure that signal 333 * delivery happens (from the POSIX spec) "as soon as possible". 334 * In the future, the threads library will also be able to map specific 335 * threads into real-time (cooperating) processes or kernel threads. 336 * The RT and SIGNAL priorities will be used internally and added to 337 * thread base priorities so that the scheduling queue can handle both 338 * normal and RT priority threads with and without signal handling. 339 * 340 * The approach taken is that, within each class, signal delivery 341 * always has priority over thread execution. 342 */ 343#define PTHREAD_DEFAULT_PRIORITY 15 344#define PTHREAD_MIN_PRIORITY 0 345#define PTHREAD_MAX_PRIORITY 31 /* 0x1F */ 346#define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */ 347#define PTHREAD_RT_PRIORITY 64 /* 0x40 */ 348#define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY 349#define PTHREAD_LAST_PRIORITY \ 350 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY) 351#define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY) 352 353/* 354 * Clock resolution in microseconds. 355 */ 356#define CLOCK_RES_USEC 10000 357#define CLOCK_RES_USEC_MIN 1000 358 359/* 360 * Time slice period in microseconds. 361 */ 362#define TIMESLICE_USEC 20000 363 364/* 365 * XXX Define a thread-safe macro to get the current time of day 366 * which is updated at regular intervals by the scheduling signal 367 * handler. 368 */ 369#define GET_CURRENT_TOD(tv) gettimeofday(&(tv), NULL) 370
| 149/* 150 * TailQ initialization values. 151 */ 152#define TAILQ_INITIALIZER { NULL, NULL } 153 154#define UMTX_INITIALIZER { NULL } 155 156struct pthread_mutex_attr { 157 enum pthread_mutextype m_type; 158 int m_protocol; 159 int m_ceiling; 160 long m_flags; 161}; 162 163/* 164 * Static mutex initialization values. 165 */ 166 167#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ 168 { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } 169 170#define PTHREAD_MUTEX_STATIC_INITIALIZER \ 171 { PTHREAD_MUTEXATTR_STATIC_INITIALIZER, UMTX_INITIALIZER, NULL, \ 172 0, 0, TAILQ_INITIALIZER } 173 174union pthread_mutex_data { 175 void *m_ptr; 176 int m_count; 177}; 178 179struct pthread_mutex { 180 enum pthread_mutextype m_type; 181 int m_protocol; 182 TAILQ_HEAD(mutex_head, pthread) m_queue; 183 struct pthread *m_owner; 184 union pthread_mutex_data m_data; 185 long m_flags; 186 int m_refcount; 187 188 /* 189 * Used for priority inheritence and protection. 190 * 191 * m_prio - For priority inheritence, the highest active 192 * priority (threads locking the mutex inherit 193 * this priority). For priority protection, the 194 * ceiling priority of this mutex. 195 * m_saved_prio - mutex owners inherited priority before 196 * taking the mutex, restored when the owner 197 * unlocks the mutex. 198 */ 199 int m_prio; 200 int m_saved_prio; 201 202 /* 203 * Link for list of all mutexes a thread currently owns. 204 */ 205 TAILQ_ENTRY(pthread_mutex) m_qe; 206 207 /* 208 * Lock for accesses to this structure. 209 */ 210 spinlock_t lock; 211}; 212 213struct pthread_spinlock { 214 void *s_owner; 215 unsigned int s_magic; 216}; 217 218/* 219 * Flags for mutexes. 220 */ 221#define MUTEX_FLAGS_PRIVATE 0x01 222#define MUTEX_FLAGS_INITED 0x02 223#define MUTEX_FLAGS_BUSY 0x04 224 225/* 226 * Condition variable definitions. 227 */ 228enum pthread_cond_type { 229 COND_TYPE_FAST, 230 COND_TYPE_MAX 231}; 232 233struct pthread_cond { 234 enum pthread_cond_type c_type; 235 TAILQ_HEAD(cond_head, pthread) c_queue; 236 pthread_mutex_t c_mutex; 237 void *c_data; 238 long c_flags; 239 int c_seqno; 240 241 /* 242 * Lock for accesses to this structure. 243 */ 244 struct umtx c_lock; 245}; 246 247struct pthread_cond_attr { 248 enum pthread_cond_type c_type; 249 long c_flags; 250}; 251 252/* 253 * Flags for condition variables. 254 */ 255#define COND_FLAGS_INITED 0x01 256 257/* 258 * Static cond initialization values. 259 */ 260#define PTHREAD_COND_STATIC_INITIALIZER \ 261 { COND_TYPE_FAST, TAILQ_INITIALIZER, NULL, NULL, \ 262 0, 0, UMTX_INITIALIZER } 263 264/* 265 * Semaphore definitions. 266 */ 267struct sem { 268#define SEM_MAGIC ((u_int32_t) 0x09fa4012) 269 u_int32_t magic; 270 pthread_mutex_t lock; 271 pthread_cond_t gtzero; 272 u_int32_t count; 273 u_int32_t nwaiters; 274}; 275 276/* 277 * Cleanup definitions. 278 */ 279struct pthread_cleanup { 280 struct pthread_cleanup *next; 281 void (*routine) (); 282 void *routine_arg; 283}; 284 285struct pthread_attr { 286 int sched_policy; 287 int sched_inherit; 288 int sched_interval; 289 int prio; 290 int suspend; 291 int flags; 292 void *arg_attr; 293 void (*cleanup_attr) (); 294 void *stackaddr_attr; 295 size_t stacksize_attr; 296 size_t guardsize_attr; 297}; 298 299/* 300 * Thread creation state attributes. 301 */ 302#define PTHREAD_CREATE_RUNNING 0 303#define PTHREAD_CREATE_SUSPENDED 1 304 305/* 306 * Miscellaneous definitions. 307 */ 308#define PTHREAD_STACK_DEFAULT 65536 309/* 310 * Size of default red zone at the end of each stack. In actuality, this "red 311 * zone" is merely an unmapped region, except in the case of the initial stack. 312 * Since mmap() makes it possible to specify the maximum growth of a MAP_STACK 313 * region, an unmapped gap between thread stacks achieves the same effect as 314 * explicitly mapped red zones. 315 * This is declared and initialized in uthread_init.c. 316 */ 317extern int _pthread_guard_default; 318 319extern int _pthread_page_size; 320 321/* 322 * Maximum size of initial thread's stack. This perhaps deserves to be larger 323 * than the stacks of other threads, since many applications are likely to run 324 * almost entirely on this stack. 325 */ 326#define PTHREAD_STACK_INITIAL 0x100000 327 328/* 329 * Define the different priority ranges. All applications have thread 330 * priorities constrained within 0-31. The threads library raises the 331 * priority when delivering signals in order to ensure that signal 332 * delivery happens (from the POSIX spec) "as soon as possible". 333 * In the future, the threads library will also be able to map specific 334 * threads into real-time (cooperating) processes or kernel threads. 335 * The RT and SIGNAL priorities will be used internally and added to 336 * thread base priorities so that the scheduling queue can handle both 337 * normal and RT priority threads with and without signal handling. 338 * 339 * The approach taken is that, within each class, signal delivery 340 * always has priority over thread execution. 341 */ 342#define PTHREAD_DEFAULT_PRIORITY 15 343#define PTHREAD_MIN_PRIORITY 0 344#define PTHREAD_MAX_PRIORITY 31 /* 0x1F */ 345#define PTHREAD_SIGNAL_PRIORITY 32 /* 0x20 */ 346#define PTHREAD_RT_PRIORITY 64 /* 0x40 */ 347#define PTHREAD_FIRST_PRIORITY PTHREAD_MIN_PRIORITY 348#define PTHREAD_LAST_PRIORITY \ 349 (PTHREAD_MAX_PRIORITY + PTHREAD_SIGNAL_PRIORITY + PTHREAD_RT_PRIORITY) 350#define PTHREAD_BASE_PRIORITY(prio) ((prio) & PTHREAD_MAX_PRIORITY) 351 352/* 353 * Clock resolution in microseconds. 354 */ 355#define CLOCK_RES_USEC 10000 356#define CLOCK_RES_USEC_MIN 1000 357 358/* 359 * Time slice period in microseconds. 360 */ 361#define TIMESLICE_USEC 20000 362 363/* 364 * XXX Define a thread-safe macro to get the current time of day 365 * which is updated at regular intervals by the scheduling signal 366 * handler. 367 */ 368#define GET_CURRENT_TOD(tv) gettimeofday(&(tv), NULL) 369
|
538#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/ 539#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ 540#define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */ 541#define PTHREAD_FLAGS_TRACE 0x0400 /* for debugging purposes */ 542#define PTHREAD_FLAGS_IN_SYNCQ \ 543 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ) 544 545 /* 546 * Base priority is the user setable and retrievable priority 547 * of the thread. It is only affected by explicit calls to 548 * set thread priority and upon thread creation via a thread 549 * attribute or default priority. 550 */ 551 char base_priority; 552 553 /* 554 * Inherited priority is the priority a thread inherits by 555 * taking a priority inheritence or protection mutex. It 556 * is not affected by base priority changes. Inherited 557 * priority defaults to and remains 0 until a mutex is taken 558 * that is being waited on by any other thread whose priority 559 * is non-zero. 560 */ 561 char inherited_priority; 562 563 /* 564 * Active priority is always the maximum of the threads base 565 * priority and inherited priority. When there is a change 566 * in either the base or inherited priority, the active 567 * priority must be recalculated. 568 */ 569 char active_priority; 570 571 /* Number of priority ceiling or protection mutexes owned. */ 572 int prio_inherit_count; 573 int prio_protect_count; 574 575 /* 576 * Queue of currently owned mutexes. 577 */ 578 TAILQ_HEAD(, pthread_mutex) mutexq; 579 580 /* 581 * List of read-write locks owned for reading _OR_ writing. 582 * This is accessed only by the current thread, so there's 583 * no need for mutual exclusion. 584 */ 585 struct rwlock_listhead *rwlockList; 586 587 void *ret; 588 struct pthread_specific_elem *specific; 589 int specific_data_count; 590 591 /* 592 * Architecture specific id field used for _{get, set}_curthread() 593 * interface. 594 */ 595 void *arch_id; 596 597 /* Cleanup handlers Link List */ 598 struct pthread_cleanup *cleanup; 599 char *fname; /* Ptr to source file name */ 600 int lineno; /* Source line number. */ 601}; 602 603/* 604 * Global variables for the uthread kernel. 605 */ 606 607SCLASS void *_usrstack 608#ifdef GLOBAL_PTHREAD_PRIVATE 609= (void *) USRSTACK; 610#else 611; 612#endif 613 614SCLASS spinlock_t stack_lock 615#ifdef GLOBAL_PTHREAD_PRIVATE 616= _SPINLOCK_INITIALIZER 617#endif 618; 619#define STACK_LOCK _SPINLOCK(&stack_lock); 620#define STACK_UNLOCK _SPINUNLOCK(&stack_lock); 621 622/* List of all threads: */ 623SCLASS TAILQ_HEAD(, pthread) _thread_list 624#ifdef GLOBAL_PTHREAD_PRIVATE 625= TAILQ_HEAD_INITIALIZER(_thread_list); 626#else 627; 628#endif 629 630/* Dead threads: */ 631SCLASS TAILQ_HEAD(, pthread) _dead_list 632#ifdef GLOBAL_PTHREAD_PRIVATE 633= TAILQ_HEAD_INITIALIZER(_dead_list); 634#else 635; 636#endif 637 638/* 639 * These two locks protect the global active threads list and 640 * the global dead threads list, respectively. Combining these 641 * into one lock for both lists doesn't seem wise, since it 642 * would likely increase contention during busy thread creation 643 * and destruction for very little savings in space. 644 * 645 * The lock for the "dead threads list" must be a pthread mutex 646 * because it is used with condition variables to synchronize 647 * the gc thread with active threads in the process of exiting or 648 * dead threads who have just been joined. 649 */ 650SCLASS spinlock_t thread_list_lock 651#ifdef GLOBAL_PTHREAD_PRIVATE 652= _SPINLOCK_INITIALIZER 653#endif 654; 655SCLASS pthread_mutex_t dead_list_lock 656#ifdef GLOBAL_PTHREAD_PRIVATE 657= NULL 658#endif 659; 660 661#define THREAD_LIST_LOCK _SPINLOCK(&thread_list_lock) 662#define THREAD_LIST_UNLOCK _SPINUNLOCK(&thread_list_lock) 663#define DEAD_LIST_LOCK _pthread_mutex_lock(&dead_list_lock) 664#define DEAD_LIST_UNLOCK _pthread_mutex_unlock(&dead_list_lock) 665 666/* Initial thread: */ 667SCLASS struct pthread *_thread_initial 668#ifdef GLOBAL_PTHREAD_PRIVATE 669= NULL; 670#else 671; 672#endif 673 674/* Default thread attributes: */ 675SCLASS struct pthread_attr pthread_attr_default 676#ifdef GLOBAL_PTHREAD_PRIVATE 677= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, 678 PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, 679 PTHREAD_STACK_DEFAULT, -1 }; 680#else 681; 682#endif 683 684/* Default mutex attributes: */ 685SCLASS struct pthread_mutex_attr pthread_mutexattr_default 686#ifdef GLOBAL_PTHREAD_PRIVATE 687= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }; 688#else 689; 690#endif 691 692/* Default condition variable attributes: */ 693SCLASS struct pthread_cond_attr pthread_condattr_default 694#ifdef GLOBAL_PTHREAD_PRIVATE 695= { COND_TYPE_FAST, 0 }; 696#else 697; 698#endif 699 700SCLASS int _clock_res_usec /* Clock resolution in usec. */ 701#ifdef GLOBAL_PTHREAD_PRIVATE 702= CLOCK_RES_USEC; 703#else 704; 705#endif 706 707/* Garbage collector condition variable. */ 708SCLASS pthread_cond_t _gc_cond 709#ifdef GLOBAL_PTHREAD_PRIVATE 710= NULL 711#endif 712; 713 714/* 715 * Array of signal actions for this process. 716 */ 717SCLASS struct sigaction _thread_sigact[NSIG]; 718 719/* Precomputed signal set for _thread_suspend. */ 720SCLASS sigset_t _thread_suspend_sigset; 721 722/* Tracks the number of threads blocked while waiting for a spinlock. */ 723SCLASS volatile int _spinblock_count 724#ifdef GLOBAL_PTHREAD_PRIVATE 725= 0 726#endif 727; 728 729/* Undefine the storage class specifier: */ 730#undef SCLASS 731 732/* 733 * Function prototype definitions. 734 */ 735__BEGIN_DECLS 736char *__ttyname_basic(int); 737char *__ttyname_r_basic(int, char *, size_t); 738char *ttyname_r(int, char *, size_t); 739void _cond_wait_backout(pthread_t); 740int _find_thread(pthread_t); 741pthread_t _get_curthread(void); 742void *_set_curthread(ucontext_t *, struct pthread *, int *); 743void _retire_thread(void *arch_id); 744void *_thread_stack_alloc(size_t, size_t); 745void _thread_stack_free(void *, size_t, size_t); 746int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t); 747int _mutex_cv_lock(pthread_mutex_t *); 748int _mutex_cv_unlock(pthread_mutex_t *); 749void _mutex_lock_backout(pthread_t); 750void _mutex_notify_priochange(pthread_t); 751int _mutex_reinit(pthread_mutex_t *); 752void _mutex_unlock_private(pthread_t); 753int _cond_reinit(pthread_cond_t *); 754void *_pthread_getspecific(pthread_key_t); 755int _pthread_key_create(pthread_key_t *, void (*) (void *)); 756int _pthread_key_delete(pthread_key_t); 757int _pthread_mutex_destroy(pthread_mutex_t *); 758int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); 759int _pthread_mutex_lock(pthread_mutex_t *); 760int _pthread_mutex_trylock(pthread_mutex_t *); 761int _pthread_mutex_unlock(pthread_mutex_t *); 762int _pthread_mutexattr_init(pthread_mutexattr_t *); 763int _pthread_mutexattr_destroy(pthread_mutexattr_t *); 764int _pthread_mutexattr_settype(pthread_mutexattr_t *, int); 765int _pthread_once(pthread_once_t *, void (*) (void)); 766pthread_t _pthread_self(void); 767int _pthread_setspecific(pthread_key_t, const void *); 768int _spintrylock(spinlock_t *); 769void _thread_exit(char *, int, char *); 770void _thread_exit_cleanup(void); 771void *_thread_cleanup(pthread_t); 772void _thread_cleanupspecific(void); 773void _thread_dump_info(void); 774void _thread_init(void); 775void _thread_sig_wrapper(int sig, siginfo_t *info, void *context); 776void _thread_printf(int fd, const char *, ...); 777void _thread_start(void); 778void _thread_seterrno(pthread_t, int); 779pthread_addr_t _thread_gc(pthread_addr_t); 780void _thread_enter_cancellation_point(void); 781void _thread_leave_cancellation_point(void); 782void _thread_cancellation_point(void); 783int _thread_suspend(pthread_t thread, const struct timespec *abstime); 784void _thread_critical_enter(pthread_t); 785void _thread_critical_exit(pthread_t); 786void _thread_sigblock(); 787void _thread_sigunblock(); 788void adjust_prio_inheritance(struct pthread *); 789void adjust_prio_protection(struct pthread *); 790void init_td_common(struct pthread *, struct pthread_attr *, int); 791void init_tdlist(struct pthread *, int); 792void proc_sigact_copyin(int, const struct sigaction *); 793void proc_sigact_copyout(int, struct sigaction *); 794void readjust_priorities(struct pthread *, struct pthread_mutex *); 795struct sigaction *proc_sigact_sigaction(int); 796 797/* #include <sys/aio.h> */ 798#ifdef _SYS_AIO_H_ 799int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); 800#endif 801 802/* #include <sys/event.h> */ 803#ifdef _SYS_EVENT_H_ 804int __sys_kevent(int, const struct kevent *, int, struct kevent *, 805 int, const struct timespec *); 806#endif 807 808/* #include <sys/ioctl.h> */ 809#ifdef _SYS_IOCTL_H_ 810int __sys_ioctl(int, unsigned long, ...); 811#endif 812 813/* #include <sys/mman.h> */ 814#ifdef _SYS_MMAN_H_ 815int __sys_msync(void *, size_t, int); 816#endif 817 818/* #include <sys/mount.h> */ 819#ifdef _SYS_MOUNT_H_ 820int __sys_fstatfs(int, struct statfs *); 821#endif 822 823/* #include <sys/socket.h> */ 824#ifdef _SYS_SOCKET_H_ 825int __sys_accept(int, struct sockaddr *, socklen_t *); 826int __sys_bind(int, const struct sockaddr *, socklen_t); 827int __sys_connect(int, const struct sockaddr *, socklen_t); 828int __sys_getpeername(int, struct sockaddr *, socklen_t *); 829int __sys_getsockname(int, struct sockaddr *, socklen_t *); 830int __sys_getsockopt(int, int, int, void *, socklen_t *); 831int __sys_listen(int, int); 832ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 833ssize_t __sys_recvmsg(int, struct msghdr *, int); 834int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int); 835ssize_t __sys_sendmsg(int, const struct msghdr *, int); 836ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t); 837int __sys_setsockopt(int, int, int, const void *, socklen_t); 838int __sys_shutdown(int, int); 839int __sys_socket(int, int, int); 840int __sys_socketpair(int, int, int, int *); 841#endif 842 843/* #include <sys/stat.h> */ 844#ifdef _SYS_STAT_H_ 845int __sys_fchflags(int, u_long); 846int __sys_fchmod(int, mode_t); 847int __sys_fstat(int, struct stat *); 848#endif 849 850/* #include <sys/uio.h> */ 851#ifdef _SYS_UIO_H_ 852ssize_t __sys_readv(int, const struct iovec *, int); 853ssize_t __sys_writev(int, const struct iovec *, int); 854#endif 855 856/* #include <sys/wait.h> */ 857#ifdef WNOHANG 858pid_t __sys_wait4(pid_t, int *, int, struct rusage *); 859#endif 860 861/* #include <dirent.h> */ 862#ifdef _DIRENT_H_ 863int __sys_getdirentries(int, char *, int, long *); 864#endif 865 866/* #include <fcntl.h> */ 867#ifdef _SYS_FCNTL_H_ 868int __sys_fcntl(int, int, ...); 869int __sys_flock(int, int); 870int __sys_open(const char *, int, ...); 871#endif 872 873/* #include <poll.h> */ 874#ifdef _SYS_POLL_H_ 875int __sys_poll(struct pollfd *, unsigned, int); 876#endif 877 878/* #include <signal.h> */ 879#ifdef _SIGNAL_H_ 880int __sys_sigaction(int, const struct sigaction *, struct sigaction *); 881int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); 882int __sys_sigprocmask(int, const sigset_t *, sigset_t *); 883int __sys_sigreturn(ucontext_t *); 884#endif 885 886/* #include <unistd.h> */ 887#ifdef _UNISTD_H_ 888int __sys_close(int); 889int __sys_dup(int); 890int __sys_dup2(int, int); 891int __sys_execve(const char *, char * const *, char * const *); 892void __sys_exit(int); 893int __sys_fchown(int, uid_t, gid_t); 894pid_t __sys_fork(void); 895long __sys_fpathconf(int, int); 896int __sys_fsync(int); 897int __sys_pipe(int *); 898ssize_t __sys_read(int, void *, size_t); 899ssize_t __sys_write(int, const void *, size_t); 900#endif 901 902__END_DECLS 903 904#endif /* !_PTHREAD_PRIVATE_H */
| 555#define PTHREAD_FLAGS_IN_CONDQ 0x0080 /* in condition queue using sqe link*/ 556#define PTHREAD_FLAGS_IN_MUTEXQ 0x0100 /* in mutex queue using sqe link */ 557#define PTHREAD_FLAGS_SUSPENDED 0x0200 /* thread is suspended */ 558#define PTHREAD_FLAGS_TRACE 0x0400 /* for debugging purposes */ 559#define PTHREAD_FLAGS_IN_SYNCQ \ 560 (PTHREAD_FLAGS_IN_CONDQ | PTHREAD_FLAGS_IN_MUTEXQ) 561 562 /* 563 * Base priority is the user setable and retrievable priority 564 * of the thread. It is only affected by explicit calls to 565 * set thread priority and upon thread creation via a thread 566 * attribute or default priority. 567 */ 568 char base_priority; 569 570 /* 571 * Inherited priority is the priority a thread inherits by 572 * taking a priority inheritence or protection mutex. It 573 * is not affected by base priority changes. Inherited 574 * priority defaults to and remains 0 until a mutex is taken 575 * that is being waited on by any other thread whose priority 576 * is non-zero. 577 */ 578 char inherited_priority; 579 580 /* 581 * Active priority is always the maximum of the threads base 582 * priority and inherited priority. When there is a change 583 * in either the base or inherited priority, the active 584 * priority must be recalculated. 585 */ 586 char active_priority; 587 588 /* Number of priority ceiling or protection mutexes owned. */ 589 int prio_inherit_count; 590 int prio_protect_count; 591 592 /* 593 * Queue of currently owned mutexes. 594 */ 595 TAILQ_HEAD(, pthread_mutex) mutexq; 596 597 /* 598 * List of read-write locks owned for reading _OR_ writing. 599 * This is accessed only by the current thread, so there's 600 * no need for mutual exclusion. 601 */ 602 struct rwlock_listhead *rwlockList; 603 604 void *ret; 605 struct pthread_specific_elem *specific; 606 int specific_data_count; 607 608 /* 609 * Architecture specific id field used for _{get, set}_curthread() 610 * interface. 611 */ 612 void *arch_id; 613 614 /* Cleanup handlers Link List */ 615 struct pthread_cleanup *cleanup; 616 char *fname; /* Ptr to source file name */ 617 int lineno; /* Source line number. */ 618}; 619 620/* 621 * Global variables for the uthread kernel. 622 */ 623 624SCLASS void *_usrstack 625#ifdef GLOBAL_PTHREAD_PRIVATE 626= (void *) USRSTACK; 627#else 628; 629#endif 630 631SCLASS spinlock_t stack_lock 632#ifdef GLOBAL_PTHREAD_PRIVATE 633= _SPINLOCK_INITIALIZER 634#endif 635; 636#define STACK_LOCK _SPINLOCK(&stack_lock); 637#define STACK_UNLOCK _SPINUNLOCK(&stack_lock); 638 639/* List of all threads: */ 640SCLASS TAILQ_HEAD(, pthread) _thread_list 641#ifdef GLOBAL_PTHREAD_PRIVATE 642= TAILQ_HEAD_INITIALIZER(_thread_list); 643#else 644; 645#endif 646 647/* Dead threads: */ 648SCLASS TAILQ_HEAD(, pthread) _dead_list 649#ifdef GLOBAL_PTHREAD_PRIVATE 650= TAILQ_HEAD_INITIALIZER(_dead_list); 651#else 652; 653#endif 654 655/* 656 * These two locks protect the global active threads list and 657 * the global dead threads list, respectively. Combining these 658 * into one lock for both lists doesn't seem wise, since it 659 * would likely increase contention during busy thread creation 660 * and destruction for very little savings in space. 661 * 662 * The lock for the "dead threads list" must be a pthread mutex 663 * because it is used with condition variables to synchronize 664 * the gc thread with active threads in the process of exiting or 665 * dead threads who have just been joined. 666 */ 667SCLASS spinlock_t thread_list_lock 668#ifdef GLOBAL_PTHREAD_PRIVATE 669= _SPINLOCK_INITIALIZER 670#endif 671; 672SCLASS pthread_mutex_t dead_list_lock 673#ifdef GLOBAL_PTHREAD_PRIVATE 674= NULL 675#endif 676; 677 678#define THREAD_LIST_LOCK _SPINLOCK(&thread_list_lock) 679#define THREAD_LIST_UNLOCK _SPINUNLOCK(&thread_list_lock) 680#define DEAD_LIST_LOCK _pthread_mutex_lock(&dead_list_lock) 681#define DEAD_LIST_UNLOCK _pthread_mutex_unlock(&dead_list_lock) 682 683/* Initial thread: */ 684SCLASS struct pthread *_thread_initial 685#ifdef GLOBAL_PTHREAD_PRIVATE 686= NULL; 687#else 688; 689#endif 690 691/* Default thread attributes: */ 692SCLASS struct pthread_attr pthread_attr_default 693#ifdef GLOBAL_PTHREAD_PRIVATE 694= { SCHED_RR, 0, TIMESLICE_USEC, PTHREAD_DEFAULT_PRIORITY, 695 PTHREAD_CREATE_RUNNING, PTHREAD_CREATE_JOINABLE, NULL, NULL, NULL, 696 PTHREAD_STACK_DEFAULT, -1 }; 697#else 698; 699#endif 700 701/* Default mutex attributes: */ 702SCLASS struct pthread_mutex_attr pthread_mutexattr_default 703#ifdef GLOBAL_PTHREAD_PRIVATE 704= { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, 0 }; 705#else 706; 707#endif 708 709/* Default condition variable attributes: */ 710SCLASS struct pthread_cond_attr pthread_condattr_default 711#ifdef GLOBAL_PTHREAD_PRIVATE 712= { COND_TYPE_FAST, 0 }; 713#else 714; 715#endif 716 717SCLASS int _clock_res_usec /* Clock resolution in usec. */ 718#ifdef GLOBAL_PTHREAD_PRIVATE 719= CLOCK_RES_USEC; 720#else 721; 722#endif 723 724/* Garbage collector condition variable. */ 725SCLASS pthread_cond_t _gc_cond 726#ifdef GLOBAL_PTHREAD_PRIVATE 727= NULL 728#endif 729; 730 731/* 732 * Array of signal actions for this process. 733 */ 734SCLASS struct sigaction _thread_sigact[NSIG]; 735 736/* Precomputed signal set for _thread_suspend. */ 737SCLASS sigset_t _thread_suspend_sigset; 738 739/* Tracks the number of threads blocked while waiting for a spinlock. */ 740SCLASS volatile int _spinblock_count 741#ifdef GLOBAL_PTHREAD_PRIVATE 742= 0 743#endif 744; 745 746/* Undefine the storage class specifier: */ 747#undef SCLASS 748 749/* 750 * Function prototype definitions. 751 */ 752__BEGIN_DECLS 753char *__ttyname_basic(int); 754char *__ttyname_r_basic(int, char *, size_t); 755char *ttyname_r(int, char *, size_t); 756void _cond_wait_backout(pthread_t); 757int _find_thread(pthread_t); 758pthread_t _get_curthread(void); 759void *_set_curthread(ucontext_t *, struct pthread *, int *); 760void _retire_thread(void *arch_id); 761void *_thread_stack_alloc(size_t, size_t); 762void _thread_stack_free(void *, size_t, size_t); 763int _thread_create(pthread_t *,const pthread_attr_t *,void *(*start_routine)(void *),void *,pthread_t); 764int _mutex_cv_lock(pthread_mutex_t *); 765int _mutex_cv_unlock(pthread_mutex_t *); 766void _mutex_lock_backout(pthread_t); 767void _mutex_notify_priochange(pthread_t); 768int _mutex_reinit(pthread_mutex_t *); 769void _mutex_unlock_private(pthread_t); 770int _cond_reinit(pthread_cond_t *); 771void *_pthread_getspecific(pthread_key_t); 772int _pthread_key_create(pthread_key_t *, void (*) (void *)); 773int _pthread_key_delete(pthread_key_t); 774int _pthread_mutex_destroy(pthread_mutex_t *); 775int _pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); 776int _pthread_mutex_lock(pthread_mutex_t *); 777int _pthread_mutex_trylock(pthread_mutex_t *); 778int _pthread_mutex_unlock(pthread_mutex_t *); 779int _pthread_mutexattr_init(pthread_mutexattr_t *); 780int _pthread_mutexattr_destroy(pthread_mutexattr_t *); 781int _pthread_mutexattr_settype(pthread_mutexattr_t *, int); 782int _pthread_once(pthread_once_t *, void (*) (void)); 783pthread_t _pthread_self(void); 784int _pthread_setspecific(pthread_key_t, const void *); 785int _spintrylock(spinlock_t *); 786void _thread_exit(char *, int, char *); 787void _thread_exit_cleanup(void); 788void *_thread_cleanup(pthread_t); 789void _thread_cleanupspecific(void); 790void _thread_dump_info(void); 791void _thread_init(void); 792void _thread_sig_wrapper(int sig, siginfo_t *info, void *context); 793void _thread_printf(int fd, const char *, ...); 794void _thread_start(void); 795void _thread_seterrno(pthread_t, int); 796pthread_addr_t _thread_gc(pthread_addr_t); 797void _thread_enter_cancellation_point(void); 798void _thread_leave_cancellation_point(void); 799void _thread_cancellation_point(void); 800int _thread_suspend(pthread_t thread, const struct timespec *abstime); 801void _thread_critical_enter(pthread_t); 802void _thread_critical_exit(pthread_t); 803void _thread_sigblock(); 804void _thread_sigunblock(); 805void adjust_prio_inheritance(struct pthread *); 806void adjust_prio_protection(struct pthread *); 807void init_td_common(struct pthread *, struct pthread_attr *, int); 808void init_tdlist(struct pthread *, int); 809void proc_sigact_copyin(int, const struct sigaction *); 810void proc_sigact_copyout(int, struct sigaction *); 811void readjust_priorities(struct pthread *, struct pthread_mutex *); 812struct sigaction *proc_sigact_sigaction(int); 813 814/* #include <sys/aio.h> */ 815#ifdef _SYS_AIO_H_ 816int __sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *); 817#endif 818 819/* #include <sys/event.h> */ 820#ifdef _SYS_EVENT_H_ 821int __sys_kevent(int, const struct kevent *, int, struct kevent *, 822 int, const struct timespec *); 823#endif 824 825/* #include <sys/ioctl.h> */ 826#ifdef _SYS_IOCTL_H_ 827int __sys_ioctl(int, unsigned long, ...); 828#endif 829 830/* #include <sys/mman.h> */ 831#ifdef _SYS_MMAN_H_ 832int __sys_msync(void *, size_t, int); 833#endif 834 835/* #include <sys/mount.h> */ 836#ifdef _SYS_MOUNT_H_ 837int __sys_fstatfs(int, struct statfs *); 838#endif 839 840/* #include <sys/socket.h> */ 841#ifdef _SYS_SOCKET_H_ 842int __sys_accept(int, struct sockaddr *, socklen_t *); 843int __sys_bind(int, const struct sockaddr *, socklen_t); 844int __sys_connect(int, const struct sockaddr *, socklen_t); 845int __sys_getpeername(int, struct sockaddr *, socklen_t *); 846int __sys_getsockname(int, struct sockaddr *, socklen_t *); 847int __sys_getsockopt(int, int, int, void *, socklen_t *); 848int __sys_listen(int, int); 849ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 850ssize_t __sys_recvmsg(int, struct msghdr *, int); 851int __sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int); 852ssize_t __sys_sendmsg(int, const struct msghdr *, int); 853ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t); 854int __sys_setsockopt(int, int, int, const void *, socklen_t); 855int __sys_shutdown(int, int); 856int __sys_socket(int, int, int); 857int __sys_socketpair(int, int, int, int *); 858#endif 859 860/* #include <sys/stat.h> */ 861#ifdef _SYS_STAT_H_ 862int __sys_fchflags(int, u_long); 863int __sys_fchmod(int, mode_t); 864int __sys_fstat(int, struct stat *); 865#endif 866 867/* #include <sys/uio.h> */ 868#ifdef _SYS_UIO_H_ 869ssize_t __sys_readv(int, const struct iovec *, int); 870ssize_t __sys_writev(int, const struct iovec *, int); 871#endif 872 873/* #include <sys/wait.h> */ 874#ifdef WNOHANG 875pid_t __sys_wait4(pid_t, int *, int, struct rusage *); 876#endif 877 878/* #include <dirent.h> */ 879#ifdef _DIRENT_H_ 880int __sys_getdirentries(int, char *, int, long *); 881#endif 882 883/* #include <fcntl.h> */ 884#ifdef _SYS_FCNTL_H_ 885int __sys_fcntl(int, int, ...); 886int __sys_flock(int, int); 887int __sys_open(const char *, int, ...); 888#endif 889 890/* #include <poll.h> */ 891#ifdef _SYS_POLL_H_ 892int __sys_poll(struct pollfd *, unsigned, int); 893#endif 894 895/* #include <signal.h> */ 896#ifdef _SIGNAL_H_ 897int __sys_sigaction(int, const struct sigaction *, struct sigaction *); 898int __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *); 899int __sys_sigprocmask(int, const sigset_t *, sigset_t *); 900int __sys_sigreturn(ucontext_t *); 901#endif 902 903/* #include <unistd.h> */ 904#ifdef _UNISTD_H_ 905int __sys_close(int); 906int __sys_dup(int); 907int __sys_dup2(int, int); 908int __sys_execve(const char *, char * const *, char * const *); 909void __sys_exit(int); 910int __sys_fchown(int, uid_t, gid_t); 911pid_t __sys_fork(void); 912long __sys_fpathconf(int, int); 913int __sys_fsync(int); 914int __sys_pipe(int *); 915ssize_t __sys_read(int, void *, size_t); 916ssize_t __sys_write(int, const void *, size_t); 917#endif 918 919__END_DECLS 920 921#endif /* !_PTHREAD_PRIVATE_H */
|