A progress property rather than a spelling rule

If a lock owner pauses inside a critical section, other users can be stalled with it. A lock-free design avoids that dependency; spinning on a lock bit does not make an algorithm lock-free.

System-wide progress differs from individual completion. An operation can repeatedly lose while others succeed. Herlihy’s stronger wait-free condition requires each participating process to finish in finitely many of its own steps regardless of other processes’ speeds.

References: [1] [2]

How compare-and-exchange supports retries

A common pattern reads state, computes a candidate and commits with compare-and-exchange only if the expected value still matches. On contention it retries using updated state rather than overwriting another operation’s change.

C++ compare-exchange updates expected on failure, and the weak form permits spurious failure. Retry logic must follow that contract. Using this primitive alone proves neither correctness nor lock-free progress of an entire data structure.

References: [3] [1]

Atomicity, lock freedom and cost are separate

Atomic operations need not have lock-free implementations. C++ supplies is_lock_free queries and treats non-lock-free atomics as potentially blocking. Types, platforms and the scope of the claimed operation matter.

Allocation, reclamation and other surrounding calls can change the progress boundary of a complete interface even if its core update is lock-free. Retry counts and low latency are not automatic; correctness, progress and performance need separate validation.

References: [4] [1] [2]