bugs such as dead-lock, live-lock and priority inversion. The mutual-exclusion property of (highly-contended) locks stands in the way to scalability of parallel programs on many-core architectures [@Scott:Sync]. Locks do not allow progress guarantees, because a task may fail inside a critical section (e.g., by entering an endless loop), preventing other tasks from accessing shared data.

Given the disadvantages of mutual exclusion locks, it is thus desirable to give up on method-level locking and allow method calls to overlap in time. Synchronization is then performed on a finer granularity within a method’s code, via atomic [*read-modify-write*]{} (RMW) operations. In the absence of mutual exclusion locks, the possibility of task-failure inside a critical section is eliminated, because critical sections are reduced to single atomic operations. These atomic operations are provided either by the CPU’s instruction set architecture (ISA), or the language run-time (with the help of the CPU’s ISA). It thus becomes possible to provide progress guarantees, which are unattainable with locks. In particular, a method is [*non-blocking*]{}, if a task’s pending invocation is never required to wait for another task’s pending invocation to complete [@Herlihy:2012].

[ll@l]{}

    -- Initial values:
    Flag := False;
    Data := 0;

\

– Task 1: Data := 