A push lock is a type of synchronization mechanism that permits kernel mode drivers to claim shared or exclusive access at IRQL PASSIVE_LEVEL or APC_LEVEL, just like an ERESOURCE. But unlike an ERESOURCE which must reside in non-paged memory, a push lock can live in pageable memory (such as paged pool). In addition a push lock, sometimes referred to as an executive push lock, cannot be recursively acquired by the same thread which is permissible for an ERESOURCE.

Introduced in Windows XP kernel, push locks come in two varieties - regular push locks and cache-aware push locks. A regular push lock is of platform pointer size (32 bits on 32 bit systems and 64 bits on 64 bit systems) which is an advantage compared to ERESOURCE1 and other synchronization primitives.

A push lock like fast mutex uses processor lock semantics to implement fast locking when there is no contention. However when there is contention, push lock uses an internal gate object2 on stack to implement locking. In other words, if a push lock is already locked, the thread wishing to claim the push lock will block on an in-stack gate object (KGATE) via KeWaitForGate. That is very similar to fast mutexes using event synchronization object to implement contention locking.

A regular push lock is initialized by calling ExInitializePushLock.  ExInitializePushLock is declared in WDK headers as follows -

ExInitializePushLock declaration in WDK header ntifs.h

EX_PUSH_LOCK is a structure with members like below

typedef struct _EX_PUSH_LOCK { 
      union { 
                   ULONG Locked: 1; 
                   ULONG Waiting: 1; 
                   ULONG Waking: 1; 
                   ULONG MultipleShared: 1; 
                   ULONG Shared: 28; 
                   ULONG Value; PVOID Ptr; 
              }; 
} EX_PUSH_LOCK, *PEX_PUSH_LOCK;

Locked bit is the last bit and is set when the push lock is claimed by one or more thread(s). Waiting bit is set when there is contention and one or more threads are waiting to claim the push lock. Shared keeps track of how many shared acquisitions are outstanding on the push lock. If Locked is set and Shared is all zeroes, the push lock is exclusively acquired by some thread.
 

To request shared acquisition of a push lock one would call ExAcquirePushLockShared3 or ExTryAcquirePushLockShared4. To relinquish shared acquisition the DDI is ExReleasePushLockShared5.

Exclusive acquisition of push lock is through ExAcquirePushLockExclusive6 (for cache-aware push lock it is ExAcquireCacheAwarePushLockExclusive). To give up exclusive lock on push lock, the DDI is ExReleasePushLockExclusive7 (for cache-aware push lock it is ExReleaseCacheAwarePushLockExclusive)

If you are using ERESOURCE and want to consider some fast alternatives, you should perhaps consider using push lock and in the process, reduce driver non-paged memory footprint as well.

 

1 ERESOURCE is 56 bytes on 32-bit Vista RTM making it 14 times bigger than push lock

2 on XP SP2, 2003 SP2, Vista

3 VOID FASTCALL ExAcquirePushLockShared(PEX_PUSH_LOCK PushLock)

4 BOOLEAN FASTCALL ExTryAcquirePushLockShared(PEX_PUSH_LOCK PushLock)

   Returns TRUE if acquisition was successful

5 VOID FASTCALL ExReleasePushLockShared(PEX_PUSH_LOCK PushLock)

6 VOID FASTCALL ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)

7 VOID FASTCALL ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)

Tagged with →  
Share →

2 Responses to Kernel mode push locks

  1. Nosayba says:

    I want to know when I can use Shared or Exclusive pushlock

  2. Satya Das says:

    Shared pushlock will allow other threads to claim pushlock in shared mode. Exclusive would block all other threads. Typically shared pushlock is used for readers and exclusive is used for writers. Just like ERESOURCEs.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Looking for something?

Use the form below to search the site:


Still not finding what you're looking for? Drop us a note so we can take care of it!

Visit our friends!

A few highly recommended friends...

Set your Twitter account name in your settings to use the TwitterBar Section.