Skip to content

Commit 56f551f

Browse files
wedsonafDarksonn
authored andcommitted
rust: add container_of! macro
This macro is used to obtain a pointer to an entire struct when given a pointer to a field in that struct. Signed-off-by: Wedson Almeida Filho <walmeida@microsoft.com> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
1 parent 7198693 commit 56f551f

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

Diff for: rust/kernel/lib.rs

+30
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,33 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
105105
// SAFETY: FFI call.
106106
unsafe { bindings::BUG() };
107107
}
108+
109+
/// Produces a pointer to an object from a pointer to one of its fields.
110+
///
111+
/// # Safety
112+
///
113+
/// The pointer passed to this macro, and the pointer returned by this macro, must both be in
114+
/// bounds of the same allocation.
115+
///
116+
/// # Examples
117+
///
118+
/// ```
119+
/// # use kernel::container_of;
120+
/// struct Test {
121+
/// a: u64,
122+
/// b: u32,
123+
/// }
124+
///
125+
/// let test = Test { a: 10, b: 20 };
126+
/// let b_ptr = &test.b;
127+
/// let test_alias = container_of!(b_ptr, Test, b);
128+
/// assert!(core::ptr::eq(&test, test_alias));
129+
/// ```
130+
#[macro_export]
131+
macro_rules! container_of {
132+
($ptr:expr, $type:ty, $($f:tt)*) => {{
133+
let ptr = $ptr as *const _ as *const u8;
134+
let offset: usize = ::core::mem::offset_of!($type, $($f)*);
135+
ptr.sub(offset) as *const $type
136+
}}
137+
}

0 commit comments

Comments
 (0)