xv6, line by line
kernel/swtch.S

kernel/swtch.S

RISC-V assembly · 42 lines · annotated 100% · kernel · upstream

About this file

The context switch itself: 29 instructions (14 stores, 14 loads and a ret) that stop one kernel thread and resume another. swtch saves the current thread’s registers into one struct context and loads another thread’s registers from a second one. When it executes ret, it “returns” into the other thread, at the point where that thread once called swtch.

In xv6 every switch goes between a process and its CPU’s scheduler thread: sched calls swtch(&p->context, &mycpu()->context) to give up the CPU, and scheduler calls swtch(&c->context, &p->context) to run a process. A process never switches directly to another process.

This has to be assembly: C cannot name registers, and the stack pointer it would need to save is the very one it is running on.

Read before: struct context in kernel/proc.h. Read next: scheduler and sched in kernel/proc.c.

1# Context switch
2#
3# void swtch(struct context *old, struct context *new);
4#
5# Save current registers in old. Load from new.
8.globl swtch
10 sd ra, 0(a0)
11 sd sp, 8(a0)
12 sd s0, 16(a0)
13 sd s1, 24(a0)
14 sd s2, 32(a0)
15 sd s3, 40(a0)
16 sd s4, 48(a0)
17 sd s5, 56(a0)
18 sd s6, 64(a0)
19 sd s7, 72(a0)
20 sd s8, 80(a0)
21 sd s9, 88(a0)
22 sd s10, 96(a0)
23 sd s11, 104(a0)
25 ld ra, 0(a1)
26 ld sp, 8(a1)
27 ld s0, 16(a1)
28 ld s1, 24(a1)
29 ld s2, 32(a1)
30 ld s3, 40(a1)
31 ld s4, 48(a1)
32 ld s5, 56(a1)
33 ld s6, 64(a1)
34 ld s7, 72(a1)
35 ld s8, 80(a1)
36 ld s9, 88(a1)
37 ld s10, 96(a1)
38 ld s11, 104(a1)
40 ret