2  * Copyright (c) 2003-2007 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_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. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29 #ifndef _KERN_LOCKS_H_ 
  30 #define _KERN_LOCKS_H_ 
  32 #include        <sys/cdefs.h> 
  33 #include        <sys/appleapiopts.h> 
  34 #include        <mach/boolean.h> 
  35 #include        <mach/mach_types.h> 
  36 #include        <kern/kern_types.h> 
  37 #include        <machine/locks.h> 
  39 #ifdef  MACH_KERNEL_PRIVATE 
  40 #include        <kern/queue.h> 
  42 extern void                             lck_mod_init( 
  43                                                                 void) __attribute__((section("__TEXT, initcode"))); 
  45 typedef unsigned int    lck_type_t
; 
  47 #define LCK_TYPE_SPIN   1 
  48 #define LCK_TYPE_MTX    2 
  53 typedef unsigned int            lck_sleep_action_t
; 
  55 #define LCK_SLEEP_DEFAULT       0x00    /* Release the lock while waiting for the event, then reclaim */ 
  56                                                                         /* RW locks are returned in the same mode */ 
  57 #define LCK_SLEEP_UNLOCK        0x01    /* Release the lock and return unheld */ 
  58 #define LCK_SLEEP_SHARED        0x02    /* Reclaim the lock in shared mode (RW only) */ 
  59 #define LCK_SLEEP_EXCLUSIVE     0x04    /* Reclaim the lock in exclusive mode (RW only) */ 
  60 #define LCK_SLEEP_SPIN          0x08    /* Reclaim the lock in spin mode (mutex only) */ 
  62 #define LCK_SLEEP_MASK          0x0f    /* Valid actions */ 
  64 #ifdef  MACH_KERNEL_PRIVATE 
  67         uint64_t                        lck_grp_spin_util_cnt
; 
  68         uint64_t                        lck_grp_spin_held_cnt
; 
  69         uint64_t                        lck_grp_spin_miss_cnt
; 
  70         uint64_t                        lck_grp_spin_held_max
; 
  71         uint64_t                        lck_grp_spin_held_cum
; 
  72 } lck_grp_spin_stat_t
; 
  75         uint64_t                        lck_grp_mtx_util_cnt
; 
  76         /* On x86, this is used as the "direct wait" count */ 
  77         uint64_t                        lck_grp_mtx_held_cnt
; 
  78         uint64_t                        lck_grp_mtx_miss_cnt
; 
  79         uint64_t                        lck_grp_mtx_wait_cnt
; 
  80         /* Rest currently unused */ 
  81         uint64_t                        lck_grp_mtx_held_max
; 
  82         uint64_t                        lck_grp_mtx_held_cum
; 
  83         uint64_t                        lck_grp_mtx_wait_max
; 
  84         uint64_t                        lck_grp_mtx_wait_cum
; 
  88         uint64_t                        lck_grp_rw_util_cnt
; 
  89         uint64_t                        lck_grp_rw_held_cnt
; 
  90         uint64_t                        lck_grp_rw_miss_cnt
; 
  91         uint64_t                        lck_grp_rw_wait_cnt
; 
  92         uint64_t                        lck_grp_rw_held_max
; 
  93         uint64_t                        lck_grp_rw_held_cum
; 
  94         uint64_t                        lck_grp_rw_wait_max
; 
  95         uint64_t                        lck_grp_rw_wait_cum
; 
  98 typedef struct _lck_grp_stat_ 
{ 
  99         lck_grp_spin_stat_t     lck_grp_spin_stat
; 
 100         lck_grp_mtx_stat_t      lck_grp_mtx_stat
; 
 101         lck_grp_rw_stat_t       lck_grp_rw_stat
; 
 104 #define LCK_GRP_MAX_NAME        64 
 106 typedef struct _lck_grp_ 
{ 
 107         queue_chain_t           lck_grp_link
; 
 108         uint32_t                lck_grp_refcnt
; 
 109         uint32_t                lck_grp_spincnt
; 
 110         uint32_t                lck_grp_mtxcnt
; 
 111         uint32_t                lck_grp_rwcnt
; 
 112         uint32_t                lck_grp_attr
; 
 113         char                    lck_grp_name
[LCK_GRP_MAX_NAME
]; 
 114         lck_grp_stat_t          lck_grp_stat
; 
 117 #define LCK_GRP_NULL    (lck_grp_t *)0 
 120 typedef struct __lck_grp__ lck_grp_t
; 
 123 #ifdef  MACH_KERNEL_PRIVATE 
 124 typedef struct _lck_grp_attr_ 
{ 
 125         uint32_t        grp_attr_val
; 
 128 extern lck_grp_attr_t  LockDefaultGroupAttr
; 
 130 #define LCK_GRP_ATTR_STAT       0x1 
 133 typedef struct __lck_grp_attr__ lck_grp_attr_t
; 
 136 #define LCK_GRP_ATTR_NULL       (lck_grp_attr_t *)0 
 140 extern  lck_grp_attr_t  
*lck_grp_attr_alloc_init( 
 143 extern  void                    lck_grp_attr_setdefault( 
 144                                                                         lck_grp_attr_t  
*attr
); 
 146 extern  void                    lck_grp_attr_setstat( 
 147                                                                         lck_grp_attr_t  
*attr
); 
 149 extern  void                    lck_grp_attr_free( 
 150                                                                         lck_grp_attr_t  
*attr
); 
 152 extern  lck_grp_t               
*lck_grp_alloc_init( 
 153                                                                         const char*             grp_name
, 
 154                                                                         lck_grp_attr_t  
*attr
); 
 158 #ifdef  MACH_KERNEL_PRIVATE 
 159 extern  void                    lck_grp_init( 
 161                                                                         const char*             grp_name
, 
 162                                                                         lck_grp_attr_t  
*attr
); 
 164 extern  void                    lck_grp_reference( 
 167 extern  void                    lck_grp_deallocate( 
 170 extern  void                    lck_grp_lckcnt_incr( 
 172                                                                         lck_type_t              lck_type
); 
 174 extern  void                    lck_grp_lckcnt_decr( 
 176                                                                         lck_type_t              lck_type
); 
 181 extern void                             lck_grp_free( 
 186 #ifdef  MACH_KERNEL_PRIVATE 
 187 typedef struct _lck_attr_ 
{ 
 188         unsigned int    lck_attr_val
; 
 191 extern lck_attr_t      LockDefaultLckAttr
; 
 193 #define LCK_ATTR_NONE           0 
 195 #define LCK_ATTR_DEBUG                          0x00000001 
 196 #define LCK_ATTR_RW_SHARED_PRIORITY     0x00010000 
 199 typedef struct __lck_attr__ lck_attr_t
; 
 202 #define LCK_ATTR_NULL (lck_attr_t *)0 
 206 extern  lck_attr_t              
*lck_attr_alloc_init( 
 209 extern  void                    lck_attr_setdefault( 
 212 extern  void                    lck_attr_setdebug( 
 215 extern  void                    lck_attr_cleardebug( 
 218 #ifdef  XNU_KERNEL_PRIVATE 
 219 extern  void                    lck_attr_rw_shared_priority( 
 223 extern  void                    lck_attr_free( 
 226 #define decl_lck_spin_data(class,name)     class lck_spin_t name; 
 228 extern lck_spin_t               
*lck_spin_alloc_init( 
 232 extern void                             lck_spin_init( 
 237 extern void                             lck_spin_lock( 
 240 extern void                             lck_spin_unlock( 
 243 extern void                             lck_spin_destroy( 
 247 extern void                             lck_spin_free( 
 251 extern wait_result_t    
lck_spin_sleep( 
 253                                                                         lck_sleep_action_t      lck_sleep_action
, 
 255                                                                         wait_interrupt_t        interruptible
); 
 257 extern wait_result_t    
lck_spin_sleep_deadline( 
 259                                                                         lck_sleep_action_t      lck_sleep_action
, 
 261                                                                         wait_interrupt_t        interruptible
, 
 264 #ifdef  KERNEL_PRIVATE 
 266 extern boolean_t                
lck_spin_try_lock( 
 269 struct _lck_mtx_ext_
; 
 270 extern void lck_mtx_init_ext(lck_mtx_t 
*lck
, struct _lck_mtx_ext_ 
*lck_ext
, 
 271     lck_grp_t 
*grp
, lck_attr_t 
*attr
); 
 276 #define decl_lck_mtx_data(class,name)     class lck_mtx_t name; 
 278 extern lck_mtx_t                
*lck_mtx_alloc_init( 
 282 extern void                             lck_mtx_init( 
 286 extern void                             lck_mtx_lock( 
 289 #if     defined(__i386__) 
 290 extern void     lck_mtx_unlock(lck_mtx_t                
*lck
) __DARWIN10_ALIAS(lck_mtx_unlock
); 
 292 extern void                             lck_mtx_unlock( 
 294 #endif  /* __i386__ */ 
 295 extern void                             lck_mtx_destroy( 
 299 extern void                             lck_mtx_free( 
 303 extern wait_result_t    
lck_mtx_sleep( 
 305                                                                         lck_sleep_action_t      lck_sleep_action
, 
 307                                                                         wait_interrupt_t        interruptible
); 
 309 extern wait_result_t    
lck_mtx_sleep_deadline( 
 311                                                                         lck_sleep_action_t      lck_sleep_action
, 
 313                                                                         wait_interrupt_t        interruptible
, 
 316 #ifdef  KERNEL_PRIVATE 
 318 extern boolean_t                
lck_mtx_try_lock( 
 321 extern void                             mutex_pause(uint32_t); 
 323 extern void                     lck_mtx_yield ( 
 326 #if defined(i386) || defined(x86_64) 
 327 extern boolean_t                
lck_mtx_try_lock_spin( 
 330 extern void                     lck_mtx_lock_spin( 
 333 extern void                     lck_mtx_convert_spin( 
 336 #define lck_mtx_try_lock_spin(l)        lck_mtx_try_lock(l) 
 337 #define lck_mtx_lock_spin(l)            lck_mtx_lock(l) 
 338 #define lck_mtx_convert_spin(l)         do {} while (0) 
 341 #endif  /* KERNEL_PRIVATE */ 
 343 extern void                             lck_mtx_assert( 
 349 #define LCK_MTX_ASSERT_OWNED    0x01 
 350 #define LCK_MTX_ASSERT_NOTOWNED 0x02 
 352 #ifdef  MACH_KERNEL_PRIVATE 
 353 extern void                             lck_mtx_lock_wait( 
 357 extern int                              lck_mtx_lock_acquire( 
 360 extern void                             lck_mtx_unlock_wakeup( 
 363 extern void                             lck_mtx_unlockspin_wakeup( 
 366 extern boolean_t                
lck_mtx_ilk_unlock( 
 371 #define decl_lck_rw_data(class,name)     class lck_rw_t name; 
 373 typedef unsigned int     lck_rw_type_t
; 
 375 #define LCK_RW_TYPE_SHARED                      0x01 
 376 #define LCK_RW_TYPE_EXCLUSIVE           0x02 
 378 #ifdef XNU_KERNEL_PRIVATE 
 379 #define LCK_RW_ASSERT_SHARED    0x01 
 380 #define LCK_RW_ASSERT_EXCLUSIVE 0x02 
 381 #define LCK_RW_ASSERT_HELD      (LCK_RW_ASSERT_SHARED | LCK_RW_ASSERT_EXCLUSIVE) 
 386 extern lck_rw_t                 
*lck_rw_alloc_init( 
 390 extern void                             lck_rw_init( 
 395 extern void                             lck_rw_lock( 
 397                                                                         lck_rw_type_t   lck_rw_type
); 
 399 extern void                             lck_rw_unlock( 
 401                                                                         lck_rw_type_t   lck_rw_type
); 
 403 extern void                             lck_rw_lock_shared( 
 406 extern void                             lck_rw_unlock_shared( 
 409 extern void                             lck_rw_lock_exclusive( 
 412 extern void                             lck_rw_unlock_exclusive( 
 415 #ifdef  XNU_KERNEL_PRIVATE 
 418  * read-write locks do not have a concept of ownership, so lck_rw_assert() 
 419  * merely asserts that someone is holding the lock, not necessarily the caller. 
 421 extern void                             lck_rw_assert( 
 426 #ifdef  KERNEL_PRIVATE 
 428 extern lck_rw_type_t    
lck_rw_done( 
 432 extern void                             lck_rw_destroy( 
 436 extern void                             lck_rw_free( 
 440 extern wait_result_t    
lck_rw_sleep( 
 442                                                                         lck_sleep_action_t      lck_sleep_action
, 
 444                                                                         wait_interrupt_t        interruptible
); 
 446 extern wait_result_t    
lck_rw_sleep_deadline( 
 448                                                                         lck_sleep_action_t      lck_sleep_action
, 
 450                                                                         wait_interrupt_t        interruptible
, 
 453 extern boolean_t                
lck_rw_lock_shared_to_exclusive( 
 456 extern void                             lck_rw_lock_exclusive_to_shared( 
 459 extern boolean_t                
lck_rw_try_lock( 
 461                                                                         lck_rw_type_t   lck_rw_type
); 
 463 #ifdef  KERNEL_PRIVATE 
 465 extern boolean_t                
lck_rw_try_lock_shared( 
 468 extern boolean_t                
lck_rw_try_lock_exclusive( 
 474 #endif /* _KERN_LOCKS_H_ */