| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | //! Atomic reference counting. |
| 4 | //! |
| 5 | //! C header: [`include/linux/refcount.h`](srctree/include/linux/refcount.h) |
| 6 | |
| 7 | use crate:: |
| 8 | build_assert, |
| 9 | Atomic, |
| 10 | Opaque, // |
| 11 | ; |
| 12 | |
| 13 | /// Atomic reference counter. |
| 14 | /// |
| 15 | /// This type is conceptually an atomic integer, but provides saturation semantics compared to |
| 16 | /// normal atomic integers. Values in the negative range when viewed as a signed integer are |
| 17 | /// saturation (bad) values. For details about the saturation semantics, please refer to top of |
| 18 | /// [`include/linux/refcount.h`](srctree/include/linux/refcount.h). |
| 19 | /// |
| 20 | /// Wraps the kernel's C `refcount_t`. |
| 21 | |
| 22 | ; |
| 23 | |
| 24 | |
| 25 | /// Construct a new [`Refcount`] from an initial value. |
| 26 | /// |
| 27 | /// The initial value should be non-saturated. |
| 28 | // Always inline to optimize out error path of `build_assert`. |
| 29 | |
| 30 | |
| 31 | build_assert!; |
| 32 | // SAFETY: There are no safety requirements for this FFI call. |
| 33 | Self |
| 34 | |
| 35 | |
| 36 | |
| 37 | *mut refcount_t |
| 38 | self.0.get |
| 39 | |
| 40 | |
| 41 | /// Get the underlying atomic counter that backs the refcount. |
| 42 | /// |
| 43 | /// NOTE: Usage of this function is discouraged as it can circumvent the protections offered by |
| 44 | /// `refcount.h`. If there is no way to achieve the result using APIs in `refcount.h`, then |
| 45 | /// this function can be used. Otherwise consider adding a binding for the required API. |
| 46 | |
| 47 | |
| 48 | let ptr = self.0.get.cast; |
| 49 | // SAFETY: `refcount_t` is a transparent wrapper of `atomic_t`, which is an atomic 32-bit |
| 50 | // integer that is layout-wise compatible with `Atomic<i32>`. All values are valid for |
| 51 | // `refcount_t`, despite some of the values being considered saturated and "bad". |
| 52 | unsafe |
| 53 | |
| 54 | |
| 55 | /// Set a refcount's value. |
| 56 | |
| 57 | |
| 58 | // SAFETY: `self.as_ptr()` is valid. |
| 59 | unsafe |
| 60 | |
| 61 | |
| 62 | /// Increment a refcount. |
| 63 | /// |
| 64 | /// It will saturate if overflows and `WARN`. It will also `WARN` if the refcount is 0, as this |
| 65 | /// represents a possible use-after-free condition. |
| 66 | /// |
| 67 | /// Provides no memory ordering, it is assumed that caller already has a reference on the |
| 68 | /// object. |
| 69 | |
| 70 | |
| 71 | // SAFETY: self is valid. |
| 72 | unsafe |
| 73 | |
| 74 | |
| 75 | /// Decrement a refcount. |
| 76 | /// |
| 77 | /// It will `WARN` on underflow and fail to decrement when saturated. |
| 78 | /// |
| 79 | /// Provides release memory ordering, such that prior loads and stores are done |
| 80 | /// before. |
| 81 | |
| 82 | |
| 83 | // SAFETY: `self.as_ptr()` is valid. |
| 84 | unsafe |
| 85 | |
| 86 | |
| 87 | /// Decrement a refcount and test if it is 0. |
| 88 | /// |
| 89 | /// It will `WARN` on underflow and fail to decrement when saturated. |
| 90 | /// |
| 91 | /// Provides release memory ordering, such that prior loads and stores are done |
| 92 | /// before, and provides an acquire ordering on success such that memory deallocation |
| 93 | /// must come after. |
| 94 | /// |
| 95 | /// Returns true if the resulting refcount is 0, false otherwise. |
| 96 | /// |
| 97 | /// # Notes |
| 98 | /// |
| 99 | /// A common pattern of using `Refcount` is to free memory when the reference count reaches |
| 100 | /// zero. This means that the reference to `Refcount` could become invalid after calling this |
| 101 | /// function. This is fine as long as the reference to `Refcount` is no longer used when this |
| 102 | /// function returns `false`. It is not necessary to use raw pointers in this scenario, see |
| 103 | /// <https://github.com/rust-lang/rust/issues/55005>. |
| 104 | |
| 105 | |
| 106 | |
| 107 | // SAFETY: `self.as_ptr()` is valid. |
| 108 | unsafe |
| 109 | |
| 110 | |
| 111 | |
| 112 | // SAFETY: `refcount_t` is thread-safe. |
| 113 | unsafe |
| 114 | |
| 115 | // SAFETY: `refcount_t` is thread-safe. |
| 116 | unsafe |