Top Banner
Implementing Implementing Mutual Exclusion Mutual Exclusion Sarah Diesburg Sarah Diesburg Operating Systems Operating Systems COP 4610 COP 4610
39

Implementing Mutual Exclusion

Jan 23, 2016

Download

Documents

verdad

Implementing Mutual Exclusion. Sarah Diesburg Operating Systems COP 4610. From the Previous Lecture. The “too much milk” example shows that writing concurrent programs directly with load and store instructions (i.e., C assignment statements) is tricky - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Implementing Mutual Exclusion

Implementing Mutual Implementing Mutual ExclusionExclusionSarah DiesburgSarah Diesburg

Operating SystemsOperating Systems

COP 4610COP 4610

Page 2: Implementing Mutual Exclusion

From the Previous LectureFrom the Previous Lecture

The “too much milk” example shows The “too much milk” example shows that writing concurrent programs that writing concurrent programs directly with load and store directly with load and store instructions (i.e., C assignment instructions (i.e., C assignment statements) is trickystatements) is tricky

Programmers want to use higher-Programmers want to use higher-level operations, such as lockslevel operations, such as locks

Page 3: Implementing Mutual Exclusion

Ways of Implementing LocksWays of Implementing Locks

Locking primitives

High-level atomic operations

Locks, semaphores, Locks, semaphores, monitors, send and monitors, send and receivereceive

Low-level atomic operations

Load/store, interrupt Load/store, interrupt disables, disables, test_and_settest_and_set

All implementations require some All implementations require some level of hardware supportlevel of hardware support

Page 4: Implementing Mutual Exclusion

Atomic Memory Load and StoreAtomic Memory Load and Store

C assignment statementsC assignment statements Examples: “too much milk” solutionsExamples: “too much milk” solutions

Page 5: Implementing Mutual Exclusion

Disable Interrupts (for Disable Interrupts (for Uniprocessors)Uniprocessors)

On a uniprocessor,On a uniprocessor,– An operation is atomic as long as a An operation is atomic as long as a

context switch does not occur in the context switch does not occur in the middle of an operationmiddle of an operation

Solution 1Solution 1Lock::Acquire() {Lock::Acquire() {

// disable interrupts;// disable interrupts;}}Lock::Release() {Lock::Release() {

// enable interrupts;// enable interrupts; }}

Page 6: Implementing Mutual Exclusion

Problems with Solution 1Problems with Solution 1

A user-level program may not re-A user-level program may not re-enable interruptsenable interrupts– The kernel can no longer regain the The kernel can no longer regain the

controlcontrol No guarantees on the duration of No guarantees on the duration of

interrupts; bad for real-time systemsinterrupts; bad for real-time systems Solution 1 will not work for more Solution 1 will not work for more

complex scenarios (nested locks)complex scenarios (nested locks)

Page 7: Implementing Mutual Exclusion

Solution 2Solution 2class Lock {class Lock {

int value = FREE;int value = FREE;}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptswhile (value != FREE) {while (value != FREE) {

// enable interrupts// enable interrupts// disable interrupts// disable interrupts

}}value = BUSY;value = BUSY;// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

value = FREE;value = FREE;

// enable interrupts// enable interrupts

}}

Page 8: Implementing Mutual Exclusion

Solution 2Solution 2class Lock {class Lock {

int value = FREE;int value = FREE;}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptswhile (value != FREE) {while (value != FREE) {

// enable interrupts// enable interrupts// disable interrupts// disable interrupts

}}value = BUSY;value = BUSY;// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

value = FREE;value = FREE;

// enable interrupts// enable interrupts

}}

The lock is initially FREE.

Page 9: Implementing Mutual Exclusion

Solution 2Solution 2class Lock {class Lock {

int value = FREE;int value = FREE;}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptswhile (while (value != FREEvalue != FREE) {) {

// enable interrupts// enable interrupts// disable interrupts// disable interrupts

}}value = BUSY;value = BUSY;// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

value = FREE;value = FREE;

// enable interrupts// enable interrupts

}}

Check the lock value whileinterrupts are disabled.

Page 10: Implementing Mutual Exclusion

Solution 2Solution 2class Lock {class Lock {

int value = FREE;int value = FREE;}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptswhile (value != FREE) {while (value != FREE) {

// enable interrupts// enable interrupts// disable interrupts// disable interrupts

}}value = BUSY;value = BUSY;// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

value = FREE;value = FREE;

// enable interrupts// enable interrupts

}}

Re-enable interrupts inside theloop, so someone may have a chance to unlock.

Page 11: Implementing Mutual Exclusion

Solution 2Solution 2class Lock {class Lock {

int value = FREE;int value = FREE;}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptswhile (value != FREE) {while (value != FREE) {

// enable interrupts// enable interrupts// disable interrupts// disable interrupts

}}value = BUSY;value = BUSY;// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

value = FREE;value = FREE;

// enable interrupts// enable interrupts

}}

Disable the interrupts againbefore checking the lock.

Page 12: Implementing Mutual Exclusion

Solution 2Solution 2class Lock {class Lock {

int value = FREE;int value = FREE;}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptswhile (value != FREE) {while (value != FREE) {

// enable interrupts// enable interrupts// disable interrupts// disable interrupts

}}value = BUSY;value = BUSY;// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

value = FREE;value = FREE;

// enable interrupts// enable interrupts

}}

If no one is holding the lock, grab the lock.

Page 13: Implementing Mutual Exclusion

Problems with Solution 2Problems with Solution 2

It works for a single processorIt works for a single processor It does not work on a multi-processor It does not work on a multi-processor

machinemachine– Other CPUs can still enter the critical Other CPUs can still enter the critical

sectionsection

Page 14: Implementing Mutual Exclusion

The The test_and_settest_and_set Operation Operation

test_and_settest_and_set works on works on multiprocessorsmultiprocessors– Atomically reads a memory locationAtomically reads a memory location– Sets it to 1Sets it to 1– Returns the old value of memory Returns the old value of memory

locationlocation

Page 15: Implementing Mutual Exclusion

The The test_and_settest_and_set Operation Operation

value = 0;value = 0;

Lock::Acquire() {Lock::Acquire() {// while the previous value is BUSY, loop// while the previous value is BUSY, loopwhile (test_and_set(value) == 1);while (test_and_set(value) == 1);

}}

Lock::Release() {Lock::Release() {value = 0;value = 0;

}}

Page 16: Implementing Mutual Exclusion

Common Problems with Mentioned Common Problems with Mentioned ApproachesApproaches

Busy-waitingBusy-waiting: consumption of CPU : consumption of CPU cycles while a thread is waiting for a cycles while a thread is waiting for a locklock– Very inefficientVery inefficient– Can be avoided with a waiting queueCan be avoided with a waiting queue

May as well sleep instead of busy-wait…

Page 17: Implementing Mutual Exclusion

A tail of two threads…A tail of two threads…

Suppose both threads want the lock, Suppose both threads want the lock, but like to be lazy…but like to be lazy…

Thread 1: Lazy Thread 2: Lazier

Page 18: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsif (value != FREE) {if (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Page 19: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Thread 1 tries to grab the lock.

Page 20: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

No more busy waiting…

Page 21: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Grab the lock.

Page 22: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Thread 1 goes on computing.

Page 23: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Thread 2 tries to grab the lock.

Page 24: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) {(value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

The lock is busy…

Page 25: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Put the thread 2 on a waiting queue.

Page 26: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Sleep it off… Context switch;wait for someone to wake up the thread. zzzz

Page 27: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Say thread 1 wants to release the lock (interrupts are already disabled by thread 2).

Page 28: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Hello? Is someone waiting there? Thread 2 is waiting.

Page 29: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Put thread 2 on ready queue; context switch.

Page 30: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Thread 2: Who woke me? I don’t do mornings…

Page 31: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Thread 2 is done with its computation.

Page 32: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Suppose no one else is waiting.

Page 33: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Release the lock. (Thread 1 hasfinished its work, so it’s okay.)

Page 34: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Warp 9, engage (let’s get out of here)…

Page 35: Implementing Mutual Exclusion

Locks Using Interrupt Disables, Locks Using Interrupt Disables, Without Busy-WaitingWithout Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

}}

Lock::Acquire() {Lock::Acquire() {// disable interrupts// disable interruptsifif (value != FREE) { (value != FREE) {

// Queue the thread// Queue the thread// Go to sleep// Go to sleep

} else {} else {value = BUSY;value = BUSY;

}}// enable interrupts// enable interrupts

}}

Lock::Release() {Lock::Release() {

// disable interrupts// disable interrupts

if (someone is waiting) {if (someone is waiting) {

// wake a thread// wake a thread

// Put it on ready // Put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

// enable interrupts// enable interrupts

}}

Eventually, the kernel will contextswitch back to thread 1.

What happened?

Page 36: Implementing Mutual Exclusion

So, What’s Going On?So, What’s Going On?

Interrupt disable and enable Interrupt disable and enable operations occur across context operations occur across context switches (at the steady state)switches (at the steady state)

Page 37: Implementing Mutual Exclusion

So, What’s Going On?So, What’s Going On?

Thread AThread A Thread BThread B

Disable interruptsSleep

Disable interruptsSleep

Return from sleepEnable interrupts

Context switch

Return from sleepEnable interrupts

Context switch

Page 38: Implementing Mutual Exclusion

Locks Using Locks Using test_and_settest_and_set, With , With Minimal Busy-WaitingMinimal Busy-Waiting

Impossible to use Impossible to use test_and_settest_and_set to to avoid busy-waitingavoid busy-waiting

However, waiting can be minimized However, waiting can be minimized with a waiting queuewith a waiting queue

Page 39: Implementing Mutual Exclusion

Locks Using Locks Using test_and_settest_and_set, With , With Minimal Busy-WaitingMinimal Busy-Waiting

class Lock {class Lock {int value = FREE;int value = FREE;

int guard = 0;int guard = 0;}}

Lock::Acquire() {Lock::Acquire() {while (test_and_set(guard));while (test_and_set(guard));if (value != FREE) {if (value != FREE) {

// queue the thread// queue the thread// guard = 0 and // guard = 0 and

sleepsleep} else {} else {

value = BUSY;value = BUSY;}}guard = 0;guard = 0;

}}

Lock::Release() {Lock::Release() {

while (test_and_set(guard));while (test_and_set(guard));

if (anyone waiting) {if (anyone waiting) {

// wake up one thread// wake up one thread

// put it on ready // put it on ready queuequeue

} else {} else {

value = FREE;value = FREE;

}}

guard = 0;guard = 0;

}}