00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "ki.h"
00028
00029
VOID
00030
FASTCALL
00031 KiUnwaitThread (
00032 IN
PRKTHREAD Thread,
00033 IN LONG_PTR WaitStatus,
00034 IN KPRIORITY Increment
00035 )
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 {
00060
00061 KPRIORITY NewPriority;
00062
PKPROCESS Process;
00063
PKQUEUE Queue;
00064
PKTIMER Timer;
00065
PRKWAIT_BLOCK WaitBlock;
00066
00067
00068
00069
00070
00071
00072 Thread->WaitStatus |= WaitStatus;
00073 WaitBlock = Thread->WaitBlockList;
00074
do {
00075 RemoveEntryList(&WaitBlock->
WaitListEntry);
00076 WaitBlock = WaitBlock->
NextWaitBlock;
00077 }
while (WaitBlock != Thread->WaitBlockList);
00078
00079 RemoveEntryList(&Thread->WaitListEntry);
00080
00081
00082
00083
00084
00085 Timer = &Thread->Timer;
00086
if (Timer->
Header.
Inserted !=
FALSE) {
00087
KiRemoveTreeTimer(Timer);
00088 }
00089
00090
00091
00092
00093
00094
00095 Queue = Thread->Queue;
00096
if (Queue !=
NULL) {
00097 Queue->
CurrentCount += 1;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 Process = Thread->ApcState.Process;
00107
if (Thread->Priority < LOW_REALTIME_PRIORITY) {
00108
if ((Thread->PriorityDecrement == 0) &&
00109 (Thread->DisableBoost ==
FALSE)) {
00110 NewPriority = Thread->
BasePriority +
Increment;
00111
if (((
PEPROCESS)Process)->Vm.MemoryPriority ==
MEMORY_PRIORITY_FOREGROUND) {
00112 NewPriority +=
PsPrioritySeperation;
00113 }
00114
00115
if (NewPriority > Thread->Priority) {
00116
if (NewPriority >= LOW_REALTIME_PRIORITY) {
00117 Thread->Priority = LOW_REALTIME_PRIORITY - 1;
00118
00119 }
else {
00120 Thread->Priority = (SCHAR)NewPriority;
00121 }
00122 }
00123 }
00124
00125
if (Thread->BasePriority >=
TIME_CRITICAL_PRIORITY_BOUND) {
00126 Thread->Quantum = Process->
ThreadQuantum;
00127
00128 }
else {
00129 Thread->Quantum -=
WAIT_QUANTUM_DECREMENT;
00130
if (Thread->Quantum <= 0) {
00131 Thread->Quantum = Process->
ThreadQuantum;
00132 Thread->Priority -= (Thread->PriorityDecrement + 1);
00133
if (Thread->Priority < Thread->BasePriority) {
00134 Thread->Priority = Thread->BasePriority;
00135 }
00136
00137 Thread->PriorityDecrement = 0;
00138 }
00139 }
00140
00141 }
else {
00142 Thread->Quantum = Process->
ThreadQuantum;
00143 }
00144
00145
00146
00147
00148
00149
KiReadyThread(Thread);
00150
return;
00151 }
00152
00153
VOID
00154 KeBoostCurrentThread(
00155 VOID
00156 )
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 {
00176
00177 KIRQL OldIrql;
00178
PKTHREAD Thread;
00179
00180
00181
00182
00183
00184
00185 Thread =
KeGetCurrentThread();
00186
00187 redoboost:
00188
KiLockDispatcherDatabase(&OldIrql);
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
if ((Thread->
PriorityDecrement == 0) && (Thread->
Priority < 14)) {
00205 Thread->
PriorityDecrement = 14 - Thread->
BasePriority;
00206 Thread->
DecrementCount =
ROUND_TRIP_DECREMENT_COUNT;
00207 Thread->
Priority = 14;
00208 Thread->
Quantum = Thread->
ApcState.
Process->
ThreadQuantum * 2;
00209
00210 }
else if (Thread->
PriorityDecrement != 0) {
00211 Thread->
DecrementCount -= 1;
00212
if (Thread->
DecrementCount == 0) {
00213
KiUnlockDispatcherDatabase(OldIrql);
00214
KeSetPriorityThread(Thread, Thread->
BasePriority);
00215
goto redoboost;
00216
00217 }
else {
00218 Thread->
Quantum = Thread->
ApcState.
Process->
ThreadQuantum * 2;
00219 }
00220 }
00221
00222
KiUnlockDispatcherDatabase(OldIrql);
00223
return;
00224 }
00225
00226
VOID
00227
FASTCALL
00228 KiWaitSatisfyAll (
00229 IN
PRKWAIT_BLOCK WaitBlock
00230 )
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 {
00250
00251
PKMUTANT Object;
00252
PRKTHREAD Thread;
00253
PRKWAIT_BLOCK WaitBlock1;
00254
00255
00256
00257
00258
00259
00260
00261 WaitBlock1 = WaitBlock;
00262 Thread = WaitBlock1->
Thread;
00263
do {
00264
if (WaitBlock1->
WaitKey != (CSHORT)STATUS_TIMEOUT) {
00265 Object = (
PKMUTANT)WaitBlock1->
Object;
00266
KiWaitSatisfyAny(Object, Thread);
00267 }
00268
00269 WaitBlock1 = WaitBlock1->
NextWaitBlock;
00270 }
while (WaitBlock1 != WaitBlock);
00271
00272
return;
00273 }
00274
00275
VOID
00276
FASTCALL
00277 KiWaitTest (
00278 IN PVOID Object,
00279 IN KPRIORITY Increment
00280 )
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 {
00302
00303
PKEVENT Event;
00304 PLIST_ENTRY ListHead;
00305
PRKWAIT_BLOCK NextBlock;
00306
PKMUTANT Mutant;
00307
PRKTHREAD Thread;
00308
PRKWAIT_BLOCK WaitBlock;
00309 PLIST_ENTRY WaitEntry;
00310
00311
00312
00313
00314
00315
00316
Event = (
PKEVENT)Object;
00317 ListHead = &
Event->Header.WaitListHead;
00318 WaitEntry = ListHead->Flink;
00319
while ((
Event->Header.SignalState > 0) &&
00320 (WaitEntry != ListHead)) {
00321 WaitBlock = CONTAINING_RECORD(WaitEntry,
KWAIT_BLOCK, WaitListEntry);
00322 Thread = WaitBlock->
Thread;
00323
if (WaitBlock->
WaitType != WaitAny) {
00324
00325
00326
00327
00328
00329
00330 NextBlock = WaitBlock->
NextWaitBlock;
00331
while (NextBlock != WaitBlock) {
00332
if (NextBlock->
WaitKey != (CSHORT)(STATUS_TIMEOUT)) {
00333 Mutant = (
PKMUTANT)NextBlock->
Object;
00334
if ((Mutant->
Header.
Type ==
MutantObject) &&
00335 (Mutant->
Header.
SignalState <= 0) &&
00336 (Thread == Mutant->
OwnerThread)) {
00337
goto next;
00338
00339 }
else if (Mutant->
Header.
SignalState <= 0) {
00340
goto scan;
00341 }
00342 }
00343
00344 next:
00345 NextBlock = NextBlock->
NextWaitBlock;
00346 }
00347
00348
00349
00350
00351
00352
00353 WaitEntry = WaitEntry->Blink;
00354
KiWaitSatisfyAll(WaitBlock);
00355
00356 }
else {
00357
00358
00359
00360
00361
00362 WaitEntry = WaitEntry->Blink;
00363
KiWaitSatisfyAny((
PKMUTANT)
Event, Thread);
00364 }
00365
00366
KiUnwaitThread(Thread, (
NTSTATUS)WaitBlock->
WaitKey,
Increment);
00367
00368 scan:
00369 WaitEntry = WaitEntry->Flink;
00370 }
00371
00372
return;
00373 }
00374