source: trunk/src/win32k/misc/locks.asm@ 10367

Last change on this file since 10367 was 5001, checked in by bird, 25 years ago

Initial coding - not tested (but I hope it works all right).

File size: 5.6 KB
Line 
1; $Id: locks.asm,v 1.2 2001-01-21 07:55:28 bird Exp $
2;
3; R/W spinlocks.
4;
5; Copyright (c) 2001 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
6;
7; Project Odin Software License can be found in LICENSE.TXT
8;
9
10 .486p
11
12;
13; Include files
14;
15 include devsegdf.inc
16
17
18;
19; Exported symbols
20;
21 public RWLockAcquireRead
22 public RWLockReleaseRead
23 public RWLockAcquireWrite
24 public RWLockReleaseWrite
25
26
27;
28; Defined Constants And Macros
29;
30ifdef DEBUG
31DEBUGINT3 EQU int 3
32else
33DEBUGINT3 EQU ;
34endif
35
36
37
38CODE32 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.
54RWLockAcquireRead proc near
55 ASSUME ds:FLAT
56 mov edx, eax ; edx = lock pointer.
57 ; eax will be used later.
58rwlar_writeloop:
59 mov eax, dword ptr [edx] ; get lock data.
60rwlar_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
68rwlar_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
74rwlar_ret:
75 xor eax, eax
76 ret ; Return successfully.
77RWLockAcquireRead 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)
93RWLockReleaseRead 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
98rwlrr_error: ; We're insane.
99 DEBUGINT3 ; This should _never_ _ever_ happen!
100 mov eax, 0ffffffffh ; Return failure.
101 ret
102
103rwlrr_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
107RWLockReleaseRead 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.
122RWLockAcquireWrite proc near
123 ASSUME ds:FLAT
124
125rwlaw_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.
134rwlaw_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
139rwlaw_error: ; We're insane!
140 DEBUGINT3 ; This should _never_ _ever_ happen!
141 mov eax, 0ffffffffh ; Return failure.
142 ret
143
144rwlaw_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
152rwlaw_ret:
153 xor eax, eax ; successful return.
154 ret
155RWLockAcquireWrite 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)
171RWLockReleaseWrite 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
175rwlrw_error:
176 DEBUGINT3 ; This should _never_ _ever_ happen!
177 mov eax, 0ffffffffh ; Return failure.
178 ret
179
180rwlrw_ok:
181 xor edx, edx
182 lock xchg edx, [eax] ; Write 0 to the entire lock dword.
183
184rwlrw_ret:
185 xor eax, eax ; Return successfully.
186 ret
187RWLockReleaseWrite endp
188
189
190
191CODE32 ends
192
193end
Note: See TracBrowser for help on using the repository browser.