xv6/调度算法及并发程序设计

 

1 proc.cscheduler函数中,有两行:

 if(setjmp(&cpus[cpu()].jmpbuf) == 0)

 longjmp(&p->jmpbuf);

 把它修改为: 

cprintf("setjmp called in scheduler\n");

if(setjmp(&cpus[cpu()].jmpbuf) == 0){

 cprintf("setjmp in scheduler returned 0; longjmp\n");

 longjmp(&p->jmpbuf);

 }else

 cprintf("setjmp in scheduler returned 1\n");

 

修改后,重编译内核,在Bochs中运行编译后的内核,你将会看到有规律的六行输出在屏幕上。

 要求:

  1. 1.      列出这有规律的六行。

 

  1. 2.      在这六行里面,每输出两行setjmp returned 才输出一行setjmp called. 试解释一下为什么

 

   int  setjmp(struct jmpbuf *jmp);

   void longjmp(struct jmpbuf *jmp); 的函数解析!

 

# Setjmp saves its stack environment in jmp for later use by longjmp.

# It returns 0.

 

# Longjmp restores the environment saved by the last call of setjmp.

# It then causes execution to continue as if the call of setjmp

# had just returned 1.

 

# The caller of setjmp must not itself have returned in the interim.

# All accessible data have values as of the time longjmp was called.

 

# [Description, but not code, borrowed from Plan 9.]

 

  这是setjmplongjmp的函数解析。意思在于setjmp会保存当前环境,上下文。然后longjmp会回溯到最后一个setjmp所指向保存的环境。如图1所示

 

                             1

cprintf("setjmp called in scheduler\n");

if(setjmp(&cpus[cpu()].jmpbuf) == 0){

 cprintf("setjmp in scheduler returned 0; longjmp\n");

 longjmp(&p->jmpbuf);  

 }else

 cprintf("setjmp in scheduler returned 1\n");

 

一开始的时候没有longjmp的时候,setjmp返回的为0.

然后执行cprintf("setjmp in scheduler returned 0; longjmp\n");

接着到longjmp 于是跳回setjmp的位置。此时因为longjmp了于是setjpm返回1

于是执行cprintf("setjmp in scheduler returned 1\n");

所以才有一次setjmp returned 才输出一行setjmp called

 

 

  1. 3.      试解释一下scheduler函数和sched函数的用途。

 

 

 

可以从scheduler函数和sched函数的注释中看出.

对于scheduler函数

// Per-CPU process scheduler.

// Each CPU calls scheduler() after setting itself up.

// Scheduler never returns.  It loops, doing:

//  - choose a process to run

//  - longjmp to start running that process

//  - eventually that process transfers control back

//    via longjmp back to the top of scheduler.

每一个CPU都有属于它自己的scheduler函数,当每一个CPU设置它本身的时候会调用scheduler函数的时候。Scheduler函数永远不会返回,它会不断的循环:(循环过程中)

   1 选择一个进程,然后运行该进程。

   2 使用longjmp跳到那个进程代码那,开始运行那个进程。

   3 最后进程将控制权转移回来。

   4 通过longjmp调到scheduler函数头。重新开始。

 

对于 sched函数

// Enter scheduler.  Must already hold proc_table_lock

// and have changed curproc[cpu()]->state.

在进入scheduler 函数,而且会在持有 proc_table_lock

并且会改变 curproc[cpu()]的状态。

 

 

 

 

 

 

 

4. 阅读trap.c 50行至第66行。Proc.c中的 yield函数、sched函数及scheduler函数,结合书本,确定xv6使用的是哪种调度算法。给出你的理由(通过分析代码证明你的观点)。

 

1先来先服务(FCFS

2短作业优先(SF

3高响应比优先

4时间片轮转(RR

5多级队列调度算法

6多级反馈队列调度算法总共有6调度算法是XV6可能的选项。

前三种都是要安装进程的某个属性排序,比如进入时间,比如作业长短,响应比。并且选择进入时间最早,作业最短,响应比最高。

Scheduler 函数中的

for(i = 0; i < NPROC; i++){

      p = &proc[i];

      if(p->state != RUNNABLE)

        continue;

 

这部分是调度算法的核心,证明了XV6是使用时间轮转(RR。因为上面代码就是一个循环,在process数组里寻找可执行的进程。然后接下去的代码的意义才是跳到被选中的进程去进行执行。

// Switch to chosen process.  It is the process's job

// to release proc_table_lock and then reacquire it

// before jumping back to us.

 

      setupsegs(p);

      curproc[cpu()] = p;

      p->state = RUNNING;

      if(setjmp(&cpus[cpu()].jmpbuf) == 0)

        longjmp(&p->jmpbuf);

 

至于yield 函数 sched函数。当一个进程使用完时间片后,会中断调用yield函数来让出CPU给新的进程,yield调用sched函数,sched会切换:

void

sched(void)

{

  struct proc *p = curproc[cpu()];

 

  if(!holding(&proc_table_lock))

    panic("sched");

  if(cpus[cpu()].nlock != 1)

    panic("sched locks");

 

  if(setjmp(&p->jmpbuf) == 0)

    longjmp(&cpus[cpu()].jmpbuf);

}

 

转载于:https://www.cnblogs.com/zzzPark/p/6865625.html

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

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

相关文章

c语言四舍五入取整向上取整,C 语言常用的函数(ceil-向上取整,floor-向下取整,round-四舍五入)...

释放双眼&#xff0c;带上耳机&#xff0c;听听看~&#xff01;1.ceil函数(向上取整)extern float ceilf(float); //参数为flot类型extern double ceil(double); //参数为double类型extern long double ceill(long double); //参数为long double类型举例&#xff1a;向上取整函…

PHP函数之HTMLSPECIALCHARS_DECODE

PHP函数之htmlspecialchars_decode htmlspecialchars_decode &#xff1a;将特殊的 HTML 实体转换回普通字符 htmlspecialchars&#xff1a; 将普通字符转换成实体转载于:https://www.cnblogs.com/lovebing/p/6866484.html

c语言中printk用法,printk和printf的区别

&&&大部分常用的C库函数在Linux内核中都已经得到了实现。在所有没有实现的函数中&#xff0c;最著名的就数printf()函数了。内核代码虽然无法调用printf()函数&#xff0c;但它可以调用printk()函数。printk()函数负责把格式化好的字符串拷贝到内核日志缓冲上&…

《Java技术》第八次作业

《Java技术》第八次作业 &#xff08;一&#xff09;学习总结 1.用思维导图对本周的学习内容进行总结。 2.通过实验内容中的具体实例说明在执行executeUpdate&#xff08;&#xff09;方法和executeQuery&#xff08;&#xff09;方法中使用动态参数时&#xff0c;为什么要使用…

android 短信 aapp,谈谈App的统一跳转和ARouter

App中每次页面跳转,都需要调用统一导航, 它用的非常频繁, 有必要对它进行一下梳理. 让他能用起来简单方便, 同时能支持各种常用的跳转业务场景.一. Android跳转遇到的问题1.intent-filter跳转不好管理Intent intent new Intent();intent.setAction(Intent.ACTION_SENDTO);inte…

android 自定义spnner弹出框,PopupWindow,ListView实现自定义Spinner

最终的效果图,点击86弹出popup这里写图片描述PupupWindow的布局文件为一个ListView 作为pupup的主体内容android:orientation"vertical"android:layout_width"match_parent"android:layout_height"match_parent">android:id"id/register…

hdu 6026 Deleting Edges(最短路计数)

题目链接&#xff1a;hdu 6026 Deleting Edges 题意&#xff1a; 给你n个点&#xff0c;和一个邻接矩阵&#xff0c;非0表示有边&#xff0c;0表示没边。 现在让你删一些边&#xff0c;构成一棵树&#xff0c;使得每个点到0这个点的距离为没删边之前的最短路。 问有多少棵这样的…

android 服务端 导入工程,如何导入与配置从网上下载的android源代码及服务器端源代码...

将Android项目导入import进Eclipse。 注意SDK版本是否匹配 。 服务器部署到Tomcat下。 你得在数据库中将这个点菜系统的数据库和表建好&#xff0c;或者导入。在服务器的代码中修改好你的数据库名和密码。首先看你的服务器配置的是什么环境 一般就2种 linux系统 window系统&…

mysql: 模糊查询 feild like keyword or feild like keyword , concat(feild1,feild2,feild3) like keyword...

mysql: 模糊查询 feild like %keyword% or feild like% keyword% , 或者 concat(feild1,feild2,feild3) like %keyword% 转载于:https://www.cnblogs.com/achengmu/p/6877852.html

android按钮控件常见问题,Android的基本控件和Activity的应用总结

Android的基本控件常用界面控件TextView 显示文本信息button 普通按钮EditText 可编辑的文本框组件(输入框)ImageView 用于显示图片ImageBUtton 图片按钮CheckBox 复选框RadioGroup 单选按钮组Spinner 下拉列表组件ProgressBar进度条SeekBar拖动条RatingBar评分组件ListView列表…

Xamarin XAML语言教程构建进度条ProgressBar

Xamarin XAML语言教程构建进度条ProgressBar Xamarin XAML语言教程构建进度条ProgressBar&#xff0c;ProgressBar被称为进度条&#xff0c;它类似于没有滑块的滑块控件。进度条总是水平放置的。本节将讲解如何使用进度条。注意&#xff1a;进度条在各个平台下基本相同&#xf…

android tv字体,best登陆「永久地址0365.tv」android默认字体android使用代码使用新的字体的常用代码...

页面类类名称&#xff1a;MainActivitypackage com.example.android_fonts_test;import android.support.v7.app.ActionBarActivity;import android.content.Context;import android.graphics.Typeface;import android.os.Bundle;import android.view.Menu;import android.view…

android 交叉编译so,Android交叉编译htop和使用方法

htop来源于top&#xff0c;top是Unix/linux下功能强大的性能检测工具之一&#xff0c;用于实时检测并统计进程的属性和状态&#xff0c;基于ncurses库&#xff0c;可上显示文字界面。但是top已经非常陈旧&#xff0c;不支持鼠标点击操作&#xff0c;不支持查看进程的各个子线程…

Java笔记(08):面向对象--抽象类

1、抽象类概述&#xff1a; 1 /*2 抽象类的概述&#xff1a;3 动物不应该定义为具体的东西&#xff0c;而且动物中的吃&#xff0c;睡等也不应该是具体的。4 我们把一个不是具体的功能称为抽象的功能&#xff0c;而一个类中如果有抽象的功能&#xff0c;该…

mac删除android sd卡,如何从mac完全删除android及其所有文件?

前一段时间我试图让科尔多瓦工作&#xff0c;但android模拟器永远不会启动。它只是挂着一个黑色的屏幕。如何从mac完全删除android及其所有文件&#xff1f;我原来是用brew install android-sdk安装的。然后我读了一个糟糕的地方。所以我已经删除它并安装了Android Studio。无论…

201521123023《Java程序设计》第13周学习总结

1. 本周学习总结 &#xff08;1&#xff09;网络中为了进行数据交换&#xff08;通信&#xff09;而建立的规则、标准或约定(语义语法规则)称之为协议&#xff08;常用http/ftp&#xff09; &#xff08;2&#xff09;大致熟悉了TCP协议&#xff0c;但是UDP怎么辣么蓝&#xff…

Android中怎获取json,Android应用中如何解析获取的json数据

Android应用中如何解析获取的json数据发布时间&#xff1a;2020-11-24 17:10:08来源&#xff1a;亿速云阅读&#xff1a;107作者&#xff1a;Leah这篇文章将为大家详细讲解有关Android应用中如何解析获取的json数据&#xff0c;文章内容质量较高&#xff0c;因此小编分享给大家…

Hibernate4之session核心方法

在学习session的核心方法之前&#xff0c;我们先了解下hibernate中几种对象的状态&#xff1a; 暂时状态&#xff1a;这样的状态就好像咱们公司请的暂时员工一样&#xff0c;他在公司里没有相关的资料和id。 特点&#xff1a;在使用代理主键的情况下, OID 通常为 null 不…

Android 同步锁死锁,Android多线程研究(3)——线程同步和互斥及死锁

为什么会有线程同步的概念呢&#xff1f;为什么要同步&#xff1f;什么是线程同步&#xff1f;先看一段代码&#xff1a;package com.maso.test;public class ThreadTest2 implements Runnable{private TestObj testObj new TestObj();public static void main(String[] args)…

QML与C++交互:登陆界面设计

QML与C交互:登陆界面设计 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境&#xff1a; 主机:WIN7 开发环境:Qt5.2.1 说明: QML设计前台界面,C后台负责逻辑 效果图: 源码: 前台qml文件 login.qml /******************************************************…