热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

schedule调用相关整理

1schedule的调用时机正常情况下进程上下文中的直接调用schedule(),就会尝试着进行上下文切换。比如:intdown_interruptible(stru

1 schedule的调用时机
×××正常情况下进程上下文中的直接调用schedule(),就会尝试着进行上下文切换。比如:

  • int down_interruptible(struct semaphore *sem)
  • copy_from_user(to, from, n)--------只能在用户上下文中调用.
×××抢占式的调用schedule()。比如:
  • 在中断里面返回时候,即in_irq() != 0(当前处于中断上下文),检查当前进程的TIF_NEED_RESCHED标志位,看是否需要进行preempt_schedule_irq()进行preempt的调度。当然如果准备这个时候进入in_irq()进行调度的话,要设置当前进程的PREEMPT_ACTIVE位,代表这个schedule的调用是因为抢占发生的。让shcedule有相应的准备。
  • schedule_tick()会做一些跟调度算法有关的计算和更新,如果当前进程需要被schedule了,就置位TIF_NEED_RESCHED,注意这里面并不调用schedule。
  • preempt_check_resched(),一般在进程上下文中被间接调用。比如在preempt_enable当中在重新设置了可以被抢占的标志位之后,就调用preempt_check_resched(),如果需要被抢占那就调用shcedule抢占之。
补充:preempt_schedule_irq()和preempt_check_resched都会调用preempt_schedule。
2 Performing the Process Switch
在switch_to(prev, next, last)函数中,直接汇编不罗嗦

从上面可以看出通用寄存器中,在进程切换到时候并不太需要保存什么寄存器。这是由进程切换到时机造成的,要么直接在内核代码中调用schedule,要么就在中断返回时候调用schedule。不保存寄存器确实无关大雅。

__switch_to中的任务包括:

  1. _ _unlazy_fpu( ) --- 存储fpu,mmx,xmm寄存器。
  2. Loads next_p->thread.esp0 in the esp0 field of the TSS relative to the local CPU.
  3. 修改GDT,LDT中一些选择子。
  4. 存储fs, gs
  5. 有必要的话,存储调试寄存器
  6. 更新IO BITMAP in TSS.
  7. movl %edi,%eax   //返回地址,为刚刚压栈的threadinfo->EIP
    ret

cpu接着跑,但不是在prev进程的上下文中跑了,而是在next进程的上下文中接着跑。
上下文很重要!

3 Hardware context storage in User pace and Kernel space

问:Userspace程序因为发生interrupt或者sys_call进入kernel时候, Userspace程序context存储在哪?
答:可以在copy_process->copy_thread函数中看到,TSS中存储的esp0就是thread_union所在的stack。所以在interrupt的时候,context是存储在esp0中的。并且凭经验,sys_call也是存储在esp0的。

问:Kernel程序运行时候发生中断,上下文存储在哪?
答:存储在当前current运行所使用的当前esp堆栈中。

问:在interrupt return或者kernel程序“主动调用schedule”时候,可能会进行schedule进行preempt,被schedule的函数的上下文又是存储在哪?
答:在进入中断的时候,上下文已经存储了,然后调用schedule 。

问:在schedule中你如何判断当前发生在上方的哪几种情况之中?从而做出相应的处理。
答:

4 HardwareIRQ and Exception Handling

×××Hardware Handling of Interrupts and Exceptions

  1. After executing an instruction,the control unit checks whether an interrupt or an exception occurred while the control unit executed the previous instruction. If one occurred,handle the IRQ。
  2. 根据idtr, gdtr得到gdt,ldt等等乱七八糟的,检查是否进行优先级(是在Userspace还是在Kernel中发生的中断),如果是用户态还要进行一系列的寄存器的切换(保护模式相关),这关心的是如果是用户态发生中断esp从TSS中取出,也换成内核态stack,在内核态发生中断就不用切换esp了。
  3. Cpu自动将ss, esp, eflags, cs, eip存储到stack中(是内核态堆栈)。

×××Saving the registers for the interrupt handler

  1. Saving registers is the first task of the interrupt handler.
  2. 就这样讲寄存器都存储在当前堆栈esp中了

5 Softirqs and Tasklets

l  Tasklets run in software interrupt context with the result that all tasklet code must be atomic.

l  Actually, atasklet, just like a kernel timer, is executed (in atomic mode) in the context of a “soft interrupt,”(different from intel’s programmable exception mechanism , soft interrupt) a kernel mechanism that executes asynchronous tasks with hardware interrupts enabled.­

l  interrupt context : it specifies that the kernel is currently executing either an interrupt handler or a deferrable function.

l  一般会在之后的某个时刻检查当前系统中是否有被pending的softirq,如果有就去执行,Linux内核中检查是否有softirq挂起的检查点主要有以下三类:

  1. 硬件中断代码返回的时候,void irq_exit(void)
  2. ksoftirqd内核服务线程运行的时候

l  软中断的执行时机,即do_softirq()的运行时机 有两种选择:

  1. 中断返回时马上调用执行.这样能对软中断即时处理.但是这样一直频繁执行软中断了(因为有的软中断本身可能还会重复触发).用户进程很可能会处于饥饿状态.
  2. 如果不马上执行.比如延后到下一次执行时机再执行(一般是下一次中断返回).但是这样当系统空闲时,也必须得等一段时间.这样利用率又不高.同时也可能有大量软中断得不到执行. 现在内核采用第二种方法,但通过一个ksoftirqd线程来解决这一问题.这个线程就是循环调用do_softirq(),每个处理器有一个这样的线程.当有大量软中断时该线程被唤醒.(do_softirq()中通过判断是否有重复触发,来决定唤醒ksoftirqd线程). ksoftirqd的优先级最低,所以不会抢占用户进程,但当系统空闲时就会调用,从而解决了空闲时也得等一段时间才能处理软中断的问题.

l  最关键的是The do_softirq() function(查看understanding the linux kernel)

6 Multiple Kernel Mode stacks

l  If the size of the tHRead_union structure is 8 KB, the Kernel Mode stack of the current process is used for every type of kernel control path: exceptions, interrupts, and deferrable functions.

l  Conversely, if the size of the thread_union structure is 4 KB, the kernel makes use of three types of Kernel Mode stacks:

  1. The exception stack is used when handling exceptions (including system calls). This is the stack contained in the per-process thread_union data structure, thus the kernel makes use of a different exception stack for each process in the system.
  2. The hard IRQ stack is used when handling interrupts. There is one hard IRQ stack for each CPU in the system, and each stack is contained in a single page frame.
  3. The soft IRQ stack is used when handling deferrable functions .There is one soft IRQ stack for each CPU in the system, and each stack is contained in a single page frame.

All hard IRQ stacks are contained in the hardirq_stack array, while all soft IRQ stacks are contained in the softirq_stack array. Each array element is a union of type irq_ctx that span a single page. At the bottom of this page is stored a thread_info structure, while the spare memory locations are used for the stack; remember that each stack grows towards lower addresses. Thus, hard IRQ stacks and soft IRQ stacks are very similar to the exception stacks described in the section "Identifying a Process" in Chapter 3; the only difference is that the tHRead_info structure coupled with each stack is associated with a CPU rather than a process.

7 一个经典的内核比喻

we will look at the kernel as a waiter who must satisfy two types of requests: those issued by customers and those issued by a limited number of different bosses. The policy adopted by the waiter is the following:

  1. If a boss calls while the waiter is idle, the waiter starts servicing the boss.
  2. If a boss calls while the waiter is servicing a customer, the waiter stops servicing the customer and starts servicing the boss.
  3. If a boss calls while the waiter is servicing another boss, the waiter stops servicing the first boss and starts servicing the second one. When he finishes servicing the new boss, he resumes servicing the former one.
  4. One of the bosses may induce the waiter to leave the customer being currently serviced. After servicing the last request of the bosses, the waiter may decide to drop temporarily his customer and to pick up a new one.

The services performed by the waiter correspond to the code executed when the CPU is in Kernel Mode. If the CPU is executing in User Mode, the waiter is considered idle.

Boss requests correspond to interrupts, while customer requests correspond to system calls or exceptions raised by User Mode processes.

The careful reader has already associated the first three rules with the nesting of kernel control paths The fourth rule corresponds to one of the most interesting new features included in the Linux 2.6 kernel, namely kernel preemption .


转载于:https://www.cnblogs.com/jack204/archive/2012/03/26/2417678.html


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
author-avatar
HuPangpang_
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有