2  * Copyright (c) 2000-2013 Apple Inc. All rights reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. Please obtain a copy of the License at 
  10  * http://www.opensource.apple.com/apsl/ and read it before using this 
  13  * The Original Code and all software distributed under the License are 
  14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  18  * Please see the License for the specific language governing rights and 
  19  * limitations under the License. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  24  * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 
  27  * Permission to use, copy, modify, and distribute this software and 
  28  * its documentation for any purpose and without fee is hereby granted, 
  29  * provided that the above copyright notice appears in all copies and 
  30  * that both the copyright notice and this permission notice appear in 
  31  * supporting documentation. 
  33  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
  34  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
  35  * FOR A PARTICULAR PURPOSE. 
  37  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 
  38  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
  39  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 
  40  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
  41  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
  49  * POSIX Threads - IEEE 1003.1c 
  52 #ifndef _POSIX_PTHREAD_INTERNALS_H 
  53 #define _POSIX_PTHREAD_INTERNALS_H 
  55 #define _PTHREAD_BUILDING_PTHREAD_ 
  57 // suppress pthread_attr_t typedef in sys/signal.h 
  58 #define _PTHREAD_ATTR_T 
  59 struct _pthread_attr_t
; /* forward reference */ 
  60 typedef struct _pthread_attr_t pthread_attr_t
; 
  69 #include <TargetConditionals.h> 
  70 #include <mach/mach.h> 
  71 #include <mach/mach_error.h> 
  72 #include <sys/queue.h> 
  74 #define __OS_EXPOSE_INTERNALS__ 1 
  75 #include <os/internal/internal_shared.h> 
  76 #include <os/once_private.h> 
  78 #if TARGET_IPHONE_SIMULATOR 
  79 #error Unsupported target 
  82 #define PTHREAD_INTERNAL_CRASH(c, x) do { \ 
  83                 _os_set_crash_log_cause_and_message((c), \ 
  84                                 "BUG IN LIBPTHREAD: " x); \ 
  88 #define PTHREAD_CLIENT_CRASH(c, x) do { \ 
  89                 _os_set_crash_log_cause_and_message((c), \ 
  90                                 "BUG IN CLIENT OF LIBPTHREAD: " x); \ 
  98 #ifndef PTHREAD_LAYOUT_SPI 
  99 #define PTHREAD_LAYOUT_SPI 1 
 102 #include "posix_sched.h" 
 103 #include "tsd_private.h" 
 104 #include "spinlock_private.h" 
 106 #define PTHREAD_EXPORT extern __attribute__((visibility("default"))) 
 107 #define PTHREAD_EXTERN extern 
 108 #define PTHREAD_NOEXPORT __attribute__((visibility("hidden"))) 
 109 #define PTHREAD_NOEXPORT_VARIANT 
 110 #define PTHREAD_NORETURN __attribute__((__noreturn__)) 
 111 #define PTHREAD_ALWAYS_INLINE __attribute__((always_inline)) 
 112 #define PTHREAD_NOINLINE __attribute__((noinline)) 
 113 #define PTHREAD_WEAK __attribute__((weak)) 
 114 #define PTHREAD_USED __attribute__((used)) 
 115 #define PTHREAD_NOT_TAIL_CALLED __attribute__((__not_tail_called__)) 
 118 #define OS_UNFAIR_LOCK_INLINE 1 
 119 #include <os/lock_private.h> 
 120 typedef os_unfair_lock _pthread_lock
; 
 121 #define _PTHREAD_LOCK_INITIALIZER OS_UNFAIR_LOCK_INIT 
 122 #define _PTHREAD_LOCK_INIT(lock) ((lock) = (_pthread_lock)_PTHREAD_LOCK_INITIALIZER) 
 123 #define _PTHREAD_LOCK(lock) os_unfair_lock_lock_with_options_inline(&(lock), OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION) 
 124 #define _PTHREAD_LOCK_FROM_MACH_THREAD(lock) os_unfair_lock_lock_inline_no_tsd_4libpthread(&(lock)) 
 125 #define _PTHREAD_UNLOCK(lock) os_unfair_lock_unlock_inline(&(lock)) 
 126 #define _PTHREAD_UNLOCK_FROM_MACH_THREAD(lock) os_unfair_lock_unlock_inline_no_tsd_4libpthread(&(lock)) 
 128 // List of all pthreads in the process. 
 129 TAILQ_HEAD(__pthread_list
, _pthread
); 
 130 extern struct __pthread_list __pthread_head
; 
 132 // Lock protects access to above list. 
 133 extern _pthread_lock _pthread_list_lock
; 
 135 extern int __is_threaded
; 
 137 #if PTHREAD_DEBUG_LOG 
 138 #include <mach/mach_time.h> 
 139 extern int _pthread_debuglog
; 
 140 extern uint64_t _pthread_debugstart
; 
 146 #if TARGET_OS_EMBEDDED 
 147 #define _EXTERNAL_POSIX_THREAD_KEYS_MAX 256 
 148 #define _INTERNAL_POSIX_THREAD_KEYS_MAX 256 
 149 #define _INTERNAL_POSIX_THREAD_KEYS_END 512 
 151 #define _EXTERNAL_POSIX_THREAD_KEYS_MAX 512 
 152 #define _INTERNAL_POSIX_THREAD_KEYS_MAX 256 
 153 #define _INTERNAL_POSIX_THREAD_KEYS_END 768 
 156 #define MAXTHREADNAMESIZE       64 
 158 typedef struct _pthread 
{ 
 160         // ABI - These fields are externally known as struct _opaque_pthread_t. 
 162         long sig
; // _PTHREAD_SIG 
 163         struct __darwin_pthread_handler_rec 
*__cleanup_stack
; 
 166         // SPI - These fields are private. 
 168         // these fields are globally protected by _pthread_list_lock: 
 174         _pthread_lock lock
; // protect access to everything below 
 184 #if defined(__LP64__) 
 188         void *(*fun
)(void*);    // thread start routine 
 189         void *arg
;              // thread start routine argument 
 190         void *exit_value
;       // thread exit value storage 
 192         semaphore_t joiner_notify
;      // pthread_join notification 
 195         int cancel_state
;       // whether the thread can be cancelled 
 198         int err_no
;             // thread-local errno 
 200         struct _pthread 
*joiner
; 
 202         struct sched_param param
;       // [aligned] 
 204         TAILQ_ENTRY(_pthread
) plist
;    // global thread list [aligned] 
 206         char pthread_name
[MAXTHREADNAMESIZE
];   // includes NUL [aligned] 
 208         void *stackaddr
;        // base of the stack (page aligned) 
 209         size_t stacksize
;       // size of stack (page multiple and >= PTHREAD_STACK_MIN) 
 211         void* freeaddr
;         // stack/thread allocation base address 
 212         size_t freesize
;        // stack/thread allocation size 
 213         size_t guardsize
;       // guard page size in bytes 
 215         // tsd-base relative accessed elements 
 216         __attribute__((aligned(8))) 
 217         uint64_t thread_id
;     // 64-bit unique thread id 
 219         /* Thread Specific Data slots 
 221          * The offset of this field from the start of the structure is difficult to 
 222          * change on OS X because of a thorny bitcompat issue: mono has hard coded 
 223          * the value into their source.  Newer versions of mono will fall back to 
 224          * scanning to determine it at runtime, but there's lots of software built 
 225          * with older mono that won't.  We will have to break them someday... 
 227         __attribute__ ((aligned (16))) 
 228         void *tsd
[_EXTERNAL_POSIX_THREAD_KEYS_MAX 
+ _INTERNAL_POSIX_THREAD_KEYS_MAX
]; 
 232 struct _pthread_attr_t 
{ 
 242         struct sched_param param
; // [aligned] 
 243         void *stackaddr
; // stack base; vm_page_size aligned 
 244         size_t stacksize
; // stack size; multiple of vm_page_size and >= PTHREAD_STACK_MIN 
 245         size_t guardsize
; // size in bytes of stack overflow guard area 
 246         unsigned long qosclass
; 
 247 #if defined(__LP64__) 
 248         uint32_t _reserved
[2]; 
 250         uint32_t _reserved
[1]; 
 257 #define _PTHREAD_MUTEX_POLICY_NONE              0 
 258 #define _PTHREAD_MUTEX_POLICY_FAIRSHARE         1 
 259 #define _PTHREAD_MUTEX_POLICY_FIRSTFIT          2 
 260 #define _PTHREAD_MUTEX_POLICY_REALTIME          3 
 261 #define _PTHREAD_MUTEX_POLICY_ADAPTIVE          4 
 262 #define _PTHREAD_MUTEX_POLICY_PRIPROTECT        5 
 263 #define _PTHREAD_MUTEX_POLICY_PRIINHERIT        6 
 265 #define _PTHREAD_MUTEXATTR_T 
 274 } pthread_mutexattr_t
; 
 276 struct _pthread_mutex_options 
{ 
 294                 struct _pthread_mutex_options options
; 
 298 #if defined(__LP64__) 
 301         uint32_t m_tid
[2]; // thread id of thread that has mutex locked 
 302         uint32_t m_seq
[2]; // mutex sequence id 
 303         uint32_t m_mis
[2]; // for misaligned locks m_tid/m_seq will span into here 
 304 #if defined(__LP64__) 
 305         uint32_t _reserved
[4]; 
 307         uint32_t _reserved
[1]; 
 312 #define _PTHREAD_CONDATTR_T 
 317 } pthread_condattr_t
; 
 326         _pthread_mutex 
*busy
; 
 328 #if defined(__LP64__) 
 329         uint32_t _reserved
[3]; 
 334 #define _PTHREAD_ONCE_T 
 341 #define _PTHREAD_RWLOCKATTR_T 
 345 #if defined(__LP64__) 
 346         uint32_t _reserved
[3]; 
 348         uint32_t _reserved
[2]; 
 350 } pthread_rwlockattr_t
; 
 360 #if defined(__LP64__) 
 363         uint32_t rw_tid
[2]; // thread id of thread that has exclusive (write) lock 
 364         uint32_t rw_seq
[4]; // rw sequence id (at 128-bit aligned boundary) 
 365         uint32_t rw_mis
[4]; // for misaligned locks rw_seq will span into here 
 366 #if defined(__LP64__) 
 367         uint32_t _reserved
[34]; 
 369         uint32_t _reserved
[18]; 
 374 #include "pthread_spis.h" 
 376 _Static_assert(sizeof(_pthread_mutex
) == sizeof(pthread_mutex_t
), 
 377                 "Incorrect _pthread_mutex structure size"); 
 379 _Static_assert(sizeof(_pthread_rwlock
) == sizeof(pthread_rwlock_t
), 
 380                 "Incorrect _pthread_rwlock structure size"); 
 382 // Internal references to pthread_self() use TSD slot 0 directly. 
 383 inline static pthread_t 
__attribute__((__pure__
)) 
 384 _pthread_self_direct(void) 
 386         return _pthread_getspecific_direct(_PTHREAD_TSD_SLOT_PTHREAD_SELF
); 
 388 #define pthread_self() _pthread_self_direct() 
 390 PTHREAD_ALWAYS_INLINE
 
 391 inline static uint64_t __attribute__((__pure__
)) 
 392 _pthread_selfid_direct(void) 
 394         return (_pthread_self_direct())->thread_id
; 
 397 #define _PTHREAD_DEFAULT_INHERITSCHED   PTHREAD_INHERIT_SCHED 
 398 #define _PTHREAD_DEFAULT_PROTOCOL       PTHREAD_PRIO_NONE 
 399 #define _PTHREAD_DEFAULT_PRIOCEILING    0 
 400 #define _PTHREAD_DEFAULT_POLICY         SCHED_OTHER 
 401 #define _PTHREAD_DEFAULT_STACKSIZE      0x80000   /* 512K */ 
 402 #define _PTHREAD_DEFAULT_PSHARED        PTHREAD_PROCESS_PRIVATE 
 404 #define _PTHREAD_NO_SIG                 0x00000000 
 405 #define _PTHREAD_MUTEX_ATTR_SIG         0x4D545841  /* 'MTXA' */ 
 406 #define _PTHREAD_MUTEX_SIG              0x4D555458  /* 'MUTX' */ 
 407 #define _PTHREAD_MUTEX_SIG_fast         0x4D55545A  /* 'MUTZ' */ 
 408 #define _PTHREAD_MUTEX_SIG_MASK         0xfffffffd 
 409 #define _PTHREAD_MUTEX_SIG_CMP          0x4D555458  /* _PTHREAD_MUTEX_SIG & _PTHREAD_MUTEX_SIG_MASK */ 
 410 #define _PTHREAD_MUTEX_SIG_init         0x32AAABA7  /* [almost] ~'MUTX' */ 
 411 #define _PTHREAD_ERRORCHECK_MUTEX_SIG_init      0x32AAABA1 
 412 #define _PTHREAD_RECURSIVE_MUTEX_SIG_init       0x32AAABA2 
 413 #define _PTHREAD_FIRSTFIT_MUTEX_SIG_init        0x32AAABA3 
 414 #define _PTHREAD_MUTEX_SIG_init_MASK            0xfffffff0 
 415 #define _PTHREAD_MUTEX_SIG_init_CMP             0x32AAABA0 
 416 #define _PTHREAD_COND_ATTR_SIG          0x434E4441  /* 'CNDA' */ 
 417 #define _PTHREAD_COND_SIG               0x434F4E44  /* 'COND' */ 
 418 #define _PTHREAD_COND_SIG_init          0x3CB0B1BB  /* [almost] ~'COND' */ 
 419 #define _PTHREAD_ATTR_SIG               0x54484441  /* 'THDA' */ 
 420 #define _PTHREAD_ONCE_SIG               0x4F4E4345  /* 'ONCE' */ 
 421 #define _PTHREAD_ONCE_SIG_init          0x30B1BCBA  /* [almost] ~'ONCE' */ 
 422 #define _PTHREAD_SIG                    0x54485244  /* 'THRD' */ 
 423 #define _PTHREAD_RWLOCK_ATTR_SIG        0x52574C41  /* 'RWLA' */ 
 424 #define _PTHREAD_RWLOCK_SIG             0x52574C4B  /* 'RWLK' */ 
 425 #define _PTHREAD_RWLOCK_SIG_init        0x2DA8B3B4  /* [almost] ~'RWLK' */ 
 428 #define _PTHREAD_KERN_COND_SIG          0x12345678  /*  */ 
 429 #define _PTHREAD_KERN_MUTEX_SIG         0x34567812  /*  */ 
 430 #define _PTHREAD_KERN_RWLOCK_SIG        0x56781234  /*  */ 
 432 #define _PTHREAD_CREATE_PARENT          4 
 433 #define _PTHREAD_EXITED                 8 
 435 #define _PTHREAD_WASCANCEL              0x10 
 439 #define _PTHREAD_MUTEX_OWNER_SELF       pthread_self() 
 441 #define _PTHREAD_MUTEX_OWNER_SELF       (pthread_t)0x12141968 
 443 #define _PTHREAD_MUTEX_OWNER_SWITCHING  (pthread_t)(~0) 
 445 #define _PTHREAD_CANCEL_STATE_MASK   0x01 
 446 #define _PTHREAD_CANCEL_TYPE_MASK    0x02 
 447 #define _PTHREAD_CANCEL_PENDING      0x10  /* pthread_cancel() has been called for this thread */ 
 448 #define _PTHREAD_CANCEL_INITIALIZED  0x20  /* the thread in the list is properly initialized */ 
 450 extern boolean_t 
swtch_pri(int); 
 452 #include "kern/kern_internal.h" 
 456 /* Internal globals. */ 
 457 PTHREAD_NOEXPORT 
extern int __pthread_supported_features
; 
 459 /* Functions defined in machine-dependent files. */ 
 460 PTHREAD_NOEXPORT 
void _pthread_setup(pthread_t th
, void (*f
)(pthread_t
), void *sp
, int suspended
, int needresume
); 
 462 PTHREAD_NOEXPORT 
void _pthread_tsd_cleanup(pthread_t self
); 
 464 PTHREAD_NOEXPORT 
int _pthread_mutex_droplock(_pthread_mutex 
*mutex
, uint32_t * flagp
, uint32_t ** pmtxp
, uint32_t * mgenp
, uint32_t * ugenp
); 
 466 /* internally redirected upcalls. */ 
 467 PTHREAD_NOEXPORT 
void* malloc(size_t); 
 468 PTHREAD_NOEXPORT 
void free(void*); 
 470 /* syscall interfaces */ 
 471 extern uint32_t __psynch_mutexwait(pthread_mutex_t 
* mutex
,  uint32_t mgen
, uint32_t  ugen
, uint64_t tid
, uint32_t flags
); 
 472 extern uint32_t __psynch_mutexdrop(pthread_mutex_t 
* mutex
,  uint32_t mgen
, uint32_t  ugen
, uint64_t tid
, uint32_t flags
); 
 474 extern uint32_t __psynch_cvbroad(pthread_cond_t 
* cv
, uint64_t cvlsgen
, uint64_t cvudgen
, uint32_t flags
, pthread_mutex_t 
* mutex
,  uint64_t mugen
, uint64_t tid
); 
 475 extern uint32_t __psynch_cvsignal(pthread_cond_t 
* cv
, uint64_t cvlsgen
, uint32_t cvugen
, int thread_port
, pthread_mutex_t 
* mutex
,  uint64_t mugen
, uint64_t tid
, uint32_t flags
); 
 476 extern uint32_t __psynch_cvwait(pthread_cond_t 
* cv
, uint64_t cvlsgen
, uint32_t cvugen
, pthread_mutex_t 
* mutex
,  uint64_t mugen
, uint32_t flags
, int64_t sec
, uint32_t nsec
); 
 477 extern uint32_t __psynch_cvclrprepost(void * cv
, uint32_t cvgen
, uint32_t cvugen
, uint32_t cvsgen
, uint32_t prepocnt
, uint32_t preposeq
, uint32_t flags
); 
 478 extern uint32_t __psynch_rw_longrdlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 479 extern uint32_t __psynch_rw_yieldwrlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 480 extern int __psynch_rw_downgrade(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 481 extern uint32_t __psynch_rw_upgrade(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 482 extern uint32_t __psynch_rw_rdlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 483 extern uint32_t __psynch_rw_wrlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 484 extern uint32_t __psynch_rw_unlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 485 extern uint32_t __psynch_rw_unlock2(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 486 extern uint32_t __bsdthread_ctl(uintptr_t cmd
, uintptr_t arg1
, uintptr_t arg2
, uintptr_t arg3
); 
 490 __proc_info(int callnum
, int pid
, int flavor
, uint64_t arg
, void * buffer
, int buffersize
); 
 492 PTHREAD_NOEXPORT 
int _pthread_join_cleanup(pthread_t thread
, void ** value_ptr
, int conforming
); 
 494 PTHREAD_NORETURN PTHREAD_NOEXPORT
 
 496 __pthread_abort(void); 
 498 PTHREAD_NORETURN PTHREAD_NOEXPORT
 
 500 __pthread_abort_reason(const char *fmt
, ...) __printflike(1,2); 
 504 _pthread_set_main_qos(pthread_priority_t qos
); 
 508 _pthread_key_global_init(const char *envp
[]); 
 512 _pthread_start(pthread_t self
, mach_port_t kport
, void *(*fun
)(void *), void * funarg
, size_t stacksize
, unsigned int flags
); 
 516 _pthread_wqthread(pthread_t self
, mach_port_t kport
, void *stackaddr
, void *keventlist
, int flags
, int nkevents
); 
 520 _pthread_main_thread_init(pthread_t p
); 
 524 _pthread_bsdthread_init(void); 
 526 PTHREAD_NOEXPORT_VARIANT
 
 528 _pthread_clear_qos_tsd(mach_port_t thread_port
); 
 530 PTHREAD_NOEXPORT_VARIANT
 
 532 _pthread_testcancel(pthread_t thread
, int isconforming
); 
 536 _pthread_exit_if_canceled(int error
); 
 540 _pthread_markcancel_if_canceled(pthread_t thread
, mach_port_t kport
); 
 544 _pthread_setcancelstate_exit(pthread_t self
, void *value_ptr
, int conforming
); 
 548 _pthread_get_exit_value(pthread_t t
, int conforming
); 
 550 PTHREAD_ALWAYS_INLINE
 
 551 static inline mach_port_t
 
 552 _pthread_kernel_thread(pthread_t t
) 
 554         return t
->tsd
[_PTHREAD_TSD_SLOT_MACH_THREAD_SELF
]; 
 557 PTHREAD_ALWAYS_INLINE
 
 559 _pthread_set_kernel_thread(pthread_t t
, mach_port_t p
) 
 561         t
->tsd
[_PTHREAD_TSD_SLOT_MACH_THREAD_SELF
] = p
; 
 564 #define PTHREAD_ABORT(f,...) __pthread_abort_reason( \ 
 565                 "%s:%s:%u: " f, __FILE__, __func__, __LINE__, ## __VA_ARGS__) 
 567 #define PTHREAD_ASSERT(b) \ 
 568                 do { if (!(b)) PTHREAD_ABORT("failed assertion `%s'", #b); } while (0) 
 570 #include <os/semaphore_private.h> 
 571 #include <os/alloc_once_private.h> 
 573 struct pthread_atfork_entry 
{ 
 574         void (*prepare
)(void); 
 575         void (*parent
)(void); 
 579 #define PTHREAD_ATFORK_INLINE_MAX 10 
 580 #define PTHREAD_ATFORK_MAX (vm_page_size/sizeof(struct pthread_atfork_entry)) 
 582 struct pthread_globals_s 
{ 
 584         pthread_t psaved_self
; 
 585         _pthread_lock psaved_self_global_lock
; 
 586         _pthread_lock pthread_atfork_lock
; 
 589         struct pthread_atfork_entry atfork_storage
[PTHREAD_ATFORK_INLINE_MAX
]; 
 590         struct pthread_atfork_entry 
*atfork
; 
 591         uint16_t qmp_logical
[THREAD_QOS_LAST
]; 
 592         uint16_t qmp_physical
[THREAD_QOS_LAST
]; 
 595 typedef struct pthread_globals_s 
*pthread_globals_t
; 
 597 __attribute__((__pure__
)) 
 598 static inline pthread_globals_t
 
 599 _pthread_globals(void) 
 601         return os_alloc_once(OS_ALLOC_ONCE_KEY_LIBSYSTEM_PTHREAD
, 
 602                              sizeof(struct pthread_globals_s
), 
 606 #pragma mark _pthread_mutex_check_signature 
 608 PTHREAD_ALWAYS_INLINE
 
 610 _pthread_mutex_check_signature_fast(_pthread_mutex 
*mutex
) 
 612         return (mutex
->sig 
== _PTHREAD_MUTEX_SIG_fast
); 
 615 PTHREAD_ALWAYS_INLINE
 
 617 _pthread_mutex_check_signature(_pthread_mutex 
*mutex
) 
 619         return ((mutex
->sig 
& _PTHREAD_MUTEX_SIG_MASK
) == _PTHREAD_MUTEX_SIG_CMP
); 
 622 PTHREAD_ALWAYS_INLINE
 
 624 _pthread_mutex_check_signature_init(_pthread_mutex 
*mutex
) 
 626         return ((mutex
->sig 
& _PTHREAD_MUTEX_SIG_init_MASK
) == 
 627                         _PTHREAD_MUTEX_SIG_init_CMP
); 
 630 #pragma mark _pthread_rwlock_check_signature 
 632 PTHREAD_ALWAYS_INLINE
 
 634 _pthread_rwlock_check_signature(_pthread_rwlock 
*rwlock
) 
 636         return (rwlock
->sig 
== _PTHREAD_RWLOCK_SIG
); 
 639 PTHREAD_ALWAYS_INLINE
 
 641 _pthread_rwlock_check_signature_init(_pthread_rwlock 
*rwlock
) 
 643         return (rwlock
->sig 
== _PTHREAD_RWLOCK_SIG_init
); 
 646 /* ALWAYS called with list lock and return with list lock */ 
 647 PTHREAD_ALWAYS_INLINE
 
 649 _pthread_is_valid_locked(pthread_t thread
) 
 653         TAILQ_FOREACH(p
, &__pthread_head
, plist
) { 
 655                         int state 
= os_atomic_load(&p
->cancel_state
, relaxed
); 
 656                         if (state 
& _PTHREAD_CANCEL_INITIALIZED
) { 
 659                         _PTHREAD_UNLOCK(_pthread_list_lock
); 
 660                         thread_switch(_pthread_kernel_thread(p
), 
 661                                         SWITCH_OPTION_OSLOCK_DEPRESS
, 1); 
 662                         _PTHREAD_LOCK(_pthread_list_lock
); 
 670 #define PTHREAD_IS_VALID_LOCK_THREAD 0x1 
 672 PTHREAD_ALWAYS_INLINE
 
 674 _pthread_is_valid(pthread_t thread
, int flags
, mach_port_t 
*portp
) 
 676         mach_port_t kport 
= MACH_PORT_NULL
; 
 679         if (thread 
== NULL
) { 
 683         if (thread 
== pthread_self()) { 
 685                 kport 
= _pthread_kernel_thread(thread
); 
 686                 if (flags 
& PTHREAD_IS_VALID_LOCK_THREAD
) { 
 687                         _PTHREAD_LOCK(thread
->lock
); 
 690                 _PTHREAD_LOCK(_pthread_list_lock
); 
 691                 if (_pthread_is_valid_locked(thread
)) { 
 692                         kport 
= _pthread_kernel_thread(thread
); 
 694                         if (flags 
& PTHREAD_IS_VALID_LOCK_THREAD
) { 
 695                                 _PTHREAD_LOCK(thread
->lock
); 
 700                 _PTHREAD_UNLOCK(_pthread_list_lock
); 
 709 PTHREAD_ALWAYS_INLINE
 
 711 _pthread_atomic_xchg_ptr_inline(void **p
, void *v
) 
 713         return os_atomic_xchg(p
, v
, seq_cst
); 
 716 PTHREAD_ALWAYS_INLINE
 
 717 static inline uint32_t 
 718 _pthread_atomic_xchg_uint32_relaxed_inline(uint32_t *p
,uint32_t v
) 
 720         return os_atomic_xchg(p
, v
, relaxed
); 
 723 #define _pthread_atomic_xchg_ptr(p, v) \ 
 724                 _pthread_atomic_xchg_ptr_inline(p, v) 
 725 #define _pthread_atomic_xchg_uint32_relaxed(p, v) \ 
 726                 _pthread_atomic_xchg_uint32_relaxed_inline(p, v) 
 728 #endif /* _POSIX_PTHREAD_INTERNALS_H */