/*
* If there is a non-zero preempt_count or interrupts are disabled,
* we do not want to preempt the current task. Just return.. */ //检查是否允许抢占,本地中断关闭,或者抢占计数器值不为0时不允许抢占 if (unlikely(ti->preempt_count || irqs_disabled())) return;
/* we could miss a preemption opportunity between schedule and now */
barrier(); if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) goto need_resched;
}
/*返回用户空间,只需要检查need_resched*/
ENTRY(resume_userspace) #返回用户空间,中断或异常发生时,任务处于用户空间 cli # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
movl TI_flags(%ebp), %ecx
andl $_TIF_WORK_MASK, %ecx # is there any work to be done on
# int/exception return?
jne work_pending #还有其它工作要做
jmp restore_all #所有工作都做完,则恢复处理器状态
#恢复处理器状态
restore_all:
RESTORE_ALL
# perform work that needs to be done immediately before resumption
ALIGN
#完成其它工作
work_pending:
testb $_TIF_NEED_RESCHED, %cl #检查是否需要重新调度
jz work_notifysig #不需要重新调度
#需要重新调度
work_resched:
call schedule #调度进程
cli # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
movl TI_flags(%ebp), %ecx
/*检查是否还有其它的事要做*/
andl $_TIF_WORK_MASK, %ecx # is there any work to be done other
# than syscall tracing? jz restore_all #没有其它的事,则恢复处理器状态
testb $_TIF_NEED_RESCHED, %cl jnz work_resched #如果need_resched再次置位,则继续调度
#VM和信号检测 work_notifysig: # deal with pending signals and
# notify-resume requests
testl $VM_MASK, EFLAGS(%esp) #检查是否是VM模式
movl %esp, %eax jne work_notifysig_v86 # returning to kernel-space or
# vm86-space
xorl %edx, %edx
#进行信号处理 call do_notify_resume jmp restore_all
#系统调用入口
ENTRY(system_call)
pushl %eax # save orig_eax
SAVE_ALL
GET_THREAD_INFO(%ebp)
# system call tracing in operation
testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) jnz syscall_trace_entry
cmpl $(nr_syscalls), %eax jae syscall_badsys syscall_call:
#调用相应的函数 call *sys_call_table(,%eax,4)
movl %eax,EAX(%esp) # store the return value,返回值保存到eax
#系统调用返回 syscall_exit: cli # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
movl TI_flags(%ebp), %ecx
testw $_TIF_ALLWORK_MASK, %cx # current->work,检查是否还有其它工作要完成
jne syscall_exit_work
#恢复处理器状态
restore_all:
RESTORE_ALL
#做其它工作
syscall_exit_work:
#检查是否系统调用跟踪,审计,单步执行,不需要则跳到work_pending(进行调度,信号处理)
testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
jz work_pending
sti # could let do_syscall_trace() call
# schedule() instead
movl %esp, %eax
movl $1, %edx
#系统调用跟踪
call do_syscall_trace
#返回用户空间
jmp resume_userspace