1 /* 2 * Copyright (c) 2018-2021 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 <kern/lock_types.h> 33 #if XNU_KERNEL_PRIVATE 34 #include <kern/startup.h> 35 #include <os/refcnt.h> 36 #endif /* XNU_KERNEL_PRIVATE */ 37 38 __BEGIN_DECLS 39 40 /*! 41 * @typedef lck_grp_t 42 * 43 * @abstract 44 * The opaque type of a lock group. 45 */ 46 typedef struct _lck_grp_ lck_grp_t; 47 #define LCK_GRP_NULL ((lck_grp_t *)NULL) 48 49 /*! 50 * @typedef lck_grp_attr_t 51 * 52 * @abstract 53 * The opaque type for attributes to a group. 54 */ 55 typedef struct _lck_grp_attr_ lck_grp_attr_t; 56 #define LCK_GRP_ATTR_NULL ((lck_grp_attr_t *)NULL) 57 58 extern lck_grp_attr_t *lck_grp_attr_alloc_init( 59 void); 60 61 extern void lck_grp_attr_setdefault( 62 lck_grp_attr_t *attr); 63 64 extern void lck_grp_attr_setstat( 65 lck_grp_attr_t *attr); 66 67 extern void lck_grp_attr_free( 68 lck_grp_attr_t *attr); 69 70 extern lck_grp_t *lck_grp_alloc_init( 71 const char *grp_name, 72 lck_grp_attr_t *attr); 73 74 extern void lck_grp_free( 75 lck_grp_t *grp); 76 77 #if XNU_KERNEL_PRIVATE 78 #pragma GCC visibility push(hidden) 79 80 /* 81 * Arguments wrapped in LCK_GRP_ARG() will be elided 82 * when LOCK_STATS is not set. 83 * 84 * Arguments wrapped with LCK_GRP_PROBEARG() will be 85 * NULL when LOCK_STATS is not set 86 */ 87 #if LOCK_STATS 88 #define LCK_GRP_ARG(expr) , expr 89 #define LCK_GRP_PROBEARG(grp) grp 90 #else 91 #define LCK_GRP_ARG(expr) 92 #define LCK_GRP_PROBEARG(grp) LCK_GRP_NULL 93 #endif /* LOCK_STATS */ 94 95 extern uint32_t LcksOpts; 96 97 __options_decl(lck_grp_options_t, uint32_t, { 98 LCK_GRP_ATTR_NONE = 0x00000000, 99 100 #if MACH_KERNEL_PRIVATE 101 LCK_GRP_ATTR_STAT = 0x00000001, 102 LCK_GRP_ATTR_TIME_STAT = 0x00000002, 103 LCK_GRP_ATTR_ALLOCATED = 0x00000004, 104 #endif 105 }); 106 107 typedef struct _lck_grp_stat_ { 108 uint64_t lgs_count; 109 uint32_t lgs_enablings; 110 #if CONFIG_DTRACE 111 /* 112 * Protected by dtrace_lock 113 */ 114 uint32_t lgs_probeid; 115 uint64_t lgs_limit; 116 #endif /* CONFIG_DTRACE */ 117 } lck_grp_stat_t; 118 119 typedef struct _lck_grp_stats_ { 120 #if LOCK_STATS 121 lck_grp_stat_t lgss_spin_held; 122 lck_grp_stat_t lgss_spin_miss; 123 lck_grp_stat_t lgss_spin_spin; 124 lck_grp_stat_t lgss_ticket_held; 125 lck_grp_stat_t lgss_ticket_miss; 126 lck_grp_stat_t lgss_ticket_spin; 127 #endif /* LOCK_STATS */ 128 129 lck_grp_stat_t lgss_mtx_held; 130 lck_grp_stat_t lgss_mtx_direct_wait; 131 lck_grp_stat_t lgss_mtx_miss; 132 lck_grp_stat_t lgss_mtx_wait; 133 } lck_grp_stats_t; 134 135 #define LCK_GRP_MAX_NAME 64 136 137 typedef struct _lck_grp_ { 138 queue_chain_t lck_grp_link; 139 os_refcnt_t lck_grp_refcnt; 140 uint32_t lck_grp_spincnt; 141 uint32_t lck_grp_ticketcnt; 142 uint32_t lck_grp_mtxcnt; 143 uint32_t lck_grp_rwcnt; 144 lck_grp_options_t lck_grp_attr; 145 char lck_grp_name[LCK_GRP_MAX_NAME]; 146 lck_grp_stats_t lck_grp_stats; 147 } lck_grp_t; 148 149 typedef struct _lck_grp_attr_ { 150 lck_grp_options_t grp_attr_val; 151 } lck_grp_attr_t; 152 153 struct lck_grp_spec { 154 lck_grp_t *grp; 155 char grp_name[LCK_GRP_MAX_NAME]; 156 lck_grp_options_t grp_flags; 157 }; 158 159 /* 160 * Auto-initializing lock group declarations 161 * ----------------------------------------- 162 * 163 * Use LCK_GRP_DECLARE to declare an automatically initialized group. 164 */ 165 #define LCK_GRP_DECLARE_ATTR(var, name, flags) \ 166 __PLACE_IN_SECTION("__DATA,__lock_grp") lck_grp_t var; \ 167 static __startup_data struct lck_grp_spec \ 168 __startup_lck_grp_spec_ ## var = { &var, name, flags }; \ 169 STARTUP_ARG(LOCKS_EARLY, STARTUP_RANK_THIRD, lck_grp_startup_init, \ 170 &__startup_lck_grp_spec_ ## var) 171 172 #define LCK_GRP_DECLARE(var, name) \ 173 LCK_GRP_DECLARE_ATTR(var, name, LCK_GRP_ATTR_NONE); 174 175 extern bool lck_grp_has_stats( 176 lck_grp_t *grp); 177 178 extern void lck_grp_startup_init( 179 struct lck_grp_spec *spec); 180 181 extern void lck_grp_init( 182 lck_grp_t *grp, 183 const char* grp_name, 184 lck_grp_attr_t *attr); 185 186 extern lck_grp_t *lck_grp_init_flags( 187 lck_grp_t *grp, 188 const char* grp_name, 189 lck_grp_options_t grp_flags); 190 191 extern void lck_grp_reference( 192 lck_grp_t *grp, 193 uint32_t *cnt); 194 195 extern void lck_grp_deallocate( 196 lck_grp_t *grp, 197 uint32_t *cnt); 198 199 extern void lck_grp_foreach( 200 bool (^block)(lck_grp_t *)); 201 202 #pragma GCC visibility pop 203 #endif /* XNU_KERNEL_PRIVATE */ 204 205 __END_DECLS 206 207 #endif /* _KERN_LOCK_GROUP_H */ 208