CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where...

26
CPS110: Implementing threads Landon Cox

Transcript of CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where...

Page 1: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

CPS110: Implementing threads

Landon Cox

Page 2: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Recap and looking ahead

HardwareHardware

OSOS

ApplicationsApplications

Where we’ve been Where we’re

going

Page 3: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Recall, thread interactions

1. Threads can access shared data E.g., use locks, monitors What we’ve done so far

2. Threads also share hardware CPU and memory

For this class, assume uni-processor Single CPU core: one thread runs at a time Unrealistic in the multicore era!

Page 4: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Hardware, OS interfaces

HardwareHardware

OSOS

ApplicationsApplications

MemoryMemory CPUCPU

CPU, MemCPU, Mem

Job 1Job 1CPU, MemCPU, Mem

Job 2Job 2CPU, MemCPU, Mem

Job 3Job 3

Remaining thread lecturesMemory lectures

Thread lectures up to this point

Page 5: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

The play analogy

Process is like a play performance Program is like the play’s script One CPU is like a one-man-show

(actor switches between roles)

Threads

Address space

Page 6: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Threads that aren’t running

What is a non-running thread? thread=“stream of executing instructions” non-running thread=“paused execution” Blocked/waiting, or suspended but ready

Must save thread’s private state Leave stack etc. in memory where it lies Save registers to memory Reload registers to resume thread

Page 7: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Private vs global thread state

What state is private to each thread? PC (where actor is in his/her script) Stack, SP (actor’s mindset)

What state is shared? Code (like lines of a play) Global variables, heap (props on set)

Page 8: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Thread control block (TCB)

The software that manages threads and schedules/dispatches them is the thread system or “OS”

OS must maintain data to describe each thread Thread control block (TCB) Container for non-running thread’s private data Values of PC, SP, other registers (“context”) Each thread also has a stack

Other OS data structures (scheduler queues, locks, waiting lists) reference these TCB objects.

Page 9: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Thread control block

CPUCPU

Address SpaceAddress Space

TCB1PCSP

registers

TCB1PCSP

registers

TCB2PCSP

registers

TCB2PCSP

registers

TCB3PCSP

registers

TCB3PCSP

registers

CodeCode

StackStackCodeCode

StackStackCodeCode

StackStack

PCSP

registers

PCSP

registersThread 1 running

Ready queue

Page 10: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Thread states

Running Currently using the CPU

Ready (suspended) Ready to run when CPU is next

available Blocked (waiting or sleeping)

Stuck in lock (), wait () or down ()

Page 11: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Switching threads

What needs to happen to switch threads?1.Thread returns control to OS

For example, via the “yield” call

2.OS chooses next thread to run3.OS saves state of current thread

To its thread control block

4.OS loads context of next thread From its thread control block

5.Run the next thread

Project 1: swapcontext

Page 12: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

1. Thread returns control to OS

How does the thread system get control? Voluntary internal events Thread might block inside lock or wait Thread might call into kernel for service

(system call)

Thread might call yield

Are internal events enough?

Page 13: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

1. Thread returns control to OS

Involuntary external events (events not initiated by the thread) Hardware interrupts

Transfer control directly to OS interrupt handlers From 104

CPU checks for interrupts while executing Jumps to OS code with interrupt mask set

OS may preempt the running thread (force yield) when an interrupt gives the OS control of its CPU

Common interrupt: timer interrupt

Page 14: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

2. Choosing the next thread

If no ready threads, just spin Modern CPUs: execute a “halt” instruction Project 1: exit if no ready threads

Loop switches to thread if one is ready Many ways to prioritize ready threads

Will discuss a little later in the semester

Page 15: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

3. Saving state of current thread

What needs to be saved? Registers, PC, SP

What makes this tricky? Self-referential sequence of actions Need registers to save state But you’re trying to save all the

registers Saving the PC is particularly tricky

Page 16: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Saving the PC

Why won’t this work?

Returning thread will execute instruction at 100 And just re-execute the switch Really want to save address 102

100 store PC in TCB101 switch to next thread

Instruction address

Page 17: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

4. OS loads the next thread

Where is the thread’s state/context? Thread control block (in memory)

How to load the registers? Use load instructions to grab from

memory How to load the stack?

Stack is already in memory, load SP

Page 18: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

5. OS runs the next thread

How to resume thread’s execution? Jump to the saved PC

On whose stack are these steps running? or Who jumps to the saved PC?

The thread that called yield (or was interrupted or called lock/wait)

How does this thread run again? Some other thread must switch to it

Page 19: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Example thread switchingThread 1 print “start thread 1” yield () print “end thread 1”

Thread 2 print “start thread 2” yield () print end thread 2”

yield () print “start yield (thread %d)” swapcontext (tcb1, tcb2) print “end yield (thread %d)”

swapcontext (tcb1, tcb2) save regs to tcb1 load regs from tcb2 // sp points to tcb2’s stack now! jump tcb2.pc // sp must point to tcb1’s stack! return

Thread 1 output Thread 2 output--------------------------------------------start thread 1start yield (thread 1)

start thread 2 start yield (thread 2)

end yield (thread 1)end thread 1

end yield (thread 2) end thread 2

Note: this assumes no pre-emptions.If OS is preemptive, then other interleavings are possible.

Page 20: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Thread states

BlockedBlockedReadyReady

RunningRunning

Thread is scheduled

Thread is Pre-empted(or yields)

Thread callsLock or wait(or makes I/O request)

Another thread calls

unlock or signal (or I/O completes)

??

Page 21: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Creating a new thread

Also called “forking” a thread Idea: create initial state, put on ready queue1.Allocate, initialize a new TCB2.Allocate a new stack3.Make it look like thread was going to call a

function PC points to first instruction in function SP points to new stack Stack contains arguments passed to function Project 1: use makecontext

4.Add thread to ready queue

Page 22: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Creating a new thread

Parentreturncall

Parentthread_create (parent work)

(child work)Child

Page 23: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Thread join

How can the parent wait for child to finish?

ParentParentthread_createthread_create (parent work)(parent work)

(child work)(child work)ChildChild

joinjoin

Page 24: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Thread join

Will this work? Sometimes, assuming

Uni-processor No pre-emptions Child runs after parent

Never, ever assume these things! Yield is like slowing the CPU

Program must work +- any yields

child () { print “child works”}

parent () { create child thread print “parent works” yield () print “parent continues”}

parent workschild worksparent continues

child worksparent worksparent continues

Page 25: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

Thread join Will this work?

No. Child can call signal first. Would this work with semaphores?

Yes No missed signals (increment sem value)

child () { lock print “child works” signal unlock}

parent () { create child thread lock print “parent works” wait print “parent continues” unlock} parent works

child worksparent continues

child worksparent worksparent continues

213

Page 26: CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.

How can we solve this?

Pair off for a couple of minuteschild () {

}

parent () {

}

parent workschild worksparent continues

child worksparent worksparent continues