pintos操作系统实验Project1-时钟
Posted puyalee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pintos操作系统实验Project1-时钟相关的知识,希望对你有一定的参考价值。
目前在学习操作系统,在这里用于记录学习过程,学习过程中主要参考了laiy的文章,作为一个初学者,有些地方理解不是很透彻,就当作是笔记了。
Project1的实验内容是重新设计timer_sleep函数,使用指定方法优化其实现方式。
pintos里面原始的timer_sleep函数是这样的,这里的实现方式是使用忙等。
1 void 2 timer_sleep (int64_t ticks) 3 { 4 int64_t start = timer_ticks (); //获取当前时钟 5 6 ASSERT (intr_get_level () == INTR_ON); //确认当前状态是开中断 7 while (timer_elapsed (start) < ticks) //当调用之后过去的时间还没到睡眠时间时 8 thread_yield (); //是当前进程进入就绪队列等待,调用新的进程 9 }
这种方法实现起来较为简单,但是也有明显的缺陷,那就是在睡眠时间里进程仍然在占用着CPU资源。我们的任务就是要解决这个问题,方案是利用阻塞机制,当用户程序调用timer_sleep时,使当前进程进入阻塞状态,并调用其它进程,当睡眠时间结束时唤醒该进程。
到这里应该思考几个问题:
- 用什么来记录用户调用时传递的睡眠时间?
- 在哪里对睡眠时间进行什么操作?
- 如何检测睡眠时间是否结束?
经过教员讲解,加之学习laiy的文章,基本理出一条思路:修改timer_sleep函数,使得睡眠时间大于0的时候将进程变为阻塞状态,为了实现这一点,需要创建一个变量sleep_ticks传递睡眠时间,在创建进程的时候初始化为0,当调用timer_sleep后传参;而后在每个时钟中断均需要对每个进程进行检测sleep_ticks是否大于0,每检测一次sleep_ticks--,直至sleep_ticks=0时唤醒该进程
下面进行具体实现:
首先在线程的结构体中加入我们需要的成员
1 int64_t sleep_ticks; /* # of timer ticks since blocked. */
在创建线程时初始化sleep_ticks
1 t->sleep_ticks = 0;
重写timer_sleep函数
1 /* modified func */ 2 void 3 timer_sleep (int64_t ticks) 4 { 5 if(ticks <= 0) //如果用户调用的睡眠时间<=0,则不阻塞该线程 6 return; 7 8 ASSERT (intr_get_level () == INTR_ON); //确认中断是打开的 9 enum intr_level old_level = intr_disable (); //关中断,并保存之前的中断状态,即lod_level是开中断状态 10 struct thread *current_thread = thread_current (); //获取当前线程信息的结构体指针 11 current_thread->sleep_ticks = ticks; //将用户需要线程睡眠的时间参数传给sleep_ticks 12 thread_block (); //将当前线程状态设置为阻塞态 13 intr_set_level (old_level); //开中断 14 }
利用每一个时钟中断对每个线程进行检测,需要在timer_interrupt中加入函数thread_foreach()
1 thread_foreach (blocked_thread_check, NULL); //对每个线程都应用函数blocked_thread_check
这里的blocked_thread_check即负责检测每个线程的sleep_ticks,如果减到0则唤醒该进程,需写入thread.c里面
1 /* Check the blocked thread */ 2 void 3 blocked_thread_check (struct thread *t,void *aux UNUSED) 4 { 5 if (t->status == THREAD_BLOCKED && t->sleep_ticks > 0) //对于处于阻塞状态的线程才会检测其sleep_ticks 6 { 7 t->sleep_ticks--; //检测其sleep_ticks值减1是否为0,等于0则表示 8 if (t->sleep_ticks == 0) //在这个时钟结束时应该被unblock 9 { 10 thread_unblock(t); //唤醒该进程 11 } 12 } 13 }
blocked_thread_check需要在thread.h里面声明
1 /* check the block state */ 2 void blocked_thread_check (struct thread *t,void *aux UNUSED);
至此Project1就完成了,测试结果也在意料之中
以上是关于pintos操作系统实验Project1-时钟的主要内容,如果未能解决你的问题,请参考以下文章
获取信号量必须是原子的。 Pintos 的 sema_down 安全吗?
Linux基于 Pintos 实现新的用户级程序的系统调用 | 冯诺依曼架构