CSE 451
Operating Systems
L7 - Concurrency: Processes and Threads - 2
Slides by: Tom Anderson
Baris Kasikci
Concurrency: Threads
Definitions
Multithreaded OS Kernel
Multithreaded User Processes
Process Thread Lifetime
Thread Operations
Déjà vu?
Thread Abstraction
Question
Why do threads execute at variable speed?
Programmer vs. Processor View
Possible Executions
Example: threadHello
#define NTHREADS 10 thread_t threads[NTHREADS]; main() {
for (i = 0; i < NTHREADS; i++) thread_create(&threads[i], &go, i); for (i = 0; i < NTHREADS; i++) {
exitValue = thread_join(threads[i]);
printf("Thread %d returned with %ld\n", i, exitValue);
}
printf("Main thread done.\n");
}
void go (int n) {
printf("Hello from thread %d\n", n); thread_exit(100 + n);
// REACHED?
}
Implementing threads
Thread Stack
xk swtch (swtch.S)
swtch:
// callee saved registers already saved
// ptr to old PCB is in rdi push %rbp
push %rbx
push %r11
push %r12
push %r13
push %r14
push %r15
mov %rsp, (%rdi)
// ptr to new PCB is in rsi mov %rsi, %rsp
pop %r15 pop %r14 pop %r13 pop %r12 pop %r11 pop %rbx pop %rbp ret
xk swtch (swtch.S): Switch from A -> B
swtch:
// callee saved registers already saved
// ptr to old PCB is in rdi
push %rbp
push %rbx
push %r11
push %r12
push %r13
push %r14
push %r15
mov %rsp, (%rdi)
// ptr to new PCB is in rsi mov %rsi, %rsp
pop %r15 pop %r14 pop %r13 pop %r12 pop %r11 pop %rbx pop %rbp ret
Step 1: Save old thread’s preserved state (A)
xk swtch (swtch.S): Switch from A -> B
swtch:
// callee saved registers already saved
// ptr to old PCB is in rdi
push %rbp
push %rbx
push %r11
push %r12
push %r13
push %r14
push %r15
mov %rsp, (%rdi)
// ptr to new PCB is in rsi mov %rsi, %rsp
pop %r15 pop %r14 pop %r13 pop %r12 pop %r11 pop %rbx pop %rbp ret
Step 2: Record A’s execution point
current stack pointer
destination register (memory field inside the TCB)
xk swtch (swtch.S): Switch from A -> B
swtch:
// callee saved registers already saved
// ptr to old PCB is in rdi
push %rbp
push %rbx
push %r11
push %r12
push %r13
push %r14
push %r15
mov %rsp, (%rdi)
// ptr to new PCB is in rsi mov %rsi, %rsp
pop %r15 pop %r14 pop %r13 pop %r12 pop %r11 pop %rbx pop %rbp ret
Step 3: Switch to the new thread’s (B) stack
xk swtch (swtch.S): Switch from A -> B
swtch:
// callee saved registers already saved
// ptr to old PCB is in rdi
push %rbp
push %rbx
push %r11
push %r12
push %r13
push %r14
push %r15
mov %rsp, (%rdi)
// ptr to new PCB is in rsi mov %rsi, %rsp
pop %r15 pop %r14 pop %r13 pop %r12 pop %r11 pop %rbx pop %rbp ret
Step 4: Restore B’s state and resume it
A Subtlety
=> Set up newly created thread so that swtch will ”resume” at start of
thread
Stack Progression
Why is there a stub at all?
Why is there a stub at all?
What Happens After Switch?
Timer Interrupt -> swtch
Two Threads Call Yield