mutual exclusion: only one core can hold a given lock
concurrent access to the same memory location, at least one write
example: acquire(l); x = x + 1; release(l);
“serialize” critical section: hide intermediate state
another example: transfer money from account A to B
put(a + 100) and put(b - 100) must be both effective, or neither
dead locks
assume per-bucket lock
acquire the lock for bucket 1 and then the lock for bucket 2
write two values
release both blocks
deadlock
thread 1: lock bucket 1; lock bucket 2
thread 2: lock bucket 2; lock bucket 1
approach
programmers enforce partial order over locks
always grab locks in pre-defined order
lock implementation
strawman
structlock{intlocked;};voidacquire(structlock*l){for(;;){if(l->locked==0){// A: test
l->locked=1;// B: set
return;}}}voidrelease(structlock*l){l->locked=0;}