xref: /xnu-10002.1.13/osfmk/kern/lock_mtx.h (revision 1031c584a5e37aff177559b9f69dbd3c8c3fd30a)
1 /*
2  * Copyright (c) 2022 Apple 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 
29 #ifndef _KERN_LOCK_MTX_H_
30 #define _KERN_LOCK_MTX_H_
31 
32 #include <kern/lock_types.h>
33 #include <kern/lock_group.h>
34 #include <kern/lock_attr.h>
35 
36 #ifdef  XNU_KERNEL_PRIVATE
37 #include <kern/startup.h>
38 #endif /* XNU_KERNEL_PRIVATE */
39 
40 __BEGIN_DECLS
41 
42 #if MACH_KERNEL_PRIVATE
43 #if !LCK_MTX_USE_ARCH
44 
45 typedef union lck_mtx_state {
46 	struct {
47 		uint32_t        owner        : 28;
48 		uint32_t        ilocked      :  1;
49 		uint32_t        spin_mode    :  1;
50 		uint32_t        needs_wakeup :  1;
51 		uint32_t        profile      :  1;
52 #define LCK_MTX_CTID_MASK       0x0fffffffu
53 #define LCK_MTX_BITS_MASK       0xf0000000u
54 #define LCK_MTX_ILOCK           0x10000000u
55 #define LCK_MTX_SPIN_MODE       0x20000000u
56 #define LCK_MTX_NEEDS_WAKEUP    0x40000000u
57 #if CONFIG_DTRACE
58 #define LCK_MTX_PROFILE         0x80000000u
59 #else
60 #define LCK_MTX_PROFILE         0x00000000u
61 #endif
62 		uint16_t        ilk_tail;
63 		uint16_t        as_tail;
64 	};
65 	uint32_t                data;
66 	uint64_t                val;
67 } lck_mtx_state_t;
68 
69 typedef struct _lck_mtx_ {
70 	uint32_t                lck_mtx_tsid : 24;      /* turnstile ID */
71 	uint8_t                 lck_mtx_type :  8;      /* Type */
72 	uint32_t                lck_mtx_grp;
73 	lck_mtx_state_t         lck_mtx;
74 } lck_mtx_t;
75 
76 /* lock marked as destroyed, sets ILOCK | WAITERS */
77 #define LCK_MTX_TAG_DESTROYED   0xf0fe2007
78 
79 /*
80  * for historical reasons the lck_mtx_t definition for the KDK
81  * are in <machine/locks.h> headers.
82  */
83 #endif /* !LCK_MTX_USE_ARCH */
84 #endif
85 
86 #define decl_lck_mtx_data(class, name)     class lck_mtx_t name
87 
88 extern lck_mtx_t        *lck_mtx_alloc_init(
89 	lck_grp_t               *grp,
90 	lck_attr_t              *attr);
91 
92 extern void             lck_mtx_init(
93 	lck_mtx_t               *lck,
94 	lck_grp_t               *grp,
95 	lck_attr_t              *attr);
96 extern void             lck_mtx_lock(
97 	lck_mtx_t               *lck);
98 
99 extern void             lck_mtx_unlock(
100 	lck_mtx_t               *lck);
101 
102 extern void             lck_mtx_destroy(
103 	lck_mtx_t               *lck,
104 	lck_grp_t               *grp);
105 
106 extern void             lck_mtx_free(
107 	lck_mtx_t               *lck,
108 	lck_grp_t               *grp);
109 
110 extern wait_result_t    lck_mtx_sleep(
111 	lck_mtx_t               *lck,
112 	lck_sleep_action_t      lck_sleep_action,
113 	event_t                 event,
114 	wait_interrupt_t        interruptible);
115 
116 extern wait_result_t    lck_mtx_sleep_deadline(
117 	lck_mtx_t               *lck,
118 	lck_sleep_action_t      lck_sleep_action,
119 	event_t                 event,
120 	wait_interrupt_t        interruptible,
121 	uint64_t                deadline);
122 
123 #define LCK_MTX_ASSERT_OWNED    LCK_ASSERT_OWNED
124 #define LCK_MTX_ASSERT_NOTOWNED LCK_ASSERT_NOTOWNED
125 
126 extern void             lck_mtx_assert(
127 	lck_mtx_t               *lck,
128 	unsigned                int    type);
129 
130 #if MACH_ASSERT
131 #define LCK_MTX_ASSERT(lck, type) lck_mtx_assert((lck),(type))
132 #else /* MACH_ASSERT */
133 #define LCK_MTX_ASSERT(lck, type)
134 #endif /* MACH_ASSERT */
135 
136 #if DEBUG
137 #define LCK_MTX_ASSERT_DEBUG(lck, type) lck_mtx_assert((lck),(type))
138 #else /* DEBUG */
139 #define LCK_MTX_ASSERT_DEBUG(lck, type)
140 #endif /* DEBUG */
141 
142 #if KERNEL_PRIVATE
143 
144 extern boolean_t        lck_mtx_try_lock(
145 	lck_mtx_t               *lck);
146 
147 extern void             mutex_pause(uint32_t);
148 
149 extern boolean_t        lck_mtx_yield(
150 	lck_mtx_t               *lck);
151 
152 extern boolean_t        lck_mtx_try_lock_spin(
153 	lck_mtx_t               *lck);
154 
155 extern void             lck_mtx_lock_spin(
156 	lck_mtx_t               *lck);
157 
158 extern boolean_t        kdp_lck_mtx_lock_spin_is_acquired(
159 	lck_mtx_t               *lck);
160 
161 extern void             lck_mtx_convert_spin(
162 	lck_mtx_t               *lck);
163 
164 extern void             lck_mtx_lock_spin_always(
165 	lck_mtx_t               *lck);
166 
167 extern boolean_t        lck_mtx_try_lock_spin_always(
168 	lck_mtx_t               *lck);
169 
170 #define lck_mtx_unlock_always(l)        lck_mtx_unlock(l)
171 
172 #endif /* KERNEL_PRIVATE */
173 #if  XNU_KERNEL_PRIVATE
174 
175 struct lck_mtx_startup_spec {
176 	lck_mtx_t               *lck;
177 	lck_grp_t               *lck_grp;
178 	lck_attr_t              *lck_attr;
179 };
180 
181 extern void             lck_mtx_startup_init(
182 	struct lck_mtx_startup_spec *spec);
183 
184 #define LCK_MTX_DECLARE_ATTR(var, grp, attr) \
185 	lck_mtx_t var; \
186 	static __startup_data struct lck_mtx_startup_spec \
187 	__startup_lck_mtx_spec_ ## var = { &var, grp, attr }; \
188 	STARTUP_ARG(LOCKS, STARTUP_RANK_FOURTH, lck_mtx_startup_init, \
189 	    &__startup_lck_mtx_spec_ ## var)
190 
191 #define LCK_MTX_DECLARE(var, grp) \
192 	LCK_MTX_DECLARE_ATTR(var, grp, LCK_ATTR_NULL)
193 
194 #endif /* XNU_KERNEL_PRIVATE */
195 
196 __END_DECLS
197 
198 #endif /* _KERN_LOCK_RW_H_ */
199