reactos操作系统实现(22)

前端之家收集整理的这篇文章主要介绍了reactos操作系统实现(22)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Boot.S文件里初始化系统基本组件后,就跳到空闲函数处理,就成为一个空闲处理的线程,其实也是一个管理系统的任务。下面就来分析KiIdleLoop函数代码,如下:

#001 .globl @KiIdleLoop@0

#002 .func @KiIdleLoop@0,@KiIdleLoop@0

#003 @KiIdleLoop@0:

#004

获取KPCR的指针地址,这样就可以方便访问KPCR里的成员。

#005 /* Set EBX */

#006 mov ebx,fs:[KPCR_SELF]

#007

跳到主循环开始位置。

#008 /* Jump into mainline code */

#009 jmp MainLoop

#010

#011 cpuIdle:

#012 /* Call the cpu's idle function */

#013 lea ecx,[ebx+KPCR_PRCB_POWER_STATE_IDLE_FUNCTION]

#014 call [ecx]

#015

主循环开始位置。

#016 MainLoop:

#017 /* Cycle interrupts for 1 cycle */

打开中断以便响应中断任务处理。

#018 sti

#019 nop

#020 nop

下面代码运行需要关闭中断,以便打乱线程调度处理。

#021 cli

#022

先检查是否有DPC请求或者时间请求,如果有就需要处理。

#023 /* Check if we have to deliver DPCs,timers,or deferred threads */

#024 mov eax,[ebx+KPCR_PRCB_DPC_QUEUE_DEPTH]

#025 or eax,[ebx+KPCR_PRCB_TIMER_REQUEST]

#026 #ifdef CONFIG_SMP

#027 or eax,[ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD]

#028 #endif

#029 jz CheckSchedule

#030

下面处理DPC或时钟请求处理。

清除软件中断。

#031 mov cl,DISPATCH_LEVEL

#032 call @HalClearSoftwareInterrupt@4

#033

#034 /* Handle the above */

处理DPC队列的请求。

#035 lea ecx,[ebx+KPCR_PRCB_DATA]

#036 call @KiRetireDpcList@4

#037

检查是否有线程可以调度运行。

#038 CheckSchedule:

#039 /* Check if a next thread is queued */

检查下一个线程是否准备好。

#040 cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD],0

#041 #ifdef CONFIG_SMP

#042 jz NoNextThread

#043 #else

如果没有准备好的线程,就跳到让cpu空闲处理。

#044 jz cpuIdle

#045 #endif

#046

#047 #ifdef CONFIG_SMP

#048 /* There is,raise IRQL to synch level */

#049 call _KeRaiseIrqlToSynchLevel@0

#050 #endif

打开cpu中断。

#051 sti

#052

#053 /* Set the current thread to ready */

获取当前线程数据指针。

#054 mov edi,[ebx+KPCR_CURRENT_THREAD]

#055 #ifdef CONFIG_SMP

#056 mov byte ptr [edi+KTHREAD_SWAP_BUSY],1

#057

#058 /* Acquire the PRCB Lock */

#059 lock bts dword ptr [ebx+KPCR_PRCB_PRCB_LOCK],0

#060 jnb CheckNext

#061 lea ecx,[ebx+KPCR_PRCB_PRCB_LOCK]

#062 call @KefAcquireSpinLockAtDpcLevel@4

#063 #endif

#064

#065 CheckNext:

#066 /* Check if the next thread is the current */

获取下一个线程数据指针。

#067 mov esi,[ebx+KPCR_PRCB_NEXT_THREAD]

#068 #ifdef CONFIG_SMP

#069 cmp esi,edi

#070 jz SameThread

#071 #endif

#072

#073 /* Clear the next thread and set this one instead */

清空下一个线程标志。

#074 and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD],0

设置当前线程为下一个运行线程数据指针。

#075 mov [ebx+KPCR_CURRENT_THREAD],esi

#076

设置下一个线程为运行状态。

#077 /* Set the thread as running */

#078 mov byte ptr [esi+KTHREAD_STATE_],Running

#079

#080 #ifdef CONFIG_SMP

#081 /* Disable the idle scheduler and release the PRCB lock */

#082 and byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE],0

#083 and dword ptr [ebx+KPCR_PRCB_PRCB_LOCK],0

#084 #endif

#085

开始切换线程的运行环境。

#086 SwapContext:

#087 /* ReactOS Mm Hack */

切换线程内存空间。

#088 mov ecx,esi

#089 call @MiSyncForContextSwitch@4

#090

从当前线程任务状态切换到即将运行的线程。

#091 /* Swap context at APC_LEVEL */

#092 mov ecx,APC_LEVEL

#093 call @KiSwapContextInternal@0

#094

#095 #ifdef CONFIG_SMP

#096 /* Lower to DPC level */

#097 mov ecx,DISPATCH_LEVEL

#098 call @KfLowerIrql@4

#099 #endif

跳到主循环开始新的处理。

#100 jmp MainLoop

#101

#102 #ifdef CONFIG_SMP

#103 SameThread:

#104 /* Clear the next thread,and put the thready as ready after lock release */

#105 and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD],0

#106 and dword ptr [ebx+KPCR_PRCB_PRCB_LOCK],0

#107 and byte ptr [edi+KTHREAD_STATE_],Ready

#108 jmp MainLoop

#109

#110 NoNextThread:

#111 /* Check if the idle scheduler is enabled */

#112 cmp byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE],0

#113 jz cpuIdle

#114

#115 /* It is,so call the scheduler */

#116 lea ecx,[ebx+KPCR_PRCB_DATA]

#117 call @KiIdleSchedule@4

#118 test eax,eax

#119

#120 /* Get new thread pointers and either swap or idle loop again */

#121 mov esi,eax

#122 mov edi,[ebx+KPCR_PRCB_IDLE_THREAD]

#123 jnz SwapContext

#124 jmp MainLoop

#125 #endif

#126 .endfunc

空闲函数主要处理DPC的队列和时间钟请求。如果有线程切换,就改变线程运行环境。

原文链接:https://www.f2er.com/react/308526.html

猜你在找的React相关文章