22.01.2015 Views

Embedded Systems Programming A simple embedded system The ...

Embedded Systems Programming A simple embedded system The ...

Embedded Systems Programming A simple embedded system The ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>Embedded</strong> <strong>Systems</strong> <strong>Programming</strong><br />

Lecture 3<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

A <strong>simple</strong> <strong>embedded</strong> <strong>system</strong><br />

Follow (track) an object using sonar echoes. Control parameters<br />

are sent over wireless. <strong>The</strong> servo controls wheels.<br />

Verónica Gaspes<br />

www2.hh.se/staff/vero<br />

Object<br />

Sonar<br />

Distance<br />

data<br />

Input<br />

Servo<br />

Controller<br />

signals<br />

Output<br />

Control<br />

Params<br />

Center for Research on <strong>Embedded</strong> <strong>Systems</strong><br />

School of Information Science, Computer and Electrical Engineering<br />

Decoder<br />

Radio<br />

packets<br />

Input<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> view from the processor<br />

Concurrent waiting<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Sensor input port<br />

Servo output port<br />

radio<br />

packets<br />

read<br />

write<br />

Program<br />

sonar<br />

echoes<br />

read<br />

Radio input port<br />

We ended up with the cyclic executive: one big loop busy waiting<br />

on all input sources!


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Concurrent execution<br />

About laboration 1<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

radio<br />

packets<br />

sonar<br />

echoes<br />

Imagine . . .<br />

. . . that we could interrupt execution of packet decoding when a<br />

sonar echo arrives so that the control algorithm can be ran. <strong>The</strong>n<br />

decoding could resume! <strong>The</strong> two tasks fragments are interleaved.<br />

In lab 1 you will program 3 functions<br />

Writing prime numbers to the LCD<br />

Blinking with a symbol in the LCD<br />

Turing on and off a symbol in the LCD using the joystick<br />

In lab 1 you will then write a big program to do all things at once.<br />

You will then test the cyclic executive and interleaving by hand (to<br />

experience the difficulties with it!)<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Automatic interleaving<br />

Two CPUs<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Sensor input port<br />

Servo output port<br />

<strong>The</strong>re are 2 tasks, driven by independent input sources.<br />

read<br />

CPU1<br />

Controller<br />

write<br />

Handle sonar echoes running the<br />

control algorithm and updating<br />

the servo.<br />

Handle radio packets by running<br />

the decoder.<br />

RAM<br />

parameters<br />

Had we had access to 2 CPUs we could place one task in each. We<br />

can imagine some contruct that allows us to express this in our<br />

program.<br />

CPU2<br />

Controller<br />

read<br />

Radio input port


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Two CPU’s program<br />

struct Params params;<br />

void controller_main(){<br />

int dist, signal;<br />

while(1){<br />

dist = sonar_read();<br />

control(dist,<br />

&signal,<br />

&params);<br />

servo_write(signal);<br />

}<br />

}<br />

We need some way of making one program of this!<br />

void decoder_main(){<br />

struct Packet packet;<br />

while(1){<br />

radio_read(&packet);<br />

decode(&packet,&params);<br />

}<br />

}<br />

Our first multithreaded program<br />

void controller_main(){<br />

int dist, signal;<br />

while(1){<br />

dist = sonar_read();<br />

control(dist,<br />

&signal,<br />

&params);<br />

servo_write(signal);<br />

}<br />

}<br />

struct Params params;<br />

void decoder_main(){<br />

struct Packet packet;<br />

while(1){<br />

radio_read(&packet);<br />

decode(&packet,&params);<br />

}<br />

}<br />

main(){<br />

spawn(decoder_main);<br />

controller_main();<br />

}<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> critical section problem<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Critical sections in real life<br />

What will happen if the params struct is read (by the controller)<br />

at the same time it is written (by the decoder)<br />

I.e., what if the scheduler happens to insert some decoder<br />

instructions while some, but not all, of the controller’s reads have<br />

been done<br />

This problem is central to concurrent programming where there is<br />

any ammount of sharing!<br />

Car dealer<br />

Displays used car<br />

Puts up price tag<br />

Displays luxury car<br />

Updates price tag<br />

Car buyer<br />

Becomes interested,sells her old<br />

car<br />

Gets angry!


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Critical sections in real life<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Critical sections in programs<br />

Car dealer<br />

Displays used car<br />

Puts up price tag<br />

Displays luxury car<br />

Updates price tag<br />

Car buyer<br />

Chooses to keep her old car<br />

All good!<br />

Imagine uppdating the same bank account from two places at<br />

approximately the same time (e.g. your employer deposits your<br />

salary at more or less the same time as you are making a small<br />

deposit).<br />

int account = 0;<br />

account = account + 500; account = account + 10000;<br />

When this is compiled there might be several instructions for each<br />

update!<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Critical sections in programs<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Critical sections in programs<br />

load account,r1<br />

add 500,r1<br />

store r1, account<br />

load account, r2<br />

add 10000, r2<br />

store r2, account<br />

load account,r1<br />

add 500,r1<br />

store r1, account<br />

load account, r2<br />

add 10000, r2<br />

store r2, account<br />

Final balance is 10500<br />

Final balance is 10500


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Critical sections in programs<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Critical sections in programs<br />

load account,r1<br />

add 500,r1<br />

store r1, account<br />

Final balance is 500<br />

load account, r2<br />

add 10000, r2<br />

store r2, account<br />

Testing and setting<br />

int shopper;<br />

if(shopper == NONE)<br />

shopper = HUSBAND<br />

Possible interleaving<br />

if(shopper == NONE)<br />

if(shopper==NONE)<br />

shopper = WIFE<br />

if(shopper==NONE)<br />

shopper = HUSBAND<br />

shopper = WIFE<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Our <strong>embedded</strong> <strong>system</strong><br />

Exchanging parameters<br />

struct Params p;<br />

while(1){<br />

while(1){<br />

... local_minD = p.minDistance;<br />

p.minDistance = e1; local_maxS = p.maxSpeed;<br />

p.maxSpeed = e2; ...<br />

} }<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> classical solution<br />

Apply an access protocol to the critical sections that ensures<br />

mutual exclusion<br />

Require that all parties follow the protocol<br />

Possible interleaving<br />

p.minDistance = 1;<br />

p.maxSpeed = 1;<br />

p.minDistance = 200;<br />

p.maxSpeed = 150;<br />

local_minD = 1;<br />

local_maxS = 150<br />

Access protocols are realized by means of a shared datastructure<br />

known as amutex or a lock.


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Mutual exclusion<br />

Exchanging parameters<br />

struct Params p;<br />

mutex m;<br />

while(1){<br />

while(1){<br />

... lock (&m)<br />

lock (&m);<br />

local_minD = p.minDistance;<br />

p.minDistance = e1; local_maxS = p.maxSpeed;<br />

p.maxSpeed = e2;<br />

unlock (&m)<br />

unlock (&m); ...<br />

}<br />

}<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

<strong>The</strong> following slides will help us understand what we will need to<br />

do to implement threads and automatic interleaving.<br />

SP<br />

Stack<br />

Locals of a()<br />

x =<br />

Globals<br />

v = 0<br />

w v = 0<br />

u = 0<br />

PC<br />

Code<br />

a(){<br />

int x;<br />

}<br />

...<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

Stack<br />

Code<br />

Stack<br />

Code<br />

SP<br />

Locals of a()<br />

x =<br />

a(){<br />

int x;<br />

SP<br />

Locals of a()<br />

x = 9<br />

a(){<br />

int x;<br />

PC<br />

...<br />

PC<br />

x = 9;<br />

w = 6;<br />

...<br />

}<br />

}<br />

Globals<br />

Globals<br />

v = 0<br />

w v = 0<br />

u = 0<br />

v = 0<br />

w = 6<br />

u = 0


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

Stack<br />

Code<br />

Stack<br />

Code<br />

SP<br />

Locals of a()<br />

x = 9<br />

a(){<br />

int x;<br />

Locals of a()<br />

x = 9<br />

a(){<br />

int x;<br />

b(int y){<br />

PC<br />

x = 9;<br />

w = 6;<br />

b(55);<br />

SP<br />

Locals of b()<br />

y = 55<br />

x = 9;<br />

w = 6;<br />

b(55);<br />

PC<br />

...<br />

}<br />

}<br />

}<br />

Globals<br />

Globals<br />

v = 0<br />

w = 6<br />

u = 0<br />

v = 0<br />

w = 6<br />

u = 0<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

Stack<br />

Code<br />

Stack<br />

Code<br />

SP<br />

Locals of a()<br />

x = 9<br />

Locals of b()<br />

y = 55<br />

a(){<br />

int x;<br />

x = 9;<br />

w = 6;<br />

b(55);<br />

}<br />

PC<br />

b(int y){<br />

...<br />

y = c();<br />

}<br />

SP<br />

Locals of a()<br />

x = 9<br />

Locals of b()<br />

y = 55<br />

Locals of c()<br />

z = 23<br />

a(){<br />

int x;<br />

x = 9;<br />

w = 6;<br />

b(55);<br />

}<br />

b(int y){<br />

...<br />

y = c();<br />

}<br />

PC<br />

c(){<br />

int z = 23;<br />

...<br />

}<br />

Globals<br />

Globals<br />

v = 0<br />

w = 6<br />

u = 0<br />

v = 0<br />

w = 6<br />

u = 0


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

Stack<br />

Code<br />

Stack<br />

Code<br />

SP<br />

Locals of a()<br />

x = 9<br />

Locals of b()<br />

y = 55<br />

Locals of c()<br />

z = 23<br />

a(){<br />

int x;<br />

x = 9;<br />

w = 6;<br />

b(55);<br />

}<br />

b(int y){<br />

...<br />

y = c();<br />

}<br />

PC<br />

c(){<br />

int z = 23;<br />

w = 77;<br />

...<br />

}<br />

SP<br />

Locals of a()<br />

x = 9<br />

Locals of b()<br />

y = 55<br />

Locals of c()<br />

z = 23<br />

a(){<br />

int x;<br />

x = 9;<br />

w = 6;<br />

b(55);<br />

}<br />

b(int y){<br />

...<br />

y = c();<br />

}<br />

PC<br />

c(){<br />

int z = 23;<br />

w = 77;<br />

return z;<br />

}<br />

Globals<br />

Globals<br />

v = 0<br />

w = 77<br />

u = 0<br />

v = 0<br />

w = 77<br />

u = 0<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Execution of a C program<br />

Stack<br />

Code<br />

Stack<br />

Code<br />

SP<br />

Locals of a()<br />

x = 9<br />

Locals of b()<br />

y = 23<br />

a(){<br />

int x;<br />

x = 9;<br />

w = 6;<br />

b(55);<br />

PC<br />

b(int y){<br />

...<br />

y = c();<br />

}<br />

c(){<br />

int z = 23;<br />

w = 77;<br />

return z;<br />

}<br />

SP<br />

Locals of a()<br />

x = 9<br />

PC<br />

a(){<br />

int x;<br />

b(int y){<br />

c(){<br />

int z = 23;<br />

x = 9;<br />

w = 6;<br />

...<br />

w = 77;<br />

b(55);<br />

y = c();<br />

... return z;<br />

}<br />

}<br />

}<br />

}<br />

Globals<br />

Globals<br />

v = 0<br />

w = 77<br />

u = 0<br />

v = 0<br />

w = 77<br />

u = 0


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

2 CPUs<br />

What is it about<br />

struct Params params;<br />

Imagine we had 2 CPUs, then we could run two programs at the<br />

same time!<br />

One way of programming this in only 1 CPU is to keep track of 2<br />

stack pointers and 2 program counters! How to do this is the<br />

content of lecture 4.<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

What might a program look like<br />

void controller_main() {<br />

int dist, signal;<br />

while(1){<br />

dist = sonar_read();<br />

control(dist,<br />

&signal,<br />

&params);<br />

servo_write(signal);<br />

}<br />

}<br />

void decoder_main() {<br />

struct Packet packet;<br />

while(1){<br />

radio_read(&packet);<br />

decode(&packet,&params);<br />

}<br />

}<br />

We want to provide means for these two mains to execute<br />

concurrently! As if we had 2 CPUs!<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Introducing setjmp/longjmp (non-local goto)<br />

Notice that the function spawn<br />

takes a function as an argument!<br />

<strong>The</strong> role of spawn is to provide<br />

one extra Program Counter and<br />

Stack Pointer<br />

main(){<br />

spawn(decoder_main);<br />

controller_main();<br />

}<br />

We should also provide a way of<br />

interleaving fragments of the<br />

threads.<br />

First we will introduce a way of<br />

yielding execution so that another<br />

thread can take over. Later we<br />

will also see how this function<br />

might be called.<br />

#include<br />

#include<br />

jmp_buf bf;<br />

main(int argc, char*argv[]){<br />

int x = atoi(argv[1]);<br />

while(1){<br />

if( setjmp(bf) ) break;<br />

f(argv[2],x);<br />

}<br />

printf("... Got here!\n\n");<br />

}<br />

void f(char * s, int n){<br />

int y = n-1;<br />

printf(s);<br />

if(y==0) longjmp(bf,1) ;<br />

else f(s, y);<br />

}


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

setjmp/longjmp<br />

Using setjmp/longjmp<br />

1 <strong>The</strong> type jmp buf is declared in the library . It is<br />

known to be an array.<br />

2 <strong>The</strong> operation setjmp(bf) saves the program counter and<br />

the stack pointer to the jmp buf bf.<br />

It returns 0.<br />

3 <strong>The</strong> operation longjmp(bf,n) loads the content of bf to the<br />

program counter and the stack pointer.<br />

It returns n.<br />

longjmp(bf,n) returns after the registers have been restored so it<br />

looks as if it is setjmp(bf) that returns n!<br />

jmp_buf buf;<br />

Locals of a<br />

x = 9<br />

v =<br />

a () {<br />

int x, v;<br />

...<br />

}<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Using setjmp/longjmp<br />

Using setjmp/longjmp<br />

jmp_buf buf;<br />

jmp_buf buf;<br />

Locals of a<br />

a () {<br />

Locals of a<br />

a () {<br />

x = 9<br />

v = 0<br />

int x, v;<br />

x = 9<br />

v = 0<br />

int x, v;<br />

...<br />

...<br />

v = setjmp(buf);<br />

v = setjmp(buf);<br />

...<br />

b();<br />

}<br />

}


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Using setjmp/longjmp<br />

Using setjmp/longjmp<br />

jmp_buf buf;<br />

jmp_buf buf;<br />

Locals of a<br />

a () {<br />

Locals of a<br />

a () {<br />

x = 9<br />

v = 0<br />

int x, v;<br />

x = 9<br />

v = 0<br />

int x, v;<br />

Locals of b<br />

y = 2<br />

...<br />

v = setjmp(buf);<br />

...<br />

b () {<br />

int y;<br />

Locals of b<br />

y = 2<br />

...<br />

v = setjmp(buf);<br />

...<br />

b () {<br />

int y;<br />

b();<br />

...<br />

b();<br />

...<br />

c();<br />

}<br />

}<br />

}<br />

}<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Using setjmp/longjmp<br />

Using setjmp/longjmp<br />

jmp_buf buf;<br />

jmp_buf buf;<br />

Locals of a<br />

a () {<br />

Locals of a<br />

a () {<br />

x = 9<br />

v = 0<br />

int x, v;<br />

x = 9<br />

v = 0<br />

int x, v;<br />

Locals of b<br />

y = 2<br />

Locals of c<br />

...<br />

v = setjmp(buf);<br />

...<br />

b();<br />

b () {<br />

int y;<br />

...<br />

c();<br />

c () {<br />

int z;<br />

...<br />

Locals of b<br />

y = 2<br />

Locals of c<br />

...<br />

v = setjmp(buf);<br />

...<br />

b();<br />

b () {<br />

int y;<br />

...<br />

c();<br />

c () {<br />

int z;<br />

...<br />

longjmp(buf,7);<br />

z = 23<br />

}<br />

}<br />

}<br />

z = 23<br />

}<br />

}<br />

}


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Using setjmp/longjmp<br />

Using setjmp/longjmp<br />

jmp_buf buf;<br />

jmp_buf buf;<br />

Locals of a<br />

a () {<br />

Locals of a<br />

a () {<br />

x = 9<br />

v = 0<br />

int x, v;<br />

x = 9<br />

v = 7<br />

int x, v;<br />

Locals of b<br />

y = 2<br />

Locals of c<br />

...<br />

v = setjmp(buf);<br />

...<br />

b();<br />

b () {<br />

int y;<br />

...<br />

c();<br />

c () {<br />

int z;<br />

...<br />

longjmp(buf,7);<br />

...<br />

v = setjmp(buf);<br />

...<br />

b();<br />

b () {<br />

int y;<br />

...<br />

c();<br />

c () {<br />

int z;<br />

...<br />

longjmp(buf,7);<br />

z = 23<br />

}<br />

}<br />

...<br />

}<br />

}<br />

}<br />

...<br />

}<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Using setjmp/longjmp for our purposes<br />

<strong>The</strong> trick<br />

setjmp(buf);<br />

STACKPTR(buf) = malloc(...);<br />

<strong>The</strong> macro STACKPTR will select the stack pointer part of the<br />

buffer.<br />

We assign to it the address of a new chunk of memory.<br />

<strong>The</strong> size of this chunk of memory is the size of a function-call<br />

stack frame.<br />

This is very much platform dependent!<br />

spawn will do the trick<br />

setjmp(buf);<br />

STACKPTR(buf) = malloc(...);<br />

before calling the function to be executed. <strong>The</strong> function will then<br />

run with its own stack!<br />

After this, the context-switching between threads is just<br />

setjmp(A);longjmp(B);<br />

setjmp(B);longjmp(C);<br />

setjmp(C);longjmp(A);


<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Completing the trick<br />

We will have to keep track of the threads, so we introduce a data<br />

structure describing a thread.<br />

struct Thread_Block{<br />

void (*fun)(int) // function to run<br />

int arg; // argument to the above<br />

jmp_buf context, // pc and sp<br />

... // ...<br />

};<br />

typedef struct Thread_Block Thread<br />

We will keep track of threads using global variables for<br />

1 a queue of Threads: the ready queue<br />

2 and the current thread.<br />

Defining spawn<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

void spawn(void (*fun)(int), int arg){<br />

Thread t = malloc(...);<br />

t->fun = fun;<br />

t->arg = arg;<br />

if(setjmp(t->context)!=0){<br />

// this will be done when a longjmp leads here:<br />

current->fun(current->arg);<br />

// What has to be done when the thread<br />

// we spawn for fun terminates<br />

}<br />

// DO the stack pointer trick:<br />

STACKPTR(t->context) = malloc(...);<br />

// enqueue t in the ready queue!<br />

}<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

<strong>The</strong> ready queue, the current thread and yield<br />

Dispatch<br />

<strong>The</strong> need for threads Mutual exclusion <strong>The</strong> C execution model Context Switch<br />

Yielding control<br />

By keeping the runnable threads<br />

in a queue, we can define a<br />

function yield() to switch<br />

execution to another thread.<br />

yield() must<br />

enqueue the current thread in the ready queue<br />

pick a new thread from the ready queue and make it the<br />

current thread<br />

perform the setjmp(A);longjmp(B); trick (also called<br />

dispatch)<br />

void dispatch(Thread next){<br />

if(setjmp(current->context)==0){<br />

current = next;<br />

longjmp(next->context,1);<br />

}<br />

}<br />

<strong>The</strong> function returns directly when control later enters via the fake<br />

return from setjmp.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!