练习0:填写已有实验
使用meld的软件进行对比即可
这里把需要填充的文件罗列如下:
proc.c
default_pmm.c
pmm.c
swap_fifo.c
vmm.c
trap.c
sche.c
练习1 理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题
0x0 哲学家问题
哲学家就餐问题,即有五个哲学家,他们的生活方式是交替地进行思考和进餐。哲学家们公用一张圆桌,
周围放有五把椅子,每人坐一把。在圆桌上有五个碗和五根筷子,当一个哲学家思考时,他不与其他人交
谈,饥饿时便试图取用其左、右最靠近他的筷子,但他可能一根都拿不到。只有在他拿到两根筷子时,方
能进餐,进餐完后,放下筷子又继续思考。
0x1 信号量介绍
struct semaphore {
int count;
queueType queue;
};
void P(semaphore S){
S.count--;
if (S.count<0) {
把进程置为睡眠态;
将进程的PCB插入到S.queue的队尾;
调度,让出CPU;
}
}
void V(semaphore S){
S.count++;
if (S.count≤0) {
唤醒在S.queue上等待的第一个进程;
}
}
基于上诉信号量实现可以认为,当多个(>1)进程可以进行互斥或同步合作时,一个进程会由于无法满足信号量设置的某条件而在某一位置停止,直到它接收到一个特定的信号(表明条件满足了)。为了发信号,需要使用一个称作信号量的特殊变量。为通过信号量s传送信号,信号量的V操作采用进程可执行原语semSignal(s);为通过信号量s接收信号,信号量的P操作采用进程可执行原语semWait(s);如果相应的信号仍然没有发送,则进程被阻塞或睡眠,直到发送完为止。
0x2 P操作&V操作实现
P操作
具体实现信号量的P操作,首先关掉中断,然后判断当前信号量的value是否大于0。如果是>0,则表明可以获得信号量,故让value减一,并打开中断返回即可;如果不是>0,则表明无法获得信号量,故需要将当前的进程加入到等待队列中,并打开中断,然后运行调度器选择另外一个进程执行。如果被V操作唤醒,则把自身关联的wait从等待队列中删除(此过程需要先关中断,完成后开中断)。具体实现如下所示:
static __noinline uint32_t __down(semaphore_t *sem, uint32_t wait_state) {
bool intr_flag;
local_intr_save(intr_flag); //关掉中断
if (sem->value > 0) {
//当前信号量value大于0
sem->value --;//直接让value减一
local_intr_restore(intr_flag);//开中断返回
return 0;
}
//当前信号量value小于等于0,表明无法获得信号量
wait_t __wait, *wait = &__wait;
wait_current_set(&(sem->wait_queue), wait, wait_state);//将当前的进程加入到等待队列中
local_intr_restore(intr_flag);//打开中断
schedule();//运行调度器选择其他进程执行
local_intr_save(intr_flag);//关中断
wait_current_del(&(sem->wait_queue), wait);//被V操作唤醒,从等待队列移除
local_intr_restore(intr_flag);//开中断
if (wait->wakeup_flags != wait_state