/// A typed DRM device with a specific `drm::Driver` implementation. /// /// The device is always reference-counted. /// /// # Invariants /// /// `self.dev` is a valid instance of a `struct device`. #[repr(C)] pubstruct Device<T: drm::Driver> {
dev: Opaque<bindings::drm_device>,
data: T::Data,
}
/// Create a new `drm::Device` for a `drm::Driver`. pubfn new(dev: &device::Device, data: impl PinInit<T::Data, Error>) -> Result<ARef<Self>> { // `__drm_dev_alloc` uses `kmalloc()` to allocate memory, hence ensure a `kmalloc()` // compatible `Layout`. let layout = Kmalloc::aligned_layout(Layout::new::<Self>());
// SAFETY: // - `VTABLE`, as a `const` is pinned to the read-only section of the compilation, // - `dev` is valid by its type invarants, let raw_drm: *mutSelf = unsafe {
bindings::__drm_dev_alloc(
dev.as_raw(),
&Self::VTABLE,
layout.size(),
mem::offset_of!(Self, dev),
)
}
.cast(); let raw_drm = NonNull::new(from_err_ptr(raw_drm)?).ok_or(ENOMEM)?;
// SAFETY: `raw_drm` is a valid pointer to `Self`. let raw_data = unsafe { ptr::addr_of_mut!((*raw_drm.as_ptr()).data) };
// SAFETY: // - `raw_data` is a valid pointer to uninitialized memory. // - `raw_data` will not move until it is dropped. unsafe { data.__pinned_init(raw_data) }.inspect_err(|_| { // SAFETY: `raw_drm` is a valid pointer to `Self`, given that `__drm_dev_alloc` was // successful. let drm_dev = unsafe { Self::into_drm_device(raw_drm) };
// SAFETY: `__drm_dev_alloc()` was successful, hence `drm_dev` must be valid and the // refcount must be non-zero. unsafe { bindings::drm_dev_put(drm_dev) };
})?;
// SAFETY: The reference count is one, and now we take ownership of that reference as a // `drm::Device`.
Ok(unsafe { ARef::from_raw(raw_drm) })
}
/// # Safety /// /// `ptr` must be a valid pointer to a `struct device` embedded in `Self`. unsafefn from_drm_device(ptr: *const bindings::drm_device) -> *mutSelf { // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a // `struct drm_device` embedded in `Self`. unsafe { crate::container_of!(Opaque::cast_from(ptr), Self, dev) }.cast_mut()
}
/// # Safety /// /// `ptr` must be a valid pointer to `Self`. unsafefn into_drm_device(ptr: NonNull<Self>) -> *mut bindings::drm_device { // SAFETY: By the safety requirements of this function, `ptr` is a valid pointer to `Self`. unsafe { &raw mut (*ptr.as_ptr()).dev }.cast()
}
/// Not intended to be called externally, except via declare_drm_ioctls!() /// /// # Safety /// /// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count, /// i.e. it must be ensured that the reference count of the C `struct drm_device` `ptr` points /// to can't drop to zero, for the duration of this function call and the entire duration when /// the returned reference exists. /// /// Additionally, callers must ensure that the `struct device`, `ptr` is pointing to, is /// embedded in `Self`. #[doc(hidden)] pubunsafefn from_raw<'a>(ptr: *const bindings::drm_device) -> &'a Self { // SAFETY: By the safety requirements of this function `ptr` is a valid pointer to a // `struct drm_device` embedded in `Self`. let ptr = unsafe { Self::from_drm_device(ptr) };
// SAFETY: `ptr` is valid by the safety requirements of this function. unsafe { &*ptr.cast() }
}
extern"C"fn release(ptr: *mut bindings::drm_device) { // SAFETY: `ptr` is a valid pointer to a `struct drm_device` and embedded in `Self`. let this = unsafe { Self::from_drm_device(ptr) };
// SAFETY: // - When `release` runs it is guaranteed that there is no further access to `this`. // - `this` is valid for dropping. unsafe { core::ptr::drop_in_place(this) };
}
}
impl<T: drm::Driver> Deref for Device<T> { type Target = T::Data;
fn deref(&self) -> &Self::Target {
&self.data
}
}
// SAFETY: DRM device objects are always reference counted and the get/put functions // satisfy the requirements. unsafeimpl<T: drm::Driver> AlwaysRefCounted for Device<T> { fn inc_ref(&self) { // SAFETY: The existence of a shared reference guarantees that the refcount is non-zero. unsafe { bindings::drm_dev_get(self.as_raw()) };
}
unsafefn dec_ref(obj: NonNull<Self>) { // SAFETY: `obj` is a valid pointer to `Self`. let drm_dev = unsafe { Self::into_drm_device(obj) };
// SAFETY: The safety requirements guarantee that the refcount is non-zero. unsafe { bindings::drm_dev_put(drm_dev) };
}
}
impl<T: drm::Driver> AsRef<device::Device> for Device<T> { fn as_ref(&self) -> &device::Device { // SAFETY: `bindings::drm_device::dev` is valid as long as the DRM device itself is valid, // which is guaranteed by the type invariant. unsafe { device::Device::from_raw((*self.as_raw()).dev) }
}
}
// SAFETY: A `drm::Device` can be released from any thread. unsafeimpl<T: drm::Driver> Send for Device<T> {}
// SAFETY: A `drm::Device` can be shared among threads because all immutable methods are protected // by the synchronization in `struct drm_device`. unsafeimpl<T: drm::Driver> Sync for Device<T> {}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-17)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.