Context-switch & Threads Goal of Todays Class Understand the - - PowerPoint PPT Presentation

context switch threads goal of today s class
SMART_READER_LITE
LIVE PREVIEW

Context-switch & Threads Goal of Todays Class Understand the - - PowerPoint PPT Presentation

Context-switch & Threads Goal of Todays Class Understand the concepts of context, context-switch and threads Understand the related functions in assignment P1 thread_init, thread_create, thread_yield, thread_exit ctx_entry,


slide-1
SLIDE 1

Context-switch & Threads

slide-2
SLIDE 2

Goal of Today’s Class

  • Understand the concepts of context, context-switch and threads
  • Understand the related functions in assignment P1
  • thread_init, thread_create, thread_yield, thread_exit
  • ctx_entry, ctx_start, ctx_switch
slide-3
SLIDE 3

Review: the minimal requirement of program execution is code & stack segments in memory address space.

slide-4
SLIDE 4

Assume 2 programs in memory

stack end … … … stack start … … … code end … … … code start … … … stack end … … … stack start … … … code end … … … code start …

program#1 stack program#1 code program#2 stack program#2 code OS puts the code & stack of both programs in the memory so that they can take turns to execute.

slide-5
SLIDE 5

Review: context defines which program the CPU is executing; context = memory address space + stack pointer + instruction pointer

slide-6
SLIDE 6

CPU in the context of program #1

program #1 stack end … … … program #1 stack start … … … program #1 code end … … … program #1 code start … … … program #2 stack end … … … program #2 stack start … … … program #2 code end … … … program #2 code start …

CPU

Stack pointer register Instruction pointer register

slide-7
SLIDE 7

CPU in the context of program #2

CPU

Stack pointer register Instruction pointer register

program #1 stack end … … … program #1 stack start … … … program #1 code end … … … program #1 code start … … … program #2 stack end … … … program #2 stack start … … … program #2 code end … … … program #2 code start …

slide-8
SLIDE 8

Context-switch

CPU switches to the context of program #2

slide-9
SLIDE 9

Context-switch

CPU switches to the context of program #1

slide-10
SLIDE 10

Question: when does context- switch happen?

slide-11
SLIDE 11

When does context-switch happen?

  • Program terminates.
  • Program calls yield system call. (next slide)
  • CPU receives a timer interrupt. (later in assignment P2)
  • CPU receives an I/O interrupt. (later in assignment P5)
slide-12
SLIDE 12

yield is a noble behavior

A car can occupy the road, but it decides to stop and let others to use the road first.

int noble_a() { …… yield(); …… }

A program can occupy the CPU, but it decides to stop and let others to use the CPU first.

slide-13
SLIDE 13

Two noble functions

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

slide-14
SLIDE 14

One possible schedule

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

1 2 3 4 5 6

Output: Noble A does some work Noble B does some work Noble A works some more Noble B works some more

slide-15
SLIDE 15

Another possible schedule

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

3 4 1 2 6 5

Output: Noble B does some work Noble A does some work Noble B works some more Noble A works some more

slide-16
SLIDE 16

Question: how do we run two functions at the same time?

Let’s review some knowledge of stack.

slide-17
SLIDE 17

Review of stack

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int main() { noble_a(); return 0; }

stack frame of main stack frame of noble_a stack frame of yield

main() calls noble_a() calls yield()

stack

slide-18
SLIDE 18

Review of stack

main() calls noble_a() calls yield()

Currently running function Only continue when yield returns Only continue when noble_a returns

For a single stack, there is

  • nly one currently running

function, so that noble_a and noble_b cannot run in the same stack at the same time.

… stack frame of main stack frame of noble_a stack frame of yield

slide-19
SLIDE 19

stack frame of noble_b

Two stacks for two nobles

… stack frame of noble_a …

Both are currently running functions! How does yield do context-switch between the two nobles?

slide-20
SLIDE 20

Noble A does some work

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

1

Output: Noble A does some work

slide-21
SLIDE 21

CPU in context of noble_a

… stack frame of noble_a …

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

slide-22
SLIDE 22

Noble A yields

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

1

Output: Noble A does some work

2

slide-23
SLIDE 23

stack frame of yield

noble_a calls yield

… stack frame of noble_a …

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

slide-24
SLIDE 24

stack frame of noble_b

yield switches context to noble_b

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

stack frame of yield … stack frame of noble_a

slide-25
SLIDE 25

Noble B does some work

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

1

Output: Noble A does some work Noble B does some work

2 3

slide-26
SLIDE 26

Noble B yields

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

1

Output: Noble A does some work Noble B does some work

2 3 4

slide-27
SLIDE 27

stack frame of yield stack frame of noble_b

noble_b calls yield

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

stack frame of yield … stack frame of noble_a

slide-28
SLIDE 28

stack frame of yield stack frame of noble_b

yield switches context to noble_a

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

stack frame of yield … stack frame of noble_a

slide-29
SLIDE 29

stack frame of yield stack frame of noble_b

yield returns to noble_a

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

… stack frame of noble_a

slide-30
SLIDE 30

Noble A works some more

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

1

Output: Noble A does some work Noble B does some work Noble A works some more

2 3 4 5

slide-31
SLIDE 31

stack frame of yield stack frame of noble_b

noble_a terminates (implicit yield)

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

slide-32
SLIDE 32

stack frame of yield stack frame of noble_b

yield switches context to noble_b

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

slide-33
SLIDE 33

stack frame of noble_b

yield returns to noble_b

CPU Stack pointer Instruction

code of noble_a code of yield code of noble_b

slide-34
SLIDE 34

Noble B works some more

int noble_a() { printf(“Noble A does some work”); …… yield(); printf(“Noble A works some more”); …… } int noble_b() { printf(“Noble B does some work”); …… yield(); printf(“Noble B works some more”); …… }

1 2 3 4 5 6

Output: Noble A does some work Noble B does some work Noble A works some more Noble B works some more

slide-35
SLIDE 35

How does yield do context-switch?

  • The answer is simple: change the stack pointer!
  • when switching from noble_a to noble_b, the yield function needs to

record the stack pointer of noble_a

  • when switching back to noble_a, the yield function restores the stack

pointer of noble_a

Context-switch from noble_b to noble_a

slide-36
SLIDE 36

Recall: when does context-switch happen?

  • Program terminates.
  • Program calls yield system call.
  • CPU receives a timer interrupt. (later in assignment P2)
  • CPU receives an I/O interrupt. (later in assignment P5)

✅ ✅

slide-37
SLIDE 37

Lesson: A thread owns a stack running a given function.

slide-38
SLIDE 38

stack of noble_b thread code stack of main thread

A thread owns a stack running a given function

int main() { thread_create(noble_b); noble_a(); return 0; } int noble_a() { …… } int noble_b() { …… }

code of noble_a code of yield code of noble_b

slide-39
SLIDE 39

stack of noble_b thread code stack of main thread

Context-switch between threads

int main() { thread_create(noble_b); noble_a(); return 0; } int noble_a() { …… } int noble_b() { …… }

code of noble_a code of yield code of noble_b

CPU Stack pointer Instruction

slide-40
SLIDE 40

stack of noble_b thread code stack of main thread

Context-switch between threads

int main() { thread_create(noble_b); noble_a(); return 0; } int noble_a() { …… } int noble_b() { …… }

code of noble_a code of yield code of noble_b

CPU Stack pointer Instruction

slide-41
SLIDE 41
  • Understand the concepts of context, context-switch and threads
  • Understand the related functions in assignment P1
  • thread_init, thread_create, thread_yield, thread_exit
  • ctx_entry, ctx_start, ctx_switch

Goal of Today’s Class

slide-42
SLIDE 42

data code stack of main thread

thread_init

struct thread { // stored stack pointer for yield // *func to call // *arg to the function // …… feel free to add new fields }; struct thread current_thread; struct queue_t runnable_threads; int main() { // initialize the two global variables thread_init(); return 0; }

code of noble_a code of yield code of noble_b They live here so shared by threads.

slide-43
SLIDE 43

data code stack of main thread

thread_create

struct thread current_thread; struct queue_t runnable_threads; void noble_b(void* arg) { …… } int main() { // initialize the two global variables thread_init(); // create a thread by modifying // the global variables thread_create(noble_b, NULL, 16 * 1024); return 0; }

code of noble_a code of yield code of noble_b

slide-44
SLIDE 44

stack of noble_b thread data code stack of main thread

thread_create

struct thread current_thread; struct queue_t runnable_threads; …… void thread_create(void (*f)(void *), void *arg, unsigned int stack_size){ // allocate a stack for noble_b // modify global variables // call ctx_start to run function f // ctx_start is defined in /src/lib/*.s } ……

code of noble_a code of yield code of noble_b

slide-45
SLIDE 45

stack of noble_b thread data code stack of main thread

thread_yield

struct thread current_thread; struct queue_t runnable_threads; …… void thread_yield(){ // choose next thread to run // call ctx_switch to run the next thread // ctx_switch requires previously stored // stack pointers // ctx_switch is defined in /src/lib/*.s } ……

code of noble_a code of yield code of noble_b

slide-46
SLIDE 46
  • Understand the concepts of context, context-switch and threads
  • Understand the related functions in assignment P1
  • thread_init, thread_create, thread_yield, thread_exit
  • ctx_entry, ctx_start, ctx_switch
  • It’s your job to explore the details of how to implement and use these
  • functions. ;-) Try to understand yourself before coming to office hours.

Goal of Today’s Class

✅ ✅

slide-47
SLIDE 47

Homework

  • P1 is due on Oct 2. Start early.
  • Implement the concepts of thread, context-switch and

synchronization of threads (next lecture).