2  * Copyright (c) 2000-2003, 2007 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 // suppress pthread_attr_t typedef in sys/signal.h 
  56 #define _PTHREAD_ATTR_T 
  57 struct _pthread_attr_t
; /* forward reference */ 
  58 typedef struct _pthread_attr_t pthread_attr_t
; 
  66 #include <mach/mach.h> 
  67 #include <mach/mach_error.h> 
  68 #include <libkern/OSAtomic.h> 
  75 #include "posix_sched.h"                /* For POSIX scheduling policy & parameter */ 
  76 #include <sys/queue.h>          /* For POSIX scheduling policy & parameter */ 
  77 #include "pthread_machdep.h"            /* Machine-dependent definitions. */ 
  78 #include "pthread_spinlock.h"           /* spinlock definitions. */ 
  80 TAILQ_HEAD(__pthread_list
, _pthread
); 
  81 extern struct __pthread_list __pthread_head
;        /* head of list of open files */ 
  82 extern pthread_lock_t _pthread_list_lock
; 
  83 extern  size_t pthreadsize
; 
  87 #define _EXTERNAL_POSIX_THREAD_KEYS_MAX 512 
  88 #define _INTERNAL_POSIX_THREAD_KEYS_MAX 256 
  89 #define _INTERNAL_POSIX_THREAD_KEYS_END 768 
  94 #define MAXTHREADNAMESIZE       64 
  96 typedef struct _pthread
 
  98         long           sig
;           /* Unique signature for this structure */ 
  99         struct __darwin_pthread_handler_rec 
*__cleanup_stack
; 
 100         pthread_lock_t lock
;          /* Used for internal mutex on structure */ 
 111         size_t         guardsize
;       /* size in bytes to guard stack overflow */ 
 112 #if  !defined(__LP64__) 
 113         int            pad0
;            /* for backwards compatibility */ 
 115         struct sched_param param
; 
 116         struct _pthread_mutex 
*mutexes
; 
 117         struct _pthread 
*joiner
; 
 118 #if !defined(__LP64__) 
 119         int             pad1
;           /* for backwards compatibility */ 
 122         semaphore_t    death
;           /* pthread_join() uses this to wait for death's call */ 
 123         mach_port_t    kernel_thread
; /* kernel thread this thread is bound to */ 
 124         void           *(*fun
)(void*);/* Thread start routine */ 
 125         void           *arg
;          /* Argment for thread start routine */ 
 126         int            cancel_state
;  /* Whether thread can be cancelled */ 
 127         int            err_no
;          /* thread-local errno */ 
 128         void           *tsd
[_EXTERNAL_POSIX_THREAD_KEYS_MAX 
+ _INTERNAL_POSIX_THREAD_KEYS_MAX
];  /* Thread specific data */ 
 129         void           *stackaddr
;     /* Base of the stack (is aligned on vm_page_size boundary */ 
 130         size_t         stacksize
;      /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ 
 131         mach_port_t    reply_port
;     /* Cached MiG reply port */ 
 132 #if defined(__LP64__) 
 133         int             pad2
;           /* for natural alignment */ 
 135         void           *cthread_self
;  /* cthread_self() if somebody calls cthread_set_self() */ 
 136         /* protected by list lock */ 
 141 #if defined(__LP64__) 
 142         int             pad4
;           /* for natural alignment */ 
 144         TAILQ_ENTRY(_pthread
) plist
; 
 147         mach_port_t     joiner_notify
; 
 148         char    pthread_name
[MAXTHREADNAMESIZE
];                /* including nulll the name */ 
 156  * This will cause a compile-time failure if someone moved the tsd field 
 157  * and we need to change _PTHREAD_TSD_OFFSET in pthread_machdep.h 
 159 typedef char _need_to_change_PTHREAD_TSD_OFFSET
[(_PTHREAD_TSD_OFFSET 
== offsetof(struct _pthread
, tsd
[0])) ? 0 : -1] ; 
 164 struct _pthread_attr_t
 
 166         long           sig
;           /* Unique signature for this structure */ 
 175         size_t         guardsize
;       /* size in bytes to guard stack overflow */ 
 176         int      reserved2
;     /* Should we free the stack when we exit? */ 
 177         struct sched_param param
; 
 178         void           *stackaddr
;     /* Base of the stack (is aligned on vm_page_size boundary */ 
 179         size_t         stacksize
;      /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */ 
 186 #define _PTHREAD_MUTEX_POLICY_NONE              0 
 187 #define _PTHREAD_MUTEX_POLICY_FAIRSHARE         1 
 188 #define _PTHREAD_MUTEX_POLICY_FIRSTFIT          2 
 189 #define _PTHREAD_MUTEX_POLICY_REALTIME          3 
 190 #define _PTHREAD_MUTEX_POLICY_ADAPTIVE          4 
 191 #define _PTHREAD_MUTEX_POLICY_PRIPROTECT        5 
 192 #define _PTHREAD_MUTEX_POLICY_PRIINHERIT        6 
 194 #define _PTHREAD_MUTEXATTR_T 
 197         long sig
;                    /* Unique signature for this structure */ 
 199         uint32_t protocol
:2,            /* protocol attribute */ 
 200                 type
:2,                 /* mutex type */ 
 204 } pthread_mutexattr_t
; 
 209 struct _pthread_mutex_options 
{ 
 210         uint32_t  protocol
:2,           /* protocol */ 
 211                 type
:2,                 /* mutex type */ 
 212                 pshared
:2,                      /* mutex type */ 
 215                 misalign
:1,             /* 8 byte aligned? */ 
 221 #define _PTHREAD_MTX_OPT_PSHARED 0x010 
 222 #define _PTHREAD_MTX_OPT_HOLD 0x200 
 223 #define _PTHREAD_MTX_OPT_NOHOLD 0x400 
 224 #define _PTHREAD_MTX_OPT_LASTDROP (_PTHREAD_MTX_OPT_NOHOLD | _PTHREAD_MTX_OPT_HOLD) 
 227 #define _PTHREAD_MUTEX_T 
 228 typedef struct _pthread_mutex
 
 230         long           sig
;           /* Unique signature for this structure */ 
 231         pthread_lock_t lock
;          /* Used for internal mutex on structure */ 
 234                 struct _pthread_mutex_options options
; 
 237         int16_t        priority
;      /* Priority to restore when mutex unlocked */ 
 238         uint32_t      waiters
;       /* Count of threads waiting for this mutex */ 
 239         pthread_t      owner
;         /* Which thread has this mutex locked */ 
 240         struct _pthread_mutex 
*next
, *prev
;  /* List of other mutexes he owns */ 
 241         struct _pthread_cond 
*busy
;   /* List of condition variables using this mutex */ 
 242         semaphore_t    sem
;           /* Semaphore used for waiting */ 
 247 typedef struct _npthread_mutex
 
 249 /* keep same as pthread_mutex_t from here to .. */ 
 250         long           sig
;           /* Unique signature for this structure */ 
 251         pthread_lock_t lock
;          /* Used for static init sequencing */ 
 254                 struct _pthread_mutex_options options
; 
 257         int16_t        priority
;      /* Priority to restore when mutex unlocked */ 
 259 #if  defined(__LP64__) 
 260         uint64_t      m_tid
;          /* Which thread has this mutex locked */ 
 261         uint32_t  *     m_lseqaddr
; 
 262         uint32_t  *     m_useqaddr
; 
 263         uint32_t        reserved
[2]; 
 265         uint32_t  *     m_lseqaddr
; 
 266         uint64_t      m_tid
;          /* Which thread has this mutex locked */ 
 267         uint32_t  *     m_useqaddr
; 
 275  * Condition variable attributes 
 277 #define _PTHREAD_CONDATTR_T 
 280         long           sig
;          /* Unique signature for this structure */ 
 281         uint32_t         pshared
:2,             /* pshared */ 
 283 } pthread_condattr_t
; 
 286  * Condition variables 
 288 #define _PTHREAD_COND_T 
 289 typedef struct _pthread_cond
 
 291         long           sig
;          /* Unique signature for this structure */ 
 292         pthread_lock_t lock
;         /* Used for internal mutex on structure */ 
 293         uint32_t        waiters
:15,     /* Number of threads waiting */ 
 294                    sigspending
:15,      /* Number of outstanding signals */ 
 296         struct _pthread_cond 
*next
, *prev
;  /* List of condition variables using mutex */ 
 297         struct _pthread_mutex 
*busy
; /* mutex associated with variable */ 
 298         semaphore_t    sem
;          /* Kernel semaphore */ 
 302 typedef struct _npthread_cond
 
 304         long           sig
;          /* Unique signature for this structure */ 
 305         pthread_lock_t lock
;         /* Used for internal mutex on structure */ 
 306         uint32_t        rfu
:29,         /* not in use*/ 
 307                         misalign
: 1,    /* structure is not aligned to 8 byte boundary */ 
 309         struct _npthread_mutex 
*busy
; /* mutex associated with variable */ 
 311 #if defined(__LP64__) 
 312         uint32_t        reserved
[3]; 
 313 #endif /* __LP64__ */ 
 317  * Initialization control (once) variables 
 319 #define _PTHREAD_ONCE_T 
 322         long           sig
;           /* Unique signature for this structure */ 
 323         pthread_lock_t lock
;          /* Used for internal mutex on structure */ 
 326 #define _PTHREAD_RWLOCKATTR_T 
 328         long           sig
;           /* Unique signature for this structure */ 
 330         int             rfu
[2];         /* reserved for future use */ 
 331 } pthread_rwlockattr_t
; 
 333 #define _PTHREAD_RWLOCK_T 
 336         pthread_mutex_t lock
;   /* monitor lock */ 
 338         pthread_cond_t  read_signal
; 
 339         pthread_cond_t  write_signal
; 
 347 #define _PTHREAD_RWLOCK_T 
 351 #if defined(__LP64__) 
 353         volatile uint32_t       rw_seq
[4]; 
 356         volatile uint32_t       rw_seq
[4]; 
 359 #endif /* __LP64__ */ 
 360         volatile uint32_t *     rw_lseqaddr
; 
 361         volatile uint32_t *     rw_wcaddr
; 
 362         volatile uint32_t *     rw_useqaddr
; 
 365 #if defined(__LP64__) 
 369 #endif /* __LP64__ */ 
 373 /* flags for rw_flags */ 
 374 #define PTHRW_KERN_PROCESS_SHARED       0x10 
 375 #define PTHRW_KERN_PROCESS_PRIVATE      0x20 
 376 #define PTHRW_KERN_PROCESS_FLAGS_MASK   0x30 
 378 #define PTHRW_EBIT      0x01 
 379 #define PTHRW_LBIT      0x02 
 380 #define PTHRW_YBIT      0x04 
 381 #define PTHRW_WBIT      0x08 
 382 #define PTHRW_UBIT      0x10 
 383 #define PTHRW_RETRYBIT      0x20 
 384 #define PTHRW_SHADOW_W      0x20        /* same as 0x20, shadow W bit for rwlock */ 
 386 #define PTHRW_TRYLKBIT      0x40 
 387 #define PTHRW_RW_HUNLOCK      0x40      /* readers responsible for handling unlock */ 
 389 #define PTHRW_MTX_NONE      0x80 
 390 #define PTHRW_RW_INIT       0x80    /* reset on the lock bits */ 
 391 #define PTHRW_RW_SPURIOUS     0x80      /* same as 0x80, spurious rwlock  unlock ret from kernel */ 
 393 #define PTHRW_INC       0x100 
 394 #define PTHRW_BIT_MASK  0x000000ff 
 395 #define PTHRW_UN_BIT_MASK 0x000000df    /* remove shadow bit */ 
 397 #define PTHRW_COUNT_SHIFT       8  
 398 #define PTHRW_COUNT_MASK        0xffffff00 
 399 #define PTHRW_MAX_READERS       0xffffff00 
 402 #define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1 
 404 #define is_rw_ewubit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) != 0) 
 405 #define is_rw_lbit_set(x) (((x) & PTHRW_LBIT) != 0) 
 406 #define is_rw_lybit_set(x) (((x) & (PTHRW_LBIT | PTHRW_YBIT)) != 0) 
 407 #define is_rw_ebit_set(x) (((x) & PTHRW_EBIT) != 0) 
 408 #define is_rw_ebit_clear(x) (((x) & PTHRW_EBIT) == 0) 
 409 #define is_rw_uebit_set(x) (((x) & (PTHRW_EBIT | PTHRW_UBIT)) != 0) 
 410 #define is_rw_ewuybit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT | PTHRW_YBIT)) != 0) 
 411 #define is_rw_ewuybit_clear(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT | PTHRW_YBIT)) == 0) 
 412 #define is_rw_ewubit_set(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) != 0) 
 413 #define is_rw_ewubit_clear(x) (((x) & (PTHRW_EBIT | PTHRW_WBIT | PTHRW_UBIT)) == 0) 
 415 /* is x lower than Y */ 
 416 #define is_seqlower(x, y) ((x  < y) || ((x - y) > (PTHRW_MAX_READERS/2))) 
 417 /* is x lower than or eq Y */ 
 418 #define is_seqlower_eq(x, y) ((x  <= y) || ((x - y) > (PTHRW_MAX_READERS/2))) 
 420 /* is x greater than Y */ 
 421 #define is_seqhigher(x, y) ((x  > y) || ((y - x) > (PTHRW_MAX_READERS/2))) 
 423 static inline  int diff_genseq(uint32_t x
, uint32_t y
) { 
 427                 return((PTHRW_MAX_READERS 
- y
) + x 
+1); 
 431 /* keep the size to 64bytes  for both 64 and 32 */ 
 432 #define _PTHREAD_WORKQUEUE_ATTR_T 
 437         unsigned int resv2
[13]; 
 438 } pthread_workqueue_attr_t
; 
 440 #define _PTHREAD_WORKITEM_T 
 441 typedef struct _pthread_workitem 
{ 
 442         TAILQ_ENTRY(_pthread_workitem
) item_entry
;      /* pthread_workitem list in prio */ 
 443         void    (*func
)(void *); 
 445         struct _pthread_workqueue 
*  workq
;      
 447         unsigned int    gencount
; 
 448 }  * pthread_workitem_t
; 
 450 #define PTH_WQITEM_INKERNEL_QUEUE       1 
 451 #define PTH_WQITEM_RUNNING              2 
 452 #define PTH_WQITEM_COMPLETED            4 
 453 #define PTH_WQITEM_REMOVED              8 
 454 #define PTH_WQITEM_BARRIER              0x10 
 455 #define PTH_WQITEM_DESTROY              0x20 
 456 #define PTH_WQITEM_NOTINLIST            0x40 
 457 #define PTH_WQITEM_APPLIED              0x80 
 458 #define PTH_WQITEM_KERN_COUNT           0x100 
 460 #define WORKITEM_POOL_SIZE 1000 
 461 TAILQ_HEAD(__pthread_workitem_pool
, _pthread_workitem
); 
 462 extern struct __pthread_workitem_pool __pthread_workitem_pool_head
;        /* head list of workitem pool  */ 
 464 #define WQ_NUM_PRIO_QS  3       /* WORKQ_HIGH/DEFAULT/LOW_PRIOQUEUE */ 
 466 #define _PTHREAD_WORKQUEUE_HEAD_T 
 467 typedef struct  _pthread_workqueue_head 
{ 
 468         TAILQ_HEAD(, _pthread_workqueue
) wqhead
; 
 469         struct _pthread_workqueue 
* next_workq
;  
 470 } * pthread_workqueue_head_t
; 
 473 #define _PTHREAD_WORKQUEUE_T 
 474 typedef struct  _pthread_workqueue 
{ 
 475         unsigned int       sig
;       /* Unique signature for this structure */ 
 476         pthread_lock_t lock
;          /* Used for internal mutex on structure */ 
 477         TAILQ_ENTRY(_pthread_workqueue
) wq_list
;        /* workqueue list in prio */ 
 478         TAILQ_HEAD(, _pthread_workitem
) item_listhead
;  /* pthread_workitem list in prio */ 
 479         TAILQ_HEAD(, _pthread_workitem
) item_kernhead
;  /* pthread_workitem list in prio */ 
 488         void            (*term_callback
)(struct _pthread_workqueue 
*,void *); 
 490         pthread_workqueue_head_t headp
; 
 492 #if defined(__ppc64__) || defined(__x86_64__) 
 493         unsigned int    rev2
[2]; 
 495         unsigned int    rev2
[12]; 
 497 }  * pthread_workqueue_t
; 
 499 #define  PTHREAD_WORKQ_IN_CREATION      1 
 500 #define  PTHREAD_WORKQ_IN_TERMINATE     2 
 501 #define  PTHREAD_WORKQ_BARRIER_ON       4 
 502 #define  PTHREAD_WORKQ_TERM_ON          8 
 503 #define  PTHREAD_WORKQ_DESTROYED        0x10 
 504 #define  PTHREAD_WORKQ_REQUEUED         0x20 
 505 #define  PTHREAD_WORKQ_SUSPEND          0x40 
 507 #define WORKQUEUE_POOL_SIZE 100 
 508 TAILQ_HEAD(__pthread_workqueue_pool
, _pthread_workqueue
); 
 509 extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head
;        /* head list of workqueue pool  */ 
 513 #if defined(__i386__) || defined(__ppc64__) || defined(__x86_64__) || (defined(__arm__) && (defined(_ARM_ARCH_7) || !defined(_ARM_ARCH_6) || !defined(__thumb__))) 
 515  * Inside libSystem, we can use r13 or %gs directly to get access to the 
 516  * thread-specific data area. The current thread is in the first slot. 
 518 inline static pthread_t 
__attribute__((__pure__
)) 
 519 _pthread_self_direct(void) 
 522 #if defined(__i386__) || defined(__x86_64__) 
 523        asm("mov %%gs:%P1, %0" : "=r" (ret
) : "i" (offsetof(struct _pthread
, tsd
[0]))); 
 524 #elif defined(__ppc64__) 
 525         register const pthread_t __pthread_self 
asm ("r13"); 
 526         ret 
= __pthread_self
; 
 527 #elif defined(__arm__) && defined(_ARM_ARCH_6) 
 528         __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r"(ret
)); 
 529 #elif defined(__arm__) && !defined(_ARM_ARCH_6) 
 530         register const pthread_t __pthread_self 
asm ("r9"); 
 531         ret 
= __pthread_self
; 
 535 #define pthread_self() _pthread_self_direct() 
 538 #define _PTHREAD_DEFAULT_INHERITSCHED   PTHREAD_INHERIT_SCHED 
 539 #define _PTHREAD_DEFAULT_PROTOCOL       PTHREAD_PRIO_NONE 
 540 #define _PTHREAD_DEFAULT_PRIOCEILING    0 
 541 #define _PTHREAD_DEFAULT_POLICY         SCHED_OTHER 
 542 #define _PTHREAD_DEFAULT_STACKSIZE      0x80000   /* 512K */ 
 543 #define _PTHREAD_DEFAULT_PSHARED        PTHREAD_PROCESS_PRIVATE 
 545 #define _PTHREAD_NO_SIG                 0x00000000 
 546 #define _PTHREAD_MUTEX_ATTR_SIG         0x4D545841  /* 'MTXA' */ 
 547 #define _PTHREAD_MUTEX_SIG              0x4D555458  /* 'MUTX' */ 
 548 #define _PTHREAD_MUTEX_SIG_init         0x32AAABA7  /* [almost] ~'MUTX' */ 
 549 #define _PTHREAD_COND_ATTR_SIG          0x434E4441  /* 'CNDA' */ 
 550 #define _PTHREAD_COND_SIG               0x434F4E44  /* 'COND' */ 
 551 #define _PTHREAD_COND_SIG_init          0x3CB0B1BB  /* [almost] ~'COND' */ 
 552 #define _PTHREAD_ATTR_SIG               0x54484441  /* 'THDA' */ 
 553 #define _PTHREAD_ONCE_SIG               0x4F4E4345  /* 'ONCE' */ 
 554 #define _PTHREAD_ONCE_SIG_init          0x30B1BCBA  /* [almost] ~'ONCE' */ 
 555 #define _PTHREAD_SIG                    0x54485244  /* 'THRD' */ 
 556 #define _PTHREAD_RWLOCK_ATTR_SIG        0x52574C41  /* 'RWLA' */ 
 557 #define _PTHREAD_RWLOCK_SIG             0x52574C4B  /* 'RWLK' */ 
 558 #define _PTHREAD_RWLOCK_SIG_init        0x2DA8B3B4  /* [almost] ~'RWLK' */ 
 561 #define _PTHREAD_KERN_COND_SIG          0x12345678  /*  */ 
 562 #define _PTHREAD_KERN_MUTEX_SIG         0x34567812  /*  */ 
 563 #define _PTHREAD_KERN_RWLOCK_SIG        0x56781234  /*  */ 
 565 #define _PTHREAD_CREATE_PARENT          4 
 566 #define _PTHREAD_EXITED                 8 
 568 #define _PTHREAD_WASCANCEL              0x10 
 572 #define _PTHREAD_MUTEX_OWNER_SELF       pthread_self() 
 574 #define _PTHREAD_MUTEX_OWNER_SELF       (pthread_t)0x12141968 
 576 #define _PTHREAD_MUTEX_OWNER_SWITCHING  (pthread_t)(~0) 
 578 #define _PTHREAD_CANCEL_STATE_MASK   0x01 
 579 #define _PTHREAD_CANCEL_TYPE_MASK    0x02 
 580 #define _PTHREAD_CANCEL_PENDING      0x10  /* pthread_cancel() has been called for this thread */ 
 582 extern boolean_t 
swtch_pri(int); 
 584 #ifndef PTHREAD_MACH_CALL 
 585 #define PTHREAD_MACH_CALL(expr, ret) (ret) = (expr) 
 590 /* Functions defined in machine-dependent files. */ 
 591 extern vm_address_t 
_sp(void); 
 592 extern vm_address_t 
_adjust_sp(vm_address_t sp
); 
 593 extern void _pthread_setup(pthread_t th
, void (*f
)(pthread_t
), void *sp
, int suspended
, int needresume
); 
 595 extern void _pthread_tsd_cleanup(pthread_t self
); 
 597 #if  defined(__i386__) || defined(__x86_64__) 
 598 __private_extern__ 
void __mtx_holdlock(npthread_mutex_t 
*mutex
, uint32_t diff
, uint32_t * flagp
, uint32_t ** pmtxp
, uint32_t * mgenp
, uint32_t * ugenp
); 
 599 __private_extern__ 
int __mtx_droplock(npthread_mutex_t 
*mutex
, int count
, uint32_t * flagp
, uint32_t ** pmtxp
, uint32_t * mgenp
, uint32_t * ugenp
, uint32_t * notifyp
); 
 600 __private_extern__ 
int __mtx_updatebits(npthread_mutex_t 
*mutex
, uint32_t updateval
, int firstfiti
, int fromcond
); 
 602 /* syscall interfaces */ 
 603 extern uint32_t __psynch_mutexwait(pthread_mutex_t 
* mutex
,  uint32_t mgen
, uint32_t  ugen
, uint64_t tid
, uint32_t flags
); 
 604 extern uint32_t __psynch_mutexdrop(pthread_mutex_t 
* mutex
,  uint32_t mgen
, uint32_t  ugen
, uint64_t tid
, uint32_t flags
); 
 605 extern int __psynch_cvbroad(pthread_cond_t 
* cv
, uint32_t cvgen
, uint32_t diffgen
, pthread_mutex_t 
* mutex
,  uint32_t mgen
, uint32_t ugen
, uint64_t tid
, uint32_t flags
); 
 606 extern int __psynch_cvsignal(pthread_cond_t 
* cv
, uint32_t cvgen
, uint32_t cvugen
, pthread_mutex_t 
* mutex
,  uint32_t mgen
, uint32_t ugen
, int thread_port
, uint32_t flags
); 
 607 extern uint32_t __psynch_cvwait(pthread_cond_t 
* cv
, uint32_t cvgen
, uint32_t cvugen
, pthread_mutex_t 
* mutex
,  uint32_t mgen
, uint32_t ugen
, uint64_t sec
, uint64_t usec
); 
 608 extern uint32_t __psynch_rw_longrdlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 609 extern uint32_t __psynch_rw_yieldwrlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 610 extern int __psynch_rw_downgrade(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 611 extern uint32_t __psynch_rw_upgrade(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 612 extern uint32_t __psynch_rw_rdlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 613 extern uint32_t __psynch_rw_wrlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 614 extern uint32_t __psynch_rw_unlock(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 615 extern uint32_t __psynch_rw_unlock2(pthread_rwlock_t 
* rwlock
, uint32_t lgenval
, uint32_t ugenval
, uint32_t rw_wc
, int flags
); 
 616 #endif /* __i386__ || __x86_64__ */ 
 618 __private_extern__ semaphore_t 
new_sem_from_pool(void); 
 619 __private_extern__ 
void restore_sem_to_pool(semaphore_t
); 
 620 __private_extern__ 
void _pthread_atfork_queue_init(void); 
 621 int _pthread_lookup_thread(pthread_t thread
, mach_port_t 
* port
, int only_joinable
); 
 622 int _pthread_join_cleanup(pthread_t thread
, void ** value_ptr
, int conforming
); 
 624 #endif /* _POSIX_PTHREAD_INTERNALS_H */