ProblemsConcurrencyLock-free counter
IntermediateConcurrency

Lock-free counter

Context

Product metrics were undercounting, and marketing happily reported '40% growth' right after the bug was fixed... sorry, 'right after a successful ad campaign'. The cause was simple: ten threads incrementing a bare long. Make the counter honest — std::atomic, no locks.

Task

Implement a Counter that can be incremented from many threads at once and always reports the exact total. Do it without a mutex — use std::atomic. A plain long here loses updates to data races.

Constraints

  • Must use std::atomic (no std::mutex / lock)
  • increment() is safe to call concurrently from any number of threads
  • get() returns the exact number of increments performed
  • No data races (a bare long increment is UB under concurrency)

Before you code

  • Why is ++x on a plain long a data race when threads share it?
  • What does std::atomic<long>::fetch_add guarantee that ++ on a long does not?
  • When is a lock-free atomic cheaper than a mutex?

Tests

  • #1Concurrent increments are all counted
  • #2Single-threaded counting

Hints

Hint 1

A single std::atomic<long> member is enough: increment() does ++value_ (atomic), get() returns value_.load().

Editoratomic-counter.cpp
Results

Hit Submit (or ⌘/Ctrl + ↵) — test results will show up here.