Skip to content

Commit e4b0895

Browse files
Lyudejannau
authored andcommitted
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>
1 parent 22b9e8e commit e4b0895

1 file changed

Lines changed: 38 additions & 15 deletions

File tree

rust/kernel/drm/gem/mod.rs

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,43 @@ use crate::{
1515
};
1616
use core::{ops::Deref, ptr::NonNull};
1717

18+
/// A macro for implementing [`AlwaysRefCounted`] for any GEM object type.
19+
///
20+
/// Since all GEM objects use the same refcounting scheme.
21+
#[macro_export]
22+
macro_rules! impl_aref_for_gem_obj {
23+
(
24+
impl $( <$( $tparam_id:ident ),+> )? for $type:ty
25+
$(
26+
where
27+
$( $bind_param:path : $bind_trait:path ),+
28+
)?
29+
) => {
30+
// SAFETY: All gem objects are refcounted
31+
unsafe impl $( <$( $tparam_id ),+> )? $crate::types::AlwaysRefCounted for $type
32+
where
33+
Self: IntoGEMObject,
34+
$( $( $bind_param : $bind_trait ),+ )?
35+
{
36+
fn inc_ref(&self) {
37+
// SAFETY: The existence of a shared reference guarantees that the refcount is
38+
// non-zero.
39+
unsafe { bindings::drm_gem_object_get(self.as_raw()) };
40+
}
41+
42+
unsafe fn dec_ref(obj: core::ptr::NonNull<Self>) {
43+
// SAFETY: `obj` is a valid pointer to an `Object<T>`.
44+
let obj = unsafe { obj.as_ref() }.as_raw();
45+
46+
// SAFETY: The safety requirements guarantee that the refcount is non-zero.
47+
unsafe { bindings::drm_gem_object_put(obj) };
48+
}
49+
}
50+
};
51+
}
52+
53+
pub(crate) use impl_aref_for_gem_obj;
54+
1855
/// A type alias for retrieving a [`Driver`]s [`DriverFile`] implementation from its
1956
/// [`DriverObject`] implementation.
2057
///
@@ -252,21 +289,7 @@ impl<T: DriverObject> Object<T> {
252289
}
253290
}
254291

255-
// SAFETY: Instances of `Object<T>` are always reference-counted.
256-
unsafe impl<T: DriverObject> crate::types::AlwaysRefCounted for Object<T> {
257-
fn inc_ref(&self) {
258-
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
259-
unsafe { bindings::drm_gem_object_get(self.as_raw()) };
260-
}
261-
262-
unsafe fn dec_ref(obj: NonNull<Self>) {
263-
// SAFETY: `obj` is a valid pointer to an `Object<T>`.
264-
let obj = unsafe { obj.as_ref() };
265-
266-
// SAFETY: The safety requirements guarantee that the refcount is non-zero.
267-
unsafe { bindings::drm_gem_object_put(obj.as_raw()) }
268-
}
269-
}
292+
impl_aref_for_gem_obj!(impl<T> for Object<T> where T: DriverObject);
270293

271294
impl<T: DriverObject> super::private::Sealed for Object<T> {}
272295

0 commit comments

Comments
 (0)