码迷,mamicode.com
首页 > 系统相关 > 详细

高级操作系统实验2-进程调度与切换分析(1)

时间:2020-03-19 15:09:19      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:处理   如何   重新编译   调用   定义   命令   ln -s   运行时间   环境   

实验目的:掌握linux进程调度的工作原理和实现方式,提高内核调度技术。

实验内容:编一个程序在3个进程中分别循环输出字母A/B/C,每输出一个字母就主动放弃CPU;然后通过对内核的调度,画出3个进程运行的详细时序图和概要时序图,时序图的时间范围涵盖上述字母至少2个(可以相同),要求在详细的时序图中标注下列控制点信息:

调度的开始及原因和结束、进程切换的开始;

中断处理的开始和结束、软中断处理的开始和结束;

系统调用的开始及系统调用号和结束;

缺页等异常的开始和结束

增加和删除CFS运行队列中的节点的时刻

更新当前进程的vruntime的时刻

准备由核心态进入用户态的时刻

设置需要剥夺当前进程而重新调度标志TIF_NEED_RESCHED的时刻

系统处于用户态的区间

系统处于哪个进程的上下文

实验步骤:

1、编写一个普通的应用程序

提示:

创建子进程可以使用系统调用fork

输出字符A可以使用系统调用write:write(2,“A”,1)

主动放弃CPU可以使用系统调用sched_yield

父进程应等待子进程结束以后才退出,可以使用系统调用waitpid

2、在Ubuntu中编译测试上述应用程序; 待成功后,重新编译生成带调试信息的32位可执行文件

3、将生成的可执行文件放入实验用的qume虚拟机

4、运行qume虚拟机,在虚拟机的命令解释器中运行和测试应用程序,确保其正确输出期望的字符序列

5、调试分析内核,绘制时序图,步骤如下

a)启动调试,设置所需要的内核断点,可执行文件的执行(do_execve,只需要跟踪普通进程对此函数的调用),调度的开始和结束(函数_schedule的进入和退出),进程切换的开始(_switch_to),参数next_p指向新进程的进程控制块,中断处理的开始(smp_apic_timer_interrupt时钟中断,do_IRQ其他中断部分),中断和异常的结束(从ret_from_intr/ret_from_exception开始准备结束;真正结束是在restore_all,但这里也有可能是系统调用的结束),软中断处理的开始和结束(函数_do_softirq的进入和退出),缺页异常的开始(do_page_fault),设备不存在异常的开始(do_device_not_available),系统调用的开始和结束(函数do_fast_syscall_32的进入和退出,在此函数的参数regs->orig_ax中记录了系统调用号;有时系统调用的结束位置是在restore_all。系统调用返回前,一般会执行函数prepare_exit_to_usermode),增加和删除CFS运行队列中的节点(enqueue_task_fair和dequeue_task_fair,函数参数p指向被操作进程的进程控制块),更新当前进程的vruntime(update_curr,此函数结束时vruntime已经更新),准备山上核心态进入用户态(prepare_exit_to_usermode),设置需要当前进程而重新调度标志(set_tsk_need_resched)

b)关闭除do_execve之外的的所有其他断点,使用disable命令

c)在应用程序abc的main函数入口处设置断点,步骤如下:1在内核源码目录下,创建指向abc.c所在目录的符号链接,ln -s <abc.c所在目录> abc,2查看可执行文件abc的".text"节(Section)的起始虚拟地址(VMA),在可执行文件abc所在目录运行:objdump -dlx abc | less,然后查看".test"节的起始虚拟地址,3在gdb导入应用程序符号信息:dir abc,add-symbol-file abc/abc <可执行文件abc的".text"节的起始虚拟地址>,4设置断点:b abc.c:main

d)跟踪到应用程序abc的main函数入口处

e)打开所有断点,使用enable命令

f)继续运行,分析操作系统的运行轨迹,画出进程运行的时序图,直到输出至少两个字母(可以相同)

 

常见问题

1、如何查看当前进程的“需要剥夺当前进程而重新调度”标志(TIF_NEED_RESCHED)?

p/x $lx_thread_info($lx_current()).flags

在该flags的第3位(位置计数从低位开始、从0开始)

2、进程调度的原因有哪些

在CONFIG_PREEMPT没有定义(实验环境的默认配置)的情况下,只有两种情况可能引发调度:a)当前进程主动放弃cpu,直接引发调度;b)从内核态返回用户态之前,如果“TIF_NEED_RESCHED”标志被设置,则剥夺当前进程,引发调度

3、如何查看当前进程的vruntime(虚拟运行时间)

p $lx_current().se.vruntime

4、系统何时处于核心态,何时处于用户态

系统调用执行期间和中断、异常处理期间处于核心态;其他时间处于用户态

5、如何知道系统处于哪个进程的上下文

查看当前进程的pid即可

6、如何查询系统调用号对应的系统调用函数名

在文件Syscalls_32.h(arch\x86\include\generated\asm)中有记录

7、如何查看当前cpu的运行队列中有进程

8、查看CFS运行队列中最小的进程vruntime

9、查看当前cpu的CFS运行队列中各进程信息

10、在每次调度停止时显示某表达式的值

11、在每次某断点被捕获而停止时都执行一组命令

12、在某函数结束处设置断点

13、在gdb启动时运行调试脚本

14、为什么会观察到一些孤立的异常返回事件(ret_from_exception)?

因为只在缺页异常处理程序的入口设置了断点,没有截获其他类型的异常

15、如何在某绝对地址处设置断点

 

高级操作系统实验2-进程调度与切换分析(1)

标签:处理   如何   重新编译   调用   定义   命令   ln -s   运行时间   环境   

原文地址:https://www.cnblogs.com/ppbb/p/12524335.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!