Lab 6 Uthread: switching between threads

Design the context switch mechanism for a user-level threading system

Task

In this exercise you will design the context switch mechanism for a user-level threading system, and then implement it.

Your job is to come up with a plan to create threads and save/restore registers to switch between threads, and implement that plan.

Lab: user-level threads and alarm

Expected Result

~/classes/6828/xv6$ **make qemu**

$ **uthread**
thread_a started
thread_b started
thread_c started
thread_c 0
thread_a 0
thread_b 0
thread_c 1
thread_a 1
thread_b 1

thread_c 99
thread_a 99
thread_b 99
thread_c: exit after 100
thread_a: exit after 100
thread_b: exit after 100
thread_schedule: no runnable threads

Hints

complete thread_create to create a properly initialized thread so that when the scheduler switches to that thread for the first time decide where to save/restore registers. You can add fields to struct thread into which to save registers.

Solution

Save registers info in thread

Add context to thread.

Setup jump function and stack in thread creation

Note:

  • Set up ra return address register to point to the thread function, so switch thread will jump to the function.

  • In the standard RISC-V calling convention, the stack grows downward and the stack pointer is always kept 16-byte aligned.

  • Set stack pointer to stack top.

Implement context switch

We save ra, sp, and all callee saved registers. This assembly function is called be thread scheduler, to switch from current thread to next runnable one. This function saves registers info in thread->context, and load registers from new thread’s context, then jump executing the new thread.

Complete thread scheduler

Define struct and vars

Find next runnable thread

Try to find next one, if reaches the end then start from beginning. If none of them is available, current_thread is unchanged and resume.

Switch thread

Ref: Full Uthread Package

心得

过去五年一直不理解的coroutine现在顿悟了,x86的繁琐和陈旧被risc-v的精简直接击垮。纤程的本质就是context switch,将储存器存入stack, 将另一个纤程的储存器从它的stack读出,将program counter设置好,这,就是fiber.

Last updated

Was this helpful?