1use crate::raw_lock::{ConstRawLock, ExclusiveLockPolicy, LockPolicy, RawLock};
6use core::ffi::c_void;
7use core::marker::PhantomData;
8use pin_init::{PinInit, pin_data, pin_init};
9
10#[cfg(feature = "lock_dep")]
11unsafe extern "C" {
12 fn cpp_lock_dep_acquire(
13 lock: *mut c_void,
14 class_id: *const c_void,
15 entry_storage: *mut c_void,
16 flags: lockdep::LockFlags,
17 );
18 fn cpp_lock_dep_release(entry_storage: *mut c_void, flags: lockdep::LockFlags);
19 fn cpp_lock_validate_release(entry_storage: *mut c_void, flags: lockdep::LockFlags);
20 fn cpp_lock_validate_acquire(entry_storage: *mut c_void, flags: lockdep::LockFlags);
21}
22
23#[cfg(feature = "lock_dep")]
25#[derive(Default)]
26#[repr(C, align(8))]
27struct LockEntryStorage(zr::OpaqueBytes<40>);
28
29#[derive(Default)]
32#[repr(C)]
33pub struct LockdepTrackedGuardState<S> {
34 #[cfg(feature = "lock_dep")]
35 entry: LockEntryStorage,
36 state: S,
37}
38
39#[pin_data]
41#[repr(C)]
42pub struct LockdepTracked<
43 L: RawLock,
44 P = <L as RawLock>::DefaultPolicy,
45 const LOCK_FLAGS: lockdep::LockFlags = { lockdep::LOCK_FLAGS_NONE },
46> {
47 #[cfg(any(feature = "lock_dep", feature = "lock_metadata_only"))]
48 class_id: *const c_void,
49 #[pin]
50 lock: L,
51 _policy: PhantomData<P>,
52}
53
54impl<L: RawLock, P, const LOCK_FLAGS: lockdep::LockFlags> LockdepTracked<L, P, LOCK_FLAGS> {
55 pub const LOCK_FLAGS: lockdep::LockFlags = LOCK_FLAGS;
57}
58
59impl<L: ConstRawLock, P, const LOCK_FLAGS: lockdep::LockFlags> LockdepTracked<L, P, LOCK_FLAGS> {
60 #[allow(clippy::declare_interior_mutable_const)]
61 pub const INIT: Self = Self::const_init(core::ptr::null());
62
63 pub const fn const_init(_class_id: *const c_void) -> Self {
65 Self {
66 #[cfg(any(feature = "lock_dep", feature = "lock_metadata_only"))]
67 class_id: _class_id,
68 lock: L::INIT,
69 _policy: PhantomData,
70 }
71 }
72}
73
74impl<L: ConstRawLock, P, const LOCK_FLAGS: lockdep::LockFlags> Default
75 for LockdepTracked<L, P, LOCK_FLAGS>
76{
77 fn default() -> Self {
78 Self::INIT
79 }
80}
81
82impl<L: RawLock, P, const LOCK_FLAGS: lockdep::LockFlags> core::ops::Deref
83 for LockdepTracked<L, P, LOCK_FLAGS>
84{
85 type Target = L;
86
87 #[inline]
88 fn deref(&self) -> &Self::Target {
89 &self.lock
90 }
91}
92
93unsafe impl<L: RawLock + Sync, P, const LOCK_FLAGS: lockdep::LockFlags> Sync
95 for LockdepTracked<L, P, LOCK_FLAGS>
96{
97}
98unsafe impl<L: RawLock + Send, P, const LOCK_FLAGS: lockdep::LockFlags> Send
100 for LockdepTracked<L, P, LOCK_FLAGS>
101{
102}
103
104unsafe impl<
107 L: RawLock,
108 P: LockPolicy<L>,
109 LP: ExclusiveLockPolicy<L>,
110 const LOCK_FLAGS: lockdep::LockFlags,
111> LockPolicy<LockdepTracked<L, LP, LOCK_FLAGS>> for LockdepTracked<L, P, LOCK_FLAGS>
112{
113 type AcquireArgs = P::AcquireArgs;
114 type GuardState = LockdepTrackedGuardState<P::GuardState>;
115
116 #[inline]
117 unsafe fn pre_validate(
118 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
119 state: &mut Self::GuardState,
120 args: Self::AcquireArgs,
121 ) {
122 unsafe {
124 P::pre_validate(&lock.lock, &mut state.state, args);
125 }
126 }
127
128 #[inline]
129 unsafe fn pre_reacquire(
130 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
131 state: &mut Self::GuardState,
132 ) {
133 unsafe {
135 P::pre_reacquire(&lock.lock, &mut state.state);
136 }
137 }
138
139 #[inline]
140 unsafe fn acquire(
141 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
142 state: &mut Self::GuardState,
143 args: Self::AcquireArgs,
144 ) {
145 unsafe {
147 Self::pre_validate(lock, state, args);
148 Self::post_validate_acquire(lock, state, args);
149 }
150 }
151
152 #[inline]
153 unsafe fn post_validate_acquire(
154 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
155 state: &mut Self::GuardState,
156 args: Self::AcquireArgs,
157 ) {
158 #[cfg(feature = "lock_dep")]
159 unsafe {
162 cpp_lock_dep_acquire(
163 lock.lock.as_mut_ptr(),
164 lock.class_id,
165 state.entry.0.get() as *mut c_void,
166 LOCK_FLAGS,
167 );
168 }
169 unsafe {
171 P::post_validate_acquire(&lock.lock, &mut state.state, args);
172 }
173 }
174
175 #[inline]
176 unsafe fn reacquire(lock: &LockdepTracked<L, LP, LOCK_FLAGS>, state: &mut Self::GuardState) {
177 unsafe {
179 Self::pre_reacquire(lock, state);
180 Self::post_validate_reacquire(lock, state);
181 }
182 }
183
184 #[inline]
185 unsafe fn post_validate_reacquire(
186 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
187 state: &mut Self::GuardState,
188 ) {
189 #[cfg(feature = "lock_dep")]
190 unsafe {
193 cpp_lock_dep_acquire(
194 lock.lock.as_mut_ptr(),
195 lock.class_id,
196 state.entry.0.get() as *mut c_void,
197 LOCK_FLAGS,
198 );
199 }
200 unsafe {
202 P::post_validate_reacquire(&lock.lock, &mut state.state);
203 }
204 }
205
206 #[inline]
207 unsafe fn untrack(lock: &LockdepTracked<L, LP, LOCK_FLAGS>, state: &mut Self::GuardState) {
208 #[cfg(feature = "lock_dep")]
209 unsafe {
211 cpp_lock_validate_release(state.entry.0.get() as *mut c_void, LOCK_FLAGS);
212 }
213 unsafe {
215 P::untrack(&lock.lock, &mut state.state);
216 }
217 }
218
219 #[inline]
220 unsafe fn retrack(lock: &LockdepTracked<L, LP, LOCK_FLAGS>, state: &mut Self::GuardState) {
221 unsafe {
223 P::retrack(&lock.lock, &mut state.state);
224 }
225 #[cfg(feature = "lock_dep")]
226 unsafe {
228 cpp_lock_validate_acquire(state.entry.0.get() as *mut c_void, LOCK_FLAGS);
229 }
230 }
231
232 #[inline]
233 unsafe fn release(lock: &LockdepTracked<L, LP, LOCK_FLAGS>, state: &mut Self::GuardState) {
234 #[cfg(feature = "lock_dep")]
235 unsafe {
238 cpp_lock_dep_release(state.entry.0.get() as *mut c_void, LOCK_FLAGS);
239 }
240 unsafe {
242 P::release(&lock.lock, &mut state.state);
243 }
244 }
245}
246
247unsafe impl<
250 L: RawLock,
251 P: ExclusiveLockPolicy<L>,
252 LP: ExclusiveLockPolicy<L>,
253 const LOCK_FLAGS: lockdep::LockFlags,
254> ExclusiveLockPolicy<LockdepTracked<L, LP, LOCK_FLAGS>> for LockdepTracked<L, P, LOCK_FLAGS>
255{
256}
257
258#[cfg(feature = "kernel")]
262macro_rules! impl_lockdep_tracked_lock_policy {
263 ($policy:ty) => {
264 unsafe impl<
267 L: RawLock,
268 LP: $crate::ExclusiveLockPolicy<L>,
269 const LOCK_FLAGS: lockdep::LockFlags,
270 > LockPolicy<LockdepTracked<L, LP, LOCK_FLAGS>> for $policy
271 where
272 $policy: LockPolicy<L>,
273 {
274 type AcquireArgs = <$policy as LockPolicy<L>>::AcquireArgs;
275 type GuardState =
276 $crate::LockdepTrackedGuardState<<$policy as LockPolicy<L>>::GuardState>;
277
278 #[inline]
279 unsafe fn pre_validate(
280 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
281 state: &mut Self::GuardState,
282 args: Self::AcquireArgs,
283 ) {
284 unsafe {
286 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
287 LockdepTracked<L, LP, LOCK_FLAGS>,
288 >>::pre_validate(lock, state, args);
289 }
290 }
291
292 #[inline]
293 unsafe fn pre_reacquire(
294 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
295 state: &mut Self::GuardState,
296 ) {
297 unsafe {
299 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
300 LockdepTracked<L, LP, LOCK_FLAGS>,
301 >>::pre_reacquire(lock, state);
302 }
303 }
304
305 #[inline]
306 unsafe fn acquire(
307 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
308 state: &mut Self::GuardState,
309 args: Self::AcquireArgs,
310 ) {
311 unsafe {
313 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
314 LockdepTracked<L, LP, LOCK_FLAGS>,
315 >>::acquire(lock, state, args);
316 }
317 }
318
319 #[inline]
320 unsafe fn post_validate_acquire(
321 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
322 state: &mut Self::GuardState,
323 args: Self::AcquireArgs,
324 ) {
325 unsafe {
327 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
328 LockdepTracked<L, LP, LOCK_FLAGS>,
329 >>::post_validate_acquire(lock, state, args);
330 }
331 }
332
333 #[inline]
334 unsafe fn reacquire(
335 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
336 state: &mut Self::GuardState,
337 ) {
338 unsafe {
340 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
341 LockdepTracked<L, LP, LOCK_FLAGS>,
342 >>::reacquire(lock, state);
343 }
344 }
345
346 #[inline]
347 unsafe fn post_validate_reacquire(
348 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
349 state: &mut Self::GuardState,
350 ) {
351 unsafe {
353 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
354 LockdepTracked<L, LP, LOCK_FLAGS>,
355 >>::post_validate_reacquire(lock, state);
356 }
357 }
358
359 #[inline]
360 unsafe fn untrack(
361 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
362 state: &mut Self::GuardState,
363 ) {
364 unsafe {
366 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
367 LockdepTracked<L, LP, LOCK_FLAGS>,
368 >>::untrack(lock, state);
369 }
370 }
371
372 #[inline]
373 unsafe fn retrack(
374 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
375 state: &mut Self::GuardState,
376 ) {
377 unsafe {
379 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
380 LockdepTracked<L, LP, LOCK_FLAGS>,
381 >>::retrack(lock, state);
382 }
383 }
384
385 #[inline]
386 unsafe fn release(
387 lock: &LockdepTracked<L, LP, LOCK_FLAGS>,
388 state: &mut Self::GuardState,
389 ) {
390 unsafe {
392 <LockdepTracked<L, $policy, LOCK_FLAGS> as LockPolicy<
393 LockdepTracked<L, LP, LOCK_FLAGS>,
394 >>::release(lock, state);
395 }
396 }
397 }
398
399 unsafe impl<
402 L: RawLock,
403 LP: $crate::ExclusiveLockPolicy<L>,
404 const LOCK_FLAGS: lockdep::LockFlags,
405 > $crate::ExclusiveLockPolicy<LockdepTracked<L, LP, LOCK_FLAGS>> for $policy
406 where
407 $policy: $crate::ExclusiveLockPolicy<L>,
408 {
409 }
410 };
411}
412
413#[cfg(feature = "kernel")]
414pub(crate) use impl_lockdep_tracked_lock_policy;
415
416unsafe impl<L: RawLock, P: ExclusiveLockPolicy<L>, const LOCK_FLAGS: lockdep::LockFlags> RawLock
419 for LockdepTracked<L, P, LOCK_FLAGS>
420{
421 type DefaultPolicy = Self;
422
423 #[inline]
424 unsafe fn init(class_id: *const c_void) -> impl PinInit<Self, core::convert::Infallible> {
425 pin_init!(Self {
426 lock <- unsafe { L::init(class_id) },
428 #[cfg(any(feature = "lock_dep", feature = "lock_metadata_only"))]
429 class_id,
430 _policy: PhantomData,
431 })
432 }
433
434 #[inline]
435 fn as_mut_ptr(&self) -> *mut c_void {
436 self.lock.as_mut_ptr()
437 }
438}
439
440impl<L: ConstRawLock, P: ExclusiveLockPolicy<L>, const LOCK_FLAGS: lockdep::LockFlags> ConstRawLock
441 for LockdepTracked<L, P, LOCK_FLAGS>
442{
443 const INIT: Self = Self::INIT;
444}