lab5:深入理解进程切换

进程切换

Linux 内核中的上下文切换函数 是content_switch

static __always_inline struct rq *
context_switch(struct rq *rq, struct task_struct *prev,
	       struct task_struct *next, struct rq_flags *rf)
{
	prepare_task_switch(rq, prev, next);
 
	/*
	 * For paravirt, this is coupled with an exit in switch_to to
	 * combine the page table reload and the switch backend into
	 * one hypercall.
	 */
	arch_start_context_switch(prev);
 
	/*
	 * kernel -> kernel   lazy + transfer active
	 *   user -> kernel   lazy + mmgrab() active
	 *
	 * kernel ->   user   switch + mmdrop() active
	 *   user ->   user   switch
	 */
	if (!next->mm) {                                // to kernel
		enter_lazy_tlb(prev->active_mm, next);
 
		next->active_mm = prev->active_mm;
		if (prev->mm)                           // from user
			mmgrab(prev->active_mm);
		else
			prev->active_mm = NULL;
	} else {                                        // to user
		membarrier_switch_mm(rq, prev->active_mm, next->mm);
		/*
		 * sys_membarrier() requires an smp_mb() between setting
		 * rq->curr / membarrier_switch_mm() and returning to userspace.
		 *
		 * The below provides this either through switch_mm(), or in
		 * case 'prev->active_mm == next->mm' through
		 * finish_task_switch()'s mmdrop().
		 */
		switch_mm_irqs_off(prev->active_mm, next->mm, next);
		lru_gen_use_mm(next->mm);
		if (!prev->mm) {                        // from kernel
			/* will mmdrop() in finish_task_switch(). */
			rq->prev_mm = prev->active_mm;
			prev->active_mm = NULL;
		}
	}
	rq->clock_update_flags &= ~(RQCF_ACT_SKIP|RQCF_REQ_SKIP);
	prepare_lock_switch(rq, next, rf);
	/* Here we just switch the register state and the stack. */
	switch_to(prev, next, prev);
	barrier();
	return finish_task_switch(prev);
}
  1. 在操作系统中,当一个进程遇到中断或者系统调用时,会发生中断上下文切换。操作系统会首先执行中断服务程序ISR,然后通过调用_schedule()函数进行进程切换,并将当前进程的标识符保存为prev进程。

  2. 接着,调度算法会确定下一个要运行的进程,也就是next进程。如果next进程和prev进程不同,那么操作系统就会调用context_switch()函数进行上下文切换,将CPU运行的任务切换到next进程上。

  3. 在context_switch()函数中,操作系统会调用switch_to()函数来完成寄存器和堆栈的切换,以实现进程的切换。prepare_task_switch()函数则用来准备任务切换,在使用过程中可能会调用一些特定于体系结构的钩子。

内核在switch_to()中执行如下操作:

  • 更新esp指针,进行硬件上下文切换,以及堆栈的切换,其中ebp指针用于确定当前用户空间属于哪个进程。

  • prepare_lock_switch(rq, next, rf),函数用于准备锁切换,主要是更新调度队列中的锁等信息。

  • finish_task_switch(prev),函数用于完成任务切换,主要是更新调度队列中的任务等信息,并返回前一个进程的调度队列。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值