1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxLock.hpp 8 9 Abstract: 10 11 This is the C++ header for the FxLock 12 13 This represents a container for handling locking 14 15 Author: 16 17 18 19 20 Revision History: 21 22 23 --*/ 24 25 #ifndef _FXLOCK_H_ 26 #define _FXLOCK_H_ 27 28 /** 29 * This is the base lock object implementation 30 * 31 * This is intended to be embedded in an FxNonPagedObject 32 * rather than forcing a separate allocation for 33 * non-verifier mode. 34 * 35 * In order to reduce the runtime memory cost of 36 * building in verifier support for a retail version, 37 * a single pointer it stored to FxVerifierLock 38 * if verifier is on. If this pointer is != NULL, 39 * lock calls are proxied to this lock function, 40 * leaving our internal spinlock redundent. 41 * 42 * The decision is to minimize the non-verifier 43 * memory footprint so we do not have to compile 44 * it out for retail builds, but always have it 45 * available through a driver debug setting. 46 */ 47 48 class FxLock { 49 50 private: 51 MxLock m_lock; 52 53 // For Verifier 54 FxVerifierLock* m_Verifier; 55 56 public: 57 FxLock( 58 VOID 59 ) 60 { 61 62 63 64 65 m_lock.Initialize(); 66 m_Verifier = NULL; 67 } 68 69 VOID 70 Initialize( 71 __in FxObject * ParentObject 72 ); 73 74 ~FxLock() 75 { 76 if (m_Verifier != NULL) { 77 delete m_Verifier; 78 } 79 } 80 81 _When_(this->m_Verifier == NULL, _Acquires_lock_(this->m_lock)) 82 inline 83 VOID 84 Lock( 85 __out PKIRQL PreviousIrql 86 ) 87 { 88 if (m_Verifier != NULL) { 89 m_Verifier->Lock(PreviousIrql, FALSE); 90 } 91 // else if (PreviousIrql == NULL) { 92 // KeAcquireSpinLockAtDpcLevel(&m_lock); 93 // } 94 else { 95 m_lock.Acquire(PreviousIrql); 96 } 97 } 98 99 _When_(this->m_Verifier == NULL, _Releases_lock_(this->m_lock)) 100 inline 101 void 102 Unlock( 103 __in KIRQL PreviousIrql 104 ) 105 { 106 if (m_Verifier != NULL) { 107 m_Verifier->Unlock(PreviousIrql, FALSE); 108 } 109 // else if (AtDpc) { 110 // KeReleaseSpinLockFromDpcLevel(&m_lock); 111 // } 112 else { 113 m_lock.Release(PreviousIrql); 114 } 115 } 116 117 _When_(this->m_Verifier == NULL, _Acquires_lock_(this->m_lock)) 118 inline 119 VOID 120 LockAtDispatch( 121 VOID 122 ) 123 { 124 if (m_Verifier != NULL) { 125 KIRQL previousIrql; 126 127 m_Verifier->Lock(&previousIrql, TRUE); 128 } 129 else { 130 m_lock.AcquireAtDpcLevel(); 131 } 132 } 133 134 _When_(this->m_Verifier == NULL, _Releases_lock_(this->m_lock)) 135 inline 136 void 137 UnlockFromDispatch( 138 VOID 139 ) 140 { 141 if (m_Verifier != NULL) { 142 m_Verifier->Unlock(DISPATCH_LEVEL, TRUE); 143 } 144 else { 145 m_lock.ReleaseFromDpcLevel(); 146 } 147 } 148 }; 149 150 #endif // _FXLOCK_H_ 151