1 / 43

Mutual Exclusion -- Addendum - PowerPoint PPT Presentation

Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections. RoadMap. Today there are libraries that provide application programmers with semaphores Semaphores are used by programmers to provide for critical sections

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

PowerPoint Slideshow about ' Mutual Exclusion -- Addendum' - gerard

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

Mutual Exclusion -- Addendum

• Today there are libraries that provide application programmers with semaphores

• Semaphores are used by programmers to provide for critical sections

• Let’s first talk about semaphores and then the OS support for them.

• A semaphore is an integer variable with the following three operations.

• Initialize: You can initialize the semaphore to any non-negative value.

• Decrement: The downoperation

• Semaphore value > 0: Decrement by 1.

• Semaphore value == 0: If value is 0, the process blocks (gets put into queue). It is said to be sleeping on the semaphore..

• Increment:The up operation.

• Semaphore value ==0 and some processes are sleeping on the semaphore, one is unblocked. Otherwise, value is incremented.

• Use downbefore entering a critical section

• Use upafter finishing with a critical section i.e.,

• Example: Assume S is initialized to 1.

………

down(S);

//critical section

up(S);

Process P0

Process P1

………………..

down(S);

//critical section

up(S);

………………..

………………..

down(S);

//critical section

up(S);

………………..

Process P0Process P1

down(S); down(S);

critical section critical section

up(S); up(S);

• Initialize the semaphore variable, S, to 1

• Why not zero?

Process P0Process P1

down(S); down(S);

critical section critical section

up(S); up(S);

• Now what would happen if P0executes the down operation?

• The semaphore Sis currently 1.

• It becomes 0 and P0 enters the critical section

Process P0Process P1

down(S); down(S);

critical section critical section

up(S); up(S);

• Now what would happen if P1executes the down operation?

• The semaphore Sis currently 0

• P1 blocks

Process P0Process P1

down(S); down(S);

critical section critical section

up(S); up(S);

• Assume now that P0is done with the critical section

• It calls the up function

• P1 is unblocked

• If there was no process waiting to enter the critical section the value of s would become one

• What happens if there are three processes: P0,P1,P2

• Assume P0 enters its critical section

• If P1 and P2execute the down operation they will block

• When P0leaves the critical section then P1is unblocked allowing P1 to enter its critical section

• P2 is still blocked

• What if P0 wants to enter its critical section again when P1is in it?

• What if we want to allow 10 processes to use a critical section?

• How would we initialize a semaphore, s?

• Binary Semaphore: Value is either 0 or 1

• Often referred to as a mutex

• Counting Semaphore: Value ranges from 0 to N where N can be any integer number

• Deadlock– Two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes

• Something to watch for

• Example: Let S and Q be two semaphores initialized to one

Process P0 Process P1

down(S); down(Q);

down(Q); down(S);

…… ….

up(S); up(Q);

up(Q); up(S);

• With each semaphore there is an associated waiting queue. Each entry in a waiting queue has two data items:

• value (of type integer)

• pointer to next record in the list

• A semaphore can be defined as a C struct along these lines:

typedefstruct {

int value;

struct process *list;

} semaphore

• down() operation can be defined as

down(semaphore *S) {

S->value--;

if (S->value < 0) {

add this process to S->list;

block();

}

}

• The block() operation suspends the process that invokes it.

• up() operation can be defined as

up(semaphore *S) {

S->value++;

if (S->value <= 0) {

remove process P from S->list;

wakeup(P);

}

}

• The wakeup() operation sends a signal that represents an event that the invoking process is no longer in the critical section

• BTW, the implementation just described is how Linux implements semaphores

• The up and down operations represent require access to a critical section which is the semaphore variable

• Need hardware/OS support e.g.,

• Hardware support e.g.,TSL.

• Signals

• Any solution to the critical section problem requires a lock

• Process must acquire a lock before entering a critical section

• Process must release the lock when it exists the critical section.

• We will present a hardware solution

while (true) {

acquire lock

critical section

release lock

other

}

• Many computers have the following type of instruction: TSL REGISTER, LOCK

• One use of this instruction is to provide a lock for a critical regionsuch code that operations on a semaphore variable

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• TSL Register, Lock

• Reads LOCK into register REGISTER

• Stores a nonzero value at the memory location LOCK

• The operations of reading the word and storing it are guaranteed to be indivisible

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• TSL Register, Lock

• The CPU executing the TSL instruction locks the memory bus to prohibit other CPUs from accessing memory until the TSL instruction is done

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• CMP Register, #0

• Compare register value with 0

• JNE Enter_Region

• If Register value is not 0 then go to the start of enter region

enter_region: leave region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• Return to caller only if Register value is 0

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• Before entering its critical region, a process calls enter_region

• What if LOCK is 1?

• Busy wait until lock is 0

• When leaving the critical section, a process calls leave_region

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• Assume two processes: P0 and P1

• LOCK is initialized to zero

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• Assume that P0 wants to enter the critical section

• It executes the TSL instruction.

• The register value is 0 which reflects the value of LOCK

• LOCK is set to 1

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• Now P1 wants to enter the critical section; It executes the TSL instruction

• The register value is 1 which reflects the value of LOCK

• P1 cannot enter the critical section

• It repeats the TSL instruction and comparison operation until it can get into the critical section

enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• P0 is done with the critical section

• LOCK becomes 0

Enter_region: leave_region:

TSL Register, Lock move Lock, #0

CMP Register, #0 RET

JNE enter_region

RET //to caller

• The next time P1 executes the TSL instruction and comparison operation it finds that the register value (which reflects LOCK) is zero. It can now enter the critical section.

• Implementing atomic TSL instructions on multiprocessors is not trivial.

• This is a subject for a computer architecture course

• A signal is used in UNIX systems to notify a process that a particular event has occurred

• A signal is generated by the occurrence of a particular event

• A generated signal is delivered to a process

• Once delivered, the signal must be handled

• A signal process is used to associate computation with a signal

• Example

• <control> <C> is entered

• This causes an event to be generated to a running process that is in the foreground

• When that process receives the event it executes a signal handler which terminates the process

• Two possible handlers

• Default signal handler: Provided by kernel

• User-defined signal handler: Provided by user and overrides the default

• What if a process has multiple threads?

• How a signal is handled depends on the type of signal. Options

• Deliver the signal to the thread to which the signal applies

• Deliver the signal to every thread in the process

• Deliver the signal to certain threads in the process

• Assign a specific threa to receive all signals for the process

• When the up is executed a blocked process is woken up. This is done using signals

• Semaphore operations are critical sections – use TSL.

How are multiple processes prevented from being in the critical section ?

Why different than disabling interrupts?

Which is better in a multicore system?

Disabling interrupts or TSL test?

• Assume that instead of a TSL instruction there is an instruction to swap the contents of a register and memory word in a single indivisible action.

• Can you write a enter_regionroutine based on this

Mars PathFinder

• Priority Inversion: Scheduling problem when lower-priority process holds a lock needed by higher-priority process

• Now back to the Mars Pathfinder problem

• High priority task was taking longer than expected to complete its work

• The task was forced to wait for a shared resource that was being held by a lower-priority process

• Lower-priority process was being pre-empted by a medium priority process

• Scheduler detected problem and would reset

Mars PathFinder

• The fix

• The OS had a global variable to enable priority inheritance on all semaphores

• It was off

• It was set to on and then everything worked

• Defined race condition

• Examined different solutions