Upload
penelope-duncan
View
36
Download
2
Embed Size (px)
DESCRIPTION
2-Dining Puppies Mutex Failure. Outline for Today. Objective: Reader-writer problem Message Passing Administrative details:. Readers/Writers Problem. - PowerPoint PPT Presentation
Citation preview
1
2-Dining Puppies Mutex Failure
2
Outline for Today• Objective:
– Reader-writer problem– Message Passing
• Administrative details:
3
Readers/Writers Problem
Synchronizing access to a file or data record in a database such that any number of threads requesting read-only access are allowed but only one thread requesting write access is allowed, excluding all readers.
4
Template for Readers/WritersReader(){while (true)
{
read
}}
Writer(){while (true)
{
write
}}
/*request r access*/
/*release r access*/
/*request w access*/
/*release w access*/
5
Template for Readers/WritersReader(){while (true)
{
read
}}
Writer(){while (true)
{
write
}}
fd = open(foo, 0);
close(fd);
fd = open(foo, 1);
close(fd);
6
Template for Readers/WritersReader(){while (true)
{
read
}}
Writer(){while (true)
{
write
}}
startRead();
endRead();
startWrite();
endWrite();
7
R/W - Monitor StyleBoolean busy = false;
int numReaders = 0;
Lock filesMutex;
Condition OKtoWrite, OKtoRead;
void startRead () {
filesMutex.Acquire( );
while ( busy )
OKtoRead.Wait(&filesMutex);
numReaders++;
filesMutex.Release( );}
void endRead () {
filesMutex.Acquire( );
numReaders--;
if (numReaders == 0)
OKtoWrite.Signal(&filesMutex);
filesMutex.Release( );}
void startWrite() {
filesMutex.Acquire( );
while (busy || numReaders != 0)
OKtoWrite.Wait(&filesMutex);
busy = true;
filesMutex.Release( );}
void endWrite() {
filesMutex.Acquire( );
busy = false;
OKtoRead.Broadcast(&filesMutex); OKtoWrite.Signal(&filesMutex);
filesMutex.Release( );}
8
Guidelines for Choosing Lock Granularity
1. Keep critical sections short. Push “noncritical” statements outside of critical sections to reduce contention.
2. Limit lock overhead. Keep to a minimum the number of times mutexes are acquired and released.
Note tradeoff between contention and lock overhead.
3. Use as few mutexes as possible, but no fewer.Choose lock scope carefully: if the operations on two different data
structures can be separated, it may be more efficient to synchronize those structures with separate locks.
Add new locks only as needed to reduce contention. “Correctness first, performance second!”
9
Semaphore Solution
int readCount = 0;
semaphore mutex = 1;
semaphore writeBlock = 1;
10
Reader(){
while (TRUE) {
other stuff;
P(mutex);
readCount = readCount +1;
if(readCount == 1)
P(writeBlock);
V(mutex);
access resource;
P(mutex);
readCount = readCount -1;
if(readCount == 0)
V(writeBlock);
V(mutex); }}
Writer(){
while(TRUE){
other stuff;
P(writeBlock);
access resource;
V(writeBlock);
}}
11
Attempt at Writer Priority
int readCount = 0, writeCount = 0;
semaphore mutex1 = 1, mutex2 = 1;
semaphore readBlock = 1;
semaphore writeBlock = 1;
12
Reader(){ while (TRUE) { other stuff; P(readBlock); P(mutex1); readCount = readCount +1; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); access resource; P(mutex1); readCount = readCount -1; if(readCount == 0) V(writeBlock); V(mutex1); }}
Writer(){ while(TRUE){ other stuff; P(mutex2); writeCount = writeCount +1; if (writeCount == 1) P(readBlock); V(mutex2); P(writeBlock); access resource; V(writeBlock); P(mutex2); writeCount - writeCount - 1; if (writeCount == 0) V(readBlock); V(mutex2); }}
Reader2
Writer1
Reader1
13
Reader(){ while (TRUE) { other stuff; P(readBlock); P(mutex1); readCount = readCount +1; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); access resource; P(mutex1); readCount = readCount -1; if(readCount == 0) V(writeBlock); V(mutex1); }}
Writer(){ while(TRUE){ other stuff; P(mutex2); writeCount = writeCount +1; if (writeCount == 1) P(readBlock); V(mutex2); P(writeBlock); access resource; V(writeBlock); P(mutex2); writeCount - writeCount - 1; if (writeCount == 0) V(readBlock); V(mutex2); }}
Reader2
Writer1Reader1
14
Reader(){ while (TRUE) { other stuff; P(writePending); P(readBlock); P(mutex1); readCount = readCount +1; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); V(writePending); access resource; P(mutex1); readCount = readCount -1; if(readCount == 0) V(writeBlock); V(mutex1); }}
Writer(){ while(TRUE){ other stuff; P(mutex2); writeCount = writeCount +1; if (writeCount == 1) P(readBlock); V(mutex2); P(writeBlock); access resource; V(writeBlock); P(mutex2); writeCount - writeCount - 1; if (writeCount == 0) V(readBlock); V(mutex2); }}
15
Reader(){ while (TRUE) { other stuff; P(writePending); P(readBlock); P(mutex1); readCount = readCount +1; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); V(writePending); access resource; P(mutex1); readCount = readCount -1; if(readCount == 0) V(writeBlock); V(mutex1); }}
Writer(){ while(TRUE){ other stuff; P(mutex2); writeCount = writeCount +1; if (writeCount == 1) P(readBlock); V(mutex2); P(writeBlock); access resource; V(writeBlock); P(mutex2); writeCount - writeCount - 1; if (writeCount == 0) V(readBlock); V(mutex2); }}
Reader1
Writer1
Reader2
Assumptions about semaphore semantics?
16
Reader(){ while (TRUE) { other stuff; P(writePending); P(readBlock); P(mutex1); readCount = readCount +1; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); V(writePending); access resource; P(mutex1); readCount = readCount -1; if(readCount == 0) V(writeBlock); V(mutex1); }}
Writer(){ while(TRUE){ other stuff; P(mutex2); writeCount = writeCount +1; if (writeCount == 1) P(readBlock); V(mutex2); P(writeBlock); access resource; V(writeBlock); P(mutex2); writeCount - writeCount - 1; if (writeCount == 0) V(readBlock); V(mutex2); }}
Assume the writePending semaphore was omitted. What would happen?
Reader1
Writer1
Reader2
17
Assume the writePending semaphore was omitted in the solution just given. What would happen?
This is supposed to give writers priority. However, consider the following sequence:
Reader 1 arrives, executes thro’ P(readBlock);
Reader 1 executes P(mutex1);
Writer 1 arrives, waits at P(readBlock);
Reader 2 arrives, waits at P(readBlock);
Reader 1 executes V(mutex1); then V(readBlock);
Reader 2 may now proceed…wrong
18
Linux Reader/Writer Spinlocks• Class of reader/writer
problems• Multiple readers OK• Mutual exclusion for
writers• No upgrade from reader
lock to writer lock• Favors readers –
starvation of writers possible
rwlock_t
read_lock,read_unlockread_lock_irq // also unlock
read_lock_irqsave
read_unlock_irqrestore
write_lock,write_unlock//_irq,_irqsave,_irqrestore
write_trylock
rw_is_locked
19
Linux Reader/Writer Semaphores
• All reader / writer semaphores are mutexes (usage count 1)
• Multiple readers, solo writer
• Uninterruptible sleep• Possible to
downgrade writer to reader
down_read
down_write
up_read
up_write
downgrade_writer
down_read_trylock
down_write_trylock
20
Message-Passing
21
Interprocess Communication - Messages
• Assume no explicit sharing of data elements in the address spaces of processes wishing to cooperate/communicate.
• Essence of message-passing is copying (although implementations may avoid actual copies whenever possible).
• Problem-solving with messages - has a feel of more active involvement by participants.
22
Issues
• System calls for sending and receiving messages with the OS(s) acting as courier.– Variations on exact semantics of primitives and in the
definition of what comprises a message.
• Naming - direct (to/from pids), indirect (to distinct objects - e.g., mailboxes, ports, sockets)– How do unrelated processes “find” each other?
• Buffering - capacity and blocking semantics.• Guarantees - in-order delivery? no lost messages?
23
Send and Receive
24
UNIX Sockets for Client/ Server Message Passing
Server1. Create a named socket
syscalls:sfd = socket(…)bind (sfd, ptr,len)
2. Listen for clientslisten(sfd,numpend)
4. Connection made and continue listeningcfd=accept(sfd, …)
5. Exchange datawrite(cfd, …)
6. Done: close(cfd);7. Really done: close(sfd);
Client
3. Create unnamed socket & ask for connectionsyscalls:cfd=socket(…)err=connect(cfd, ptr, …)
5. Exchange data read(cfd, …)
6. Done: close(cfd);
name
name
In a child process of server
25
5 DP – Direct Send/Receive Message Passing Between Philosophers
Philosopher 0(thinking)
Philosopher 1
Philosopher 2
Philosopher 3(eating)
Philosopher 4
Forkplease?
26
Philosopher 0(thinking)
Philosopher 1
Philosopher 2
Philosopher 3(eating)
Philosopher 4
Umm. Oh yeah.
27
Philosopher 0(thinking)
Philosopher 1
Philosopher 2
Philosopher 3(eating)
Philosopher 4
Forkplease?
28
Philosopher 0(thinking)
Philosopher 1
Philosopher 2
Philosopher 3(eating)
Philosopher 4
Forkplease?
I’ll ignorethat requestuntil I’m done
29
Philosopher 0(thinking)
Philosopher 1
Philosopher 2
Philosopher 3(eating)
Philosopher 4Forkplease?
Forkplease?
30
Client / Server
server->
Start here
31
Example: Time Service
32
Example: Time Service via Messages
33
Client / Server with Threads
34
Hiding Message-Passing: RPC
35
Remote Procedure Call - RPC
• Looks like a nice familiar procedure call
P0
result = foo(param);
P1
Receive
36
Remote Procedure Call - RPC
• Looks like a nice familiar procedure call
P0
result = foo(param);please do foo for P0
with param
P1
Receive
blockedhere
37
Remote Procedure Call - RPC
• Looks like a nice familiar procedure call
P0
result = foo(param);please do foo for P0
with param
P1
Receiver = foo(param);// actual callblocked
here
38
Remote Procedure Call - RPC
• Looks like a nice familiar procedure call
P0
result = foo(param);
P1
Receiver = foo(param);// actual call
Replyreturningr to P0
blockedhere
39
Remote Procedure Call - RPC
• Looks like a nice familiar procedure call
P0
result = foo(param);
P1
Receiver = foo(param);// actual call
Replyreturningr to P0
40
Remote Procedure Call - RPC
• Looks like a nice familiar procedure call
P0
result = foo(param);
P1
Receiver = foo(param);// actual call
Reply
41
5DP via RPC with Fork Manager
• Looks like a nice familiar procedure call
Philosopher0
result = PickupForks (0);
Fork Server
Receiver = proc(param);// explicit queuingwhen necessary
Reply
42
Example: Time Service via RPC
44
RPC Issues