微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

reactos操作系统实现(43)

前面介绍放到延迟队列是单核的版本,下面来学习多核的版本,代码如下:

#001 //

#002 // This routine makes the thread deferred ready on the boot cpu.

#003 //

#004 FORCEINLINE

#005 VOID

#006 KiInsertDeferredReadyList(IN PKTHREAD Thread)

#007 {

设置线程状态和运行线程的cpu

#008 /* Set the thread to deferred state and boot cpu */

#009 Thread->State = DeferredReady;

#010 Thread->DeferredProcessor = 0;

#011

立即把线程放到延迟就绪队列。

#012 /* Make the thread ready immediately */

#013 KiDeferredReadyThread(Thread);

#014 }

从上面的函数可以看到,调用函数KiDeferredReadyThread来放到延迟就绪队列。它的代码如下:

#001 VOID

#002 NTAPI

#003 KiDeferredReadyThread(IN PKTHREAD Thread)

#004 {

#005 PKPRCB Prcb;

#006 BOOLEAN Preempted;

#007 ULONG Processor = 0;

#008 KPRIORITY OldPriority;

#009 PKTHREAD NextThread;

#010

#011 /* Sanity checks */

#012 ASSERT(Thread->State == DeferredReady);

#013 ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));

#014

检查线程是否需要调整优先级。

#015 /* Check if we have any adjusts to do */

#016 if (Thread->AdjustReason == AdjustBoost)

#017 {

锁住线程,以便修改线程的数据。

#018 /* Lock the thread */

#019 KiAcquireThreadLock(Thread);

#020

检查线程是否可以提高优先级。

#021 /* Check if the priority is low enough to qualify for boosting */

#022 if ((Thread->Priority <= Thread->AdjustIncrement) &&

#023 (Thread->Priority < (LOW_REALTIME_PRIORITY - 3)) &&

#024 !(Thread->disableBoost))

#025 {

计算可以设置最高的优先级。

#026 /* Calculate the new priority based on the adjust increment */

#027 OldPriority = min(Thread->AdjustIncrement + 1,

#028 LOW_REALTIME_PRIORITY - 3);

#029

测试优先级是否在可以设置的范围。

#030 /* Make sure we're not decreasing outside of the priority range */

#031 ASSERT((Thread->PriorityDecrement >= 0) &&

#032 (Thread->PriorityDecrement <= Thread->Priority));

#033

计算可以减少的最大优先级数。

#034 /* Calculate the new priority decrement based on the boost */

#035 Thread->PriorityDecrement += ((SCHAR)OldPriority - Thread->Priority);

#036

测试减少的优先级是否有效。

#037 /* Again verify that this decrement is valid */

#038 ASSERT((Thread->PriorityDecrement >= 0) &&

#039 (Thread->PriorityDecrement <= OldPriority));

#040

设置最新的优先级。

#041 /* Set the new priority */

#042 Thread->Priority = (SCHAR)OldPriority;

#043 }

#044

设置线程获取的时间片。

#045 /* We need 4 quanta,make sure we have them,then decrease by one */

#046 if (Thread->Quantum < 4) Thread->Quantum = 4;

#047 Thread->Quantum--;

#048

#049 /* Make sure the priority is still valid */

#050 ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));

#051

释放线程锁。

#052 /* Release the lock and clear the adjust reason */

#053 KiReleaseThreadLock(Thread);

#054 Thread->AdjustReason = AdjustNone;

#055 }

#056 else if (Thread->AdjustReason == AdjustUnwait)

#057 {

检查线程是否为实时优先线程。

#058 /* Acquire the thread lock and check if this is a real-time thread */

#059 KiAcquireThreadLock(Thread);

#060 if (Thread->Priority < LOW_REALTIME_PRIORITY)

#061 {

它不是实时优先线程,判断线程是否为临界线程。

#062 /* It's not real time,but is it time critical? */

#063 if (Thread->BasePriority >= (LOW_REALTIME_PRIORITY - 2))

#064 {

是否为可变实时优先级。

#065 /* It is,so simply reset its quantum */

#066 Thread->Quantum = Thread->QuantumReset;

#067 }

#068 else

#069 {

前面已经自动调整过优先级。

#070 /* Has the priority been adjusted prevIoUsly? */

#071 if (!(Thread->PriorityDecrement) && (Thread->AdjustIncrement))

#072 {

#073 /* Yes,reset its quantum */

#074 Thread->Quantum = Thread->QuantumReset;

#075 }

#076

计算最新的优先级。

#077 /* Wait code already handles quantum adjustment during APCs */

#078 if (Thread->WaitStatus != STATUS_KERNEL_APC)

#079 {

#080 /* Decrease the quantum by one and check if we're out */

#081 if (--Thread->Quantum <= 0)

#082 {

#083 /* We are,reset the quantum and get a new priority */

#084 Thread->Quantum = Thread->QuantumReset;

#085 Thread->Priority = KiComputeNewPriority(Thread,1);

#086 }

#087 }

#088 }

#089

检查是否需要调整优先级。

#090 /* Now check if we have no decrement and boosts are enabled */

#091 if (!(Thread->PriorityDecrement) && !(Thread->disableBoost))

#092 {

#093 /* Make sure we have an increment */

#094 ASSERT(Thread->AdjustIncrement >= 0);

#095

#096 /* Calculate the new priority after the increment */

#097 OldPriority = Thread->BasePriority + Thread->AdjustIncrement;

#098

#099 /* Check if this new priority is higher */

#100 if (OldPriority > Thread->Priority)

#101 {

#102 /* Make sure we don't go into the real time range */

#103 if (OldPriority >= LOW_REALTIME_PRIORITY)

#104 {

#105 /* normalize it back down one notch */

#106 OldPriority = LOW_REALTIME_PRIORITY - 1;

#107 }

#108

#109 /* Check if the priority is higher then the boosted base */

#110 if (OldPriority > (Thread->BasePriority +

#111 Thread->AdjustIncrement))

#112 {

#113 /* Setup a priority decrement to nullify the boost */

#114 Thread->PriorityDecrement = ((SCHAR)OldPriority -

#115 Thread->BasePriority -

#116 Thread->AdjustIncrement);

#117 }

#118

#119 /* Make sure that the priority decrement is valid */

#120 ASSERT((Thread->PriorityDecrement >= 0) &&

#121 (Thread->PriorityDecrement <= OldPriority));

#122

#123 /* Set this new priority */

#124 Thread->Priority = (SCHAR)OldPriority;

#125 }

#126 }

#127 }

#128 else

#129 {

线程是实时优先级。

#130 /* It's a real-time thread,so just reset its quantum */

#131 Thread->Quantum = Thread->QuantumReset;

#132 }

#133

#134 /* Make sure the priority makes sense */

#135 ASSERT((Thread->Priority >= 0) && (Thread->Priority <= HIGH_PRIORITY));

#136

#137 /* Release the thread lock and reset the adjust reason */

#138 KiReleaseThreadLock(Thread);

#139 Thread->AdjustReason = AdjustNone;

#140 }

#141

清除线程的preemption状态和保存当前值。

#142 /* Clear thread preemption status and save current values */

#143 Preempted = Thread->Preempted;

#144 OldPriority = Thread->Priority;

#145 Thread->Preempted = FALSE;

#146

设置线程为引导cpu运行,也就是0cpu

#147 /* Queue the thread on cpu 0 and get the PRCB */

#148 Thread->NextProcessor = 0;

#149 Prcb = KiProcessorBlock[0];

#150

检查当前处理器是否为空闲状态,如果为空闲状态,就设置为下一个运行的线程。

#151 /* Check if we have an idle summary */

#152 if (KiIdleSummary)

#153 {

#154 /* Clear it and set this thread as the next one */

#155 KiIdleSummary = 0;

#156 Thread->State = Standby;

#157 Prcb->NextThread = Thread;

#158 return;

#159 }

#160

设置线程下一个运行的cpu编号。

#161 /* Set the cpu number */

#162 Thread->NextProcessor = (UCHAR)Processor;

#163

获取一个准备调度的线程。

#164 /* Get the next scheduled thread */

#165 NextThread = Prcb->NextThread;

#166 if (NextThread)

#167 {

#168 /* Sanity check */

#169 ASSERT(NextThread->State == Standby);

#170

如果当前线程的优先级大于队列中准备运行的线程,那么当前线程设置为运行状态,下一个线程重新计算运行状态。

#171 /* Check if priority changed */

#172 if (OldPriority > NextThread->Priority)

#173 {

#174 /* Preempt the thread */

#175 NextThread->Preempted = TRUE;

#176

#177 /* Put this one as the next one */

#178 Thread->State = Standby;

#179 Prcb->NextThread = Thread;

#180

#181 /* Set it in deferred ready mode */

#182 NextThread->State = DeferredReady;

#183 NextThread->DeferredProcessor = Prcb->Number;

#184 KiReleasePrcbLock(Prcb);

#185 KiDeferredReadyThread(NextThread);

#186 return;

#187 }

#188 }

#189 else

#190 {

如果队列里没有就绪线程,就把当前线程设置为就绪线程。

#191 /* Set the next thread as the current thread */

#192 NextThread = Prcb->CurrentThread;

#193 if (OldPriority > NextThread->Priority)

#194 {

#195 /* Preempt it if it's already running */

#196 if (NextThread->State == Running) NextThread->Preempted = TRUE;

#197

#198 /* Set the thread on standby and as the next thread */

#199 Thread->State = Standby;

#200 Prcb->NextThread = Thread;

#201

#202 /* Release the lock */

#203 KiReleasePrcbLock(Prcb);

#204

#205 /* Check if we're running on another cpu */

#206 if (KeGetCurrentProcessorNumber() != Thread->NextProcessor)

#207 {

#208 /* We are,send an IPI */

#209 KiIpiSend(AFFINITY_MASK(Thread->NextProcessor),IPI_DPC);

#210 }

#211 return;

#212 }

#213 }

#214

#215 /* Sanity check */

#216 ASSERT((OldPriority >= 0) && (OldPriority <= HIGH_PRIORITY));

#217

设置线程为准备好状态。

#218 /* Set this thread as ready */

#219 Thread->State = Ready;

#220 Thread->WaitTime = KeTickCount.LowPart;

#221

把线程插入到队列里合适的位置。

#222 /* Insert this thread in the appropriate order */

#223 Preempted ? InsertHeadList(&Prcb->dispatcherReadyListHead[OldPriority],

#224 &Thread->WaitListEntry) :

#225 InsertTailList(&Prcb->dispatcherReadyListHead[OldPriority],

#226 &Thread->WaitListEntry);

#227

更新当前处理器优先级别。

#228 /* Update the ready summary */

#229 Prcb->ReadySummary |= PRIORITY_MASK(OldPriority);

#230

#231 /* Sanity check */

#232 ASSERT(OldPriority == Thread->Priority);

#233

#234 /* Release the lock */

#235 KiReleasePrcbLock(Prcb);

#236 }

KiDeferredReadyThread函数处理了插入线程和当前处理器、队列线程的比较优先级,以便设置为合适地方运行,或者放到队列里合适位置。

原文地址:https://www.jb51.cc/react/308490.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐