# AtomicCounter Atomic (thread-safe) counters for Rust. This crate contains an [`AtomicCounter`](trait.AtomicCounter.html) trait that can safely be shared across threads. This crate provides two implementations: * [`RelaxedCounter`](struct.RelaxedCounter.html) which is suitable for e.g. collecting metrics or generate IDs, but which does not provide ["Sequential Consistency"](https://doc.rust-lang.org/nomicon/atomics.html#sequentially-consistent). `RelaxedCounter` uses [`Relaxed`](https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html#variant.Relaxed) memory ordering. * [`ConsistentCounter`](struct.ConsistentCounter.html) which provides the same interface but is sequentially consistent. Use this counter if the order of update from multiple threads is important. `ConsistentCounter` uses [`Sequentially Consistent`](https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html#variant.SeqCst) memory ordering. Both implementations are lock-free. Both are a very thin layer over [`AtomicUsize`](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html) which is more powerful but might be harder to use correctly. ## Which counter to use * If you are just collecting metrics, the `RelaxedCounter` is probably right choice. * If you are generating IDs, but don't make strong assumptions (like allocating memory based on the ID count), `RelaxedCounter` is probably the right choice. * If you are generating multiple IDs where you maintain an ordering invariant (e.g. ID `a` is always greater than ID `b`), you need "Sequential Consistency" and thus need to use `ConsistentCounter`. The same is true for all use cases where the _ordering_ of incrementing the counter is important. ## No updates are lost - It's just about the ordering! Note that in both implementations, _no count is lost_ and all operations are atomic. The difference is _only_ in how the order of operations are observed by different threads. ## Example: Assume `a` is 5 and `b` is 4. You always want to maintain `a > b`. Thread 1 executes this code: ```rust,ignore a.inc(); b.inc(); ``` Thread 2 gets counts: ```rust,ignore let a_local = a.get(); let b_local = b.get(); ``` What are the values for `a_local` and `b_local`? That depends on the order in which thread 1 and 2 have run: * `a_local` could still be 5 and `b_local` is still be 4 (e.g. if thread 2 ran before thread 1) * `a_local` could be increment to 6 while `b_local` is still at 4 (e.g. if thread 1 and 2 ran in parallel) * `a_local` could be increment to 6 and `b_local` be incremented to 5 (e.g. if thread 2 ran after thread 1). * Additionally, if at least one counter is a `RelaxedCounter`, we cannot make assumption on the order of `a.inc()` and `b.inc()`. Thus, in this case thread 2 can also observe `a_local` to be 5 (not incremented yet) but `b_local` to be incremented to 5, _breaking the invariant_ `a > b`. Note that if thread 2 (or any other thread) `get()` the counts again, at some point they will observe both values to be incremented. No operations will be lost. It is only the _ordering_ of the operations that cannot be assumed if `Ordering` is `Relaxed`. So in order to maintain invariants such as `a > b` across multiple threads, use `ConsistentCounter`.