lock_group.h
1 /* 2 * Copyright (c) 2018 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 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. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 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. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 #ifndef _KERN_LOCK_GROUP_H 29 #define _KERN_LOCK_GROUP_H 30 31 #include <kern/queue.h> 32 #include <mach/mach_types.h> 33 34 __BEGIN_DECLS 35 36 #define LCK_GRP_NULL (lck_grp_t *)NULL 37 38 typedef enum lck_type { 39 LCK_TYPE_SPIN, 40 LCK_TYPE_MTX, 41 LCK_TYPE_RW, 42 LCK_TYPE_TICKET 43 } lck_type_t; 44 45 #if XNU_KERNEL_PRIVATE 46 #include <kern/startup.h> 47 #include <os/refcnt.h> 48 49 /* 50 * Arguments wrapped in LCK_GRP_ARG() will be elided 51 * when LOCK_STATS is not set. 52 * 53 * Arguments wrapped with LCK_GRP_PROBEARG() will be 54 * NULL when LOCK_STATS is not set 55 */ 56 #if LOCK_STATS 57 #define LCK_GRP_ARG(expr) ,expr 58 #define LCK_GRP_PROBEARG(grp) grp 59 #else 60 #define LCK_GRP_ARG(expr) 61 #define LCK_GRP_PROBEARG(grp) LCK_GRP_NULL 62 #endif /* LOCK_STATS */ 63 64 typedef struct _lck_grp_stat_ { 65 uint64_t lgs_count; 66 uint32_t lgs_enablings; 67 #if CONFIG_DTRACE 68 /* 69 * Protected by dtrace_lock 70 */ 71 uint32_t lgs_probeid; 72 uint64_t lgs_limit; 73 #endif /* CONFIG_DTRACE */ 74 } lck_grp_stat_t; 75 76 typedef struct _lck_grp_stats_ { 77 #if LOCK_STATS 78 lck_grp_stat_t lgss_spin_held; 79 lck_grp_stat_t lgss_spin_miss; 80 lck_grp_stat_t lgss_spin_spin; 81 lck_grp_stat_t lgss_ticket_held; 82 lck_grp_stat_t lgss_ticket_miss; 83 lck_grp_stat_t lgss_ticket_spin; 84 #endif /* LOCK_STATS */ 85 86 lck_grp_stat_t lgss_mtx_held; 87 lck_grp_stat_t lgss_mtx_direct_wait; 88 lck_grp_stat_t lgss_mtx_miss; 89 lck_grp_stat_t lgss_mtx_wait; 90 } lck_grp_stats_t; 91 92 #define LCK_GRP_MAX_NAME 64 93 94 typedef struct _lck_grp_ { 95 queue_chain_t lck_grp_link; 96 os_refcnt_t lck_grp_refcnt; 97 uint32_t lck_grp_spincnt; 98 uint32_t lck_grp_ticketcnt; 99 uint32_t lck_grp_mtxcnt; 100 uint32_t lck_grp_rwcnt; 101 uint32_t lck_grp_attr; 102 char lck_grp_name[LCK_GRP_MAX_NAME]; 103 lck_grp_stats_t lck_grp_stats; 104 } lck_grp_t; 105 106 #else 107 typedef struct _lck_grp_ lck_grp_t; 108 #endif /* XNU_KERNEL_PRIVATE */ 109 110 #define LCK_GRP_ATTR_STAT 0x1 111 #define LCK_GRP_ATTR_TIME_STAT 0x2 112 113 #ifdef XNU_KERNEL_PRIVATE 114 typedef struct _lck_grp_attr_ { 115 uint32_t grp_attr_val; 116 } lck_grp_attr_t; 117 118 struct lck_grp_attr_startup_spec { 119 lck_grp_attr_t *grp_attr; 120 uint32_t grp_attr_set_flags; 121 uint32_t grp_attr_clear_flags; 122 }; 123 124 struct lck_grp_startup_spec { 125 lck_grp_t *grp; 126 const char *grp_name; 127 lck_grp_attr_t *grp_attr; 128 }; 129 130 extern void lck_grp_attr_startup_init( 131 struct lck_grp_attr_startup_spec *spec); 132 133 extern void lck_grp_startup_init( 134 struct lck_grp_startup_spec *spec); 135 136 /* 137 * Auto-initializing lock group declarations 138 * ----------------------------------------- 139 * 140 * Use LCK_GRP_DECLARE to declare an automatically initialized group. 141 * 142 * Unless you need to configure your lock groups in very specific ways, 143 * there is no point creating explicit lock group attributes. If however 144 * you do need to tune the group, then LCK_GRP_DECLARE_ATTR can be used 145 * and takes an extra lock group attr argument previously declared with 146 * LCK_GRP_ATTR_DECLARE. 147 */ 148 #define LCK_GRP_ATTR_DECLARE(var, set_flags, clear_flags) \ 149 SECURITY_READ_ONLY_LATE(lck_grp_attr_t) var; \ 150 static __startup_data struct lck_grp_attr_startup_spec \ 151 __startup_lck_grp_attr_spec_ ## var = { &var, set_flags, clear_flags }; \ 152 STARTUP_ARG(LOCKS_EARLY, STARTUP_RANK_SECOND, lck_grp_attr_startup_init, \ 153 &__startup_lck_grp_attr_spec_ ## var) 154 155 #define LCK_GRP_DECLARE_ATTR(var, name, attr) \ 156 __PLACE_IN_SECTION("__DATA,__lock_grp") lck_grp_t var; \ 157 static __startup_data struct lck_grp_startup_spec \ 158 __startup_lck_grp_spec_ ## var = { &var, name, attr }; \ 159 STARTUP_ARG(LOCKS_EARLY, STARTUP_RANK_THIRD, lck_grp_startup_init, \ 160 &__startup_lck_grp_spec_ ## var) 161 162 #define LCK_GRP_DECLARE(var, name) \ 163 LCK_GRP_DECLARE_ATTR(var, name, LCK_GRP_ATTR_NULL); 164 165 #else 166 typedef struct __lck_grp_attr__ lck_grp_attr_t; 167 #endif /* XNU_KERNEL_PRIVATE */ 168 169 #define LCK_GRP_ATTR_NULL (lck_grp_attr_t *)NULL 170 171 extern lck_grp_attr_t *lck_grp_attr_alloc_init( 172 void); 173 174 extern void lck_grp_attr_setdefault( 175 lck_grp_attr_t *attr); 176 177 extern void lck_grp_attr_setstat( 178 lck_grp_attr_t *attr); 179 180 extern void lck_grp_attr_free( 181 lck_grp_attr_t *attr); 182 183 extern lck_grp_t *lck_grp_alloc_init( 184 const char* grp_name, 185 lck_grp_attr_t *attr); 186 187 extern void lck_grp_free( 188 lck_grp_t *grp); 189 190 #ifdef MACH_KERNEL_PRIVATE 191 extern void lck_grp_init( 192 lck_grp_t *grp, 193 const char* grp_name, 194 lck_grp_attr_t *attr); 195 196 extern void lck_grp_reference( 197 lck_grp_t *grp); 198 199 extern void lck_grp_deallocate( 200 lck_grp_t *grp); 201 202 extern void lck_grp_lckcnt_incr( 203 lck_grp_t *grp, 204 lck_type_t lck_type); 205 206 extern void lck_grp_lckcnt_decr( 207 lck_grp_t *grp, 208 lck_type_t lck_type); 209 #endif /* MACH_KERNEL_PRIVATE */ 210 211 __END_DECLS 212 213 #endif /* _KERN_LOCK_GROUP_H */