1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxSpinLock.hpp 8 9 Abstract: 10 11 Author: 12 13 14 Revision History: 15 16 --*/ 17 18 #ifndef _FXSPINLOCK_H_ 19 #define _FXSPINLOCK_H_ 20 21 #define FX_SPIN_LOCK_NUM_HISTORY_ENTRIES (10) 22 23 struct FX_SPIN_LOCK_HISTORY_ENTRY { 24 PVOID CallersAddress; 25 LARGE_INTEGER AcquiredAtTime; 26 LONGLONG LockedDuraction; 27 }; 28 29 typedef struct FX_SPIN_LOCK_HISTORY_ENTRY *PFX_SPIN_LOCK_HISTORY_ENTRY; 30 31 struct FX_SPIN_LOCK_HISTORY { 32 MxThread OwningThread; 33 34 PFX_SPIN_LOCK_HISTORY_ENTRY CurrentHistory; 35 36 FX_SPIN_LOCK_HISTORY_ENTRY History[FX_SPIN_LOCK_NUM_HISTORY_ENTRIES]; 37 }; 38 39 typedef struct FX_SPIN_LOCK_HISTORY *PFX_SPIN_LOCK_HISTORY; 40 41 class FxSpinLock : public FxObject { 42 43 public: 44 FxSpinLock( 45 __in PFX_DRIVER_GLOBALS FxDriverGlobals, 46 __in USHORT ExtraSize 47 ); 48 49 50 __drv_raisesIRQL(DISPATCH_LEVEL) 51 __drv_maxIRQL(DISPATCH_LEVEL) 52 VOID 53 AcquireLock( 54 __in PVOID CallersAddress 55 ); 56 57 __drv_requiresIRQL(DISPATCH_LEVEL) 58 VOID 59 ReleaseLock( 60 VOID 61 ); 62 63 64 MdLock* 65 GetLock( 66 VOID 67 ) 68 { 69 return &m_SpinLock.Get(); 70 } 71 72 VOID 73 SetInterruptSpinLock( 74 VOID 75 ) 76 { 77 m_InterruptLock = TRUE; 78 } 79 80 BOOLEAN 81 IsInterruptLock( 82 VOID 83 ) 84 { 85 return m_InterruptLock; 86 } 87 88 protected: 89 PFX_SPIN_LOCK_HISTORY 90 GetHistory( 91 VOID 92 ) 93 { 94 if (GetObjectSize() == WDF_ALIGN_SIZE_UP(sizeof(FxSpinLock), 95 MEMORY_ALLOCATION_ALIGNMENT)) { 96 return NULL; 97 } 98 else { 99 return WDF_PTR_ADD_OFFSET_TYPE( 100 this, 101 COMPUTE_RAW_OBJECT_SIZE(sizeof(FxSpinLock)), 102 PFX_SPIN_LOCK_HISTORY); 103 } 104 } 105 106 protected: 107 MxLock m_SpinLock; 108 109 KIRQL m_Irql; 110 111 // 112 // TRUE, this lock is being used to synchronize FxInterrupts. As such, the 113 // caller is not allowed to actually call WDFSPINLOCK APIs on the handle 114 // because it would then be acquiring a spinlock at DISPATCH_LEVEL and the 115 // interrupt could be attempting to acquire the same lock at a higher IRQL 116 // on the same processor. 117 // 118 BOOLEAN m_InterruptLock; 119 }; 120 121 #endif // _FXSPINLOCK_H_ 122