Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ddkresrc.c File Reference

#include "exp.h"
#include <nturtl.h>

Go to the source code of this file.

Defines

#define ASSERT_RESOURCE(_Resource)
#define ExclusiveWaiter   0x01
#define SharedWaiter   0x02
#define DisablePriorityBoost   0x08
#define CounterShiftBit   0x04
#define IsExclusiveWaiting(a)   (((a)->Flag & ExclusiveWaiter) != 0)
#define IsOwnedExclusive(a)   (((a)->Flag & ResourceOwnedExclusive) != 0)
#define IsOwnedExclusive(a)   (((a)->Flag & ResourceOwnedExclusive) != 0)
#define IsBoostAllowed(a)   (((a)->Flag & DisablePriorityBoost) == 0)
#define AcquireResourceLock(_Resource, _Irql)
#define ReleaseResourceLock(_Resource, _Irql)
#define INITIAL_TABLE_SIZE   4
#define WaitForResourceExclusive(_Resource, _OldIrql)
#define WakeExclusiveWaiters(_Resource)

Functions

VOID ExpWaitForResourceDdk (IN PNTDDK_ERESOURCE Resource, IN PVOID Object)
NTSTATUS ExInitializeResource (IN PNTDDK_ERESOURCE Resource)
BOOLEAN ExAcquireResourceExclusive (IN PNTDDK_ERESOURCE Resource, IN BOOLEAN Wait)
VOID ExReleaseResourceForThread (IN PNTDDK_ERESOURCE Resource, IN ERESOURCE_THREAD OurThread)
NTSTATUS ExDeleteResource (IN PNTDDK_ERESOURCE Resource)

Variables

LARGE_INTEGER ExpTimeout
ULONG ExpResourceTimeoutCount
KSPIN_LOCK ExpResourceSpinLock
LIST_ENTRY ExpSystemResourcesList


Define Documentation

#define AcquireResourceLock _Resource,
_Irql   ) 
 

Value:

{ \ ExAcquireSpinLock( &_Resource->SpinLock, _Irql ); \ ASSERT_RESOURCE( _Resource ); \ }

Definition at line 115 of file ddkresrc.c.

Referenced by ExAcquireResourceExclusive(), ExpWaitForResourceDdk(), and ExReleaseResourceForThread().

#define ASSERT_RESOURCE _Resource   ) 
 

Definition at line 70 of file ddkresrc.c.

Referenced by ExAcquireResourceExclusiveLite(), ExAcquireResourceSharedLite(), ExAcquireSharedStarveExclusive(), ExAcquireSharedWaitForExclusive(), ExConvertExclusiveToSharedLite(), ExDeleteResource(), ExDeleteResourceLite(), ExDisableResourceBoostLite(), ExIsResourceAcquiredExclusiveLite(), ExIsResourceAcquiredSharedLite(), ExpFindCurrentThread(), ExReleaseResourceForThreadLite(), ExReleaseResourceLite(), ExSetResourceOwnerPointer(), and ExTryToAcquireResourceExclusiveLite().

#define CounterShiftBit   0x04
 

Definition at line 86 of file ddkresrc.c.

#define DisablePriorityBoost   0x08
 

Definition at line 80 of file ddkresrc.c.

Referenced by ExDisableResourceBoostLite().

#define ExclusiveWaiter   0x01
 

Definition at line 77 of file ddkresrc.c.

#define INITIAL_TABLE_SIZE   4
 

Definition at line 124 of file ddkresrc.c.

Referenced by ExInitializeResource().

#define IsBoostAllowed  )     (((a)->Flag & DisablePriorityBoost) == 0)
 

Definition at line 92 of file ddkresrc.c.

Referenced by ExpWaitForResource(), and ExpWaitForResourceDdk().

#define IsExclusiveWaiting  )     (((a)->Flag & ExclusiveWaiter) != 0)
 

Definition at line 89 of file ddkresrc.c.

Referenced by ExAcquireResourceSharedLite(), ExAcquireSharedWaitForExclusive(), ExDeleteResource(), ExDeleteResourceLite(), ExpWaitForResource(), ExpWaitForResourceDdk(), ExReleaseResourceForThread(), ExReleaseResourceForThreadLite(), and ExReleaseResourceLite().

#define IsOwnedExclusive  )     (((a)->Flag & ResourceOwnedExclusive) != 0)
 

Definition at line 91 of file ddkresrc.c.

#define IsOwnedExclusive  )     (((a)->Flag & ResourceOwnedExclusive) != 0)
 

Definition at line 91 of file ddkresrc.c.

Referenced by ExAcquireResourceExclusive(), ExAcquireResourceExclusiveLite(), ExAcquireResourceSharedLite(), ExAcquireSharedStarveExclusive(), ExAcquireSharedWaitForExclusive(), ExConvertExclusiveToSharedLite(), ExIsResourceAcquiredExclusiveLite(), ExpWaitForResource(), ExpWaitForResourceDdk(), ExReleaseResourceForThreadLite(), ExReleaseResourceLite(), ExSetResourceOwnerPointer(), and ExTryToAcquireResourceExclusiveLite().

#define ReleaseResourceLock _Resource,
_Irql   ) 
 

Value:

{ \ ExReleaseSpinLock( &_Resource->SpinLock, _Irql ); \ }

Definition at line 120 of file ddkresrc.c.

Referenced by ExAcquireResourceExclusive(), ExpWaitForResourceDdk(), and ExReleaseResourceForThread().

#define SharedWaiter   0x02
 

Definition at line 78 of file ddkresrc.c.

#define WaitForResourceExclusive _Resource,
_OldIrql   ) 
 

Value:

{ \ _Resource->Flag |= ExclusiveWaiter; \ _Resource->NumberOfExclusiveWaiters += 1; \ ReleaseResourceLock ( _Resource, _OldIrql ); \ ExpWaitForResourceDdk ( _Resource, &_Resource->ExclusiveWaiters ); \ AcquireResourceLock ( _Resource, &_OldIrql); \ if (--_Resource->NumberOfExclusiveWaiters != 0) { \ _Resource->Flag |= ExclusiveWaiter; \ } \ }

Definition at line 126 of file ddkresrc.c.

Referenced by ExAcquireResourceExclusive().

#define WakeExclusiveWaiters _Resource   ) 
 

Value:

{ \ _Resource->Flag &= ~ExclusiveWaiter; \ KeSetEvent(&_Resource->ExclusiveWaiters, 0, FALSE); \ }

Definition at line 137 of file ddkresrc.c.

Referenced by ExReleaseResourceForThread().


Function Documentation

BOOLEAN ExAcquireResourceExclusive IN PNTDDK_ERESOURCE  Resource,
IN BOOLEAN  Wait
 

Definition at line 249 of file ddkresrc.c.

References AcquireResourceLock, _ERESOURCE::ActiveCount, ASSERT, ASSERTMSG, ERESOURCE_THREAD, ExGetCurrentResourceThread, FALSE, _ERESOURCE::Flag, IsOwnedExclusive, _ERESOURCE::OwnerThreads, ReleaseResourceLock, Resource, ResourceNeverExclusive, ResourceOwnedExclusive, TRUE, and WaitForResourceExclusive.

00256 : 00257 00258 The routine acquires the resource for exclusive access. Upon return from 00259 the procedure the resource is acquired for exclusive access. 00260 00261 Arguments: 00262 00263 Resource - Supplies the resource to acquire 00264 00265 Wait - Indicates if the call is allowed to wait for the resource 00266 to become available for must return immediately 00267 00268 Return Value: 00269 00270 BOOLEAN - TRUE if the resource is acquired and FALSE otherwise 00271 00272 --*/ 00273 00274 { 00275 KIRQL OldIrql; 00276 ERESOURCE_THREAD OurThread; 00277 00278 ASSERTMSG("Routine cannot be called at DPC ", !KeIsExecutingDpc() ); 00279 00280 ASSERT((Resource->Flag & ResourceNeverExclusive) == 0); 00281 00282 OurThread = (ULONG_PTR)ExGetCurrentResourceThread(); 00283 00284 // 00285 // Get exclusive access to this resource structure 00286 // 00287 00288 AcquireResourceLock( Resource, &OldIrql ); 00289 00290 // 00291 // Loop until the resource is ours or exit if we cannot wait. 00292 // 00293 00294 while (TRUE) { 00295 if (Resource->ActiveCount == 0) { 00296 00297 // 00298 // Resource is un-owned, obtain it exclusive 00299 // 00300 00301 Resource->InitialOwnerThreads[0] = OurThread; 00302 Resource->OwnerThreads[0] = OurThread; 00303 Resource->OwnerCounts[0] = 1; 00304 Resource->ActiveCount = 1; 00305 Resource->Flag |= ResourceOwnedExclusive; 00306 ReleaseResourceLock ( Resource, OldIrql ); 00307 return TRUE; 00308 } 00309 00310 if (IsOwnedExclusive(Resource) && 00311 Resource->OwnerThreads[0] == OurThread) { 00312 00313 // 00314 // Our thread is already the exclusive resource owner 00315 // 00316 00317 Resource->OwnerCounts[0] += 1; 00318 ReleaseResourceLock( Resource, OldIrql ); 00319 return TRUE; 00320 } 00321 00322 // 00323 // Check if we are allowed to wait or must return immediately, and 00324 // indicate that we didn't acquire the resource 00325 // 00326 00327 if (!Wait) { 00328 ReleaseResourceLock( Resource, OldIrql ); 00329 return FALSE; 00330 } 00331 00332 // 00333 // Otherwise we need to wait to acquire the resource. 00334 // 00335 00336 WaitForResourceExclusive ( Resource, OldIrql ); 00337 } 00338 }

NTSTATUS ExDeleteResource IN PNTDDK_ERESOURCE  Resource  ) 
 

Definition at line 422 of file ddkresrc.c.

References ASSERT, ASSERT_RESOURCE, ASSERTMSG, ExpResourceSpinLock, IsExclusiveWaiting, Resource, and _ERESOURCE::SystemResourcesList.

00428 : 00429 00430 This routine deletes (i.e., uninitializes) the input resource variable 00431 00432 00433 Arguments: 00434 00435 Resource - Supplies the resource variable being deleted 00436 00437 Return Value: 00438 00439 None 00440 00441 --*/ 00442 00443 { 00444 ASSERTMSG("Routine cannot be called at DPC ", !KeIsExecutingDpc() ); 00445 00446 ASSERT_RESOURCE( Resource ); 00447 ASSERT( !IsExclusiveWaiting(Resource) ); 00448 00449 00450 if (Resource >= (PNTDDK_ERESOURCE)MM_USER_PROBE_ADDRESS) { 00451 KIRQL OldIrql; 00452 00453 ExAcquireSpinLock( &ExpResourceSpinLock, &OldIrql ); 00454 RemoveEntryList( &Resource->SystemResourcesList ); 00455 ExReleaseSpinLock( &ExpResourceSpinLock, OldIrql ); 00456 00457 } 00458 00459 return STATUS_SUCCESS; 00460 }

NTSTATUS ExInitializeResource IN PNTDDK_ERESOURCE  Resource  ) 
 

Definition at line 172 of file ddkresrc.c.

References _ERESOURCE::ActiveCount, ASSERTMSG, _ERESOURCE::ContentionCount, _ERESOURCE::CreatorBackTraceIndex, _ERESOURCE::ExclusiveWaiters, ExInterlockedInsertTailList(), ExpResourceSpinLock, ExpSystemResourcesList, FALSE, _ERESOURCE::Flag, INITIAL_TABLE_SIZE, KeInitializeEvent, KeInitializeSemaphore(), KeInitializeSpinLock(), MmDeterminePoolType(), NonPagedPool, NtGlobalFlag, _ERESOURCE::NumberOfExclusiveWaiters, _ERESOURCE::NumberOfSharedWaiters, _ERESOURCE::OwnerThreads, Resource, _ERESOURCE::SharedWaiters, _ERESOURCE::SpinLock, and _ERESOURCE::SystemResourcesList.

00178 : 00179 00180 This routine initializes the input resource variable 00181 00182 Arguments: 00183 00184 Resource - Supplies the resource variable being initialized 00185 00186 Return Value: 00187 00188 Status of the operation. 00189 00190 --*/ 00191 00192 { 00193 ULONG i; 00194 00195 ASSERTMSG("A resource cannot be in paged pool ", MmDeterminePoolType(Resource) == NonPagedPool); 00196 // 00197 // Initialize the shared and exclusive waiting counters and semaphore. 00198 // The counters indicate how many are waiting for access to the resource 00199 // and the semaphores are used to wait on the resource. Note that 00200 // the semaphores can also indicate the number waiting for a resource 00201 // however there is a race condition in the algorithm on the acquire 00202 // side if count if not updated before the critical section is exited. 00203 // So we need to have an outside counter. 00204 // 00205 00206 Resource->NumberOfSharedWaiters = 0; 00207 Resource->NumberOfExclusiveWaiters = 0; 00208 00209 KeInitializeSemaphore ( &Resource->SharedWaiters, 0, MAXLONG ); 00210 KeInitializeEvent ( &Resource->ExclusiveWaiters, SynchronizationEvent, FALSE ); 00211 KeInitializeSpinLock ( &Resource->SpinLock ); 00212 00213 Resource->OwnerThreads = Resource->InitialOwnerThreads; 00214 Resource->OwnerCounts = Resource->InitialOwnerCounts; 00215 00216 Resource->TableSize = INITIAL_TABLE_SIZE; 00217 Resource->ActiveCount = 0; 00218 Resource->TableRover = 1; 00219 Resource->Flag = 0; 00220 00221 for(i=0; i < INITIAL_TABLE_SIZE; i++) { 00222 Resource->OwnerThreads[i] = 0; 00223 Resource->OwnerCounts[i] = 0; 00224 } 00225 00226 Resource->ContentionCount = 0; 00227 InitializeListHead( &Resource->SystemResourcesList ); 00228 00229 #if i386 && !FPO 00230 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) { 00231 Resource->CreatorBackTraceIndex = RtlLogStackBackTrace(); 00232 } 00233 else { 00234 Resource->CreatorBackTraceIndex = 0; 00235 } 00236 #endif // i386 && !FPO 00237 if (Resource >= (PNTDDK_ERESOURCE)MM_USER_PROBE_ADDRESS) { 00238 ExInterlockedInsertTailList ( 00239 &ExpSystemResourcesList, 00240 &Resource->SystemResourcesList, 00241 &ExpResourceSpinLock ); 00242 } 00243 00244 return STATUS_SUCCESS; 00245 }

VOID ExpWaitForResourceDdk IN PNTDDK_ERESOURCE  Resource,
IN PVOID  Object
 

Definition at line 463 of file ddkresrc.c.

References AcquireResourceLock, _ERESOURCE::ActiveCount, ASSERT, _ERESOURCE::ContentionCount, DbgPrint, ERESOURCE_INCREMENT, Executive, ExpResourceTimeoutCount, ExpTimeout, FALSE, IsBoostAllowed, IsExclusiveWaiting, IsOwnedExclusive, KeBoostPriorityThread(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), _ERESOURCE::NumberOfExclusiveWaiters, _ERESOURCE::OwnerThreads, ReleaseResourceLock, Resource, and Status.

00469 : 00470 00471 The routine waits on the Resource's object to be set. If the 00472 wait is too long the current owners of the resource are boosted 00473 in priority. 00474 00475 Arguments: 00476 00477 Resource - Supplies the resource 00478 00479 Object - Event or Semaphore to wait on 00480 00481 Return Value: 00482 00483 None 00484 00485 --*/ 00486 { 00487 KIRQL OldIrql; 00488 NTSTATUS Status; 00489 ULONG i; 00490 00491 00492 Resource->ContentionCount += 1; 00493 00494 i = 0; 00495 for (; ;) { 00496 Status = KeWaitForSingleObject ( 00497 Object, 00498 Executive, 00499 KernelMode, 00500 FALSE, 00501 &ExpTimeout ); 00502 00503 if (Status != STATUS_TIMEOUT) { 00504 break; 00505 } 00506 00507 if (i++ >= ExpResourceTimeoutCount) { 00508 i = 0; 00509 00510 DbgPrint("Resource @ %lx\n", Resource); 00511 DbgPrint(" ActiveCount = %04lx Flags = %s%s%s\n", 00512 Resource->ActiveCount, 00513 IsOwnedExclusive(Resource) ? "IsOwnedExclusive " : "", 00514 "", 00515 IsExclusiveWaiting(Resource) ? "ExclusiveWaiter " : "" 00516 ); 00517 00518 DbgPrint(" NumberOfExclusiveWaiters = %04lx\n", Resource->NumberOfExclusiveWaiters); 00519 00520 DbgPrint(" Thread = %08lx, Count = %02x\n", 00521 Resource->OwnerThreads[0], 00522 Resource->OwnerCounts[0] ); 00523 00524 DbgBreakPoint(); 00525 DbgPrint("EX - Rewaiting\n"); 00526 } 00527 00528 // 00529 // Give owning thread(s) a priority boost 00530 // 00531 00532 AcquireResourceLock( Resource, &OldIrql ); 00533 00534 if (IsBoostAllowed(Resource) && IsOwnedExclusive(Resource)) { 00535 00536 // 00537 // Only one thread, boost it 00538 // 00539 00540 KeBoostPriorityThread((PKTHREAD) Resource->OwnerThreads[0], 00541 ERESOURCE_INCREMENT ); 00542 } 00543 00544 ReleaseResourceLock( Resource, OldIrql ); 00545 00546 // 00547 // Loop and wait some more 00548 // 00549 } 00550 00551 // 00552 // Wait was satisfied 00553 // 00554 00555 ASSERT(NT_SUCCESS(Status)); 00556 return ; 00557 }

VOID ExReleaseResourceForThread IN PNTDDK_ERESOURCE  Resource,
IN ERESOURCE_THREAD  OurThread
 

Definition at line 342 of file ddkresrc.c.

References AcquireResourceLock, _ERESOURCE::ActiveCount, ASSERT, _ERESOURCE::Flag, IsExclusiveWaiting, _ERESOURCE::OwnerThreads, ReleaseResourceLock, Resource, ResourceOwnedExclusive, and WakeExclusiveWaiters.

00349 : 00350 00351 This routine release the input resource for the indicated thread. The 00352 resource could have been acquired for either shared or exclusive access. 00353 00354 Arguments: 00355 00356 Resource - Supplies the resource to release 00357 00358 Thread - Supplies the thread that originally acquired the resource 00359 00360 Return Value: 00361 00362 None. 00363 00364 --*/ 00365 00366 { 00367 KIRQL OldIrql; 00368 00369 ASSERT( OurThread != 0 ); 00370 00371 // 00372 // Get exclusive access to this resource structure 00373 // 00374 00375 AcquireResourceLock( Resource, &OldIrql ); 00376 00377 ASSERT( Resource->OwnerThreads[0] == OurThread ); 00378 00379 // 00380 // OwnerThread[0] is optimized for resources which get 00381 // single users. We check it first, plus we clear the 00382 // threadid if the counts goes to zero 00383 // 00384 00385 if (--Resource->OwnerCounts[0] != 0) { 00386 ReleaseResourceLock( Resource, OldIrql ); 00387 return; 00388 } 00389 00390 Resource->OwnerThreads[0] = 0; 00391 Resource->InitialOwnerThreads[0] = 0; 00392 00393 // 00394 // Thread's count went to zero, lower the resource's active count. 00395 // 00396 00397 Resource->ActiveCount -= 1; 00398 00399 ASSERT( Resource->ActiveCount == 0 ); 00400 00401 // 00402 // Resource's activecount went to zero - clear possible exclusive 00403 // owner bit, and wake any waiters 00404 // 00405 00406 if (IsExclusiveWaiting(Resource)) { 00407 00408 WakeExclusiveWaiters ( Resource ); 00409 } 00410 00411 // 00412 // No longer owned exclusive 00413 // 00414 00415 Resource->Flag &= ~ResourceOwnedExclusive; 00416 00417 ReleaseResourceLock( Resource, OldIrql ); 00418 return; 00419 }


Variable Documentation

KSPIN_LOCK ExpResourceSpinLock [static]
 

Definition at line 99 of file ddkresrc.c.

Referenced by ExDeleteResource(), and ExInitializeResource().

ULONG ExpResourceTimeoutCount
 

Definition at line 41 of file ddkresrc.c.

LIST_ENTRY ExpSystemResourcesList
 

Definition at line 157 of file ddkresrc.c.

Referenced by ExInitializeResource(), ExInitializeResourceLite(), ExpCheckForResource(), ExpResourceInitialization(), and ExQuerySystemLockInformation().

LARGE_INTEGER ExpTimeout
 

Definition at line 35 of file ddkresrc.c.

Referenced by ExpResourceInitialization(), ExpWaitForResource(), and ExpWaitForResourceDdk().


Generated on Sat May 15 19:43:25 2004 for test by doxygen 1.3.7