diff --git a/课程设计.md b/课程设计.md
index aa538d0..a9a08d4 100644
--- a/课程设计.md
+++ b/课程设计.md
@@ -2,7 +2,10 @@
> 扩充proxy kernel的代码,使你的内核可以支持以下应用程序:
-## 应用程序一: ##
+## 实验一 多进程支持 ##
+
+### 应用: ###
+
App5_1的代码如下:
int main(){
@@ -35,14 +38,79 @@ App5_1的代码如下:
return 0;
}
+
+### 实验一任务: ###
+
+
+#### 任务一 : proc_pagetable/ vmcopy ####
+
+ 实验任务描述:
+
+实现pk/proc.c中的proc_pagetable与vmcopy函数,为进程创建用户页表,并映射用户内存,确保你的代码仍可以保证app5的正确运行。
-以上是一段多进程的代码,我们可以结合下图进行分析:
+实验预期输出:
-
+ $ spike obj/pke app/elf/app5
+得到输出:
+ PKE IS RUNNING
+ to host 10
+ from host 0
+ elf name app/elf/app5
+ sched class: RR_scheduler
+ ++ setup timer interrupts
+ log: proc init
+ father process
+ this is father process;my pid = 1
+ this is child process;my pid = 2
+
+
+#### 任务二:do_wait ####
+
+ 实验任务描述:
+实现`do_wait`函数,支持app5_1.c的运行
+
+ $ spike obj/pke app/elf/app5_1
+预期得到输出:
+
+ PKE IS RUNNING
+ to host 10
+ from host 0
+ elf name app/elf/app5_1
+ sched class: RR_scheduler
+ ++ setup timer interrupts
+ log: proc init
+ print proc app5_1
+ print proc this is child process;my pid = 2
+ print proc a=9
+ print proc this is child process;my pid = 3
+ print proc a=6
+ print proc this is farther process;my pid = 2
+ print proc a=5
+ print proc this is farther process;my pid = 1
+ print proc a=8
+ print proc this is child process;my pid = 4
+ print proc a=5
+ print proc this is farther process;my pid = 1
+
+此时运行测试脚本:
+
+ $ python3 ./pke-final-1
+
+预期得到输出:
+
+ build pk : OK
+ running app5_1 : OK
+ test fork : OK
+ Score: 20/20
+
+
+### 实验一提示: ###
+
+app5_1.c是一段多进程的代码,我们可以结合下图进行分析:
@@ -265,25 +333,6 @@ start_user中首先恢复sstatus以及sepc,然后加载32个通用寄存器,
- 其四、该虚拟地址对应着用户栈,由于我们在proc_pagetable函数中已近为其分配了内存,此时只需要复制父进程的用户栈。
-### 任务一:proc_pagetable/ vmcopy ###
-任务描述:实现pk/proc.c中的proc_pagetable与vmcopy函数,为进程创建用户页表,并映射用户内存,确保你的代码仍可以保证app5的正确运行。
-
- $ spike obj/pke app/elf/app5
-
-预期得到输出:
-
- PKE IS RUNNING
- to host 10
- from host 0
- elf name app/elf/app5
- sched class: RR_scheduler
- ++ setup timer interrupts
- log: proc init
- father process
- this is father process;my pid = 1
- this is child process;my pid = 2
-
-----------
至此,我们进一步完善了对fork的支持。接下来,我们来看进程间的同步。
@@ -369,48 +418,17 @@ Schedule会选取下一个进程,随即进入switch_to,这又是一段汇编
当父进程被唤醒后,进入`wakeup_proc`的代码,在`wakeup_proc`函数中恢复了父进程的运行状态,随即再次调用schedule函数。如上文所述,schedule再次加载父进程的上下文,还记的方才父进程上下文中的ra寄存器的值吗?父进程将根据此值返回schedule中`proc_run`的下一行地址继续上次的代码,并返回schedule的调用函数`do_wai`t。`do_wait`里我们将再次查看子进程的state,若为PROC_ZOMBIE则返回。至此wait系统调用执行完毕。
-### 任务二:do_wait ###
-任务描述:实现`do_wait`函数,支持app5_1.c的运行
- $ spike obj/pke app/elf/app5_1
-预期得到输出:
+----------
- PKE IS RUNNING
- to host 10
- from host 0
- elf name app/elf/app5_1
- sched class: RR_scheduler
- ++ setup timer interrupts
- log: proc init
- print proc app5_1
- print proc this is child process;my pid = 2
- print proc a=9
- print proc this is child process;my pid = 3
- print proc a=6
- print proc this is farther process;my pid = 2
- print proc a=5
- print proc this is farther process;my pid = 1
- print proc a=8
- print proc this is child process;my pid = 4
- print proc a=5
- print proc this is farther process;my pid = 1
-此时运行测试脚本:
+## 实验二 信号量 ##
- $ python3 ./pke-final-1
-
-预期得到输出:
-
- build pk : OK
- running app5_1 : OK
- test fork : OK
- Score: 20/20
+### 实验二应用输入: ###
-----------
-## 应用程序二 ##
到目前为止,我们已近实现了进程间的简单同步。接下来,我们更进一步,考虑信号量的实现。App5_2的代码如下:
#include
@@ -501,6 +519,30 @@ Schedule会选取下一个进程,随即进入switch_to,这又是一段汇编
上述代码是一个简单的生产者消费者程序,由一个父进程创建两个子进程,父进程作为producer而子进程作为consumer。这里维护了三个信号量,mutex作为互斥信号量,为临界区提供互斥访问,empty用来维护空闲缓冲区,full则用来维护被填充的缓存区。
+
+### 实验二任务: ###
+
+实验二任务描述:
+
+实现`__down`函数,支持app5_2.c的运行
+
+实验二预期输出:
+
+ $ spike obj/pke app/elf/app5_2
+预期得到输出中,父进程生产的数量等于两个子进程消费的数量之和。运行脚本:
+
+ $ python3 ./pke-final-2
+预期得到输出:
+
+ build pk : OK
+ running app5_2 : OK
+ test sema : OK
+ Score: 20/20
+
+
+### 实验二提示: ###
+
+
在程序执行的过程中,任务常常会因为某一条件没有达成而进入等待状态,具到的上述的例子,当producer发现没有空闲的缓存区即empty不足时,或者consumer发现full不足时,二者均会进入等待状态。等待条件得到满足,然后继续运行。这种机制,我们可以使用等待队列来实现,等待某一条件的进程在条件未满足时加入到等待队列当中,当条件满足时在遍历对应的队列唤醒进程,并且将进程从队列中删除。
在此,我们定义结构体wait_t如下:
@@ -614,22 +656,11 @@ vaddr是信号量在用户空间的地址,即&empty的值。这里我们将信
相应的,在down的代码中需要执行相反的逻辑,首先,需要判断value的值是否大于0,若value值大于0,则可以直接进行减操作。若否则需要将当前进程加入等待队列,并设置其state与wait_state。接着需要调用schedule。当schedule返回时,需要对唤醒标准进行判断,并将进程从等待队列中删除。
-### 任务三:__down ###
-任务描述:实先`__down`函数,支持app5_2.c的运行
-
- $ spike obj/pke app/elf/app5_2
-预期得到输出中,父进程生产的数量等于两个子进程消费的数量之和。运行脚本:
-
- $ python3 ./pke-final-2
-预期得到输出:
-
- build pk : OK
- running app5_2 : OK
- test sema : OK
- Score: 20/20
----------
+### 提交课设 ###
+
至此为止,你已经完成了本实验的所有代码,运行脚本./pke-final:
$ python3 ./pke-final