CSC501 Operating Systems Principles Process Synchronization 1
Last Lecture q Process Scheduling Question I: Within one second, how many times the timer interrupt will occur? Question II: Within one second, how many times the resched() will be called? 2
A Bug in resched() 3
Outline q Why synchronization? q Semaphore 4
Race Condition while (1) { while (count == BUFFER_SIZE) /* noop */; // produce an item and put in next buffer[in] = nextproduced; in = (in + 1) % BUFFER_SIZE; count++; } while (1) { while (count == 0) /* noop */; next = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--; // consume the item in next }
Race Condition q count++ could be q implemented as register1 = count register1 = register1 + 1 count = register1 count-- could be implemented as register2 = count register2 = register2-1 count = register2 Producer: Consumer: Values: register1 = count {register1 = 5} register1 = register1 + 1 {register1 = 6} register2 = count {register2 = 5} register2 = register2 1 {register2 = 4} count = register2 {count = 4} count = register1 {count = 6} Initially, count = 5 6
Example: Shared Linked List (1) n->next = p->next (2) p->next = n (a) m->next = p->next (b) p->next = m Order: a b 1 2 p X X n m
Example: Shared Linked List (1) n->next = p->next (2) p->next = n (a) m->next = p->next (b) p->next = m Order: a 1 2 b p X X n m
Race Condition q A race condition occurs when Q Multiple processes or threads read and write shared data items Q They do so in a way where the final result depends on the order of execution of the processes. 9
Race Condition q The existence of critical section Q A section of code within a process that requires access to shared resources and that must not be executed while another process is in a corresponding section of code q Why should we care? Q Concurrent access to shared data may result in data inconsistency 10
Race Condition q The existence of critical section Q A section of code within a process that requires access to shared resources and that must not be executed while another process is in a corresponding section of code q Necessary conditions Q Concurrency Q Shared data Q Interference Question: How to achieve concurrency of multiple processes/threads on shared data without interference? 11
Solution to Critical-Section Problem q Mutual Exclusion Q If process P i is executing in its critical section, then no other processes can be executing in their critical sections q Two other follow-up problems Q Deadlock Q Starvation Progress Bounded Waiting 12
Mutual Exclusion Hardware Support q Interrupt disabling Q E. g., cti/sti while (true) { /* disable interrupts */; /* critical section */; /* enable interrupts */; /* remainder */; } 13
Mutual Exclusion Hardware Support q Special machine instructions Q Exchange instruction (e.g., xchg) Q Compare&Exchange instruction void exchange (int register, int memory) { int temp; temp = memory; memory = register; register = temp; } Statements are executed atomically int keyi = 1; do exchange(keyi, lock); while (keyi!=0) } /* critical section */; lock = 0; spinlock /* remainder */; Question: In a single CPU environment, do we need spinlock? 14
Mutual Exclusion Hardware Support q Advantages Q It is simple and therefore easy to verify Q Applicable to any number of processes sharing main memory Q It can be used to support multiple critical sections q Disadvantages Q Busy-waiting consumes processor time Q Starvation is possible Q Deadlock is possible v E.g., priority-driven preemptive scheduling 15
Mutual Exclusion Software Support q Semaphore: Q An integer value used for signalling among processes. Q Three operations, each of which is atomic: v initialize v decrement P, wait, semwait, or acquire v increment V, signal, semsignal, or release 16
Semaphore q Counting semaphore Q An integer value can range over an unrestricted domain q Binary semaphore Q An integer value can range only between 0 and 1; can be simpler to implement QAlso known as mutex locks Semaphore S; // initialized to 1 acquire(s); criticalsection(); release(s); 17
Semaphore sys/ in Xinu: screate.c sdelete.c wait.c signal.c 18
Strong/Weak Semaphore q A queue is used to hold processes waiting on the semaphore Q In what order are processes removed from the queue? q Strong Semaphores use FIFO q Weak Semaphores don t specify the order of removal from the queue 19
Example of Strong Semaphore 20
Example of Semaphore Mechanism 21
Semaphore Implementation q Must guarantee that no two processes can execute acquire() and release() on the same semaphore at the same time q Thus implementation becomes the critical section problem Q Busy waiting (spinlock) in critical section implementation v Implementation code is short v Little busy waiting if critical section rarely occupied v More busy waiting waste of CPU resources Q Applications may spend lots of time in critical sections v Performance issues need to be addressed 22
Mutual Exclusion Software Support q Advantages Q It is simple and therefore easy to verify? Q It can be used to support multiple critical sections? q Disadvantages Q Starvation is possible? Q Deadlock is possible? Hardware-based mutual exclusion Software-based mutual exclusion 23
Deadlock and Starvation q Deadlock two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes q Let S and Q be two semaphores initialized to 1 P 0 P 1 acquire(s); acquire(q);...... release(s); release(q); acquire(q); acquire(s); release(q); release(s); q Starvation indefinite blocking. A process may never be removed from the semaphore queue in which it is suspended 24
Classical Problems of Synchronization q Bounded-Buffer Problem q Readers and Writers Problem q Dining-Philosophers Problem 25
Bounded Buffer N producers width q q q Buffer has limited slots Producer waits if buffer full Consumer waits if buffer empty M consumers 26
Semaphore solution Item buffer[n]; int in = 0, out = 0; Semaphore mutex = 1; Semaphore empty = N; // count empty slots Semaphore full = 0; // count full slots public void insert (Item item){ empty.acquire(); mutex.acquire(); Question: How about single producer /consumer? public Item Remove(){ full.acquire(); mutex.acquire(); // add an item to the buffer buffer[in] = item; in = (in + 1) % N; // remove an item item = buffer[out]; out = (out + 1) % N; } mutex.release(); full.release(); } mutex.release(); empty.release(); return item;
Readers and Writers Problem q Protect shared data or database Q A writer has exclusive access to data (no other concurrent writers or readers) Q Readers can have concurrent access (allow multiple readers) q Formally Q nw = # of active writers Q nr = # of active readers Q Safety condition: (nr = 0 or nw = 0) and nw <= 1 28
Solution using Semaphores int nr = 0; Semaphore mutex = 1, db = 1; writer() { while (1) { P(db) // write V(db) } } reader() { while (1) { P(mutex) nr++ if (nr == 1) P(db) V(mutex) // read P(mutex) nr-- if (nr == 0) V(db) V(mutex) } }
Solution using Semaphores int nr = 0; Semaphore mutex = 1, db = 1; writer() { while (1) { P(db) // write V(db) } } reader() { while (1) { P(mutex) nr++ if (nr == 1) P(db) V(mutex) // read P(mutex) nr-- if (nr == 0) V(db) V(mutex) } }
Solution using Semaphores q What is the use of: Q mutex? Q db? 31
Dining-Philosophers Problem q 5 philosophers: Think, or Eat QNeeds two forks to eat, one from each side q Shared data Semaphore fork[] = new Semaphore[5]; 32
Semaphore solution Semaphore forks[5] = {1,1,1,1,1} philospher(int i) { while (1) { fork[i].acquire(); fork[(i+1)%5].acquire(); eat; fork[i].release(); fork[(i+1)%5].release(); think; } } q q Problem deadlock Q How? Solution Q Q Q Allow at most 4 sitting Allow one to pick up only if both forks available (pick both in CS) Break symmetry, e.g., an odd person picks up left first, and even person picks up right first
Next Lecture q Process Synchronization q Lab0 34