Skip to main content

lockdep/
lib.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#![no_std]
6
7// Keep dependency alive even when lockdep is disabled to satisfy unused dependency lints.
8use zr as _;
9
10/// Trait implemented by lock class types to expose their dynamic LockClassId pointer.
11pub trait LockClass {
12    const ID: *mut core::ffi::c_void;
13}
14
15#[cfg(any(feature = "lock_dep", feature = "lock_metadata_only"))]
16mod enabled {
17    core::cfg_select! {
18        feature = "lock_dep" => {
19            const LOCK_CLASS_STATE_SIZE: usize = 1608;
20            const LOCK_CLASS_REGISTRATION_SIZE: usize = 1624;
21        }
22        feature = "lock_metadata_only" => {
23            const LOCK_CLASS_STATE_SIZE: usize = 8;
24            const LOCK_CLASS_REGISTRATION_SIZE: usize = 24;
25        }
26    }
27
28    #[repr(C, align(8))]
29    #[derive(Default)]
30    struct LockClassStateStorage(zr::OpaqueBytes<LOCK_CLASS_STATE_SIZE>);
31
32    impl LockClassStateStorage {
33        const fn uninit() -> Self {
34            Self(zr::OpaqueBytes::uninit())
35        }
36    }
37
38    /// A registration entry for a Rust lock class.
39    ///
40    /// This struct is registered with the C++ lockdep implementation via a linker section. The
41    /// layout of this struct is known to C++.
42    #[repr(C)]
43    pub struct LockClassRegistration {
44        name: *const kstring::interned_string::InternedString,
45        flags: u16,
46        state_storage: LockClassStateStorage,
47    }
48
49    unsafe impl Sync for LockClassRegistration {}
50    unsafe impl Send for LockClassRegistration {}
51
52    impl LockClassRegistration {
53        pub const fn new(name: &'static ::kstring::interned_string::InternedString) -> Self {
54            Self { name, flags: 0, state_storage: LockClassStateStorage::uninit() }
55        }
56
57        pub const fn with_flags(
58            name: &'static ::kstring::interned_string::InternedString,
59            flags: u16,
60        ) -> Self {
61            Self { name, flags, state_storage: LockClassStateStorage::uninit() }
62        }
63
64        #[inline]
65        pub const fn get(&self) -> *mut core::ffi::c_void {
66            self.state_storage.0.get() as *mut _
67        }
68    }
69
70    zr::static_assert!(
71        core::mem::size_of::<LockClassRegistration>() == LOCK_CLASS_REGISTRATION_SIZE
72    );
73    zr::static_assert!(core::mem::align_of::<LockClassRegistration>() == 8);
74}
75
76#[cfg(any(feature = "lock_dep", feature = "lock_metadata_only"))]
77pub use enabled::LockClassRegistration;
78
79#[cfg(not(any(feature = "lock_dep", feature = "lock_metadata_only")))]
80mod disabled {
81    /// A registration entry for a Rust lock class (stub for disabled lockdep).
82    pub struct LockClassRegistration;
83
84    impl LockClassRegistration {
85        pub const fn new(_name: &'static ::kstring::interned_string::InternedString) -> Self {
86            Self
87        }
88
89        pub const fn with_flags(
90            _name: &'static ::kstring::interned_string::InternedString,
91            _flags: u16,
92        ) -> Self {
93            Self
94        }
95
96        #[inline]
97        pub const fn get(&self) -> *mut core::ffi::c_void {
98            core::ptr::null_mut()
99        }
100    }
101}
102
103#[cfg(not(any(feature = "lock_dep", feature = "lock_metadata_only")))]
104pub use disabled::LockClassRegistration;