操作系统学习笔记(35)--创建新进程并调度

新进程创建:

 

1 初始化内存,分配内存页面

2 初始化内核进程

 

3 添加到进程列表 

 

然后通过进程调度器调度运行

 

/* * Schedule a thread that is waiting to run. * Must be called with interrupts off! * The current thread should already have been placed * on whatever queue is appropriate (i.e., either the * run queue if it is still runnable, or a wait queue * if it is waiting for an event to occur). */ void Schedule(void) { struct Kernel_Thread* runnable; /* Make sure interrupts really are disabled */ KASSERT(!Interrupts_Enabled()); /* Preemption should not be disabled. */ KASSERT(!g_preemptionDisabled); /* Get next thread to run from the run queue */ runnable = Get_Next_Runnable(); /* * Activate the new thread, saving the context of the current thread. * Eventually, this thread will get re-activated and Switch_To_Thread() * will "return", and then Schedule() will return to wherever * it was called from. */ Switch_To_Thread(runnable); }

 

 

进程调度进行进程运行的切换

 

Switch_To_Thread: ; Modify the stack to allow a later return via an iret instruction. ; We start with a stack that looks like this: ; ; thread_ptr ; esp --> return addr ; ; We change it to look like this: ; ; thread_ptr ; eflags ; cs ; esp --> return addr push eax ; save eax mov eax, [esp+4] ; get return address mov [esp-4], eax ; move return addr down 8 bytes from orig loc add esp, 8 ; move stack ptr up pushfd ; put eflags where return address was mov eax, [esp-4] ; restore saved value of eax push dword KERNEL_CS ; push cs selector sub esp, 4 ; point stack ptr at return address ; Push fake error code and interrupt number push dword 0 push dword 0 ; Save general purpose registers. Save_Registers ; Save stack pointer in the thread context struct (at offset 0). mov eax, [g_currentThread] mov [eax+0], esp ; Clear numTicks field in thread context, since this ; thread is being suspended. mov [eax+4], dword 0 ; Load the pointer to the new thread context into eax. ; We skip over the Interrupt_State struct on the stack to ; get the parameter. mov eax, [esp+INTERRUPT_STATE_SIZE] ; Make the new thread current, and switch to its stack. mov [g_currentThread], eax mov esp, [eax+0] ; Restore general purpose and segment registers, and clear interrupt ; number and error code. Restore_Registers ; We'll return to the place where the thread was ; executing last. iret

 

 

进程切换过程如下:

 

0 仿中断调用

1 保存当前进程的寄存器等信息进入当前堆栈

2 清当前进程的计时器为0

3 恢复切换进程为当前进程(切换进程需要传递信息 结合数据定义获取下面恢复设置)

4 恢复切换进程的堆栈设置

5 根据堆栈信息回复寄存器

6 中断退出

7 运行新切换的进程

 

你可能感兴趣的:(C/C++,Linux/Unix/AIX,操作系统)