- Timestamp:
- Jan 21, 2001, 8:55:28 AM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/win32k/misc/locks.asm
r4996 r5001 1 ; $Id: locks.asm,v 1. 1 2001-01-20 23:48:53bird Exp $1 ; $Id: locks.asm,v 1.2 2001-01-21 07:55:28 bird Exp $ 2 2 ; 3 ; My own R/W lock implementation.3 ; R/W spinlocks. 4 4 ; 5 5 ; Copyright (c) 2001 knut st. osmundsen (knut.stange.osmundsen@mynd.no) … … 14 14 ; 15 15 include devsegdf.inc 16 include locks.inc 16 17 17 18 18 ; 19 19 ; Exported symbols 20 20 ; 21 public RWLockAquireRead 22 public RWLockAquireWrite 21 public RWLockAcquireRead 23 22 public RWLockReleaseRead 23 public RWLockAcquireWrite 24 24 public RWLockReleaseWrite 25 25 26 26 27 ; 28 ; Defined Constants And Macros 29 ; 30 ifdef DEBUG 31 DEBUGINT3 EQU int 3 32 else 33 DEBUGINT3 EQU ; 34 endif 27 35 36 37 38 CODE32 segment 39 40 41 ;; 42 ; Acquires Read access to a R/W lock. 43 ; @cproto APIRET _Optlink RWLockAcquireRead(PRWLOCK pLock) 44 ; @returns NO_ERROR (never failes) 45 ; @param eax pLock - pointer to lock structure. 46 ; @uses eax, ecx, edx 47 ; @sketch spin while write locked. 48 ; try increment. 49 ; if failed restart spin loop. 50 ; else return successfully. 51 ; @status completely implemented. 52 ; @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 53 ; @remark This is non-blocking. 54 RWLockAcquireRead proc near 55 ASSUME ds:FLAT 56 mov edx, eax ; edx = lock pointer. 57 ; eax will be used later. 58 rwlar_writeloop: 59 mov eax, dword ptr [edx] ; get lock data. 60 rwlar_reloop: 61 bt eax, 1fh ; test if write bit is set. 62 jnc rwlar_tryinc ; spin until it's cleared. 63 nop ; We're not in a hurry any longer. 64 nop 65 nop 66 jmp rwlar_writeloop ; spin. 67 68 rwlar_tryinc: 69 les ecx, [eax+1] ; ecx <- new read lock count (eax + 1) 70 lock cmpxchg dword ptr [edx], ecx 71 jz rwlar_ret ; ZF set ok success. 72 jmp rwlar_reloop ; ZF clear on error, eax is [edx] - restart spin loop. 73 74 rwlar_ret: 75 xor eax, eax 76 ret ; Return successfully. 77 RWLockAcquireRead endp 78 79 80 ;; 81 ; Releases a read lock. 82 ; @cproto APIRET _Optlink RWLockReleaseRead(PRWLOCK pLock) 83 ; @returns NO_ERROR on success. 84 ; -1 on error. 85 ; @param eax pLock - Pointer to the lock structure. 86 ; @uses eax, edx 87 ; @sketch If the lock count is larger than zero Then 88 ; Descrement it and return successfully. 89 ; else 90 ; Fail. 91 ; @status completely implemented. 92 ; @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 93 RWLockReleaseRead proc near 94 mov edx, dword ptr [eax] ; Get lock count. 95 and edx, 7fffffffh ; Sanity check. 96 jnz rwlrr_ok ; Jump if sane. 97 98 rwlrr_error: ; We're insane. 99 DEBUGINT3 ; This should _never_ _ever_ happen! 100 mov eax, 0ffffffffh ; Return failure. 101 ret 102 103 rwlrr_ok: 104 lock dec dword ptr [eax] ; Decrement the read count (works with write bit set too). 105 xor eax, eax ; Return successfully. 106 ret 107 RWLockReleaseRead endp 108 109 110 111 ;; 112 ; Acquire write access to a R/W lock. 113 ; @cproto APIRET _Optlink RWLockAcquireWrite(PRWLOCK pLock) 114 ; @returns NO_ERROR (never failes) 115 ; @param eax pLock - Pointer to lock structure. 116 ; @uses eax, edx 117 ; @sketch Spin while trying to set write lock flag (bit 31). 118 ; Spin while still read locked. (until lower 31 bits is zero) 119 ; @status completely implemented. 120 ; @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 121 ; @remark Will never block. 122 RWLockAcquireWrite proc near 123 ASSUME ds:FLAT 124 125 rwlaw_writeloop: 126 lock bts dword ptr [eax], 01fh ; Try set the write bit. 127 jnc rwlaw_readloop ; break loop - we set the write bit. 128 nop ; We're not in a hurry any longer. 129 nop 130 nop 131 jmp rwlaw_writeloop ; Spin 132 133 ; Wait for reads to finish. 134 rwlaw_readloop: 135 mov edx, dword ptr [eax] ; Get lock value. 136 bt edx, 01fh ; Sanity check - Ensure that the write bit is not cleared. 137 jc rwlaw_ok ; Jump if sane. 138 139 rwlaw_error: ; We're insane! 140 DEBUGINT3 ; This should _never_ _ever_ happen! 141 mov eax, 0ffffffffh ; Return failure. 142 ret 143 144 rwlaw_ok: 145 and edx, 7fffffffh ; Spin while until read lock count is 0. 146 jz rwlaw_ret ; break loop 147 nop ; We're not in a hurry any longer. 148 nop 149 nop 150 jmp rwlaw_ret ; Spin. 151 152 rwlaw_ret: 153 xor eax, eax ; successful return. 154 ret 155 RWLockAcquireWrite endp 156 157 158 ;; 159 ; Releases a Write lock. 160 ; @cproto APIRET _Optlink RWLockReleaseWrite(PRWLOCK pLock) 161 ; @returns NO_ERROR on success. 162 ; -1 on error. 163 ; @param eax pLock - pointer to the lock structure. 164 ; @uses eax, edx 165 ; @sketch If write bit is set Then 166 ; Clear entire lock and return succesfully. 167 ; else 168 ; Return failure. 169 ; @status completely implemented. 170 ; @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 171 RWLockReleaseWrite proc near 172 cmp dword ptr [eax], 80000000h ; Sanity check - state should be write locked and no read locks. 173 je rwlrw_ok ; Jump if sane. 174 175 rwlrw_error: 176 DEBUGINT3 ; This should _never_ _ever_ happen! 177 mov eax, 0ffffffffh ; Return failure. 178 ret 179 180 rwlrw_ok: 181 xor edx, edx 182 lock xchg edx, [eax] ; Write 0 to the entire lock dword. 183 184 rwlrw_ret: 185 xor eax, eax ; Return successfully. 186 ret 187 RWLockReleaseWrite endp 188 189 190 191 CODE32 ends 192 193 end
Note:
See TracChangeset
for help on using the changeset viewer.