5.2.concurrency-locks
5.2.concurrency-locks
Endadul Hoque
Acknowledgement
• Fairness
– Does each thread contending for the lock get a fair shot at
acquiring it once it is free? (Addressing starvation)
• Performance
– The time overheads added by using the lock
• Cases: (a) No contention, (b) contention on single CPU, (c) contention on
multiple CPUs
Naïve solution: Controlling Interrupts
• Disable Interrupts for critical sections
– One of the earliest solutions used to provide mutual exclusion
– Invented for single-processor systems.
1 void lock() {
2 DisableInterrupts();
3 }
4 void unlock() {
5 EnableInterrupts();
6 }
Naïve solution: Controlling Interrupts
• Disable Interrupts for critical sections
– One of the earliest solutions used to provide mutual exclusion
– Invented for single-processor systems.
1 void lock() {
2 DisableInterrupts();
3 }
4 void unlock() {
5 EnableInterrupts();
• Problems:
6 }
• Fairness: no
– Spin locks don’t provide any fairness guarantees.
– Indeed, a thread spinning may spin forever.
• Performance:
– In the single CPU, performance overheads can be quite substantial.
– If the number of threads roughly equals the number of CPUs, spin
locks work reasonably well.
Some other H/W instructions for Spin
Locks
• Compare-and-Swap
• Load-Linked and Store-Conditional
• Fetch-And-Add
1 void init() {
2 flag = 0;
3 }
4
5 void lock() {
6 while (TestAndSet(&flag, 1) == 1)
7 yield(); // give up the CPU
8 }
9
10 void unlock() {
11 flag = 0;
12 }
1 queue_add(m->q, gettid());
2 setpark(); // new code
3 m->guard = 0;
4 park();
Code modification inside of lock()
Futex
• Linux provides a futex (is similar to Solaris’s park
and unpark), part of nptl library
– futex_wait(address, expected)
• Put the calling thread to sleep
• If the value at address is not equal to expected, the call
returns immediately.
– futex_wake(address)
• Wake one thread that is waiting on the queue.
Reading Material