Pintos实验一

本文档详述了在Pintos操作系统中完成的三个实验任务:重新实现timer_sleep()函数以避免忙等待,实现优先级调度,以及构建多级队列反馈调度系统。实验涉及线程状态管理、中断处理、线程调度算法的实现,以及锁的优化以适应多级队列调度的需求。
摘要由CSDN通过智能技术生成

 

目录

一、实验简介

二、实验环境的安装与搭建

三、Mission 1:重新实现timer_sleep()函数

1、相关函数介绍

2、具体实验过程

四、Mission 2:在Pintos中实现优先级调度

五、Mission 3:实现多级队列反馈调度



一、实验简介

Pintos是Standford大学为操作系统课程专门开发的一个基于80x86架构的简单操作系统框架(A simple operating system framework)。他支持内核线程、加载和运行用户程序以及文件系统。

小组成员:郭鑫玥,胡小波,贾浩男,贾飞阳,陈俊良

二、实验环境的安装与搭建

1. 下载bochs 和 pintos压缩包

2. 安装bochs 和 pintos

1)将pintos/src/utils中的一些文件复制进usr/bin/文件夹

2)配置安装pintos-gdb

3)此处注意:要修改/usr/bin/pintos-gdb中的配置

GDBMACROS=/usr/bin/gdb-macros

4)修改相关文件的权限

5)复制squish-pty到usr/bin,并修改权限

6)链接bochs

7)运行pintos,使用命令pintos -v -- run alarm-multiple测试pintos样例 

8)之后进行makecheck测试,可见此时全部为FAIL

三、Mission 1:重新实现timer_sleep()函数

1、相关函数介绍

首先实验一的操作是需要通过修改pintos的线程休眠函数来保证pintos不会在一个线程休眠时忙等待

1)用到的相关文件:

pintos/src/devices目录:

       timer.h, timer.c

pintos/src/threads目录:

       thread.h, thread.c

2)thread.h定义了一个thread的结构体用于存储线程的信息

其中enum thread_status这个枚举类型的变量表示这个线程现在所处的状态

 3)timer.c中实现了线程休眠的函数thread_sleep,当线程休眠时必须保证中断是打开的。当前执行进程调用timer_sleep(ticks)时,函数通过不断轮询检查经过时间是否达到ticks,若还没达到则调用thread_yield函数,达到了ticks就会结束休眠。这个函数作用是实现让某个线程睡眠ticks时间,即让该线程暂时放弃CPU。ASSERT作用是若语句不为真则退出。

4)thread_yield函数会把当前线程放进ready队列,并调度下一个线程,线程调度时要保证中断关闭。Thread_yield函数只是把线程放进调度队列,然后切换线程,此时休眠线程状态是ready,在一个tick内依然有可能会被调度,继续消耗cpu时间,没有完全把时间让给别的进程,这样就违反了线程休眠的原则,造成了忙等待。

其中,schedule()是专门负责线程切换的函数,执行了以后会把当前线程放进队列里并调度出下一个线程

5)pintos默认每一个ticks调用一次时间中断。即每一个线程最多可以占据CPU一个ticks的时长。每隔一段时间操作系统必须获得CPU时间进行进程调度等工作,操作系统是通过中断来获得CPU时间。在timer中断产生时这个函数就会被调用

6)timer_ticks()函数, 就是获取ticks的当前值返回,其中,intr_get_level返回了intr_level的值;intr_disable的作用是返回关中断,然后返回中断关闭前的状态。所以禁止当前行为被中断, 保存禁止被中断前的中断状态(用old_level储存)

enum intr_level这个枚举定义了中断是开还是关,在原子操作中必须保证中断是关的。

7)thread_foreach(thread_action_func *func, void *aux) 遍历当前ready queue中的所有线程,并且对于每一个线程执行一次func操作。这里的func是一个任意给定函数的指针,参数aux则是你想要传给这个函数的参数。pintos中,所有ready的线程被保存在一个链表中。这个函数做得不过是遍历了一遍链表而已。这个函数只能在中断关闭的时候调用。


8)thread_block()和thread_unblock(thread *t)。区别在于thread_block()函数的作用是把当前占用cpu的线程阻塞掉,而thread_unblock(thread *t)函数作用是将已经被阻塞掉的进程t唤醒到ready队列中。

2、具体实验过程

函数重新实现:

 实现思路: 调用timer_sleep的时候直接把线程阻塞掉,然后给线程结构体加一个成员ticks_blocked来记录这个线程被sleep了多少时间, 然后利用操作系统自身的时钟中断(每个tick会执行一次)加入对线程状态的检测, 每次检测将ticks_blocked减1, 如果减到0就唤醒这个线程。

具体代码:

/* Sleeps for approximately TICKS timer ticks.  Interrupts must
   be turned on. */
void
timer_sleep (int64_t ticks)
{
  if (ticks <= 0)
  {
    return;
  }
  ASSERT (intr_get_level () == INTR_ON);
  enum intr_level old_level = intr_disable ();
  struct thread *current_thread = thread_current ();
  current_thread->tic
  • 22
    点赞
  • 155
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值