Lecture 4 - Non-blockinng synchronisation of concurrent shared data structures Flashcards
Mutual Exclusion using TestAndSet
do { while ( TestAndSet (&lock )) ; // do nothing but spinning on the lock (busy waiting) // … critical section lock = FALSE; // … remainder section } while ( TRUE);
Fine-Grained locking
A concurrent hashtable with fine-grained locking
1 mutex lock per hash value / list, as operations on different lists are independent
A parallel FIFO queue with k heads. • Queue items distributed round-robin over the k subqueues • Up to k operations in parallel • k must be a power of 2 for fast modulo computation. • Shared uint counters ngets, nputs initialized to 0. • Use fetch&incr( &nputs, 1) % k to determine subqueue for next insert • Use fetch&incr( &ngets, 1) % k to determine subqueue for next extract • Each subqueue is protected by a fair lock.
FetchAndIncr Instruction
boolean FetchAndIncr ( int *target, int k ) { int old = *target; *target = old + k; return old; }
Fair lock with FetchAndIncr
Acquire:
myticket = FetchAndIncr( &ticket, 1 );
while (myticket != active) ; // busy waiting
Release:
Fetch&Incr( &active, 1 );
(or: active ++; if store is atomic)
LoadLinked address, register
records the version number of the value read
StoreConditional register, address
l will only succeed if no other operations were executed on
the accessed memory location since my last LoadLinked
instruction to address,
(cf. a svn commit)
l and set the register operand of Store-conditional to 0,
otherwise.
Mutual Exclusion using LL/SC
do { register = 0; while ( register == 0) { dummy = LoadLinked ( &lock ); if (dummy == 0) { // read a 0 – found unlocked register = 1; register = StoreConditional ( register, &lock ); } // if register is 0, StoreConditional failed, retry… } // … critical section lock = 0; // ordinary store // … remainder section } while ( TRUE);
Mutual Exclusion using CAS
register = 1; CAS ( &lock, 0, register ); while (register != 0) CAS ( &lock, 0, register ); // … … critical section lock = 0;
Atomic Counter Increment with CAS
do { oldval = counter; newval = oldval + 1; CAS ( &counter, oldval, &newval ); } while (newval != oldval );
The ABA Problem with Compare&Swap
ABA-Problem:
CAS cannot detect if a memory location has changed value
from a value A to a value B and then back to A again.
Doubly Linked List - How to atomically update both prev and next pointers?
Requires DCAS (double compare-and-swap)
transactional memory
atomic {
}