00224 {
00225
00226 ULONG
Index;
00227 OBJECT_ATTRIBUTES
ObjectAttributes;
00228 ULONG NumberOfDelayedThreads;
00229 ULONG NumberOfCriticalThreads;
00230
NTSTATUS Status;
00231 HANDLE Thread;
00232 BOOLEAN NtAs;
00233
WORK_QUEUE_TYPE WorkQueueType;
00234
00235
00236
00237
00238
00239 NtAs =
MmIsThisAnNtAsSystem();
00240
switch (
MmQuerySystemSize()) {
00241
case MmSmallSystem:
00242 NumberOfDelayedThreads =
MEDIUM_NUMBER_OF_THREADS;
00243
if (
MmNumberOfPhysicalPages > ((12*1024*1024)/
PAGE_SIZE) ) {
00244 NumberOfCriticalThreads =
MEDIUM_NUMBER_OF_THREADS;
00245 }
else {
00246 NumberOfCriticalThreads =
SMALL_NUMBER_OF_THREADS;
00247 }
00248
break;
00249
00250
case MmMediumSystem:
00251 NumberOfDelayedThreads =
MEDIUM_NUMBER_OF_THREADS;
00252 NumberOfCriticalThreads =
MEDIUM_NUMBER_OF_THREADS;
00253
if ( NtAs ) {
00254 NumberOfCriticalThreads +=
MEDIUM_NUMBER_OF_THREADS;
00255 }
00256
break;
00257
00258
case MmLargeSystem:
00259 NumberOfDelayedThreads =
MEDIUM_NUMBER_OF_THREADS;
00260 NumberOfCriticalThreads =
LARGE_NUMBER_OF_THREADS;
00261
if ( NtAs ) {
00262 NumberOfCriticalThreads +=
LARGE_NUMBER_OF_THREADS;
00263 }
00264
break;
00265
00266
default:
00267 NumberOfDelayedThreads =
SMALL_NUMBER_OF_THREADS;
00268 NumberOfCriticalThreads =
SMALL_NUMBER_OF_THREADS;
00269 }
00270
00271
00272
00273
00274
00275
00276
if (
ExpAdditionalCriticalWorkerThreads >
MAX_ADDITIONAL_THREADS ) {
00277
ExpAdditionalCriticalWorkerThreads =
MAX_ADDITIONAL_THREADS;
00278 }
00279
00280
if (
ExpAdditionalDelayedWorkerThreads >
MAX_ADDITIONAL_THREADS ) {
00281
ExpAdditionalDelayedWorkerThreads =
MAX_ADDITIONAL_THREADS;
00282 }
00283
00284
00285
00286
00287
00288
for (WorkQueueType = 0; WorkQueueType <
MaximumWorkQueue; WorkQueueType++) {
00289
00290 RtlZeroMemory(&ExWorkerQueue[WorkQueueType],
00291
sizeof(
EX_WORK_QUEUE));
00292
00293
KeInitializeQueue(&ExWorkerQueue[WorkQueueType].WorkerQueue, 0);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
ExWorkerQueue[
CriticalWorkQueue].
MakeThreadsAsNecessary =
TRUE;
00306
00307
00308
00309
00310
00311
KeInitializeEvent(&ExThreadSetManagerEvent,
00312 SynchronizationEvent,
00313 FALSE);
00314
00315
00316
00317
00318
00319
00320 InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
00321
00322
00323
00324
00325
00326
for (
Index = 0;
Index < (NumberOfCriticalThreads +
ExpAdditionalCriticalWorkerThreads);
Index += 1) {
00327
00328
00329
00330
00331
00332
Status =
ExpCreateWorkerThread( CriticalWorkQueue, FALSE );
00333
if (!
NT_SUCCESS(Status)) {
00334
break;
00335 }
00336
ExCriticalWorkerThreads++;
00337 }
00338
00339
00340
for (
Index = 0;
Index < (NumberOfDelayedThreads +
ExpAdditionalDelayedWorkerThreads);
Index += 1) {
00341
00342
00343
00344
00345
00346
Status =
ExpCreateWorkerThread( DelayedWorkQueue, FALSE );
00347
if (!
NT_SUCCESS(Status)) {
00348
break;
00349 }
00350
00351
ExDelayedWorkerThreads++;
00352 }
00353
00354
Status =
ExpCreateWorkerThread( HyperCriticalWorkQueue, FALSE );
00355
00356
00357
00358
00359
00360
Status =
PsCreateSystemThread(&Thread,
00361 THREAD_ALL_ACCESS,
00362 &ObjectAttributes,
00363 0L,
00364 NULL,
00365 ExpWorkerThreadBalanceManager,
00366 NULL);
00367
if (
NT_SUCCESS(Status)) {
00368 ZwClose( Thread );
00369 }
00370
00371
return (BOOLEAN)
NT_SUCCESS(Status);
00372 }