41
Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

  • View
    243

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Synchronization

CSCI 3753 Operating Systems

Spring 2005

Prof. Rick Han

Page 2: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Announcements

• HW #3 is online, due Friday Feb. 25 at 11 am

• PA #2 is coming, assigned next Tuesday

• Midterm is tentatively Thursday March 10

• Read chapter 8

Page 3: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

From last time...

• Many cases where processes and threads want to access shared common variables, buffers, etc.

• Producer-Consumer with a shared bounded buffer in between– Producer increments counter++– Consumer decrements counter--

• race conditions between producer and consumer– Machine-level instructions can be interleaved,

resulting in unpredictable value of shared counter variable

Page 4: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Synchronization

while(1) { while(counter==MAX); buffer[in] = nextdata; in = (in+1) % MAX; counter++;}

Data

Bounded Buffer

counter

ProducerProcess

ConsumerProcess

while(1) { while(counter==0); getdata = buffer[out]; out = (out+1) % MAX; counter--;}

Producer writes new data intobuffer and increments counter

Consumer reads new data frombuffer and decrements counter

counterupdates

can conflict!

buffer[0]

buffer[MAX]

Page 5: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Synchronization

counter++; can translate into several machine language instructions, e.g.

reg1 = counter;

reg1 = reg1 + 1;

counter = reg1;

counter--; can translate into several machine language instructions, e.g.

reg2 = counter;

reg2 = reg2 - 1;

counter = reg2;

If these low-level instructions are interleaved, e.g. the Producer processis context-switched out, and the Consumer process is context-switched in,and vice versa, then the results of counter’s value can be unpredictable

Page 6: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Synchronization

// counter++ reg1 = counter; reg1 = reg1 + 1; counter = reg1;

// counter--;

reg2 = counter;

reg2 = reg2 - 1;

counter = reg2;

(1) [5](3) [6]

(2) [5](4) [4]

(5) [6]

(6) [4]

• Suppose we have the following sequence of interleaving, where the brackets [value] denote the local value of counter in either the producer or consumer’s process. Let counter=5 initially.

• At the end, counter = 4. But if steps (5) and (6) were reversed, then counter=6 !!!

• Value of shared variable counter changes depending upon (an arbitrary) order of writes - very undesirable!

Page 7: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Critical Section• Kernel data structures - e.g. access to list of open files subject to

race condition• Kernel developer must ensure that no such race conditions occur• Identify critical sections in code where each process access shared

variables

do { entry section critical section (manipulate common var’s) exit section remainder code} while (1)

mutual exclusion, bounded waiting, progress

Page 8: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Critical Section

• How do we protect access to critical sections?– want to prevent another process from

executing while current process is modifying this variable - mutual exclusion

– disable interrupts• bad, because I/O may be prevented• bad, because program may have an infinite loop

Page 9: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Critical Section

• Don’t disable interrupts for the entire time you’re in the critical section

• Solution: Set a variable/flag called a lock to indicate that the critical section is busy, then unset the flag when critical section is done– doesn’t disable interrupts in the critical section– also Peterson’s solution

Page 10: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Using a Lock Variableshared boolean lock = FALSE;shared int counter;

Code for p1 Code for p2

/* Acquire the lock */ /* Acquire the lock */ while(lock) ; while(lock) ; lock = TRUE; lock = TRUE;/* Execute critical sect */ /* Execute critical sect */ counter++; counter--;/* Release lock */ /* Release lock */ lock = FALSE; lock = FALSE;

Page 11: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Busy Wait Conditionshared boolean lock = FALSE;shared int counter;

Code for p1 Code for p2

/* Acquire the lock */ /* Acquire the lock */ while(lock) ; while(lock) ; lock = TRUE; lock = TRUE;/* Execute critical sect */ /* Execute critical sect */ counter++; counter--;/* Release lock */ /* Release lock */ lock = FALSE; lock = FALSE;

p1

p2

Blo

cked

at while

lock = TRUE

lock = FALSE

Inte

rrup

t

Inte

rrup

t

Inte

rrup

t

Page 12: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Unsafe “Solution”shared boolean lock = FALSE;shared double balance;

Code for p1 Code for p2

/* Acquire the lock */ /* Acquire the lock */ while(lock) ; while(lock) ; lock = TRUE; lock = TRUE;/* Execute critical sect */ /* Execute critical sect */ counter++; counter--;/* Release lock */ /* Release lock */ lock = FALSE; lock = FALSE;

• Worse yet … another race condition …

• Is it possible to solve the problem?

Page 13: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Critical Section

while (lock==TRUE) ;lock = TRUE;

• test-and-set solution doesn’t work if process is interrupted right after while()

• Want an atomic instruction testandset() that tests shared variable lock then sets it

• Some hardware provides such an instruction

Page 14: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Atomic Lock Manipulationshared boolean lock = FALSE;shared int counter;

Code for p1 Code for p2

/* Acquire the lock */ /* Acquire the lock */ while(TestandSet(&lock)) ; while(TestandSet(&lock)) ;

/* Execute critical sect */ /* Execute critical sect */ counter++; counter--;/* Release lock */ /* Release lock */ lock = FALSE; lock = FALSE;______________________________________________________________

boolean TestandSet(boolean *target) { // this is atomic, one machine instruction boolean rv = *target; *target = TRUE; return rv;}

Page 15: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Atomic Lock Manipulation

• The system is exclusively occupied for only a short time - the time to test and set the lock, and not for entire critical section– about 10 instructions

• don’t have to disable and reenable interrupts - time-consuming

• disadvantage: requires user to put in while()• low level assembly language manipulation of a

machine instruction TS

Page 16: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han
Page 17: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Bounded Buffer Problem

ProducerProducer ConsumerConsumer

Empty Pool

Full Pool

Page 18: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Bounded Buffer Problem (2)producer() { buf_type *next, *here; while(TRUE) { produce_item(next); /* Claim an empty */ P(empty); P(mutex); here = obtain(empty); V(mutex); copy_buffer(next, here); P(mutex); release(here, fullPool); V(mutex); /* Signal a full buffer */ V(full); }}semaphore mutex = 1;semaphore full = 0; /* A general (counting) semaphore */semaphore empty = N; /* A general (counting) semaphore */buf_type buffer[N];fork(producer, 0);fork(consumer, 0);

consumer() { buf_type *next, *here; while(TRUE) { /* Claim full buffer */ P(mutex); P(full); here = obtain(full); V(mutex); copy_buffer(here, next); P(mutex); release(here, emptyPool); V(mutex); /* Signal an empty buffer */ V(empty); consume_item(next); }}

Page 19: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Bounded Buffer Problem (3)producer() { buf_type *next, *here; while(TRUE) { produce_item(next); /* Claim an empty */ P(empty); P(mutex); here = obtain(empty); V(mutex); copy_buffer(next, here); P(mutex); release(here, fullPool); V(mutex); /* Signal a full buffer */ V(full); }}semaphore mutex = 1;semaphore full = 0; /* A general (counting) semaphore */semaphore empty = N; /* A general (counting) semaphore */buf_type buffer[N];fork(producer, 0);fork(consumer, 0);

consumer() { buf_type *next, *here; while(TRUE) { /* Claim full buffer */ P(full); P(mutex); here = obtain(full); V(mutex); copy_buffer(here, next); P(mutex); release(here, emptyPool); V(mutex); /* Signal an empty buffer */ V(empty); consume_item(next); }}

Page 20: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Readers-Writers Problem

Readers

Writers

Page 21: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Readers-Writers Problem (2)

ReaderReader

Shared Resource

ReaderReaderReaderReader

ReaderReaderReaderReaderReaderReader

ReaderReaderReaderReader

WriterWriterWriterWriterWriterWriter

WriterWriterWriterWriterWriterWriter

WriterWriter

Page 22: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Readers-Writers Problem (3)

ReaderReader

Shared Resource

ReaderReaderReaderReaderReaderReaderReaderReader

ReaderReaderReaderReaderReaderReader

WriterWriterWriterWriterWriterWriter

WriterWriterWriterWriterWriterWriter

WriterWriter

Page 23: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Readers-Writers Problem (4)

ReaderReader

Shared Resource

ReaderReaderReaderReader

ReaderReaderReaderReaderReaderReader

ReaderReaderReaderReader

WriterWriterWriterWriterWriterWriter

WriterWriterWriterWriterWriterWriter

WriterWriter

Page 24: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

First Solutionreader() { while(TRUE) { <other computing>; P(mutex); readCount++; if(readCount == 1) P(writeBlock); V(mutex); /* Critical section */ access(resource); P(mutex); readCount--; if(readCount == 0) V(writeBlock); V(mutex); }}resourceType *resource;int readCount = 0;semaphore mutex = 1;semaphore writeBlock = 1;fork(reader, 0);fork(writer, 0);

writer() { while(TRUE) { <other computing>; P(writeBlock); /* Critical section */ access(resource); V(writeBlock); }}

•First reader competes with writers•Last reader signals writers

Page 25: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

First Solution (2)reader() { while(TRUE) { <other computing>; P(mutex); readCount++; if(readCount == 1) P(writeBlock); V(mutex); /* Critical section */ access(resource); P(mutex); readCount--; if(readCount == 0) V(writeBlock); V(mutex); }}resourceType *resource;int readCount = 0;semaphore mutex = 1;semaphore writeBlock = 1;fork(reader, 0);fork(writer, 0);

writer() { while(TRUE) { <other computing>; P(writeBlock); /* Critical section */ access(resource); V(writeBlock); }}

•First reader competes with writers•Last reader signals writers•Any writer must wait for all readers•Readers can starve writers•“Updates” can be delayed forever•May not be what we want

Page 26: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Writer Precedencereader() { while(TRUE) { <other computing>;

P(readBlock); P(mutex1); readCount++; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock);

access(resource); P(mutex1); readCount--; if(readCount == 0) V(writeBlock); V(mutex1); }}int readCount = 0, writeCount = 0;semaphore mutex = 1, mutex2 = 1;semaphore readBlock = 1, writeBlock = 1, writePending = 1;fork(reader, 0);fork(writer, 0);

writer() { while(TRUE) { <other computing>; P(mutex2); writeCount++; if(writeCount == 1) P(readBlock); V(mutex2); P(writeBlock); access(resource); V(writeBlock); P(mutex2) writeCount--; if(writeCount == 0) V(readBlock); V(mutex2); }}

1

23

4

Page 27: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Writer Precedence (2)reader() { while(TRUE) { <other computing>; P(writePending); P(readBlock); P(mutex1); readCount++; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); V(writePending); access(resource); P(mutex1); readCount--; if(readCount == 0) V(writeBlock); V(mutex1); }}int readCount = 0, writeCount = 0;semaphore mutex = 1, mutex2 = 1;semaphore readBlock = 1, writeBlock = 1, writePending = 1;fork(reader, 0);fork(writer, 0);

writer() { while(TRUE) { <other computing>; P(mutex2); writeCount++; if(writeCount == 1) P(readBlock); V(mutex2); P(writeBlock); access(resource); V(writeBlock); P(mutex2) writeCount--; if(writeCount == 0) V(readBlock); V(mutex2); }}

1

23

4

Page 28: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

The Sleepy Barber

Waiting Room

Entrance to WaitingRoom (sliding door)

Entrance to Barber’sRoom (sliding door)

Shop Exit

• Barber can cut one person’s hair at a time

• Other customers wait in a waiting room

Page 29: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Sleepy Barber (aka Bounded Buffer)customer() {

while(TRUE) { customer = nextCustomer(); if(emptyChairs == 0) continue; P(chair); P(mutex); emptyChairs--; takeChair(customer); V(mutex); V(waitingCustomer); }}

semaphore mutex = 1, chair = N, waitingCustomer = 0;int emptyChairs = N;fork(customer, 0);fork(barber, 0);

barber() { while(TRUE) { P(waitingCustomer); P(mutex); emptyChairs++; takeCustomer(); V(mutex); V(chair); }}

Page 30: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Cigarette Smoker’s Problem

• Three smokers (processes)

• Each wish to use tobacco, papers, & matches– Only need the three resources periodically– Must have all at once

• 3 processes sharing 3 resources– Solvable, but difficult

Page 31: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Implementing Semaphores

• Minimize effect on the I/O system

• Processes are only blocked on their own critical sections (not critical sections that they should not care about)

• If disabling interrupts, be sure to bound the time they are disabled

Page 32: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Implementing Semaphores:enter() & exit()

class semaphore { int value;public: semaphore(int v = 1) { value = v;}; P(){ disableInterrupts(); while(value == 0) { enableInterrupts(); disableInterrupts(); } value--; enableInterrupts(); }; V(){ disableInterrupts(); value++; enableInterrupts(); };};

Page 33: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Implementing Semaphores:Test and Set Instruction

FALSEm

PrimaryMemory

…R3 …

DataRegister

CCRegister

(a) Before Executing TS

TRUEm

PrimaryMemory

FALSER3 =0

DataRegister

CCRegister

(b) After Executing TS

• TS(m): [Reg_i = memory[m]; memory[m] = TRUE;]

Page 34: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Using the TS Instruction

boolean s = FALSE; . . . while(TS(s)) ; <critical section> s = FALSE; . . .

semaphore s = 1; . . . P(s) ; <critical section> V(s); . . .

Page 35: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Implementing the General Semaphore

struct semaphore { int value = <initial value>; boolean mutex = FALSE; boolean hold = TRUE;};

shared struct semaphore s;

P(struct semaphore s) { while(TS(s.mutex)) ; s.value--; if(s.value < 0) ( s.mutex = FALSE; while(TS(s.hold)) ; } else s.mutex = FALSE;}

V(struct semaphore s) { while(TS(s.mutex)) ; s.value++; if(s.value <= 0) ( while(!s.hold) ; s.hold = FALSE; } s.mutex = FALSE;}

Page 36: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Active vs Passive Semaphores• A process can dominate the semaphore

– Performs V operation, but continues to execute

– Performs another P operation before releasing the CPU

– Called a passive implementation of V

• Active implementation calls scheduler as part of the V operation.– Changes semantics of semaphore!– Cause people to rethink solutions

Page 37: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Atomic Lock Manipulation

shared double balance;

shared int lock = FALSE;

P1

enter(lock);

counter++;

exit(lock);

P2

enter(lock); // atomic system call

counter--;

exit(lock);

Page 38: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Atomic Lock Manipulation

enter(lock) { exit(lock) { disableInterrupts(); disableInterrupts();/* Loop until lock is TRUE */ lock = FALSE; while(lock) { enableInterrupts(); /* Let interrupts occur */ } enableInterrupts(); disableInterrupts(); } lock = TRUE; enableInterrupts();}

• Bound the amount of time that interrupts are disabled• Can include other code to check that it is OK to assign a lock• … but this is still overkill …

Page 39: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han
Page 40: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Critical Section

do { flag[i] = TRUE

turn = j; while (flag[j] && turn==j);

critical section

flag[i] = FALSE

remainder section

} while (TRUE)

Page 41: Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han

Critical Section

• Solution: instead disable only on entry and exit. Use a shared variable to control access to another shared variable.– this introduces complexity - what if you’re

interrupted while having the lock?