nachos project 3

32
Nachos Project 3 Lecturer: Hao-Hua Chu TA: Chun-Po Wang (Artoo) Date: 2008/10/25

Upload: euridice-cerelia

Post on 01-Jan-2016

87 views

Category:

Documents


3 download

DESCRIPTION

Nachos Project 3. Lecturer: Hao-Hua Chu TA: Chun-Po Wang (Artoo) Date: 2008/10/25. Project 3. Practice thread synchronization Producer-consumer problem Dining philosophers problem Implement these problems with Nachos thread and synchronization routines. Summary. Motivation & Objective - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Nachos Project 3

Nachos Project 3

Lecturer: Hao-Hua Chu

TA: Chun-Po Wang (Artoo)

Date: 2008/10/25

Page 2: Nachos Project 3

2

Project 3

• Practice thread synchronization– Producer-consumer problem– Dining philosophers problem– Implement these problems with

Nachos thread and synchronization routines

Page 3: Nachos Project 3

3

Summary

• Motivation & Objective• Synchronization Problems• Nachos Synchronization Routines

– Semaphore– Lock– Condition

• Requirement• Submission

Page 4: Nachos Project 3

4

Motivation & Objective

• In previous project, you learnt to run multiple threads.– Now we should practice to make them

work together by implementing some classic synchronization problems

• Nachos has already implemented some class and routines to help you solve these problems

Page 5: Nachos Project 3

5

Synchronization Problems

• Producer-consumer problem– A fixed-size buffer– Producer generates data and put it into buffer– Consumer retrieves data from buffer– They work simultaneously– The objective is to make sure that

• producer won’t put data into buffer when it’s full• consumer won’t remove data from en empty buffer• the state of buffer is consistent after each action

BufferProducer Consumer

Page 6: Nachos Project 3

6

Producer-consumer problem

• When it comes to Nachos …– A buffer may be a global variable, e.g. a

global array– The consumer and the producer would be

threads• Where the problem lies …

– Threads may be yielded at any point– When both threads access the same data,

we must make sure that a thread won’t access it when another is working on it.

– Or, the data may be corrupted

Page 7: Nachos Project 3

7

Synchronization Problems (cont.)

• Dining philosophers problem– 5 philosophers, with 5

chopsticks– A philosopher can either think or

eat– When she/he want to eat,

she/he must take both chopsticks on her/his left and right

– If all philosophers hold one chopstick, we have a deadlock(philosophers are strange, aren’t they?)

http://en.wikipedia.org/wiki/Image:Dining_philosophers.png

Page 8: Nachos Project 3

8

Dining philosophers problem

• Now we deal with 5 threads, apparently

• Figure out a method to prevent deadlock– An easy solution is to make sure

that a philosopher need to pick up both chopsticks at the same time

Page 9: Nachos Project 3

9

Nachos synchronization classes

• code/thread/synch.h and synch.cc• Semaphore

– A counter for a set of available resources– Nachos promised that the actions on semaphores will

not be interrupted• Lock

– A lock can be either BUSY or FREE– Only the thread that acquired the lock can release it– Lock is implemented by semaphores

• Condition– A condition variable is used on monitors, where many

threads wait on this condition– We discuss condition variables when introducing

monitors later

Page 10: Nachos Project 3

10

Semaphore class

• int value; // value >= 0• P(): waits until value > 0, then decreases it• V(): increases the value, and wakes up a

thread waiting in P()• How does OS make these operations

atomic?– Disable interrupts (this method only works on

uniprocessor machines), or– Use special instructions (eg. test-and-set)– Nachos uses the former

Page 11: Nachos Project 3

11

Lock class

• A Lock is implemented by a Semaphore: – value 0 means busy, value 1 means free

• Acquire(): wait until the lock is free, then set it to busy (by calling Semaphore::P())

• Release(): release the lock and wake up a thread waiting on this lock (by calling Semaphore::V())– However, only the thread which acquired the lock

can release it– This is different to a semaphore

Page 12: Nachos Project 3

12

An example

• See class SynchConsoleOutput (code/userprog/synchconsole.cc)

void SynchConsoleOutput::PutChar(char ch){ lock->Acquire(); consoleOutput->PutChar(ch); waitFor->P(); lock->Release();}

void SynchConsoleOutput::CallBack(){ waitFor->V();}

Page 13: Nachos Project 3

13

Monitor

• “A monitor is an approach to synchronize two or more computer tasks that use a shared resource”

• Why use it? Why not just use semaphores?– Programmers are prone to errors

• A monitor consists of– Procedures for manipulating shared resources– A mutual exclusion lock: only one thread can

operate in a monitor at any time– Conditions (optional): sometimes a thread

operating in a monitor must wait for some condition to be true before it proceeds

Page 14: Nachos Project 3

14

Monitor example

• Following pseudo code demonstrate a channel which can only store one integer value at a time

monitor channel { int contents boolean full := false condition snd condition rcv

function send(int message) { while full do wait(rcv) contents := message full := true notify(snd) }

function receive() { var int received

while not full do wait(snd) received := contents full := false notify(rcv) return received }}//End of monitor

Source: http://en.wikipedia.org/wiki/Monitor_(synchronization)

Page 15: Nachos Project 3

15

Condition class

• Nachos DOES NOT provide a Monitor class, but it does provide a Condition class, which can be used to build a “monitor-style” C++ class– E.g. class SynchList

(code/thread/synchlist.cc), this is a List which can be accessed by multiple threads without any synchronization problems

Page 16: Nachos Project 3

16

Condition class (cont.)

• Wait(lock): a thread in a monitor waits for this condition. – The lock is supplied by the monitor which uses this

condition, because when a thread waits, it should release the lock for other threads to operate in the monitor

• Signal(): the condition is met, and a monitor wakes up a thread waiting on this condition.

• Broadcast(): just like Signal(), but now the monitor wakes up all threads waiting on the condition

Page 17: Nachos Project 3

17

Implementation

• Implements producer-consumer problem with semaphores and locks (built by Nachos)

• Implements dining philosopher problem with a monitor-style class (built by you)

Page 18: Nachos Project 3

18

Implementation (cont.)

• Make Nachos run producer-consumer problem with flag -PC, and run dining philosopher problem with flag -DP– Just like -K (ThreadSelfTest) and -S

(previous project) flags

Page 19: Nachos Project 3

19

Producer-Consumer problem

• Produce and consume 30 items: 0~29• The buffer size is 5• Print the item number you produced or consumed, and

the current total number of items in the shared buffer// Thread body for producervoid Producer(int arg) {

int i;for(i=0;i<30;i++){

// Produce item i here (maybe stores it in a global array)printf("Produced item %d, Total %d item(s)\n“, ...);

}}

// Thread body for consumervoid Consumer(int arg) {

int i;for(i=0;i<30;i++){

// Consume item i here (maybe retrieve it from a global array)printf(“Consumed item %d, Total %d item(s)\n“, ...);

}}

Page 20: Nachos Project 3

20

Producer-Consumer problem (cont.)

• Sample output:

Produced item 0, Total 1 item(s)Produced item 1, Total 2 item(s)Consumed item 0, Total 1 item(s)Consumed item 1, Total 0 item(s)Produced item 2, Total 1 item(s)Produced item 3, Total 2 item(s)Produced item 4, Total 3 item(s)Consumed item 2, Total 2 item(s)Produced item 5, Total 3 item(s)Consumed item 3, Total 2 item(s)Consumed item 4, Total 1 item(s)Produced item 6, Total 2 item(s)Consumed item 5, Total 1 item(s)Produced item 7, Total 2 item(s)Produced item 8, Total 3 item(s)Produced item 9, Total 4 item(s)Consumed item 6, Total 3 item(s)...

Page 21: Nachos Project 3

21

Dining Philosopher problem

• Following skeleton is an example, you can design by yourself

• A monitor-style class DiningTable:• We have 5 philosophers (0~4), which means

5 threads• Each philosopher starts at thinking, then

eating, then thinking … for 10 times• Print what a philosopher is doing when

she/he starts to do that

Page 22: Nachos Project 3

22

Dining Philosopher problem (cont.)

class DiningTable {public: void pickup (int it, int id) { // Philosopher “id” wants to eat for the “it”-th times printf(“%d: Philosopher %d is eating\n”, it, id); }

void putdown (int it, int id) { // Philosopher “id” goes back to think for the “it”-th times printf(“%d: Philosopher %d is thinking\n”, it, id); }}

DiningTable dining_table;// Thread body for each philosophervoid philosopher (int id) { for(int i=0; i<10; i++) { dining_table.pickup(i, id); dining_table.putdown(i, id); }}

Page 23: Nachos Project 3

23

Dining Philosopher problem (cont.)

• Sample output:

0: Philosopher 0 is eating0: Philosopher 0 is thinking1: Philosopher 0 is eating0: Philosopher 3 is eating0: Philosopher 3 is thinking0: Philosopher 2 is eating1: Philosopher 0 is thinking0: Philosopher 2 is thinking0: Philosopher 1 is eating0: Philosopher 1 is thinking1: Philosopher 1 is eating1: Philosopher 1 is thinking0: Philosopher 4 is eating0: Philosopher 4 is thinking2: Philosopher 0 is eating1: Philosopher 3 is eating...

Page 24: Nachos Project 3

24

Please do me a favor

• We all know that in a real system synchronization problems arise because threads can be interrupted at any point

• However, currently we are working in Nachos kernel, not in user programs, and we don’t call OneTick() so no interrupts would occur in our thread body implementations.

• Things will become too easy…

Page 25: Nachos Project 3

25

Please do me a favor (cont.)

• So, let’s make it HARD!• Please put following code into your

thread bodies, and every functions you built which may be called in thread bodies.

• This code will call kernel->currentThread->Yield() with some probability, effectively interrupts your code at any point.

Page 26: Nachos Project 3

26

Please do me a favor (cont.)

#define PY { if(rand()%5==0) { kernel->currentThread->Yield(); } }...class DiningTable {public: void pickup (int it, int id) {PY printf(“%d: Philosopher %d is eating\n”, it, id); }

void putdown (int it, int id) {PY printf(“%d: Philosopher %d is thinking\n”, it, id); }}...void philosopher (int id) {PY for(int i=0; i<10; i++) {PY dining_table.pickup(i, id);PY dining_table.putdown(i, id);PY }}

Page 27: Nachos Project 3

27

Please do me a favor (cont.)

• Please add “{ }” to all if-else and for,while loops, or this macro would mess up your program.

• You can change random seed to see different results by using flag “-rs”– ./nachos -rs 100 -PC– Please test with different random seed to

make sure that your implementations are correct

Page 28: Nachos Project 3

28

Some notes

• Just like Thread, Semaphore, Lock, and Condition all have a name argument in constructor: please DO NOT provide a local string to them

• You should make sure that main thread (the only thread which builds other threads) “waits” until other threads finish– How to do? This is also a synchronization

problem (an easy one)

Page 29: Nachos Project 3

29

Requirement

• Implement 2 synchronization problems– Make sure that no deadlock would occur– The output should be reasonable

• E.g. in first problem, following output is wrong

• E.g. in second problem, following output is wrong

Produced item 0, Total 1 item(s)Produced item 1, Total 1 item(s) # Total should be 2Consumed item 2, Total 1 item(s) # Item 2 is not generated yet

0: Philosopher 0 is eating0: Philosopher 1 is eating # Ph. 1 cannot eat because Ph. 0 is eating and holding the chopstick Ph. 1 needs

Page 30: Nachos Project 3

30

Requirement

• Write a 2-page report– Don’t just paste your code, I’ll read it myself– Explain why your implementations would

generate correct output, and why there is no deadlock

• If your project submission can’t compile and execute on Linux in Workstation Room 217, we will consider it as fail.– Please contact me to apply a workstation account

if you need it.

Page 31: Nachos Project 3

31

Submission

• Two people in one group (Write down the name and student ID of all members in the report)

• The file you need to send:1. A report in .pdf or .doc2. threads.cc, threads.h, and main.cc

• Send your files– Tar your files to an archieve named:

os_hw3_bXXXXXXXX_bOOOOOOOO.tar.gz– E-mail to [email protected] with following title:

[os_hw3] bXXXXXXXX_bOOOOOOOO– Please follow the format carefully or our auto-reply

system will not work

tar zcvf os_hw3_bXXXXXXXX_bOOOOOOOO.tar.gz report.doc other files...

Page 32: Nachos Project 3

32

Submission (cont.)

• Deadline: 11/10 24:00– For the delayed submission, deduct

5 points for each day

• DO NOT COPY!!Protect your code well!!