1*2c2f96dcSApple OSS Distributions /*
2*2c2f96dcSApple OSS Distributions * Copyright (c) 2000-2021 Apple Inc. All rights reserved.
3*2c2f96dcSApple OSS Distributions *
4*2c2f96dcSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*2c2f96dcSApple OSS Distributions *
6*2c2f96dcSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*2c2f96dcSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*2c2f96dcSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*2c2f96dcSApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*2c2f96dcSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*2c2f96dcSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*2c2f96dcSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*2c2f96dcSApple OSS Distributions * terms of an Apple operating system software license agreement.
14*2c2f96dcSApple OSS Distributions *
15*2c2f96dcSApple OSS Distributions * Please obtain a copy of the License at
16*2c2f96dcSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*2c2f96dcSApple OSS Distributions *
18*2c2f96dcSApple OSS Distributions * The Original Code and all software distributed under the License are
19*2c2f96dcSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*2c2f96dcSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*2c2f96dcSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*2c2f96dcSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*2c2f96dcSApple OSS Distributions * Please see the License for the specific language governing rights and
24*2c2f96dcSApple OSS Distributions * limitations under the License.
25*2c2f96dcSApple OSS Distributions *
26*2c2f96dcSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*2c2f96dcSApple OSS Distributions */
28*2c2f96dcSApple OSS Distributions /*
29*2c2f96dcSApple OSS Distributions * @OSF_COPYRIGHT@
30*2c2f96dcSApple OSS Distributions */
31*2c2f96dcSApple OSS Distributions /*
32*2c2f96dcSApple OSS Distributions * Mach Operating System
33*2c2f96dcSApple OSS Distributions * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
34*2c2f96dcSApple OSS Distributions * All Rights Reserved.
35*2c2f96dcSApple OSS Distributions *
36*2c2f96dcSApple OSS Distributions * Permission to use, copy, modify and distribute this software and its
37*2c2f96dcSApple OSS Distributions * documentation is hereby granted, provided that both the copyright
38*2c2f96dcSApple OSS Distributions * notice and this permission notice appear in all copies of the
39*2c2f96dcSApple OSS Distributions * software, derivative works or modified versions, and any portions
40*2c2f96dcSApple OSS Distributions * thereof, and that both notices appear in supporting documentation.
41*2c2f96dcSApple OSS Distributions *
42*2c2f96dcSApple OSS Distributions * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43*2c2f96dcSApple OSS Distributions * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44*2c2f96dcSApple OSS Distributions * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
45*2c2f96dcSApple OSS Distributions *
46*2c2f96dcSApple OSS Distributions * Carnegie Mellon requests users of this software to return to
47*2c2f96dcSApple OSS Distributions *
48*2c2f96dcSApple OSS Distributions * Software Distribution Coordinator or [email protected]
49*2c2f96dcSApple OSS Distributions * School of Computer Science
50*2c2f96dcSApple OSS Distributions * Carnegie Mellon University
51*2c2f96dcSApple OSS Distributions * Pittsburgh PA 15213-3890
52*2c2f96dcSApple OSS Distributions *
53*2c2f96dcSApple OSS Distributions * any improvements or extensions that they make and grant Carnegie Mellon
54*2c2f96dcSApple OSS Distributions * the rights to redistribute these changes.
55*2c2f96dcSApple OSS Distributions */
56*2c2f96dcSApple OSS Distributions
57*2c2f96dcSApple OSS Distributions #define LOCK_PRIVATE 1
58*2c2f96dcSApple OSS Distributions
59*2c2f96dcSApple OSS Distributions #include <mach_ldebug.h>
60*2c2f96dcSApple OSS Distributions #include <debug.h>
61*2c2f96dcSApple OSS Distributions
62*2c2f96dcSApple OSS Distributions #include <mach/mach_host_server.h>
63*2c2f96dcSApple OSS Distributions #include <mach_debug/lockgroup_info.h>
64*2c2f96dcSApple OSS Distributions
65*2c2f96dcSApple OSS Distributions #if __x86_64__
66*2c2f96dcSApple OSS Distributions #include <i386/tsc.h>
67*2c2f96dcSApple OSS Distributions #endif
68*2c2f96dcSApple OSS Distributions
69*2c2f96dcSApple OSS Distributions #include <kern/compact_id.h>
70*2c2f96dcSApple OSS Distributions #include <kern/kalloc.h>
71*2c2f96dcSApple OSS Distributions #include <kern/lock_stat.h>
72*2c2f96dcSApple OSS Distributions #include <kern/locks.h>
73*2c2f96dcSApple OSS Distributions
74*2c2f96dcSApple OSS Distributions #include <os/atomic_private.h>
75*2c2f96dcSApple OSS Distributions
76*2c2f96dcSApple OSS Distributions static KALLOC_TYPE_DEFINE(KT_LCK_GRP_ATTR, lck_grp_attr_t, KT_PRIV_ACCT);
77*2c2f96dcSApple OSS Distributions static KALLOC_TYPE_DEFINE(KT_LCK_GRP, lck_grp_t, KT_PRIV_ACCT);
78*2c2f96dcSApple OSS Distributions static KALLOC_TYPE_DEFINE(KT_LCK_ATTR, lck_attr_t, KT_PRIV_ACCT);
79*2c2f96dcSApple OSS Distributions
80*2c2f96dcSApple OSS Distributions SECURITY_READ_ONLY_LATE(lck_attr_t) lck_attr_default;
81*2c2f96dcSApple OSS Distributions static SECURITY_READ_ONLY_LATE(lck_grp_attr_t) lck_grp_attr_default;
82*2c2f96dcSApple OSS Distributions static lck_grp_t lck_grp_compat_grp;
83*2c2f96dcSApple OSS Distributions COMPACT_ID_TABLE_DEFINE(static, lck_grp_table);
84*2c2f96dcSApple OSS Distributions struct lck_debug_state lck_debug_state;
85*2c2f96dcSApple OSS Distributions
86*2c2f96dcSApple OSS Distributions #pragma mark lock group attributes
87*2c2f96dcSApple OSS Distributions
88*2c2f96dcSApple OSS Distributions lck_grp_attr_t *
lck_grp_attr_alloc_init(void)89*2c2f96dcSApple OSS Distributions lck_grp_attr_alloc_init(void)
90*2c2f96dcSApple OSS Distributions {
91*2c2f96dcSApple OSS Distributions lck_grp_attr_t *attr;
92*2c2f96dcSApple OSS Distributions
93*2c2f96dcSApple OSS Distributions attr = zalloc(KT_LCK_GRP_ATTR);
94*2c2f96dcSApple OSS Distributions lck_grp_attr_setdefault(attr);
95*2c2f96dcSApple OSS Distributions return attr;
96*2c2f96dcSApple OSS Distributions }
97*2c2f96dcSApple OSS Distributions
98*2c2f96dcSApple OSS Distributions void
lck_grp_attr_setdefault(lck_grp_attr_t * attr)99*2c2f96dcSApple OSS Distributions lck_grp_attr_setdefault(lck_grp_attr_t *attr)
100*2c2f96dcSApple OSS Distributions {
101*2c2f96dcSApple OSS Distributions attr->grp_attr_val = lck_grp_attr_default.grp_attr_val;
102*2c2f96dcSApple OSS Distributions }
103*2c2f96dcSApple OSS Distributions
104*2c2f96dcSApple OSS Distributions void
lck_grp_attr_setstat(lck_grp_attr_t * attr __unused)105*2c2f96dcSApple OSS Distributions lck_grp_attr_setstat(lck_grp_attr_t *attr __unused)
106*2c2f96dcSApple OSS Distributions {
107*2c2f96dcSApple OSS Distributions attr->grp_attr_val |= LCK_GRP_ATTR_STAT;
108*2c2f96dcSApple OSS Distributions }
109*2c2f96dcSApple OSS Distributions
110*2c2f96dcSApple OSS Distributions
111*2c2f96dcSApple OSS Distributions void
lck_grp_attr_free(lck_grp_attr_t * attr)112*2c2f96dcSApple OSS Distributions lck_grp_attr_free(lck_grp_attr_t *attr)
113*2c2f96dcSApple OSS Distributions {
114*2c2f96dcSApple OSS Distributions zfree(KT_LCK_GRP_ATTR, attr);
115*2c2f96dcSApple OSS Distributions }
116*2c2f96dcSApple OSS Distributions
117*2c2f96dcSApple OSS Distributions #pragma mark lock groups
118*2c2f96dcSApple OSS Distributions
119*2c2f96dcSApple OSS Distributions __startup_func
120*2c2f96dcSApple OSS Distributions static void
lck_group_init(void)121*2c2f96dcSApple OSS Distributions lck_group_init(void)
122*2c2f96dcSApple OSS Distributions {
123*2c2f96dcSApple OSS Distributions if (LcksOpts & LCK_OPTION_ENABLE_STAT) {
124*2c2f96dcSApple OSS Distributions lck_grp_attr_default.grp_attr_val |= LCK_GRP_ATTR_STAT;
125*2c2f96dcSApple OSS Distributions }
126*2c2f96dcSApple OSS Distributions if (LcksOpts & LCK_OPTION_ENABLE_TIME_STAT) {
127*2c2f96dcSApple OSS Distributions lck_grp_attr_default.grp_attr_val |= LCK_GRP_ATTR_TIME_STAT;
128*2c2f96dcSApple OSS Distributions }
129*2c2f96dcSApple OSS Distributions if (LcksOpts & LCK_OPTION_ENABLE_DEBUG) {
130*2c2f96dcSApple OSS Distributions lck_grp_attr_default.grp_attr_val |= LCK_GRP_ATTR_DEBUG;
131*2c2f96dcSApple OSS Distributions }
132*2c2f96dcSApple OSS Distributions
133*2c2f96dcSApple OSS Distributions if (LcksOpts & LCK_OPTION_ENABLE_DEBUG) {
134*2c2f96dcSApple OSS Distributions lck_attr_default.lck_attr_val = LCK_ATTR_DEBUG;
135*2c2f96dcSApple OSS Distributions } else {
136*2c2f96dcSApple OSS Distributions lck_attr_default.lck_attr_val = LCK_ATTR_NONE;
137*2c2f96dcSApple OSS Distributions }
138*2c2f96dcSApple OSS Distributions
139*2c2f96dcSApple OSS Distributions /*
140*2c2f96dcSApple OSS Distributions * This is a little gross, this allows us to use the table before
141*2c2f96dcSApple OSS Distributions * compact_table_init() is called on it, but we have a chicken
142*2c2f96dcSApple OSS Distributions * and egg problem otherwise.
143*2c2f96dcSApple OSS Distributions *
144*2c2f96dcSApple OSS Distributions * compact_table_init() really only inits the ticket lock
145*2c2f96dcSApple OSS Distributions * with the proper lock group
146*2c2f96dcSApple OSS Distributions */
147*2c2f96dcSApple OSS Distributions lck_grp_init(&lck_grp_compat_grp, "Compatibility APIs",
148*2c2f96dcSApple OSS Distributions &lck_grp_attr_default);
149*2c2f96dcSApple OSS Distributions *compact_id_resolve(&lck_grp_table, 0) = LCK_GRP_NULL;
150*2c2f96dcSApple OSS Distributions }
151*2c2f96dcSApple OSS Distributions STARTUP(LOCKS, STARTUP_RANK_FIRST, lck_group_init);
152*2c2f96dcSApple OSS Distributions
153*2c2f96dcSApple OSS Distributions __startup_func
154*2c2f96dcSApple OSS Distributions void
lck_grp_startup_init(struct lck_grp_spec * sp)155*2c2f96dcSApple OSS Distributions lck_grp_startup_init(struct lck_grp_spec *sp)
156*2c2f96dcSApple OSS Distributions {
157*2c2f96dcSApple OSS Distributions lck_grp_init_flags(sp->grp, sp->grp_name, sp->grp_flags |
158*2c2f96dcSApple OSS Distributions lck_grp_attr_default.grp_attr_val);
159*2c2f96dcSApple OSS Distributions }
160*2c2f96dcSApple OSS Distributions
161*2c2f96dcSApple OSS Distributions bool
lck_grp_has_stats(lck_grp_t * grp)162*2c2f96dcSApple OSS Distributions lck_grp_has_stats(lck_grp_t *grp)
163*2c2f96dcSApple OSS Distributions {
164*2c2f96dcSApple OSS Distributions return grp->lck_grp_attr_id & LCK_GRP_ATTR_STAT;
165*2c2f96dcSApple OSS Distributions }
166*2c2f96dcSApple OSS Distributions
167*2c2f96dcSApple OSS Distributions lck_grp_t *
lck_grp_alloc_init(const char * grp_name,lck_grp_attr_t * attr)168*2c2f96dcSApple OSS Distributions lck_grp_alloc_init(const char *grp_name, lck_grp_attr_t *attr)
169*2c2f96dcSApple OSS Distributions {
170*2c2f96dcSApple OSS Distributions lck_grp_t *grp;
171*2c2f96dcSApple OSS Distributions
172*2c2f96dcSApple OSS Distributions if (attr == LCK_GRP_ATTR_NULL) {
173*2c2f96dcSApple OSS Distributions attr = &lck_grp_attr_default;
174*2c2f96dcSApple OSS Distributions }
175*2c2f96dcSApple OSS Distributions grp = zalloc(KT_LCK_GRP);
176*2c2f96dcSApple OSS Distributions lck_grp_init_flags(grp, grp_name,
177*2c2f96dcSApple OSS Distributions attr->grp_attr_val | LCK_GRP_ATTR_ALLOCATED);
178*2c2f96dcSApple OSS Distributions return grp;
179*2c2f96dcSApple OSS Distributions }
180*2c2f96dcSApple OSS Distributions
181*2c2f96dcSApple OSS Distributions void
lck_grp_init(lck_grp_t * grp,const char * grp_name,lck_grp_attr_t * attr)182*2c2f96dcSApple OSS Distributions lck_grp_init(lck_grp_t *grp, const char *grp_name, lck_grp_attr_t *attr)
183*2c2f96dcSApple OSS Distributions {
184*2c2f96dcSApple OSS Distributions if (attr == LCK_GRP_ATTR_NULL) {
185*2c2f96dcSApple OSS Distributions attr = &lck_grp_attr_default;
186*2c2f96dcSApple OSS Distributions }
187*2c2f96dcSApple OSS Distributions lck_grp_init_flags(grp, grp_name, attr->grp_attr_val);
188*2c2f96dcSApple OSS Distributions }
189*2c2f96dcSApple OSS Distributions
190*2c2f96dcSApple OSS Distributions lck_grp_t *
lck_grp_init_flags(lck_grp_t * grp,const char * grp_name,lck_grp_options_t flags)191*2c2f96dcSApple OSS Distributions lck_grp_init_flags(lck_grp_t *grp, const char *grp_name, lck_grp_options_t flags)
192*2c2f96dcSApple OSS Distributions {
193*2c2f96dcSApple OSS Distributions bzero(grp, sizeof(lck_grp_t));
194*2c2f96dcSApple OSS Distributions os_ref_init_raw(&grp->lck_grp_refcnt, NULL);
195*2c2f96dcSApple OSS Distributions (void)strlcpy(grp->lck_grp_name, grp_name, LCK_GRP_MAX_NAME);
196*2c2f96dcSApple OSS Distributions
197*2c2f96dcSApple OSS Distributions #if CONFIG_DTRACE
198*2c2f96dcSApple OSS Distributions lck_grp_stats_t *stats = &grp->lck_grp_stats;
199*2c2f96dcSApple OSS Distributions
200*2c2f96dcSApple OSS Distributions if (flags & LCK_GRP_ATTR_STAT) {
201*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_spin_held);
202*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_spin_miss);
203*2c2f96dcSApple OSS Distributions
204*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_ticket_held);
205*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_ticket_miss);
206*2c2f96dcSApple OSS Distributions
207*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_mtx_held);
208*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_mtx_direct_wait);
209*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_mtx_miss);
210*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_mtx_wait);
211*2c2f96dcSApple OSS Distributions }
212*2c2f96dcSApple OSS Distributions if (flags & LCK_GRP_ATTR_TIME_STAT) {
213*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_spin_spin);
214*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(&stats->lgss_ticket_spin);
215*2c2f96dcSApple OSS Distributions }
216*2c2f96dcSApple OSS Distributions #endif /* CONFIG_DTRACE */
217*2c2f96dcSApple OSS Distributions
218*2c2f96dcSApple OSS Distributions /* must be last as it publishes the group */
219*2c2f96dcSApple OSS Distributions if (startup_phase > STARTUP_SUB_LOCKS) {
220*2c2f96dcSApple OSS Distributions compact_id_table_lock(&lck_grp_table);
221*2c2f96dcSApple OSS Distributions }
222*2c2f96dcSApple OSS Distributions flags |= compact_id_get_locked(&lck_grp_table, LCK_GRP_ATTR_ID_MASK, grp);
223*2c2f96dcSApple OSS Distributions grp->lck_grp_attr_id = flags;
224*2c2f96dcSApple OSS Distributions if (startup_phase > STARTUP_SUB_LOCKS) {
225*2c2f96dcSApple OSS Distributions compact_id_table_unlock(&lck_grp_table);
226*2c2f96dcSApple OSS Distributions }
227*2c2f96dcSApple OSS Distributions
228*2c2f96dcSApple OSS Distributions return grp;
229*2c2f96dcSApple OSS Distributions }
230*2c2f96dcSApple OSS Distributions
231*2c2f96dcSApple OSS Distributions lck_grp_t *
lck_grp_resolve(uint32_t grp_attr_id)232*2c2f96dcSApple OSS Distributions lck_grp_resolve(uint32_t grp_attr_id)
233*2c2f96dcSApple OSS Distributions {
234*2c2f96dcSApple OSS Distributions grp_attr_id &= LCK_GRP_ATTR_ID_MASK;
235*2c2f96dcSApple OSS Distributions return *compact_id_resolve(&lck_grp_table, grp_attr_id);
236*2c2f96dcSApple OSS Distributions }
237*2c2f96dcSApple OSS Distributions
238*2c2f96dcSApple OSS Distributions __abortlike
239*2c2f96dcSApple OSS Distributions static void
__lck_grp_assert_id_panic(lck_grp_t * grp,uint32_t grp_attr_id)240*2c2f96dcSApple OSS Distributions __lck_grp_assert_id_panic(lck_grp_t *grp, uint32_t grp_attr_id)
241*2c2f96dcSApple OSS Distributions {
242*2c2f96dcSApple OSS Distributions panic("lck_grp_t %p has ID %d, but %d was expected", grp,
243*2c2f96dcSApple OSS Distributions grp->lck_grp_attr_id & LCK_GRP_ATTR_ID_MASK,
244*2c2f96dcSApple OSS Distributions grp_attr_id & LCK_GRP_ATTR_ID_MASK);
245*2c2f96dcSApple OSS Distributions }
246*2c2f96dcSApple OSS Distributions
247*2c2f96dcSApple OSS Distributions __attribute__((always_inline))
248*2c2f96dcSApple OSS Distributions void
lck_grp_assert_id(lck_grp_t * grp,uint32_t grp_attr_id)249*2c2f96dcSApple OSS Distributions lck_grp_assert_id(lck_grp_t *grp, uint32_t grp_attr_id)
250*2c2f96dcSApple OSS Distributions {
251*2c2f96dcSApple OSS Distributions if ((grp->lck_grp_attr_id ^ grp_attr_id) & LCK_GRP_ATTR_ID_MASK) {
252*2c2f96dcSApple OSS Distributions __lck_grp_assert_id_panic(grp, grp_attr_id);
253*2c2f96dcSApple OSS Distributions }
254*2c2f96dcSApple OSS Distributions }
255*2c2f96dcSApple OSS Distributions
256*2c2f96dcSApple OSS Distributions static void
lck_grp_destroy(lck_grp_t * grp)257*2c2f96dcSApple OSS Distributions lck_grp_destroy(lck_grp_t *grp)
258*2c2f96dcSApple OSS Distributions {
259*2c2f96dcSApple OSS Distributions compact_id_put(&lck_grp_table,
260*2c2f96dcSApple OSS Distributions grp->lck_grp_attr_id & LCK_GRP_ATTR_ID_MASK);
261*2c2f96dcSApple OSS Distributions zfree(KT_LCK_GRP, grp);
262*2c2f96dcSApple OSS Distributions }
263*2c2f96dcSApple OSS Distributions
264*2c2f96dcSApple OSS Distributions void
lck_grp_free(lck_grp_t * grp)265*2c2f96dcSApple OSS Distributions lck_grp_free(lck_grp_t *grp)
266*2c2f96dcSApple OSS Distributions {
267*2c2f96dcSApple OSS Distributions lck_grp_deallocate(grp, NULL);
268*2c2f96dcSApple OSS Distributions }
269*2c2f96dcSApple OSS Distributions
270*2c2f96dcSApple OSS Distributions void
lck_grp_reference(lck_grp_t * grp,uint32_t * cnt)271*2c2f96dcSApple OSS Distributions lck_grp_reference(lck_grp_t *grp, uint32_t *cnt)
272*2c2f96dcSApple OSS Distributions {
273*2c2f96dcSApple OSS Distributions if (cnt) {
274*2c2f96dcSApple OSS Distributions os_atomic_inc(cnt, relaxed);
275*2c2f96dcSApple OSS Distributions }
276*2c2f96dcSApple OSS Distributions if (grp->lck_grp_attr_id & LCK_GRP_ATTR_ALLOCATED) {
277*2c2f96dcSApple OSS Distributions os_ref_retain_raw(&grp->lck_grp_refcnt, NULL);
278*2c2f96dcSApple OSS Distributions }
279*2c2f96dcSApple OSS Distributions }
280*2c2f96dcSApple OSS Distributions
281*2c2f96dcSApple OSS Distributions void
lck_grp_deallocate(lck_grp_t * grp,uint32_t * cnt)282*2c2f96dcSApple OSS Distributions lck_grp_deallocate(lck_grp_t *grp, uint32_t *cnt)
283*2c2f96dcSApple OSS Distributions {
284*2c2f96dcSApple OSS Distributions if (cnt) {
285*2c2f96dcSApple OSS Distributions os_atomic_dec(cnt, relaxed);
286*2c2f96dcSApple OSS Distributions }
287*2c2f96dcSApple OSS Distributions if ((grp->lck_grp_attr_id & LCK_GRP_ATTR_ALLOCATED) &&
288*2c2f96dcSApple OSS Distributions os_ref_release_raw(&grp->lck_grp_refcnt, 0) == 0) {
289*2c2f96dcSApple OSS Distributions lck_grp_destroy(grp);
290*2c2f96dcSApple OSS Distributions }
291*2c2f96dcSApple OSS Distributions }
292*2c2f96dcSApple OSS Distributions
293*2c2f96dcSApple OSS Distributions void
294*2c2f96dcSApple OSS Distributions lck_grp_foreach(bool (^block)(lck_grp_t *))
295*2c2f96dcSApple OSS Distributions {
296*2c2f96dcSApple OSS Distributions compact_id_for_each(&lck_grp_table, 64, (bool (^)(void *))block);
297*2c2f96dcSApple OSS Distributions }
298*2c2f96dcSApple OSS Distributions
299*2c2f96dcSApple OSS Distributions void
lck_grp_enable_feature(lck_debug_feature_t feat)300*2c2f96dcSApple OSS Distributions lck_grp_enable_feature(lck_debug_feature_t feat)
301*2c2f96dcSApple OSS Distributions {
302*2c2f96dcSApple OSS Distributions uint32_t bit = 1u << feat;
303*2c2f96dcSApple OSS Distributions
304*2c2f96dcSApple OSS Distributions compact_id_table_lock(&lck_grp_table);
305*2c2f96dcSApple OSS Distributions if (lck_debug_state.lds_counts[feat]++ == 0) {
306*2c2f96dcSApple OSS Distributions os_atomic_or(&lck_debug_state.lds_value, bit, relaxed);
307*2c2f96dcSApple OSS Distributions }
308*2c2f96dcSApple OSS Distributions compact_id_table_unlock(&lck_grp_table);
309*2c2f96dcSApple OSS Distributions }
310*2c2f96dcSApple OSS Distributions
311*2c2f96dcSApple OSS Distributions void
lck_grp_disable_feature(lck_debug_feature_t feat)312*2c2f96dcSApple OSS Distributions lck_grp_disable_feature(lck_debug_feature_t feat)
313*2c2f96dcSApple OSS Distributions {
314*2c2f96dcSApple OSS Distributions uint32_t bit = 1u << feat;
315*2c2f96dcSApple OSS Distributions long v;
316*2c2f96dcSApple OSS Distributions
317*2c2f96dcSApple OSS Distributions compact_id_table_lock(&lck_grp_table);
318*2c2f96dcSApple OSS Distributions v = --lck_debug_state.lds_counts[feat];
319*2c2f96dcSApple OSS Distributions if (v < 0) {
320*2c2f96dcSApple OSS Distributions panic("lck_debug_state: feature %d imbalance", feat);
321*2c2f96dcSApple OSS Distributions }
322*2c2f96dcSApple OSS Distributions if (v == 0) {
323*2c2f96dcSApple OSS Distributions os_atomic_andnot(&lck_debug_state.lds_value, bit, relaxed);
324*2c2f96dcSApple OSS Distributions }
325*2c2f96dcSApple OSS Distributions compact_id_table_unlock(&lck_grp_table);
326*2c2f96dcSApple OSS Distributions }
327*2c2f96dcSApple OSS Distributions
328*2c2f96dcSApple OSS Distributions kern_return_t
host_lockgroup_info(host_t host,lockgroup_info_array_t * lockgroup_infop,mach_msg_type_number_t * lockgroup_infoCntp)329*2c2f96dcSApple OSS Distributions host_lockgroup_info(
330*2c2f96dcSApple OSS Distributions host_t host,
331*2c2f96dcSApple OSS Distributions lockgroup_info_array_t *lockgroup_infop,
332*2c2f96dcSApple OSS Distributions mach_msg_type_number_t *lockgroup_infoCntp)
333*2c2f96dcSApple OSS Distributions {
334*2c2f96dcSApple OSS Distributions lockgroup_info_t *info;
335*2c2f96dcSApple OSS Distributions vm_offset_t addr;
336*2c2f96dcSApple OSS Distributions vm_size_t size, used;
337*2c2f96dcSApple OSS Distributions vm_size_t vmsize, vmused;
338*2c2f96dcSApple OSS Distributions uint32_t needed;
339*2c2f96dcSApple OSS Distributions __block uint32_t count = 0;
340*2c2f96dcSApple OSS Distributions vm_map_copy_t copy;
341*2c2f96dcSApple OSS Distributions kern_return_t kr;
342*2c2f96dcSApple OSS Distributions
343*2c2f96dcSApple OSS Distributions if (host == HOST_NULL) {
344*2c2f96dcSApple OSS Distributions return KERN_INVALID_HOST;
345*2c2f96dcSApple OSS Distributions }
346*2c2f96dcSApple OSS Distributions
347*2c2f96dcSApple OSS Distributions /*
348*2c2f96dcSApple OSS Distributions * Give about 10% of slop here, lock groups are mostly allocated
349*2c2f96dcSApple OSS Distributions * during boot or kext loads, and is extremely unlikely to grow
350*2c2f96dcSApple OSS Distributions * rapidly.
351*2c2f96dcSApple OSS Distributions */
352*2c2f96dcSApple OSS Distributions needed = os_atomic_load(&lck_grp_table.cidt_count, relaxed);
353*2c2f96dcSApple OSS Distributions needed += needed / 8;
354*2c2f96dcSApple OSS Distributions size = needed * sizeof(lockgroup_info_t);
355*2c2f96dcSApple OSS Distributions vmsize = vm_map_round_page(size, VM_MAP_PAGE_MASK(ipc_kernel_map));
356*2c2f96dcSApple OSS Distributions kr = kmem_alloc(ipc_kernel_map, &addr, vmsize,
357*2c2f96dcSApple OSS Distributions KMA_DATA | KMA_ZERO, VM_KERN_MEMORY_IPC);
358*2c2f96dcSApple OSS Distributions if (kr != KERN_SUCCESS) {
359*2c2f96dcSApple OSS Distributions return kr;
360*2c2f96dcSApple OSS Distributions }
361*2c2f96dcSApple OSS Distributions
362*2c2f96dcSApple OSS Distributions info = (lockgroup_info_t *)addr;
363*2c2f96dcSApple OSS Distributions
364*2c2f96dcSApple OSS Distributions lck_grp_foreach(^bool (lck_grp_t *grp) {
365*2c2f96dcSApple OSS Distributions info[count].lock_spin_cnt = grp->lck_grp_spincnt;
366*2c2f96dcSApple OSS Distributions info[count].lock_rw_cnt = grp->lck_grp_rwcnt;
367*2c2f96dcSApple OSS Distributions info[count].lock_mtx_cnt = grp->lck_grp_mtxcnt;
368*2c2f96dcSApple OSS Distributions
369*2c2f96dcSApple OSS Distributions #if CONFIG_DTRACE
370*2c2f96dcSApple OSS Distributions info[count].lock_spin_held_cnt = grp->lck_grp_stats.lgss_spin_held.lgs_count;
371*2c2f96dcSApple OSS Distributions info[count].lock_spin_miss_cnt = grp->lck_grp_stats.lgss_spin_miss.lgs_count;
372*2c2f96dcSApple OSS Distributions
373*2c2f96dcSApple OSS Distributions // Historically on x86, held was used for "direct wait" and util for "held"
374*2c2f96dcSApple OSS Distributions info[count].lock_mtx_util_cnt = grp->lck_grp_stats.lgss_mtx_held.lgs_count;
375*2c2f96dcSApple OSS Distributions info[count].lock_mtx_held_cnt = grp->lck_grp_stats.lgss_mtx_direct_wait.lgs_count;
376*2c2f96dcSApple OSS Distributions info[count].lock_mtx_miss_cnt = grp->lck_grp_stats.lgss_mtx_miss.lgs_count;
377*2c2f96dcSApple OSS Distributions info[count].lock_mtx_wait_cnt = grp->lck_grp_stats.lgss_mtx_wait.lgs_count;
378*2c2f96dcSApple OSS Distributions #endif /* CONFIG_DTRACE */
379*2c2f96dcSApple OSS Distributions
380*2c2f96dcSApple OSS Distributions memcpy(info[count].lockgroup_name, grp->lck_grp_name, LOCKGROUP_MAX_NAME);
381*2c2f96dcSApple OSS Distributions
382*2c2f96dcSApple OSS Distributions return ++count >= needed ? false : true;
383*2c2f96dcSApple OSS Distributions });
384*2c2f96dcSApple OSS Distributions
385*2c2f96dcSApple OSS Distributions /*
386*2c2f96dcSApple OSS Distributions * We might have found less groups than `needed`
387*2c2f96dcSApple OSS Distributions * get rid of the excess now:
388*2c2f96dcSApple OSS Distributions * - [0, used) is what we want to return
389*2c2f96dcSApple OSS Distributions * - [0, size) is what we allocated
390*2c2f96dcSApple OSS Distributions */
391*2c2f96dcSApple OSS Distributions used = count * sizeof(lockgroup_info_t);
392*2c2f96dcSApple OSS Distributions vmused = vm_map_round_page(used, VM_MAP_PAGE_MASK(ipc_kernel_map));
393*2c2f96dcSApple OSS Distributions
394*2c2f96dcSApple OSS Distributions if (vmused < vmsize) {
395*2c2f96dcSApple OSS Distributions kmem_free(ipc_kernel_map, addr + vmused, vmsize - vmused);
396*2c2f96dcSApple OSS Distributions }
397*2c2f96dcSApple OSS Distributions
398*2c2f96dcSApple OSS Distributions kr = vm_map_unwire(ipc_kernel_map, addr, addr + vmused, FALSE);
399*2c2f96dcSApple OSS Distributions assert(kr == KERN_SUCCESS);
400*2c2f96dcSApple OSS Distributions
401*2c2f96dcSApple OSS Distributions kr = vm_map_copyin(ipc_kernel_map, addr, used, TRUE, ©);
402*2c2f96dcSApple OSS Distributions assert(kr == KERN_SUCCESS);
403*2c2f96dcSApple OSS Distributions
404*2c2f96dcSApple OSS Distributions *lockgroup_infop = (lockgroup_info_t *)copy;
405*2c2f96dcSApple OSS Distributions *lockgroup_infoCntp = count;
406*2c2f96dcSApple OSS Distributions
407*2c2f96dcSApple OSS Distributions return KERN_SUCCESS;
408*2c2f96dcSApple OSS Distributions }
409*2c2f96dcSApple OSS Distributions
410*2c2f96dcSApple OSS Distributions #pragma mark lock attributes
411*2c2f96dcSApple OSS Distributions
412*2c2f96dcSApple OSS Distributions __startup_func
413*2c2f96dcSApple OSS Distributions void
lck_attr_startup_init(struct lck_attr_startup_spec * sp)414*2c2f96dcSApple OSS Distributions lck_attr_startup_init(struct lck_attr_startup_spec *sp)
415*2c2f96dcSApple OSS Distributions {
416*2c2f96dcSApple OSS Distributions lck_attr_t *attr = sp->lck_attr;
417*2c2f96dcSApple OSS Distributions lck_attr_setdefault(attr);
418*2c2f96dcSApple OSS Distributions attr->lck_attr_val |= sp->lck_attr_set_flags;
419*2c2f96dcSApple OSS Distributions attr->lck_attr_val &= ~sp->lck_attr_clear_flags;
420*2c2f96dcSApple OSS Distributions }
421*2c2f96dcSApple OSS Distributions
422*2c2f96dcSApple OSS Distributions lck_attr_t *
lck_attr_alloc_init(void)423*2c2f96dcSApple OSS Distributions lck_attr_alloc_init(void)
424*2c2f96dcSApple OSS Distributions {
425*2c2f96dcSApple OSS Distributions lck_attr_t *attr;
426*2c2f96dcSApple OSS Distributions
427*2c2f96dcSApple OSS Distributions attr = zalloc(KT_LCK_ATTR);
428*2c2f96dcSApple OSS Distributions lck_attr_setdefault(attr);
429*2c2f96dcSApple OSS Distributions return attr;
430*2c2f96dcSApple OSS Distributions }
431*2c2f96dcSApple OSS Distributions
432*2c2f96dcSApple OSS Distributions
433*2c2f96dcSApple OSS Distributions void
lck_attr_setdefault(lck_attr_t * attr)434*2c2f96dcSApple OSS Distributions lck_attr_setdefault(lck_attr_t *attr)
435*2c2f96dcSApple OSS Distributions {
436*2c2f96dcSApple OSS Distributions attr->lck_attr_val = lck_attr_default.lck_attr_val;
437*2c2f96dcSApple OSS Distributions }
438*2c2f96dcSApple OSS Distributions
439*2c2f96dcSApple OSS Distributions
440*2c2f96dcSApple OSS Distributions void
lck_attr_setdebug(lck_attr_t * attr)441*2c2f96dcSApple OSS Distributions lck_attr_setdebug(lck_attr_t *attr)
442*2c2f96dcSApple OSS Distributions {
443*2c2f96dcSApple OSS Distributions os_atomic_or(&attr->lck_attr_val, LCK_ATTR_DEBUG, relaxed);
444*2c2f96dcSApple OSS Distributions }
445*2c2f96dcSApple OSS Distributions
446*2c2f96dcSApple OSS Distributions void
lck_attr_cleardebug(lck_attr_t * attr)447*2c2f96dcSApple OSS Distributions lck_attr_cleardebug(lck_attr_t *attr)
448*2c2f96dcSApple OSS Distributions {
449*2c2f96dcSApple OSS Distributions os_atomic_andnot(&attr->lck_attr_val, LCK_ATTR_DEBUG, relaxed);
450*2c2f96dcSApple OSS Distributions }
451*2c2f96dcSApple OSS Distributions
452*2c2f96dcSApple OSS Distributions void
lck_attr_rw_shared_priority(lck_attr_t * attr)453*2c2f96dcSApple OSS Distributions lck_attr_rw_shared_priority(lck_attr_t *attr)
454*2c2f96dcSApple OSS Distributions {
455*2c2f96dcSApple OSS Distributions os_atomic_or(&attr->lck_attr_val, LCK_ATTR_RW_SHARED_PRIORITY, relaxed);
456*2c2f96dcSApple OSS Distributions }
457*2c2f96dcSApple OSS Distributions
458*2c2f96dcSApple OSS Distributions
459*2c2f96dcSApple OSS Distributions void
lck_attr_free(lck_attr_t * attr)460*2c2f96dcSApple OSS Distributions lck_attr_free(lck_attr_t *attr)
461*2c2f96dcSApple OSS Distributions {
462*2c2f96dcSApple OSS Distributions zfree(KT_LCK_ATTR, attr);
463*2c2f96dcSApple OSS Distributions }
464*2c2f96dcSApple OSS Distributions
465*2c2f96dcSApple OSS Distributions #pragma mark lock stat
466*2c2f96dcSApple OSS Distributions #if CONFIG_DTRACE
467*2c2f96dcSApple OSS Distributions
468*2c2f96dcSApple OSS Distributions void
lck_grp_stat_enable(lck_grp_stat_t * stat)469*2c2f96dcSApple OSS Distributions lck_grp_stat_enable(lck_grp_stat_t *stat)
470*2c2f96dcSApple OSS Distributions {
471*2c2f96dcSApple OSS Distributions /* callers ensure this is properly synchronized */
472*2c2f96dcSApple OSS Distributions stat->lgs_enablings++;
473*2c2f96dcSApple OSS Distributions }
474*2c2f96dcSApple OSS Distributions
475*2c2f96dcSApple OSS Distributions void
lck_grp_stat_disable(lck_grp_stat_t * stat)476*2c2f96dcSApple OSS Distributions lck_grp_stat_disable(lck_grp_stat_t *stat)
477*2c2f96dcSApple OSS Distributions {
478*2c2f96dcSApple OSS Distributions stat->lgs_enablings--;
479*2c2f96dcSApple OSS Distributions }
480*2c2f96dcSApple OSS Distributions
481*2c2f96dcSApple OSS Distributions bool
lck_grp_stat_enabled(lck_grp_stat_t * stat)482*2c2f96dcSApple OSS Distributions lck_grp_stat_enabled(lck_grp_stat_t *stat)
483*2c2f96dcSApple OSS Distributions {
484*2c2f96dcSApple OSS Distributions return stat->lgs_enablings != 0;
485*2c2f96dcSApple OSS Distributions }
486*2c2f96dcSApple OSS Distributions
487*2c2f96dcSApple OSS Distributions
488*2c2f96dcSApple OSS Distributions __attribute__((always_inline))
489*2c2f96dcSApple OSS Distributions void
lck_grp_stat_inc(lck_grp_t * grp,lck_grp_stat_t * stat,bool always)490*2c2f96dcSApple OSS Distributions lck_grp_stat_inc(lck_grp_t *grp, lck_grp_stat_t *stat, bool always)
491*2c2f96dcSApple OSS Distributions {
492*2c2f96dcSApple OSS Distributions #pragma unused(grp)
493*2c2f96dcSApple OSS Distributions if (always || lck_grp_stat_enabled(stat)) {
494*2c2f96dcSApple OSS Distributions __unused uint64_t val = os_atomic_inc_orig(&stat->lgs_count, relaxed);
495*2c2f96dcSApple OSS Distributions if (__improbable(stat->lgs_limit && (val % (stat->lgs_limit)) == 0)) {
496*2c2f96dcSApple OSS Distributions lockprof_probe(grp, stat, val);
497*2c2f96dcSApple OSS Distributions }
498*2c2f96dcSApple OSS Distributions }
499*2c2f96dcSApple OSS Distributions }
500*2c2f96dcSApple OSS Distributions
501*2c2f96dcSApple OSS Distributions #if LOCK_STATS
502*2c2f96dcSApple OSS Distributions
503*2c2f96dcSApple OSS Distributions static inline void
lck_grp_inc_time_stats(lck_grp_t * grp,lck_grp_stat_t * stat,uint64_t time)504*2c2f96dcSApple OSS Distributions lck_grp_inc_time_stats(lck_grp_t *grp, lck_grp_stat_t *stat, uint64_t time)
505*2c2f96dcSApple OSS Distributions {
506*2c2f96dcSApple OSS Distributions if (lck_grp_stat_enabled(stat)) {
507*2c2f96dcSApple OSS Distributions __unused uint64_t val = os_atomic_add_orig(&stat->lgs_count, time, relaxed);
508*2c2f96dcSApple OSS Distributions if (__improbable(stat->lgs_limit)) {
509*2c2f96dcSApple OSS Distributions while (__improbable(time > stat->lgs_limit)) {
510*2c2f96dcSApple OSS Distributions time -= stat->lgs_limit;
511*2c2f96dcSApple OSS Distributions lockprof_probe(grp, stat, val);
512*2c2f96dcSApple OSS Distributions }
513*2c2f96dcSApple OSS Distributions if (__improbable(((val % stat->lgs_limit) + time) > stat->lgs_limit)) {
514*2c2f96dcSApple OSS Distributions lockprof_probe(grp, stat, val);
515*2c2f96dcSApple OSS Distributions }
516*2c2f96dcSApple OSS Distributions }
517*2c2f96dcSApple OSS Distributions }
518*2c2f96dcSApple OSS Distributions }
519*2c2f96dcSApple OSS Distributions
520*2c2f96dcSApple OSS Distributions void
__lck_grp_spin_update_held(lck_grp_t * grp)521*2c2f96dcSApple OSS Distributions __lck_grp_spin_update_held(lck_grp_t *grp)
522*2c2f96dcSApple OSS Distributions {
523*2c2f96dcSApple OSS Distributions if (grp) {
524*2c2f96dcSApple OSS Distributions lck_grp_stat_inc(grp, &grp->lck_grp_stats.lgss_spin_held, false);
525*2c2f96dcSApple OSS Distributions }
526*2c2f96dcSApple OSS Distributions }
527*2c2f96dcSApple OSS Distributions
528*2c2f96dcSApple OSS Distributions void
__lck_grp_spin_update_miss(lck_grp_t * grp)529*2c2f96dcSApple OSS Distributions __lck_grp_spin_update_miss(lck_grp_t *grp)
530*2c2f96dcSApple OSS Distributions {
531*2c2f96dcSApple OSS Distributions if (grp) {
532*2c2f96dcSApple OSS Distributions lck_grp_stat_inc(grp, &grp->lck_grp_stats.lgss_spin_miss, false);
533*2c2f96dcSApple OSS Distributions }
534*2c2f96dcSApple OSS Distributions }
535*2c2f96dcSApple OSS Distributions
536*2c2f96dcSApple OSS Distributions void
__lck_grp_spin_update_spin(lck_grp_t * grp,uint64_t time)537*2c2f96dcSApple OSS Distributions __lck_grp_spin_update_spin(lck_grp_t *grp, uint64_t time)
538*2c2f96dcSApple OSS Distributions {
539*2c2f96dcSApple OSS Distributions if (grp) {
540*2c2f96dcSApple OSS Distributions lck_grp_stat_t *stat = &grp->lck_grp_stats.lgss_spin_spin;
541*2c2f96dcSApple OSS Distributions lck_grp_inc_time_stats(grp, stat, time);
542*2c2f96dcSApple OSS Distributions }
543*2c2f96dcSApple OSS Distributions }
544*2c2f96dcSApple OSS Distributions
545*2c2f96dcSApple OSS Distributions void
__lck_grp_ticket_update_held(lck_grp_t * grp)546*2c2f96dcSApple OSS Distributions __lck_grp_ticket_update_held(lck_grp_t *grp)
547*2c2f96dcSApple OSS Distributions {
548*2c2f96dcSApple OSS Distributions if (grp) {
549*2c2f96dcSApple OSS Distributions lck_grp_stat_inc(grp, &grp->lck_grp_stats.lgss_ticket_held, false);
550*2c2f96dcSApple OSS Distributions }
551*2c2f96dcSApple OSS Distributions }
552*2c2f96dcSApple OSS Distributions
553*2c2f96dcSApple OSS Distributions void
__lck_grp_ticket_update_miss(lck_grp_t * grp)554*2c2f96dcSApple OSS Distributions __lck_grp_ticket_update_miss(lck_grp_t *grp)
555*2c2f96dcSApple OSS Distributions {
556*2c2f96dcSApple OSS Distributions if (grp) {
557*2c2f96dcSApple OSS Distributions lck_grp_stat_inc(grp, &grp->lck_grp_stats.lgss_ticket_miss, false);
558*2c2f96dcSApple OSS Distributions }
559*2c2f96dcSApple OSS Distributions }
560*2c2f96dcSApple OSS Distributions
561*2c2f96dcSApple OSS Distributions void
__lck_grp_ticket_update_spin(lck_grp_t * grp,uint64_t time)562*2c2f96dcSApple OSS Distributions __lck_grp_ticket_update_spin(lck_grp_t *grp, uint64_t time)
563*2c2f96dcSApple OSS Distributions {
564*2c2f96dcSApple OSS Distributions if (grp) {
565*2c2f96dcSApple OSS Distributions lck_grp_stat_t *stat = &grp->lck_grp_stats.lgss_ticket_spin;
566*2c2f96dcSApple OSS Distributions lck_grp_inc_time_stats(grp, stat, time);
567*2c2f96dcSApple OSS Distributions }
568*2c2f96dcSApple OSS Distributions }
569*2c2f96dcSApple OSS Distributions
570*2c2f96dcSApple OSS Distributions #endif /* LOCK_STATS */
571*2c2f96dcSApple OSS Distributions
572*2c2f96dcSApple OSS Distributions void
lck_mtx_time_stat_record(enum lockstat_probe_id pid,lck_mtx_t * mtx,uint32_t grp_attr_id,uint64_t start)573*2c2f96dcSApple OSS Distributions lck_mtx_time_stat_record(
574*2c2f96dcSApple OSS Distributions enum lockstat_probe_id pid,
575*2c2f96dcSApple OSS Distributions lck_mtx_t *mtx,
576*2c2f96dcSApple OSS Distributions uint32_t grp_attr_id,
577*2c2f96dcSApple OSS Distributions uint64_t start)
578*2c2f96dcSApple OSS Distributions {
579*2c2f96dcSApple OSS Distributions uint32_t id = lockstat_probemap[pid];
580*2c2f96dcSApple OSS Distributions
581*2c2f96dcSApple OSS Distributions if (__improbable(start && id)) {
582*2c2f96dcSApple OSS Distributions uint64_t delta = ml_get_timebase() - start;
583*2c2f96dcSApple OSS Distributions lck_grp_t *grp = lck_grp_resolve(grp_attr_id);
584*2c2f96dcSApple OSS Distributions
585*2c2f96dcSApple OSS Distributions #if __x86_64__
586*2c2f96dcSApple OSS Distributions delta = tmrCvt(delta, tscFCvtt2n);
587*2c2f96dcSApple OSS Distributions #endif
588*2c2f96dcSApple OSS Distributions dtrace_probe(id, (uintptr_t)mtx, delta, (uintptr_t)grp, 0, 0);
589*2c2f96dcSApple OSS Distributions }
590*2c2f96dcSApple OSS Distributions }
591*2c2f96dcSApple OSS Distributions
592*2c2f96dcSApple OSS Distributions #endif /* CONFIG_DTRACE */
593