This implements the CAS approach to lock-free synchronization, in
other words a sequence of atomic changes. Each change is represented by an
integer sequence number. Each sequence number may represent a single atomic
change for a single thread. All other threads, who fail to acquire permission
to update the sequence must obtain another sequence number and try again.
If the call to update succeeds, the the caller must call commit to notify other
threads that they are finished modifying the sequence. Otherwise deadlock will occur.
Atomic means that only one change per sequence number is possible. And that changes
to numerically lower numbers are guaranteed to occur prior to changes to numerically higher
sequence numbers.
Unlike synchronization, this mechanism does not include a fence operation. No thread state
is synchronized by this call. If your usage requires a fence that should be implemented with
volatile variables.
Its possible for the sequence to flip negative, over hundreds of years or with incredibly fast hardware
this would have no impact on the correctness of the atomic sequence. However, the best practice for code of this nature is
to make only relative comparison, sequence1 - sequence2 > 0, rather than sequence1 > sequence2
The general strategy is as follows:
for(;;) {
long lock = sequence.get();
// any preliminary checking (capacity, etc. can be done here
// the next call ensures that no other thread has modified the sequence
// while we work
if(sequence.update(lock)) {
try {
// update something atomically here
return;
} finally {
sequence.commit();
}
}
}
Created by jcairns on 9/24/14.