Linux操作系统内核抢占补丁的基本原理(2)

2008-02-23 07:26:45来源:互联网 阅读 ()

int this_cpu, c;

#ifdef CONFIG_PREEMPT

ctx_sw_off();

#endif

if (!current->active_mm) BUG();

need_resched_back:

prev = current;

this_cpu = prev->processor;

if (in_interrupt())

goto scheduling_in_interrupt;

release_kernel_lock(prev, this_cpu);

/* Do "administrative" work here while we don't hold any locks */

if (softirq_active(this_cpu) & softirq_mask(this_cpu))

goto handle_softirq;

handle_softirq_back:

/*

* 'sched_data' is protected by the fact that we can run

* only one process per CPU.

*/

sched_data = & aligned_data[this_cpu].schedule_data;

spin_lock_irq(&runqueue_lock);

/* move an exhausted RR process to be last.. */

if (prev->policy == SCHED_RR)

goto move_rr_last;

move_rr_back:

switch (prev->state) {

case TASK_INTERRUPTIBLE:

if (signal_pending(prev)) {

prev->state = TASK_RUNNING;

break;

}

default:

#ifdef CONFIG_PREEMPT

if (prev->state & TASK_PREEMPTED)

break; 如果是内核抢占调度,则保留运行队列

#endif

del_from_runqueue(prev);

#ifdef CONFIG_PREEMPT

case TASK_PREEMPTED:

#endif

case TASK_RUNNING:

}

prev->need_resched = 0;

/*

* this is the scheduler proper:

*/

repeat_schedule:

/*

* Default process to select..

*/

next = idle_task(this_cpu);

c = -1000;

if (task_on_runqueue(prev))

goto still_running;

still_running_back:

list_for_each(tmp, &runqueue_head) {

p = list_entry(tmp, struct task_struct, run_list);

if (can_schedule(p, this_cpu)) {

int weight = goodness(p, this_cpu, prev->active_mm);

if (weight > c)

c = weight, next = p;

}

}

/* Do we need to re-calculate counters? */

if (!c)

goto recalculate;

/*

* from this point on nothing can prevent us from

* switching to the next task, save this fact in

* sched_data.

*/

sched_data->curr = next;

#ifdef CONFIG_SMP

next->has_cpu = 1;

next->processor = this_cpu;

#endif

spin_unlock_irq(&runqueue_lock);

if (prev == next)

goto same_process;

#ifdef CONFIG_SMP

/*

* maintain the per-process 'last schedule' value.

* (this has to be recalculated even if we reschedule to

* the same process) Currently this is only used on SMP,

* and it's approximate, so we do not have to maintain

* it while holding the runqueue spinlock.

*/

sched_data->last_schedule = get_cycles();

/*

* We drop the scheduler lock early (it's a global spinlock),

* thus we have to lock the previous process from getting

* rescheduled during switch_to().

*/

#endif /* CONFIG_SMP */

kstat.context_swtch ;

/*

* there are 3 processes which are affected by a context switch:

*

* prev == .... ==> (last => next)

*

* It's the 'much more previous' 'prev' that is on next's stack,

* but prev is set to (the just run) 'last' process by switch_to().

* This might sound slightly confusing but makes tons of sense.

*/

prepare_to_switch();

{

struct mm_struct *mm = next->mm;

struct mm_struct *oldmm = prev->active_mm;

if (!mm) {

if (next->active_mm) BUG();

next->active_mm = oldmm;

atomic_inc(&oldmm->mm_count);

enter_lazy_tlb(oldmm, next, this_cpu);

} else {

if (next->active_mm != mm) BUG();

switch_mm(oldmm, mm, next, this_cpu);

}

if (!prev->mm) {

prev->active_mm = NULL;

mmdrop(oldmm);

}

}

/*

* This just switches the register state and the

* stack.

*/

switch_to(prev, next, prev);

__schedule_tail(prev);

same_process:

reacquire_kernel_lock(current);

if (current->need_resched)

goto need_resched_back;

#ifdef CONFIG_PREEMPT

ctx_sw_on_no_preempt();

#endif

return;

recalculate:

{

struct task_struct *p;

spin_unlock_irq(&runqueue_lock);

read_lock(&tasklist_lock);

for_each_task(p)

p->counter = (p->counter >> 1) NICE_TO_TICKS(p->nice);

read_unlock(&tasklist_lock);

spin_lock_irq(&runqueue_lock);

}

goto repeat_schedule;

still_running:

c = goodness(prev, this_cpu, prev->active_mm);

next = prev;

goto still_running_back;

handle_softirq:

do_softirq();

goto handle_softirq_back;

move_rr_last:

if (!prev->counter) {

prev->counter = NICE_TO_TICKS(prev->nice);

move_last_runqueue(prev);

}

goto move_rr_back;

scheduling_in_interrupt:

printk("Scheduling in interrupt\n");

BUG();

return;

}

void schedule_tail(struct task_struct *prev)

{

__schedule_tail(prev);

#ifdef CONFIG_PREEMPT

ctx_sw_on();

#endif

}

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

相关文章

linux操作系统 抢占式,Linux操作系统内核抢占补丁的基本原理(2)相关推荐

  1. 抢占式内核与非抢占式内核

    抢占式内核 与非抢占 式内核 linux抢占 式内核与实时系统的关系 一个好的系统的进程调度机制,要兼顾三种不同的应用的需求: 1交互式应用.这种应用,着重于系统的响应速度,当系统中有大量的进程共存时 ...

  2. 隐藏linux操作系统版本信息,linux centos 如何查看操作系统版本信息?

    本文介绍常用的四种查看linux下查看系统版本信息的方法: 一.uname -a [app@VM_11_211_centos ~]$ uname -a Linux VM_11_211_centos 2 ...

  3. 一步一步学linux操作系统: 14 进程调度三完_抢占式调度

    抢占式调度 情况1:最常见的现象就是一个进程执行时间太长了,是时候切换到另一个进程 那怎么衡量一个进程的运行时间呢? 在计算机里面有一个时钟,会过一段时间触发一次时钟中断,通知操作系统,时间又过去一个 ...

  4. 鼠标在linux下如何工作,Linux操作系统下的鼠标操作

    本不想写这些玩意儿,其实我并不喜欢它们,只不过没办法,谁叫我是靠这些家伙糊口的呢! 若干年前,我自认为很喜欢Linux操作系统:若干年后,我发现我当初是何等的天真. 恩,一分钱,一分货!我坚信这一点! ...

  5. 【Linux 操作系统】Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用

    . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21056029 . 1. Linux运行等级介绍 Lin ...

  6. 抢占式内核和非抢占式内核的区别

    内核抢占(可抢占式内核):即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程. 非抢占式内核:高优先级的进程不能中止正在内核中运行的 ...

  7. 抢占式内核与非抢占式内核的区别

    内核抢占(可抢占式内核): 即当进程位于内核空间时,有一个更高优先级的任务出现时,如果当前内核允许抢占,则可以将当前任务挂起,执行优先级更高的进程. 非抢占式内核: 高优先级的进程不能中止正在内核中运 ...

  8. 抢占式任务调度和非抢占式(轮询任务调度)的区别,以及任务调度算法的用途。

    1.说说轮巡任务调度与抢占式任务调度的区别? 答:轮询任务调度与抢占式任务调度的区别在于抢占式调度可以因为优先级高的任务抢占cpu,而轮询的不能.  2当软件线程个数超过硬件线程个数的时候,支持抢占式 ...

  9. 【转载】笔记:计算机_体系结构_操作系统_软件_操作系统内核_GNU_Linux_C_Python_Latex_Java_TCP/IP_MacOS_Windows这些词语的历史,关系

    一.计算机的发明 世上本无路,走的人多了,就有了路.世上本无计算机,琢磨的人多了--没有计算机,一切无从谈起. 三个人对计算机的发明功不可没,居功至伟.阿兰·图灵(Alan Mathison Turi ...

最新文章

  1. centos安装后两个启动项、_centos8的启动项配置
  2. mine 规范_《民用建筑热工设计规范》GB50176-2016
  3. hdu 5542(树状数组优化dp)
  4. Java之Callable和Runnable
  5. python向量化和c哪个快_在python中向量化6 for循环累积和
  6. python创建一个csv文件_python如何写入csv
  7. 还是畅通工程 最小生成树
  8. Conditional Generative Adversarial Nets论文翻译
  9. 【转】使用Python的Requests库进行web接口测试
  10. Java API 帮助文档中英文版下载
  11. python标准库不需要导入即可使用其中的所有对象和方法_Python扩展库需导入以后才能使用其中的对象,Python标准库不需要导入即可使用其中的所有对象和方法...
  12. NGINX Sprint 年度线上会议:报名通道已开启,立即预定您的 NGINX 深潜之旅
  13. 股票回测Web应用开发
  14. shader篇-动画
  15. 自制win10 PE usb启动盘教程
  16. android判断应用是否回到桌面的两种方法
  17. Linux下的文件管理
  18. QQRobot一款基于Java的娱乐qq机器人
  19. hive 大数据 除重问题研究
  20. 【Vitis Accel】2 - Vitis 应用加速开发平台简介

热门文章

  1. hp服务器 新增硬盘_HP服务器linux操作系统如何添加硬盘
  2. 原创 | 开源AI测试专题、Jmeter测试专题
  3. 模拟导入系统通讯录5000+手机号 校验大量数据处理
  4. 利用openpyxl,Python对excel读写文件
  5. WINFORM 调用 Close 不会释放窗体
  6. Testlink1.9.5的安装配置
  7. 怎么打败腾讯[纯讨论]
  8. FileInputStreamTest
  9. deque python_3 . python Collections -- Deque Object
  10. python爬取10个网站_十个Python爬虫武器库示例,十个爬虫框架,十种实现爬虫的方法!...