Академический Документы
Профессиональный Документы
Культура Документы
Verónica Gaspes
www2.hh.se/staff/vero
What is it about?
void controller_main() {
int dist, signal;
void decoder_main() {
while(1){
struct Packet packet;
dist = sonar_read();
while(1){
control(dist,
radio_read(&packet);
&signal,
decode(&packet,¶ms);
¶ms);
}
servo_write(signal);
}
}
}
What is it about?
void controller_main() {
int dist, signal;
void decoder_main() {
while(1){
struct Packet packet;
dist = sonar_read();
while(1){
control(dist,
radio_read(&packet);
&signal,
decode(&packet,¶ms);
¶ms);
}
servo_write(signal);
}
}
}
main(){
spawn(decoder_main);
controller_main();
}
main(){
spawn(decoder_main);
controller_main();
}
main(){
spawn(decoder_main);
controller_main();
}
main(){
spawn(decoder_main);
controller_main();
}
main(){
spawn(decoder_main);
controller_main();
}
#include<stdio.h>
#include<setjmp.h>
jmp_buf bf;
#include<stdio.h>
#include<setjmp.h>
jmp_buf bf;
#include<stdio.h>
#include<setjmp.h>
jmp_buf bf;
setjmp/longjmp
setjmp/longjmp
setjmp/longjmp
setjmp/longjmp
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=
...
}
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=0
...
v = setjmp(buf);
}
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=0
...
v = setjmp(buf);
...
b();
}
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=0
Locals of b ...
v = setjmp(buf); b () {
y=2 ... int y;
b(); ...
} }
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=0
Locals of b ...
v = setjmp(buf); b () {
y=2 ... int y;
b(); ...
c();
} }
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=0
Locals of b ...
v = setjmp(buf); b () { c () {
y=2 ... int y; int z;
b(); ... ...
Locals of c c();
z = 23
} } }
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=0
Locals of b ...
v = setjmp(buf); b () { c () {
y=2 ... int y; int z;
b(); ... ...
Locals of c c(); longjmp(buf,7);
z = 23
} } }
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v=0
Locals of b ...
v = setjmp(buf); b () { c () {
y=2 ... int y; int z;
b(); ... ...
Locals of c c(); longjmp(buf,7);
z = 23 ...
} } }
Context switch Tracing an example Epilog
Using setjmp/longjmp
jmp_buf buf;
Locals of a a () {
x=9 int x, v;
v = 7
...
v = setjmp(buf); b () { c () {
... int y; int z;
b(); ... ...
c(); longjmp(buf,7);
...
} } }
Context switch Tracing an example Epilog
setjmp(buf);
STACKPTR(buf) = malloc(...);
The macro STACKPTR will select the stack pointer part of the
buffer.
setjmp(buf);
STACKPTR(buf) = malloc(...);
The macro STACKPTR will select the stack pointer part of the
buffer.
setjmp(buf);
STACKPTR(buf) = malloc(...);
The macro STACKPTR will select the stack pointer part of the
buffer.
setjmp(buf);
STACKPTR(buf) = malloc(...);
The macro STACKPTR will select the stack pointer part of the
buffer.
The trick
setjmp(buf);
STACKPTR(buf) = malloc(...);
setjmp(A);longjmp(B);
setjmp(B);longjmp(C);
setjmp(C);longjmp(A);
Context switch Tracing an example Epilog
The trick
setjmp(buf);
STACKPTR(buf) = malloc(...);
setjmp(A);longjmp(B);
setjmp(B);longjmp(C);
setjmp(C);longjmp(A);
Context switch Tracing an example Epilog
struct Thread_Block{
void (*fun)(int) // function to run
int arg; // argument to the above
jmp_buf context, // pc and sp
... // ...
};
typedef struct Thread_Block Thread
struct Thread_Block{
void (*fun)(int) // function to run
int arg; // argument to the above
jmp_buf context, // pc and sp
... // ...
};
typedef struct Thread_Block Thread
Defining spawn
Yielding control
By keeping the runnable threads
in a queue, we can define a
function yield() to switch
execution to another thread.
yield() must
enqueue the current thread in the ready queue
pick a new thread from the ready queue and make it the
current thread
perform the setjmp(A);longjmp(B); trick (also called
dispatch)
Context switch Tracing an example Epilog
Yielding control
By keeping the runnable threads
in a queue, we can define a
function yield() to switch
execution to another thread.
yield() must
enqueue the current thread in the ready queue
pick a new thread from the ready queue and make it the
current thread
perform the setjmp(A);longjmp(B); trick (also called
dispatch)
Context switch Tracing an example Epilog
Yielding control
By keeping the runnable threads
in a queue, we can define a
function yield() to switch
execution to another thread.
yield() must
enqueue the current thread in the ready queue
pick a new thread from the ready queue and make it the
current thread
perform the setjmp(A);longjmp(B); trick (also called
dispatch)
Context switch Tracing an example Epilog
Yielding control
By keeping the runnable threads
in a queue, we can define a
function yield() to switch
execution to another thread.
yield() must
enqueue the current thread in the ready queue
pick a new thread from the ready queue and make it the
current thread
perform the setjmp(A);longjmp(B); trick (also called
dispatch)
Context switch Tracing an example Epilog
Yielding control
By keeping the runnable threads
in a queue, we can define a
function yield() to switch
execution to another thread.
yield() must
enqueue the current thread in the ready queue
pick a new thread from the ready queue and make it the
current thread
perform the setjmp(A);longjmp(B); trick (also called
dispatch)
Context switch Tracing an example Epilog
Dispatch
The function returns directly when control later enters via the fake
return from setjmp.
Context switch Tracing an example Epilog
Dispatch
The function returns directly when control later enters via the fake
return from setjmp.
Context switch Tracing an example Epilog
Tracing an example
The example
Two threads calculating prime numbers starting from different
start values.
While the code in the example is not complete, you will work with
the complete version in laboration 3!
Context switch Tracing an example Epilog
Tracing an example
The example
Two threads calculating prime numbers starting from different
start values.
While the code in the example is not complete, you will work with
the complete version in laboration 3!
Context switch Tracing an example Epilog
Tracing an example
The example
Two threads calculating prime numbers starting from different
start values.
While the code in the example is not complete, you will work with
the complete version in laboration 3!
Context switch Tracing an example Epilog
Tracing an example
The example
Two threads calculating prime numbers starting from different
start values.
While the code in the example is not complete, you will work with
the complete version in laboration 3!
Context switch Tracing an example Epilog
Tracing an example
The example
Two threads calculating prime numbers starting from different
start values.
While the code in the example is not complete, you will work with
the complete version in laboration 3!
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { fun = main
current = next; arg = 0
longjmp(next->context, 1); context =
}
}
primes(int start) {
int n = start;
while (...) {
...
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { spawn()
fun = main
current = next; fun = primes
arg = 0
longjmp(next->context, 1); arg = 101
context =
} t=
}
primes(int start) {
int n = start;
while (...) {
...
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { spawn()
fun = main
current = next; fun = primes
arg = 0
longjmp(next->context, 1); arg = 101
context =
} t=B
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { spawn()
fun = main
current = next; fun = primes
arg = 0
longjmp(next->context, 1); arg = 101
context =
} t=B
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { spawn()
fun = main
current = next; fun = primes
arg = 0
longjmp(next->context, 1); arg = 101
context =
} t=B
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { spawn()
fun = main
current = next; fun = primes
arg = 0
longjmp(next->context, 1); arg = 101
context =
} t=B
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { spawn()
fun = main
current = next; fun = primes
arg = 0
longjmp(next->context, 1); arg = 101
context =
} t=B
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { spawn()
fun = main
current = next; fun = primes
arg = 0
longjmp(next->context, 1); arg = 101
context =
} t=B
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { fun = main
current = next; arg = 0
longjmp(next->context, 1); context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 202
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 203
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 203
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
STACKPTR(t->context) = malloc(...)
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
STACKPTR(t->context) = malloc(...)
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
STACKPTR(t->context) = malloc(...)
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
STACKPTR(t->context) = malloc(...)
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
STACKPTR(t->context) = malloc(...)
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() { Note that fun and arg can’t be found on the stack anymore!
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n=
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n =101
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 102
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 102
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A,B]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [B]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [B]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = [B]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = [B]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = [B]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
yield()
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 223
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) { dispatch()
int n = start; next = A
fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
} yield()
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 107
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
primes()
STACKPTR(t->context) = malloc(...)
start = 101
enqueue(t, &readyQ);
n = 199
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = [A]
dispatch(dequeue(&readyQ));
}
STACKPTR(t->context) = malloc(...)
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = []
dispatch(dequeue(&readyQ));
}
dispatch()
STACKPTR(t->context) = malloc(...)
next = A
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = B
current->fun(current->arg); readyQ = []
dispatch(dequeue(&readyQ));
}
dispatch()
STACKPTR(t->context) = malloc(...)
next = A
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = []
dispatch(dequeue(&readyQ));
}
dispatch()
STACKPTR(t->context) = malloc(...)
next = A
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = []
dispatch(dequeue(&readyQ));
}
dispatch()
STACKPTR(t->context) = malloc(...)
next = A
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
dispatch()
void spawn(void (*fun)(int), int arg) { next = B
Thread *t = malloc(...)
t->fun = fun;
t->arg = arg;
if (setjmp(t->context) == 1) { current = A
current->fun(current->arg); readyQ = []
dispatch(dequeue(&readyQ));
}
dispatch()
STACKPTR(t->context) = malloc(...)
next = A
enqueue(t, &readyQ);
...
}
B
primes(int start) {
int n = start; fun = primes
while (...) { arg = 101
... context =
if (...) yield();
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
yield()
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
void yield() {
enqueue(current, &readyQ);
dispatch(dequeue(&readyQ));
}
A main()
void dispatch(Thread *next) {
if (setjmp(current->context) == 0) { primes()
fun = main
current = next; start = 202
arg = 0
longjmp(next->context, 1); n = 271
context =
}
}
main() {
spawn(primes, 101);
primes(202);
Context switch Tracing an example Epilog
Calling yield()
Explicitly
ld a, r1
ld b, r2
yield:
add r, r2
sub #2, sp
st r2, c
...
jsr yield
mov #0, r0
ld c, r0
rts
cmp #37, r0
ble label34
...
Context switch Tracing an example Epilog
Calling yield()
Explicitly
ld a, r1
ld b, r2
yield:
add r, r2
sub #2, sp
st r2, c
...
jsr yield
mov #0, r0
ld c, r0
rts
cmp #37, r0
ble label34
...
Context switch Tracing an example Epilog
Calling yield()
Implicitly
vector_3:
ld a, r1 push r0-r2
ld b, r2 jsr yield
add r, r2 pop r0-r2
st r2, c rti
←− Interrupt on pin 3!
yield:
ld c, r0 sub #2, sp
cmp #37, r0 ...
ble label34 mov #0, r0
... rts
Context switch Tracing an example Epilog
Calling yield()
Implicitly
vector_3:
ld a, r1 push r0-r2
ld b, r2 jsr yield
add r, r2 pop r0-r2
st r2, c rti
←− Interrupt on pin 3!
yield:
ld c, r0 sub #2, sp
cmp #37, r0 ...
ble label34 mov #0, r0
... rts
Context switch Tracing an example Epilog
Calling yield()
Implicitly
vector_3:
ld a, r1 push r0-r2
ld b, r2 jsr yield
add r, r2 pop r0-r2
st r2, c rti
←− Interrupt on pin 3!
yield:
ld c, r0 sub #2, sp
cmp #37, r0 ...
ble label34 mov #0, r0
... rts
Context switch Tracing an example Epilog
Calling yield()
Implicitly
vector_3:
ld a, r1 push r0-r2
ld b, r2 jsr yield
add r, r2 pop r0-r2
st r2, c rti
←− Interrupt on pin 3!
yield:
ld c, r0 sub #2, sp
cmp #37, r0 ...
ble label34 mov #0, r0
... rts
Context switch Tracing an example Epilog
#include<avr/interrupt.h>
...
ISR(interrupt_name){
...
// code as in a function body!
...
}
#include<avr/interrupt.h>
...
ISR(interrupt_name){
...
// code as in a function body!
...
}