safer_ring/buffer/generation.rs
1//! Generation tracking for buffer lifecycle management.
2
3use std::sync::atomic::{AtomicU64, Ordering};
4
5/// Atomic generation counter for tracking buffer lifecycle events.
6///
7/// This counter provides thread-safe tracking of buffer state changes throughout
8/// its lifecycle. Each buffer operation (allocation, use, reuse) can increment
9/// the generation to help with debugging buffer lifecycle issues and detecting
10/// use-after-free scenarios in development builds.
11///
12/// The counter uses relaxed atomic ordering since exact ordering of generation
13/// updates across threads is not critical for its debugging purposes.
14///
15/// # Thread Safety
16///
17/// All operations on `GenerationCounter` are thread-safe and can be called
18/// concurrently from multiple threads.
19///
20/// # Examples
21///
22/// ```rust
23/// use safer_ring::buffer::GenerationCounter;
24///
25/// let counter = GenerationCounter::new();
26/// assert_eq!(counter.get(), 0);
27///
28/// counter.increment();
29/// assert_eq!(counter.get(), 1);
30///
31/// counter.set(42);
32/// assert_eq!(counter.get(), 42);
33/// ```
34#[derive(Debug)]
35pub struct GenerationCounter {
36 /// Atomic counter that tracks buffer lifecycle events
37 counter: AtomicU64,
38}
39
40impl GenerationCounter {
41 /// Creates a new generation counter starting at 0.
42 #[inline]
43 pub const fn new() -> Self {
44 Self {
45 counter: AtomicU64::new(0),
46 }
47 }
48
49 /// Returns the current generation value.
50 #[inline]
51 pub fn get(&self) -> u64 {
52 self.counter.load(Ordering::Relaxed)
53 }
54
55 /// Increments the generation counter atomically.
56 #[inline]
57 pub fn increment(&self) {
58 self.counter.fetch_add(1, Ordering::Relaxed);
59 }
60
61 /// Sets the generation counter to a specific value.
62 #[inline]
63 pub fn set(&self, value: u64) {
64 self.counter.store(value, Ordering::Relaxed);
65 }
66}
67
68impl Default for GenerationCounter {
69 fn default() -> Self {
70 Self::new()
71 }
72}
73
74impl Clone for GenerationCounter {
75 /// Creates a new counter with the same generation value.
76 fn clone(&self) -> Self {
77 Self {
78 counter: AtomicU64::new(self.get()),
79 }
80 }
81}