Operating System 24
Mutex Locks and Semaphores
Prof Neeraj Bhargava
Vaibhav Khanna
Department of Computer Science
School of Engineering and Systems Sciences
Maharshi Dayanand Saraswati University Ajmer
Solution to Critical-Section Problem
1. Mutual Exclusion - If process Pi is executing in its critical
section, then no other processes can be executing in their
critical sections
2. Progress - If no process is executing in its critical section and
there exist some processes that wish to enter their critical
section, then the selection of the processes that will enter
the critical section next cannot be postponed indefinitely
3. Bounded Waiting - A bound must exist on the number of
times that other processes are allowed to enter their critical
sections after a process has made a request to enter its
critical section and before that request is granted
 Assume that each process executes at a nonzero speed
 No assumption concerning relative speed of the n processes
Critical-Section Handling in OS
Two approaches depending on if
kernel is preemptive or non-
preemptive
– Preemptive– allows preemption of
process when running in kernel mode
– Non-preemptive – runs until exits kernel
mode, blocks, or voluntarily yields CPU
• Essentially free of race conditions in kernel
mode
Mutex Locks
Previous solutions are complicated and generally
inaccessible to application programmers
OS designers build software tools to solve critical
section problem
Simplest is mutex lock
Protect a critical section by first acquire() a lock
then release() the lock
Boolean variable indicating if lock is available or not
Calls to acquire() and release() must be atomic
Usually implemented via hardware atomic instructions
But this solution requires busy waiting
This lock therefore called a spinlock
acquire() and release()
• acquire() {
while (!available)
; /* busy wait */
available = false;;
}
• release() {
available = true;
}
• do {
acquire lock
critical section
release lock
remainder section
} while (true);
Semaphore
• Synchronization tool that provides more sophisticated ways (than Mutex locks) for
process to synchronize their activities.
• Semaphore S – integer variable
• Can only be accessed via two indivisible (atomic) operations
– wait() and signal()
• Originally called P() and V()
• Definition of the wait() operation
wait(S) {
while (S <= 0)
; // busy wait
S--;
}
• Definition of the signal() operation
signal(S) {
S++;
}
Semaphore Usage
• Counting semaphore – integer value can range over an unrestricted domain
• Binary semaphore – integer value can range only between 0 and 1
– Same as a mutex lock
• Can solve various synchronization problems
• Consider P1 and P2 that require S1 to happen before S2
Create a semaphore “synch” initialized to 0
P1:
S1;
signal(synch);
P2:
wait(synch);
S2;
• Can implement a counting semaphore S as a binary semaphore
Semaphore Implementation
• Must guarantee that no two processes can execute the
wait() and signal() on the same semaphore at the same
time
• Thus, the implementation becomes the critical section
problem where the wait and signal code are placed in the
critical section
– Could now have busy waiting in critical section
implementation
• But implementation code is short
• Little busy waiting if critical section rarely occupied
• Note that applications may spend lots of time in critical
sections and therefore this is not a good solution
Semaphore Implementation with no Busy waiting
• 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
• Two operations:
– block – place the process invoking the operation on the
appropriate waiting queue
– wakeup – remove one of processes in the waiting queue
and place it in the ready queue
• typedef struct{
int value;
struct process *list;
} semaphore;
Implementation with no Busy waiting (Cont.)
wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
block();
}
}
signal(semaphore *S) {
S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}
Deadlock and Starvation
• Deadlock – two or more processes are waiting
indefinitely for an event that can be caused by only
one of the waiting processes
• Let S and Q be two semaphores initialized to 1
P0 P1
wait(S); wait(Q);
wait(Q); wait(S);
... ...
signal(S); signal(Q);
signal(Q); signal(S);
• Starvation – indefinite blocking
– A process may never be removed from the semaphore queue in which it is suspended
• Priority Inversion – Scheduling problem when
lower-priority process holds a lock needed by
higher-priority process
– Solved via priority-inheritance protocol
Assignment
• Explain the concept of Mutex Locks
• What is a Semaphore. Explain Semaphore
Implementation.

Operating system 24 mutex locks and semaphores

  • 1.
    Operating System 24 MutexLocks and Semaphores Prof Neeraj Bhargava Vaibhav Khanna Department of Computer Science School of Engineering and Systems Sciences Maharshi Dayanand Saraswati University Ajmer
  • 2.
    Solution to Critical-SectionProblem 1. Mutual Exclusion - If process Pi is executing in its critical section, then no other processes can be executing in their critical sections 2. Progress - If no process is executing in its critical section and there exist some processes that wish to enter their critical section, then the selection of the processes that will enter the critical section next cannot be postponed indefinitely 3. Bounded Waiting - A bound must exist on the number of times that other processes are allowed to enter their critical sections after a process has made a request to enter its critical section and before that request is granted  Assume that each process executes at a nonzero speed  No assumption concerning relative speed of the n processes
  • 3.
    Critical-Section Handling inOS Two approaches depending on if kernel is preemptive or non- preemptive – Preemptive– allows preemption of process when running in kernel mode – Non-preemptive – runs until exits kernel mode, blocks, or voluntarily yields CPU • Essentially free of race conditions in kernel mode
  • 4.
    Mutex Locks Previous solutionsare complicated and generally inaccessible to application programmers OS designers build software tools to solve critical section problem Simplest is mutex lock Protect a critical section by first acquire() a lock then release() the lock Boolean variable indicating if lock is available or not Calls to acquire() and release() must be atomic Usually implemented via hardware atomic instructions But this solution requires busy waiting This lock therefore called a spinlock
  • 5.
    acquire() and release() •acquire() { while (!available) ; /* busy wait */ available = false;; } • release() { available = true; } • do { acquire lock critical section release lock remainder section } while (true);
  • 6.
    Semaphore • Synchronization toolthat provides more sophisticated ways (than Mutex locks) for process to synchronize their activities. • Semaphore S – integer variable • Can only be accessed via two indivisible (atomic) operations – wait() and signal() • Originally called P() and V() • Definition of the wait() operation wait(S) { while (S <= 0) ; // busy wait S--; } • Definition of the signal() operation signal(S) { S++; }
  • 7.
    Semaphore Usage • Countingsemaphore – integer value can range over an unrestricted domain • Binary semaphore – integer value can range only between 0 and 1 – Same as a mutex lock • Can solve various synchronization problems • Consider P1 and P2 that require S1 to happen before S2 Create a semaphore “synch” initialized to 0 P1: S1; signal(synch); P2: wait(synch); S2; • Can implement a counting semaphore S as a binary semaphore
  • 8.
    Semaphore Implementation • Mustguarantee that no two processes can execute the wait() and signal() on the same semaphore at the same time • Thus, the implementation becomes the critical section problem where the wait and signal code are placed in the critical section – Could now have busy waiting in critical section implementation • But implementation code is short • Little busy waiting if critical section rarely occupied • Note that applications may spend lots of time in critical sections and therefore this is not a good solution
  • 9.
    Semaphore Implementation withno Busy waiting • 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 • Two operations: – block – place the process invoking the operation on the appropriate waiting queue – wakeup – remove one of processes in the waiting queue and place it in the ready queue • typedef struct{ int value; struct process *list; } semaphore;
  • 10.
    Implementation with noBusy waiting (Cont.) wait(semaphore *S) { S->value--; if (S->value < 0) { add this process to S->list; block(); } } signal(semaphore *S) { S->value++; if (S->value <= 0) { remove a process P from S->list; wakeup(P); } }
  • 11.
    Deadlock and Starvation •Deadlock – two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes • Let S and Q be two semaphores initialized to 1 P0 P1 wait(S); wait(Q); wait(Q); wait(S); ... ... signal(S); signal(Q); signal(Q); signal(S); • Starvation – indefinite blocking – A process may never be removed from the semaphore queue in which it is suspended • Priority Inversion – Scheduling problem when lower-priority process holds a lock needed by higher-priority process – Solved via priority-inheritance protocol
  • 12.
    Assignment • Explain theconcept of Mutex Locks • What is a Semaphore. Explain Semaphore Implementation.