| 1 | module lockfree |
| 2 | |
| 3 | import sync.stdatomic |
| 4 | |
| 5 | // Counter is a thread-safe atomic counter supporting multiple integer types. |
| 6 | // It provides atomic increment, decrement, and value retrieval operations. |
| 7 | @[noinit] |
| 8 | struct Counter[T] { |
| 9 | mut: |
| 10 | value &stdatomic.AtomicVal[T] |
| 11 | } |
| 12 | |
| 13 | // new_counter creates a new atomic counter with the specified initial value. |
| 14 | // It only supports integer types (8-bit to 64-bit integers). |
| 15 | pub fn new_counter[T](init T) &Counter[T] { |
| 16 | // Compile-time type check: only integers are supported |
| 17 | $if T !is $int { |
| 18 | $compile_error('new_counter(): only integers are supported.') |
| 19 | } |
| 20 | return &Counter[T]{ |
| 21 | value: stdatomic.new_atomic[T](init) |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | // increment_by atomically adds a delta value to the counter and returns |
| 26 | // the previous value before the operation (fetch-and-add). |
| 27 | @[inline] |
| 28 | pub fn (mut c Counter[T]) increment_by(delta T) T { |
| 29 | return c.value.add(delta) |
| 30 | } |
| 31 | |
| 32 | // increment atomically increments the counter by 1 and returns |
| 33 | // the previous value before the operation. |
| 34 | @[inline] |
| 35 | pub fn (mut c Counter[T]) increment() T { |
| 36 | return c.increment_by(T(1)) |
| 37 | } |
| 38 | |
| 39 | // decrement_by atomically subtracts a delta value from the counter and returns |
| 40 | // the previous value before the operation (fetch-and-sub). |
| 41 | @[inline] |
| 42 | pub fn (mut c Counter[T]) decrement_by(delta T) T { |
| 43 | return c.value.sub(delta) |
| 44 | } |
| 45 | |
| 46 | // decrement atomically decrements the counter by 1 and returns |
| 47 | // the previous value before the operation. |
| 48 | @[inline] |
| 49 | pub fn (mut c Counter[T]) decrement() T { |
| 50 | return c.decrement_by(T(1)) |
| 51 | } |
| 52 | |
| 53 | // get atomically retrieves the current value of the counter. |
| 54 | @[inline] |
| 55 | pub fn (mut c Counter[T]) get() T { |
| 56 | return c.value.load() |
| 57 | } |
| 58 | |
| 59 | // clear atomically resets the counter to zero. |
| 60 | @[inline] |
| 61 | pub fn (mut c Counter[T]) clear() { |
| 62 | c.value.store(0) |
| 63 | } |
| 64 | |