PintOS lab1 threads 实验记录

news2024/11/16 5:35:53

Background

首先完成这个实验我们需要理清线程怎么启动的和切换的

下面这张图可以大体表示线程状态的切换

 让我们看看thread init的前世今生吧(:

从start.S汇编调用了一个c函数

 pintos_init初始化了一堆东西,当然里面也包括了thread啦

int
pintos_init (void)
{
  char **argv;

  /* Clear BSS. */  
  bss_init ();

  /* Break command line into arguments and parse options. */
  argv = read_command_line ();
  argv = parse_options (argv);

  /* Initialize ourselves as a thread so we can use locks,
     then enable console locking. */
  thread_init ();
  console_init ();  

  /* Greet user. */
  printf ("Pintos booting with %'"PRIu32" kB RAM...\n",
          init_ram_pages * PGSIZE / 1024);

  /* Initialize memory system. */
  palloc_init (user_page_limit);
  malloc_init ();
  paging_init ();

  /* Segmentation. */
#ifdef USERPROG
  tss_init ();
  gdt_init ();
#endif

  /* Initialize interrupt handlers. */
  intr_init ();
  timer_init ();
  kbd_init ();
  input_init ();
#ifdef USERPROG
  exception_init ();
  syscall_init ();
#endif

  /* Start thread scheduler and enable interrupts. */
  thread_start ();
  serial_init_queue ();
  timer_calibrate ();

#ifdef FILESYS
  /* Initialize file system. */
  ide_init ();
  locate_block_devices ();
  filesys_init (format_filesys);
#endif

  printf ("Boot complete.\n");
  
  if (*argv != NULL) {
    /* Run actions specified on kernel command line. */
    run_actions (argv);
  } else {
    //...
  }
  //...
}

 初始化init线程也叫main线程

 

让我们从最开始开始,我们还要初始化一个init_thread, idel_thread放到ready_list里面,为了即使一个线程也可以做tswith.有点链表哑结点那味。

void
thread_start (void) 
{
  /* Create the idle thread. */
  struct semaphore idle_started;
  sema_init (&idle_started, 0);
  thread_create ("idle", PRI_MIN, idle, &idle_started);

  /* Start preemptive thread scheduling. */
  intr_enable ();

  /* Wait for the idle thread to initialize idle_thread. */
  sema_down (&idle_started);
}

然后就是thread_unblock,thread_block

一般是sleep,或者lock阻塞才用到,把状态变为block

 在ready_list里面选择优先级最高的,然后切换线程上下文

然后就是thread_schedule_tail:Completes a thread switch by activating the new thread's page

  tables, and, if the previous thread is dying, destroying it。还有就是设置一下struct thread*的状态

 thread_unblock就是把线程插入到ready_list里面等待调度。

thread_yield就是出让cpu给别的线程,自己放入ready_list里面

 

thread_exit不言自明

 然后关于时间片这个概念,我们要先从一个硬件中断定时器说起,实际上这个也是单核上能做到并发假象的关键,如果我们关中断的话,就是一个串行程序了,这个debug时可以用的一个trick

注册一个中断函数。

 中断函数来做提高时间,可能这个时间就是本地时钟吧,sleep_tick来唤醒sleep的线程

thread_tick 来做一个时间片耗尽后的出让,也就是thread_yiled()

 大体背景也就是这样,实际上说到这,后面的lab也就是修修补补

分三个部分来讲吧

lab内容

lab1.1 实现 sleep

然后记录下ticks,然后等中断时,遍历减一 


lab1.2 实现优先级调度和优先级捐赠

优先级调度就是ready_list按thread priority做排序,然后每次run_next_thread的时,取优先级最大的

但是在持有锁的情况下,可能发生不符合我们预期的事,这就是优先级翻转,解决办法就是优先级捐赠

 

 还有一个挑战就是优先级捐赠有传递性,多重性(持有多个锁,优先级取最高的)

举个例子

那么我们的实现也就很正常水到渠成了

就是thread里面做一个wait_lockomg因为一个thread只能被一个lock阻塞,然后我们传递优先级也是传递到这个wait_locking,lock->holder可以定位到那个thread,然后递归做就行了。

然后lock_release时,要减低优先级。

让我们看看lock_acquire和lock_release的实现吧

 

 

lab1,3 高级调度

就是实现一个类似BSD4.4 的调度器

有什么优势吗?

 

我们看到recent_cpu和load_avg有一个系数,实际上也就是说更近的recent_cpu和load_avg有着更大的权重。

 

 pintos通过解析参数来选择调度器,如果选择的是mlqfs就是这个调度器,同时也学习了要static(如果不是全局的话,最好加一下,不然可能会重复定义)和external(全局,一个共享,一个是只声明)具体可以看看这篇bloghttps://www.cnblogs.com/honernan/p/13431431.html

然后pintos内核不支持浮点运算,因为Pintos does not support floating-point arithmetic in the kernel, because it would complicate and slow the kernel.

最后也是放大100倍在float里面,然后我们就可以这样观察到小数点后面的东西了,小数点后面两位就不会被转化抹掉。因为我们最终还是int,没有int表示浮点,没有float类型! 

 

 结果

fail了一个点,但是这个中断好像无法避免?因为可能时间刚好卡的比较准,tick+1了,导致这两个点不相等

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/839269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络(5) --- http协议

计算机网络(4) --- 协议定制_哈里沃克的博客-CSDN博客协议定制https://blog.csdn.net/m0_63488627/article/details/132070683?spm1001.2014.3001.5501 目录 1.http协议介绍 1.协议的延申 2.http协议介绍 3.URL 4.urlencode和urldecode 2.HTTP协…

langchain-ChatGLM源码阅读:参数设置

文章目录 上下文关联对话轮数向量匹配 top k控制生成质量的参数参数设置心得 上下文关联 上下文关联相关参数: 知识相关度阈值score_threshold内容条数k是否启用上下文关联chunk_conent上下文最大长度chunk_size 其主要作用是在所在文档中扩展与当前query相似度较高…

HCIP MPLS综合实验

目录 题目 实验步骤 第一步、IP地址规划 第二步、配置接口IP地址 第三步、IGP配置OSPF 第五步、公网配置MPLS 第五步、使用MPLS-VPN 第六步、R2-R4使用BGP建邻并实现VPN建邻 第六步、配置B静态路由 第七步、配置B动态路由 第八步、重发布 第九步、测试 题目 1、R1…

GO语言的垃圾回收机制

内存垃圾的产生 程序在内存上被分为堆区、栈区、全局数据区、代码段、数据区五个部分。对于C等早期编程语言栈上的内存回由编译器负责管理回收,而堆上的内存空间需要编程人员负责申请和释放。在Go中栈上内存仍由编译器负责管理回收,而堆上的内存由编译器…

王道计网 第四章笔记

4.1 生活在网络层的“工人”是路由器,他负责各种异构网络的连接,但是因为他只生活在前三层所以从网络层之上的东西他不能管理,所以网路层之上的数据对于路由器来说必须是相同的、透明的。 常见的网络层协议有IP 和 ICMPTCP IP传输层协议FTP应用层协议一句话区分IP和MAC地址…

Typescript - 索引签名

目录 1,什么是索引签名1,js 中使用对象的属性2,ts 中的索引签名3,扩展索引签名定义的类型 2,与 Record 对比3,遇到的问题1,索引 key 的类型问题,keyof2,索引 key 的类型问…

CADintosh X for mac CAD绘图软件2D CAD 程序 兼容 M1

CADintosh X for Mac是一个功能强大的2D CAD绘图程序,专为Mac用户设计。它由Lemke Software开发,提供了一套丰富的工具和功能,使用户能够轻松创建高质量的技术图纸,平面图和设计。 CADintosh X for Mac具有直观的用户界面&#x…

Python3 处理PDF之PyMuPDF 入门

PyMuPDF 简介 PyMuPDF是一个用于处理PDF文件的Python库,它提供了丰富的功能来操作、分析和转换PDF文档。这个库的设计目标是提供一个简单易用的API,使得开发者能够轻松地在Python程序中实现PDF文件的各种操作。 PyMuPDF的主要特点如下: 跨平台兼容性&a…

【分布式系统】聊聊服务调度

什么是服务治理 对于程序员来说的话,把功能按照一定的设计进行开发上线之后,其实并不够,在未来的时间内,其实还需要做好功能的维护工作,而维护项目的成本远远高于开发出一个软件的成本。 对于功能开发起来期来说&am…

ensp-GVRP服务

ensp-GVRP服务 日期:6-26 📎GVRP实验.zip📎GVRP服务.docx

无涯教程-Perl - 环境配置

在开始编写Perl程序之前,让我们了解如何设置我们的Perl环境。 您的系统更有可能安装了perl。只需尝试在$提示符下给出以下命令- $perl -v 如果您的计算机上安装了perl,那么您将收到以下消息: This is perl 5, version 16, subversion 2 (v5.16.2) b…

谁更适合搭配甜点显卡?i7-13700KF、锐龙7 7800X3D对比:游戏相当 生产力Intel强了50%...

一、前言:如果搭配2000元甜点显卡 i7-13700KF和锐龙7 7800X3D谁更有性价比? 现在AMD最受欢迎的处理器无疑是拥有96MB三级缓存的锐龙7 7800X3D,这是一颗专为游戏而生的处理器。 Intel这边,i7-13700KF以略高于i5-13600K的售价&#…

python:卡尔曼和贝叶斯滤波器

本文分享一个Filerpy的说明文档和代码示例文档,有关于 Python 中的卡尔曼和贝叶斯滤波器。该方法可以应用于气象遥感等领域。 说明文档:https://filterpy.readthedocs.io/en/latest/kalman/KalmanFilter.html 参考代码链接:https://nbviewer.…

conda install 和pip install有什么区别?

本篇为分享贴,截图部分选自知乎,部分选自csdn,文字内容是结合自己实践进行总结。 环境引用的包在哪? 首先,一条命令: python -m site 这条命令可以定位引用的包在哪里 ,当然也可以自己设置默认…

K8s中的Secret

Secret作用:加密数据存在etcd里面,让pod容器以挂载Volume方式进行访问。场景:凭据

基于Open3D的点云处理14-法向量

法向量 计算法向量的接口函数: Open3d使用estimate_normals函数来计算法向量。其参数设置Open3d提供了3中参数搜索的方法(所有计算的法向量模长为1): open3d.geometry.KDTreeSearchParamKNN(knn20) # 计…

win11设置管理员权限

【win11家庭版怎么找管理员权限,怎么找gpedit】 win11家庭版怎么找管理员权限,怎么找gpedit_哔哩哔哩_bilibili echo offpushd "%~dp0"dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum …

【雕爷学编程】Arduino动手做(185)---WK104 亚克力机械爪

收了一套 亚克力机械爪的散件,准备尝试组装一下。 All parts 2 left claw 2 right claw 4 half claw 2 plate fixer 双通铜柱 Double copper column 铜柱 copper pillar 螺母 Nut 螺丝 Screw Prepare several parts of the picture and start assembling the l…

小蜗语音1.2 文本生成字幕 文本生成语音配音

1、文本转字幕,可以把一部小说直接生成字幕 2、文本转语音,可以直接把一部小说或者字幕文件生成语音,并且新生成的语音和字幕一一对应 链接:https://pan.baidu.com/s/1X_rY4Wjkk2cWqsFcu4JSHA?pwdvtpm 提取码:vtpm

S7-200SMART与ET200SP远程IO模块进行PROFINET通信的具体方法

S7-200SMART与ET200SP远程IO模块进行PROFINET通信的具体方法 使用前提: 只有标准型且固件版本为V2.4及以上的S7-200 SMART CPU才支持 PROFINET 控制器功能。 S7-200 SMART 作 PROFINET 控制器最多可带8个 IO 设备(例如:远程 IO、阀岛、变频器、伺服和机器人等)。 本例中以 …