1*bb38f35bSGary Guo // SPDX-License-Identifier: GPL-2.0 2*bb38f35bSGary Guo 3*bb38f35bSGary Guo //! Atomic reference counting. 4*bb38f35bSGary Guo //! 5*bb38f35bSGary Guo //! C header: [`include/linux/refcount.h`](srctree/include/linux/refcount.h) 6*bb38f35bSGary Guo 7*bb38f35bSGary Guo use crate::build_assert; 8*bb38f35bSGary Guo use crate::types::Opaque; 9*bb38f35bSGary Guo 10*bb38f35bSGary Guo /// Atomic reference counter. 11*bb38f35bSGary Guo /// 12*bb38f35bSGary Guo /// This type is conceptually an atomic integer, but provides saturation semantics compared to 13*bb38f35bSGary Guo /// normal atomic integers. Values in the negative range when viewed as a signed integer are 14*bb38f35bSGary Guo /// saturation (bad) values. For details about the saturation semantics, please refer to top of 15*bb38f35bSGary Guo /// [`include/linux/refcount.h`](srctree/include/linux/refcount.h). 16*bb38f35bSGary Guo /// 17*bb38f35bSGary Guo /// Wraps the kernel's C `refcount_t`. 18*bb38f35bSGary Guo #[repr(transparent)] 19*bb38f35bSGary Guo pub struct Refcount(Opaque<bindings::refcount_t>); 20*bb38f35bSGary Guo 21*bb38f35bSGary Guo impl Refcount { 22*bb38f35bSGary Guo /// Construct a new [`Refcount`] from an initial value. 23*bb38f35bSGary Guo /// 24*bb38f35bSGary Guo /// The initial value should be non-saturated. 25*bb38f35bSGary Guo #[inline] 26*bb38f35bSGary Guo pub fn new(value: i32) -> Self { 27*bb38f35bSGary Guo build_assert!(value >= 0, "initial value saturated"); 28*bb38f35bSGary Guo // SAFETY: There are no safety requirements for this FFI call. 29*bb38f35bSGary Guo Self(Opaque::new(unsafe { bindings::REFCOUNT_INIT(value) })) 30*bb38f35bSGary Guo } 31*bb38f35bSGary Guo 32*bb38f35bSGary Guo #[inline] 33*bb38f35bSGary Guo fn as_ptr(&self) -> *mut bindings::refcount_t { 34*bb38f35bSGary Guo self.0.get() 35*bb38f35bSGary Guo } 36*bb38f35bSGary Guo 37*bb38f35bSGary Guo /// Set a refcount's value. 38*bb38f35bSGary Guo #[inline] 39*bb38f35bSGary Guo pub fn set(&self, value: i32) { 40*bb38f35bSGary Guo // SAFETY: `self.as_ptr()` is valid. 41*bb38f35bSGary Guo unsafe { bindings::refcount_set(self.as_ptr(), value) } 42*bb38f35bSGary Guo } 43*bb38f35bSGary Guo 44*bb38f35bSGary Guo /// Increment a refcount. 45*bb38f35bSGary Guo /// 46*bb38f35bSGary Guo /// It will saturate if overflows and `WARN`. It will also `WARN` if the refcount is 0, as this 47*bb38f35bSGary Guo /// represents a possible use-after-free condition. 48*bb38f35bSGary Guo /// 49*bb38f35bSGary Guo /// Provides no memory ordering, it is assumed that caller already has a reference on the 50*bb38f35bSGary Guo /// object. 51*bb38f35bSGary Guo #[inline] 52*bb38f35bSGary Guo pub fn inc(&self) { 53*bb38f35bSGary Guo // SAFETY: self is valid. 54*bb38f35bSGary Guo unsafe { bindings::refcount_inc(self.as_ptr()) } 55*bb38f35bSGary Guo } 56*bb38f35bSGary Guo 57*bb38f35bSGary Guo /// Decrement a refcount. 58*bb38f35bSGary Guo /// 59*bb38f35bSGary Guo /// It will `WARN` on underflow and fail to decrement when saturated. 60*bb38f35bSGary Guo /// 61*bb38f35bSGary Guo /// Provides release memory ordering, such that prior loads and stores are done 62*bb38f35bSGary Guo /// before. 63*bb38f35bSGary Guo #[inline] 64*bb38f35bSGary Guo pub fn dec(&self) { 65*bb38f35bSGary Guo // SAFETY: `self.as_ptr()` is valid. 66*bb38f35bSGary Guo unsafe { bindings::refcount_dec(self.as_ptr()) } 67*bb38f35bSGary Guo } 68*bb38f35bSGary Guo 69*bb38f35bSGary Guo /// Decrement a refcount and test if it is 0. 70*bb38f35bSGary Guo /// 71*bb38f35bSGary Guo /// It will `WARN` on underflow and fail to decrement when saturated. 72*bb38f35bSGary Guo /// 73*bb38f35bSGary Guo /// Provides release memory ordering, such that prior loads and stores are done 74*bb38f35bSGary Guo /// before, and provides an acquire ordering on success such that memory deallocation 75*bb38f35bSGary Guo /// must come after. 76*bb38f35bSGary Guo /// 77*bb38f35bSGary Guo /// Returns true if the resulting refcount is 0, false otherwise. 78*bb38f35bSGary Guo /// 79*bb38f35bSGary Guo /// # Notes 80*bb38f35bSGary Guo /// 81*bb38f35bSGary Guo /// A common pattern of using `Refcount` is to free memory when the reference count reaches 82*bb38f35bSGary Guo /// zero. This means that the reference to `Refcount` could become invalid after calling this 83*bb38f35bSGary Guo /// function. This is fine as long as the reference to `Refcount` is no longer used when this 84*bb38f35bSGary Guo /// function returns `false`. It is not necessary to use raw pointers in this scenario, see 85*bb38f35bSGary Guo /// <https://github.com/rust-lang/rust/issues/55005>. 86*bb38f35bSGary Guo #[inline] 87*bb38f35bSGary Guo #[must_use = "use `dec` instead if you do not need to test if it is 0"] 88*bb38f35bSGary Guo pub fn dec_and_test(&self) -> bool { 89*bb38f35bSGary Guo // SAFETY: `self.as_ptr()` is valid. 90*bb38f35bSGary Guo unsafe { bindings::refcount_dec_and_test(self.as_ptr()) } 91*bb38f35bSGary Guo } 92*bb38f35bSGary Guo } 93*bb38f35bSGary Guo 94*bb38f35bSGary Guo // SAFETY: `refcount_t` is thread-safe. 95*bb38f35bSGary Guo unsafe impl Send for Refcount {} 96*bb38f35bSGary Guo 97*bb38f35bSGary Guo // SAFETY: `refcount_t` is thread-safe. 98*bb38f35bSGary Guo unsafe impl Sync for Refcount {} 99