Synchronization

Concurrent access to shared data in the data section of a multi- process, in the shared memory of multiple processes, or in a shared file Although every example in this chapter is for main memory data, we can easily use the techniques for the shared data in a shared file (lower level statements = load/op/store = read/op/write).

1. Motivation (Race Condition)

P1: A=A+1; P2: A=A-1;

Expect A=6 Expect A=4

A=5

Figure 6.1 Concurrent access to shared data

Implementation of the statement “A=A+1;” in machine language: Step 1.1: Register1=A Step 1.2: Register1=Register1+1 Step 1.3: A=Register1

Implementation of the statement “A=A-1;” in machine language: Step 2.1: Register2=A Step 2.2: Register2=Register2-1 Step 2.3: A=Register2

Race Condition : Order1: Step1.1 2.1 1.2 2.2 1.3 2.3 A=4 Order2: Step2.1 1.1 2.2 1.2 2.3 1.3 A=6 Order3: Step1.1 1.2 1.3 2.1 2.2 2.3 A=5  Inconsistency of shared data “A”

Critical Section : A segment of Code Section that changes, updates, or writes shared data. The execution of concurrent critical sections that access the same data must be mutually exclusive.

1

2. Solutions to the Critical Section Problem

repeat

Entry Section

Critical Section

Exit Section

Remainder Section until false

Figure 6.2 Process model

2.1 Requirements • : If there are n cooperative processes or threads that update the same data, only one of them can be in its critical section at a time and no other one will be allowed to enter its critical section before current one completes its critical section.

• Progress: A process that is currently in its remainder section should not participate in the decision of which waiting process will enter its critical section. This decision cannot be postponed indefinitely. If Mutual Exclusion is not guaranteed, then Progress is meaningless

• Bounded Waiting : Once a process P has made a request to enter its critical section, the number of other process (or threads) that are allowed to access the shared data before P must be bounded. If Progress is not guaranteed, then Bounded Waiting is meaningless.

2.2 Solutions

• A synchronization tool • • Can solve complex synchronization problems

• Definition: A semaphore S is an integer (or binary) variable that is accessed through two atomic operations wait (i.e., P) and (i.e., V).

• S is integer or binary semaphore

2 o wait(S): while S <= 0 do nothing; (in binary, “while S==0 do nothing”) S=S-1; (in binary, “S=0”) o signal(S): S=S+1; (in binary, “S=1”)

• Solving mutual exclusion with semaphore: Repeat wait(mutex) Critical Section signal(mutex) Remainder Section Until false

• Solving synchronization problem using semaphores: We want to execute the code segment 2 of process 2 after the code segment 1 of process 1. Initial value of semaphore sync is 0.

Process 1 Process 2 ...... Segment1 wait(sync) Signal(sync) Segment2

• Busy waiting o All the previous solutions to critical section require busy waiting . o Busy waiting: Waiting for an event by spinning through a tight loop (e.g., while do nothing) that polls for the event on each pass.  wastes CPU time

3

• Semaphore without Busy Waiting o To overcome busy waiting , we modify the definition of semaphore, wait(), and signal() to block and resume processes to increase CPU utilization.

o New Semaphore Definition:  Type semaphore = record value:integer; L: List of processes; End;  Each semaphore structure has an integer value and a list (queue) of processes.

o wait():  S.value=S.value-1; If S.value < 0 Add calling process to S.L; Block the calling process; End  If semaphore value is < 0, Pi blocks and is put on the semaphore queue.  If semaphore value is >= 0, Pi enters its CS.  -S.value is the number of processes in S.L (i.e., semaphore queue)

o signal():  S.value=S.value+1 If S.value <= 0 Remove P from S.L; Wakeup process P; end  Wakes up the next process in the semaphore queue.  Change its state from block (i.e., waiting) to ready.

o Semaphore list (queue) S.L can be implemented using any queuing strategy (e.g., FIFO, LIFO, Priority, …)

• wait() and signal() execute atomically o Uniprocessor: disable o Multiprocessor: special instruction or software CS solution. In latter case, the CS is wait() or signal() call. Software CS solution cause another & busy waiting problem.

• Satisfies mutual exclusion and progress. Bounded waiting is dependent on the queuing strategy of the semaphore list. For example, LIFO queue may not satisfy bounded waiting requirement.

4 • Deadlock & Starvation o Deadlock: deadly embraced processes o e.g., Process 0 Process 1 wait(S) wait(Q) wait(Q) wait(S) ...... signal(S) signal(Q) signal(Q) signal(S)

o Starvation: occurs when a process is constantly denied access to a resource. o e.g., LIFO style S.L

3. Classical Examples In this section, we skip the bounded-buffer problem, since the example can make you confused.

3.1 Readers-Writers Problem

Approach 1: no reader should be waiting unless a writer has the permission to write.

Approach 2: if a writer is waiting to write, then no new reader can start reading.

• Solution to either variant will lead to starvation.

3.2 Dining-Philosophers Problem

• Represent each chopstick by a semaphore. • Use wait() to grab a chopstick and signal() to release it. • If all philosophers are trying to eat at the same time, deadlock will occur. • Some solutions to avoid deadlock: o # of philosophers < # of chairs. o Each philosopher picks up chopsticks only if both are available (pick up both chopsticks in a single critical section) o Odd-numbered philosophers pick up the left chopstick first and then the right chopstick, whereas even-numbered philosophers pick up the right chopstick first and then the left one.

5

4. Use Carefully

• Incorrect use of semaphores can result in serious errors that are difficult to detect.

• Example 1: signal(mutex); Critical section wait(mutex)

or omit “wait()” before critical section

 several processes may be executing in their critical section simultaneously

• Example 2: wait(mutex) Critical section wait(mutex)

or omit “signal()” after critical section

 deadlock, no process can execute in its critical section.

6