cop 4600 operating systems spring 2011

25
COP 4600 Operating Systems Spring 2011 Dan C. Marinescu Office: HEC 304 Office hours: Tu-Th 5:00-6:00 PM

Upload: grady

Post on 22-Feb-2016

32 views

Category:

Documents


0 download

DESCRIPTION

COP 4600 Operating Systems Spring 2011. Dan C. Marinescu Office: HEC 304 Office hours: Tu-Th 5:00-6:00 PM. Last time: Threads Thread state Processor switching - YIELD system call Today: Processor switching Communication with a bounded buffer Next time - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: COP 4600 Operating Systems Spring 2011

COP 4600 Operating Systems Spring 2011

Dan C. MarinescuOffice: HEC 304 Office hours: Tu-Th 5:00-6:00 PM

Page 2: COP 4600 Operating Systems Spring 2011

Last time: Threads Thread state Processor switching - YIELD system call

Today: Processor switching Communication with a bounded buffer

Next time Communication with a bounded buffer Semaphores Deadlocks

Lecture 17 – Thursday, March 24, 2011

Lecture 17 2

Page 3: COP 4600 Operating Systems Spring 2011

YIELD System call executed by the kernel at the request of an application

allows an active thread A to voluntarily release control of the processor. YIELD invokes the ENTER_PROCESSOR_LAYER procedure

locks the thread table and unlock it when it finishes it work changes the state of thread A from RUNNING to RUNNABLE invokes the SCHEDULER the SCHEDULER searches the thread table to find another tread B in RUNNABLE state the state of thread B is changed from RUNNABLE to RUNNING the registers of the processor are loaded with the ones saved on the stack for thread B thread B becomes active

Why is it necessary to lock the thread table? We may have multiple cores/processors so another thread my be active. An interrupt may occur

The pseudo code assumes that we have a fixed number of threads, 7. The flow of control YIELDENTER_PROCESSOR_LAYERSCHEDULEREXIT_PROCESSOR_LAYERYIELD

Lecture 17 3

Page 4: COP 4600 Operating Systems Spring 2011

shared structure processor_table(2) integer thread_idshared structure thread_table(7) integer topstack integer stateshared lock instance thread_table_lock

procedure GET_THREAD_ID() return processor_table(CPUID).thread_id

procedure YIELD() ACQUIRE (thread_table_lock) ENTER_PROCESSOR_LAYER(GET_THREAD_ID()) RELEASE(thread_table_lock)return

procedure ENTER_PROCESSOR_LAYER(this_thread) thread_table(this_thread).state ß RUNNABLE thread_table(this_thread).topstackß SP SCHEDULER()return

procedure SCHEDULER() jß _GET_THREAD_ID() do jß j+1 (mod 7)

while thread_table(j).state¬= RUNNABLE thread_table(j).state ß RUNNING processor_table(CPUID).thread_idß j EXIT_PROCESSOR_LAYER(j) return

procedure EXIT_PROCESSOR_LAYER(new) SPß thread_table(new).topstack return

Save SP of YIELD before SCH

Restore SP of YIELD Return to YIELD

Release lock after RETURN from Exit_PL

Skip running threads

4Lecture 17

Page 5: COP 4600 Operating Systems Spring 2011

Dynamic thread creation and termination

Until now we assumed a fixed number, 7 threads; the thread table was of fixed size.

We have to support two other system calls: EXIT_THREAD Allow a tread to self-destroy and clean-up DESTRY_THREAD Allow a thread to terminate another thread of the same application

Lecture 17 5

Page 6: COP 4600 Operating Systems Spring 2011

Important facts to remember

Each thread has a unique ThreadId Threads save their state on the stack. The stack pointer of a thread is stored in the thread table. To activate a thread the registers of the processor are loaded with

information from the thread state. What if no thread is able to run

create a dummy thread for each processor called a processor_thread which is scheduled to run when no other thread is available

the processor_thread runs in the thread layer the SCHEDULER runs in the processor layer

We have a processor thread for each processor/core.

Lecture 17 6

Page 7: COP 4600 Operating Systems Spring 2011

System start-up procedure

Procedure RUN_PROCESSORS() for each processor do allocate stack and setup processor thread /*allocation of the stack done at

processor layer shutdown FALSE SCHEDULER() deallocate processor_thread stack /*deallocation of the stack done at processor

layer halt processor

Lecture 17 7

Page 8: COP 4600 Operating Systems Spring 2011

Switching threads with dynamic thread creation Switching from one user thread to another requires two steps

Switch from the thread releasing the processor to the processor thread Switch from the processor thread to the new thread which is going to have the

control of the processor The last step requires the SCHEDULER to circle through the thread_table until a

thread ready to run is found The boundary between user layer threads and processor layer

thread is crossed twice Example: switch from thread 0 to thread 6 using

YIELD ENTER_PROCESSOR_LAYER EXIT_PROCESSOR_LAYER

Lecture 17 8

Page 9: COP 4600 Operating Systems Spring 2011

Dynamic thread creation/destruction

As before, the control flow is not obvious as some of the procedures reload the stack pointer (SP)

When a procedure reloads the stack pointer then the place where it transfers control when it executes a return is the procedure whose SP was saved on the stack and was reloaded before the execution of the return.

ENTER_PROCESSOR_LAYER Changes the state of the thread calling YIELD from RUNNING to RUNNABLE Save the state of the procedure calling it , YIELD, on the stack Loads the processors registers with the state of the processor thread, thus starting the

SCHEDULER EXIT_PROCESSOR_LAYER

Saves the state of processor thread into the corresponding PROCESSOR_TABLE and loads the state of the thread selected by the SCHEDULER to run (in our example of thread 6) in the processor’s registers

Loads the SP with the values saved by the ENTER_PROCESSOR_LAYER

Lecture 17 9

Page 10: COP 4600 Operating Systems Spring 2011

Lecture 17 10

Page 11: COP 4600 Operating Systems Spring 2011

Lecture 17 11

Page 12: COP 4600 Operating Systems Spring 2011

Lecture 17 12

Page 13: COP 4600 Operating Systems Spring 2011

Lecture 17 13

Page 14: COP 4600 Operating Systems Spring 2011

Thread coordination with bounded buffers Bounded buffer the virtualization of a communication channel Thread coordination

Locks for serialization Bounded buffers for communication

Producer thread writes data into the buffer Consumer thread read data from the buffer

Basic assumptions: We have only two threads Threads proceed concurrently at independent speeds/rates Bounded buffer – only N buffer cells Messages are of fixed size and occupy only one buffer cell.

Spin lock a thread keeps checking a control variable/semaphore “until the light turns

green.” feasible only when the threads run on a different processors (how could

otherwise give a chance to other threads?)

Lecture 17 14

Page 15: COP 4600 Operating Systems Spring 2011

1 2 N-1N-2

out

in

Read from the bufferlocation

pointed by out

Write to the bufferlocation

pointed by out

shared structure buffer message instance message[N] integer in initially 0 integer out initially 0

procedure SEND (buffer reference p, message instance msg) while p.in – p.out = N do nothing /* if buffer full wait p.message [p.in modulo N] ß msg /* insert message into buffer cell p.in ß p.in + 1 /* increment pointer to next free cell

procedure RECEIVE (buffer reference p) while p.in = p.out do nothing /* if buffer empty wait for message msgß p.message [p.in modulo N] /* copy message from buffer cell p.out ß p.out + 1 /* increment pointer to next message return msg

0 1

Lecture 17 15

Page 16: COP 4600 Operating Systems Spring 2011

Implicit assumptions for the correctness of the implementation1. One sending and one receiving thread. Only one thread updates each

shared variable.2. Sender and receiver threads run on different processors to allow spin

locks3. in and out are implemented as integers large enough so that they do not

overflow (e.g., 64 bit integers)4. The shared memory used for the buffer provides read/write coherence5. The memory provides before-or-after atomicity for the shared variables in

and out 6. The result of executing a statement becomes visible to all threads in

program order. No compiler optimization supported

Lecture 17 16

Page 17: COP 4600 Operating Systems Spring 2011

In practice….. Threads run concurrently Race conditions may occur data in the buffer may be overwritten a lock for the bounded buffer the producer acquires the lock before writing the consumer acquires the lock before reading

Lecture 17 17

Page 18: COP 4600 Operating Systems Spring 2011

time

Operations of Thread A

Buffer is empty

in=out=0

on=out=0

Fill entry 0 at time t1 with item b

0

Operations of Thread B

Fill entry 0 at time t2with item a

Increment pointer at time t3

inß 1

Increment pointer at time t4

inß 2

Two senders execute the code concurrently

Processor 1 runs thread A

Processor 2 runs thread B

Memory contains shared dataBuffer, In, Out

Processor-memory bus

Item b is overwritten, it is lost

t1 t4t3t2

Lecture 17 18

Page 19: COP 4600 Operating Systems Spring 2011

We have to avoid deadlocks

If a producer thread cannot write because the buffer is full it has to release the lock to allow the consumer thread to acquire the lock to read, otherwise we have a deadlock.

If a consumer thread cannot read because the there is no new item in the buffer it has to release the lock to allow the consumer thread to acquire the lock to write, otherwise we have a deadlock.

Lecture 17 19

Page 20: COP 4600 Operating Systems Spring 2011

Lecture 17 20

Page 21: COP 4600 Operating Systems Spring 2011

In practice…

We have to ensure atomicity of some operations, e.g., updating the pointers

Lecture 17 21

Page 22: COP 4600 Operating Systems Spring 2011

One more pitfall of the previous implementation of bounded buffer

If in and out are long integers (64 or 128 bit) then a load requires two registers, e.,g, R1 and R2.

int “00000000FFFFFFFF” L R1,int /* R1 00000000 L R2,int+1 /* R2 FFFFFFFF Race conditions could affect a load or a store of the long integer.

Lecture 17 22

Page 23: COP 4600 Operating Systems Spring 2011

time

Another manifestation of race conditions à incrementing a pointer is not atomic

in ß in+11. L R1,in

2. ADD R1,1

3. ST R1,in

Operations of Thread A

Operations of Thread B

A1 A2 A3

B1 B2 B3

inß 1 inß 2

Correct execution

Operations of Thread A

Operations of Thread B

A1 A2 A3

B1 B2 B3

inß 1 inß 1

Incorrect execution

Lecture 17 23

Page 24: COP 4600 Operating Systems Spring 2011

In practice the threads may run on the same system…. We cannot use spinlocks for a thread to wait until an event occurs. That’s why we have spent time on YIELD…

Lecture 17 24

Page 25: COP 4600 Operating Systems Spring 2011

1 2 N-1N-2

out

inRead from the bufferlocation pointed by out

Write to the bufferlocation pointed by out

shared structure buffer message instance message[N] integer in initially 0 integer out initially 0 lock instance buffer_lock initially UNLOCKED

procedure SEND (buffer reference p, message instance msg) ACQUIRE (p_buffer_lock) while p.in – p.out = N do /* if buffer full wait RELEASE (p_buffer_lock) YIELD() ACQUIRE (p_buffer_lock) p.message [p.in modulo N] ß msg /* insert message into buffer cell p.in ß p.in + 1 /* increment pointer to next free cell RELEASE (p_buffer_lock)

procedure RECEIVE (buffer reference p) ACQUIRE (p_buffer_lock) while p.in = p.out do /* if buffer empty wait for message RELEASE (p_buffer_lock) YIELD() ACQUIRE (p_buffer_lock) msgß p.message [p.in modulo N] /* copy message from buffer cell p.out ß p.out + 1 /* increment pointer to next message return msg

0 1

25Lecture 17