mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 03:11:11 -04:00
rust: drm: Add gem::impl_aref_for_gem_obj!
In the future we're going to be introducing more GEM object types in rust then just gem::Object<T>. Since all types of GEM objects have refcounting, let's introduce a macro that we can use in the gem crate in order to copy this boilerplate implementation for each type: impl_aref_for_gem_obj!(). Signed-off-by: Lyude Paul <lyude@redhat.com> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> Reviewed-by: Janne Grunau <j@jananu.net> Tested-by: Deborah Brouwer <deborah.brouwer@collabora.com> Link: https://patch.msgid.link/20260316211646.650074-2-lyude@redhat.com [ Resolve merge conflicts. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
committed by
Danilo Krummrich
parent
dff8302ca1
commit
e64b9cc293
@@ -26,6 +26,41 @@
|
||||
ptr::NonNull, //
|
||||
};
|
||||
|
||||
/// A macro for implementing [`AlwaysRefCounted`] for any GEM object type.
|
||||
///
|
||||
/// Since all GEM objects use the same refcounting scheme.
|
||||
#[macro_export]
|
||||
macro_rules! impl_aref_for_gem_obj {
|
||||
(
|
||||
impl $( <$( $tparam_id:ident ),+> )? for $type:ty
|
||||
$(
|
||||
where
|
||||
$( $bind_param:path : $bind_trait:path ),+
|
||||
)?
|
||||
) => {
|
||||
// SAFETY: All GEM objects are refcounted.
|
||||
unsafe impl $( <$( $tparam_id ),+> )? $crate::types::AlwaysRefCounted for $type
|
||||
where
|
||||
Self: IntoGEMObject,
|
||||
$( $( $bind_param : $bind_trait ),+ )?
|
||||
{
|
||||
fn inc_ref(&self) {
|
||||
// SAFETY: The existence of a shared reference guarantees that the refcount is
|
||||
// non-zero.
|
||||
unsafe { bindings::drm_gem_object_get(self.as_raw()) };
|
||||
}
|
||||
|
||||
unsafe fn dec_ref(obj: core::ptr::NonNull<Self>) {
|
||||
// SAFETY: `obj` is a valid pointer to an `Object<T>`.
|
||||
let obj = unsafe { obj.as_ref() }.as_raw();
|
||||
|
||||
// SAFETY: The safety requirements guarantee that the refcount is non-zero.
|
||||
unsafe { bindings::drm_gem_object_put(obj) };
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// A type alias for retrieving a [`Driver`]s [`DriverFile`] implementation from its
|
||||
/// [`DriverObject`] implementation.
|
||||
///
|
||||
@@ -263,21 +298,7 @@ extern "C" fn free_callback(obj: *mut bindings::drm_gem_object) {
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: Instances of `Object<T>` are always reference-counted.
|
||||
unsafe impl<T: DriverObject> crate::sync::aref::AlwaysRefCounted for Object<T> {
|
||||
fn inc_ref(&self) {
|
||||
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
|
||||
unsafe { bindings::drm_gem_object_get(self.as_raw()) };
|
||||
}
|
||||
|
||||
unsafe fn dec_ref(obj: NonNull<Self>) {
|
||||
// SAFETY: `obj` is a valid pointer to an `Object<T>`.
|
||||
let obj = unsafe { obj.as_ref() };
|
||||
|
||||
// SAFETY: The safety requirements guarantee that the refcount is non-zero.
|
||||
unsafe { bindings::drm_gem_object_put(obj.as_raw()) }
|
||||
}
|
||||
}
|
||||
impl_aref_for_gem_obj!(impl<T> for Object<T> where T: DriverObject);
|
||||
|
||||
impl<T: DriverObject> super::private::Sealed for Object<T> {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user