MIT 6.S081 实验7 笔记与心得

Lab: Multithreading

背景知识

本练习将让您熟悉多线程。您将在用户级线程包中实现线程之间的切换,使用多个线程来加速程序,并实现barrier函数。

在编写代码之前,您应该确保已经阅读了xv6书中的“第7章:调度”,并研究和阅读了相应的代码

如果之前学过多线程以及线程处理函数就更好了!

Uthread:在线程之间切换(中等)

题目翻译

在本练习中,您将为用户级线程系统设计上下文切换机制,然后实现它。为了帮助您入门,xv6 有两个文件 user/uthread.c 和 user/uthread_switch.S,以及 Makefile 中的一条规则,用于构建一个 uthread 程序。uthread.c包含大部分用户级线程包,以及三个简单测试线程的代码。线程包缺少一些用于创建线程和在线程之间切换的代码。

您的工作是制定一个计划来创建线程并保存/恢复寄存器以在线程之间切换,并实施该计划。完成后,make grade 应该说明您的解决方案通过了 uthread 测试。

完成后,在 xv6 上运行 uthread 时,您应该会看到以下输出(三个线程可能以不同的顺序开始):

$ 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
$

这个输出来自三个测试线程,每个线程都有一个循环,打印一行,然后将CPU让给其他线程。

然而,在这一点上,由于没有上下文切换代码,你会看到没有输出。

你需要给user/uthread.c中的thread_create()thread_schedule()以及user/uthread_switch.S中 thread_switch添加代码。一个目标是确保当thread_schedule()第一次运行一个给定的线程时,该线程在自己的堆栈中执行传递给thread_create()的函数。另一个目标是确保thread_switch保存被切换走的线程的寄存器,恢复被切换到的线程的寄存器,并返回到后一个线程的指令中它最后离开的地方。你必须决定在哪里保存/恢复寄存器;修改struct thread以保存寄存器是一个好计划。你需要在thread_schedule中添加对thread_switch的调用;你可以向thread_switch传递任何你需要的参数,但其意图是将线程t切换到下一个线程。

一些提示:

  • thread_switch只需要保存/恢复callee-save寄存器。为什么呢?

  • 你可以在user/uthread.asm中看到uthread的汇编代码,这对于调试来说可能很方便。

  • 为了测试你的代码,使用riscv64-linux-gnu-gdb单步浏览你的thread_switch可能会有帮助。你可以用这种方式开始:

(gdb) file user/_uthread
Reading symbols from user/_uthread...
(gdb) b uthread.c:60

这在uthread.c的第60行设置了一个断点。这个断点可能(也可能不)在你运行uthread之前就被触发了。这怎么可能发生呢?

一旦你的xv6 shell运行,输入 “uthread”,gdb就会在第60行中断。现在你可以键入类似下面的命令来检查uthread的状态。

   (gdb) p/x *next_thread

用 “x”,你可以检查一个内存位置的内容。

   (gdb) x/x next_thread->stack

你可以这样跳到thread_switch的开头。

   (gdb) b thread_switch
   (gdb) c

你可以使用单步汇编指令

   (gdb) si

gdb的在线文档在这里

题目答案

要实现在用户级线程之间进行切换,需要保存和恢复线程的寄存器,这里可以参考swtch的用法,注意这里需要在user/uthread_switch.S进行修改,之前一直没看清题目,于是在user/uthread_switch.asm 中就行添加代码。

  1     .text              
  2 
  3     /*
  4          * save the old thread's registers,
  5          * restore the new thread's registers.
  6          */
  7 
  8     .globl thread_switch
  9 thread_switch:
 10     /* YOUR CODE HERE */
 11 
 12         sd ra, 0(a0)
 13         sd sp, 8(a0)
 14         sd s0, 16(a0)
 15         sd s1, 24(a0)
 16         sd s2, 32(a0)
 17         sd s3, 40(a0)
 18         sd s4, 48(a0)
 19         sd s5, 56(a0)
 20         sd s6, 64(a0)
 21         sd s7, 72(a0)
 22         sd s8, 80(a0)
 23         sd s9, 88(a0)
 24         sd s10, 96(a0)
 25         sd s11, 104(a0)
 26 
 27         ld ra, 0(a1)
 28         ld sp, 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值