source: trunk/src/kernel32/interlock.asm@ 2012

Last change on this file since 2012 was 2009, checked in by sandervl, 26 years ago

InterlockExchange bugfix

File size: 7.1 KB
Line 
1; $Id: interlock.asm,v 1.5 1999-12-07 18:19:07 sandervl Exp $
2
3;/*
4; * Interlocked apis
5; *
6; * IMPORTANT NOTE: THIS CODE WILL NOT RUN ON 386 CPUs,
7; * 486 IS MINIMUM REQUIREMENT!
8; *
9; * Copyright 1999 Sander van Leeuwen
10; * Copyright 1999 Patrick Haller
11; *
12; * Project Odin Software License can be found in LICENSE.TXT
13; *
14; */
15.486P
16 NAME interlocked
17
18CODE32 SEGMENT DWORD PUBLIC USE32 'CODE'
19
20
21;************************************************************************
22;* InterlockedIncrement [KERNEL32] *
23;* *
24;* InterlockedIncrement adds 1 to a long variable and returns *
25;* - a negative number if the result < 0 *
26;* - zero if the result == 0 *
27;* - a positive number if the result > 0 *
28;* *
29;* The returned number need not be equal to the result!!!! *
30;************************************************************************
31
32 public _InterlockedIncrement@4
33_InterlockedIncrement@4 proc near
34
35;@@@PH similar to NT4
36 mov ecx, [esp+4]
37 mov eax, 1
38 nop
39 lock xadd dword ptr [ecx], eax
40 inc eax
41 retn 4
42
43; @@@PH 1999/12/06 old implementation similar to W95
44;var_4 = dword ptr -4
45;arg_0 = dword ptr 4
46;
47; sub esp, 4
48; mov eax, [esp + 4 + arg_0]
49; lock inc dword ptr [eax]
50; mov ecx, 0ffffffffh
51; js _ic_2
52; jz _ic_1
53; inc ecx
54;_ic_1: inc ecx
55;_ic_2: mov [esp + 4 + var_4], ecx
56; mov eax, ecx
57; retn 4
58;
59; @@@PH 1999/12/06 old implementation from WINE
60; mov eax, dword ptr [esp+4] ; LPLONG lpAddend
61; lock inc dword ptr [eax]
62; mov eax, 0
63; je @end ; not incremented?
64; jl @decr
65; inc eax ; ?
66; jmp @end
67;@decr: dec eax ; ?
68;@end: ret 4
69_InterlockedIncrement@4 endp
70
71
72;************************************************************************
73;* InterlockedDecrement [KERNEL32] *
74;* *
75;* InterlockedIncrement adds 1 to a long variable and returns *
76;* - a negative number if the result < 0 *
77;* - zero if the result == 0 *
78;* - a positive number if the result > 0 *
79;* *
80;* The returned number need not be equal to the result!!!! *
81;************************************************************************
82
83 public _InterlockedDecrement@4
84_InterlockedDecrement@4 proc near
85
86;@@@PH similar to NT4
87 mov ecx, [esp+4]
88 mov eax, 0ffffffffh
89 nop
90 lock xadd dword ptr [ecx], eax
91 dec eax
92 retn 4
93
94
95; @@@PH 1999/12/06 old implementation similar to W95
96;var_4 = dword ptr -4
97;arg_0 = dword ptr 4
98;
99; sub esp, 4
100; mov eax, dword ptr[esp+4+arg_0]
101; lock dec dword ptr [eax]
102; mov ecx, 0ffffffffh
103; js _id_2
104; jz _id_1
105; inc ecx
106;_id_1: inc ecx
107;_id_2: mov dword ptr [esp+4+var_4], ecx
108; mov eax, ecx
109; add esp, 4
110; retn 4
111
112; @@@PH 1999/12/06 old implementation from WINE
113; mov eax, dword ptr [esp+4] ; LPLONG lpAddend
114; lock dec dword ptr [eax]
115; mov eax, 0
116; je @end ; not decremented?
117; jl @decr
118; inc eax ; ?
119; jmp @end
120;@decr: dec eax ; ?
121;@end: ret 4
122
123_InterlockedDecrement@4 endp
124
125
126;************************************************************************
127;* InterlockedExchange [KERNEL32.???] *
128;* *
129;* Atomically exchanges a pair of values. *
130;* *
131;* RETURNS *
132;* Prior value of value pointed to by Target *
133;************************************************************************
134
135 public _InterlockedExchange@8
136_InterlockedExchange@8 proc near
137
138;@@@PH similar to NT4
139 mov ecx, [esp+4] ; LPLONG target
140 mov edx, [esp+8] ; LONG value
141 mov eax, dword ptr [ecx]
142_ie_1:
143 nop
144 lock cmpxchg dword ptr [ecx], edx
145 jnz _ie_1
146 retn 8
147
148; @@@PH 1999/12/06 old implementation similar to W95
149;var_4 = dword ptr -4
150;arg_0 = dword ptr 8
151;arg_4 = dword ptr 0Ch
152;
153; push ebp
154; mov ebp, esp
155; sub esp, 4
156; mov eax, dword ptr [ebp+arg_0]
157; mov ecx, dword ptr [ebp+arg_4]
158; xchg ecx, dword ptr [eax]
159; mov dword ptr [ebp+var_4], ecx
160; mov eax, ecx
161; mov esp, ebp
162; pop ebp
163; retn 8
164
165; @@@PH 1999/12/06 old implementation from WINE
166; push edx
167; mov eax, [esp+12] ; LONG value
168; mov edx,[esp+8] ; LPLONG target
169; lock xchg eax, dword ptr [edx]
170; pop edx
171; ret 8
172_InterlockedExchange@8 endp
173
174
175
176 public _InterlockedCompareExchange@12
177;************************************************************************
178;* InterlockedCompareExchange [KERNEL32.879]
179;*
180;* Atomically compares Destination and Comperand, and if found equal exchanges
181;* the value of Destination with Exchange
182;*
183;* RETURNS
184;* Prior value of value pointed to by Destination
185;*
186;************************************************************************
187_InterlockedCompareExchange@12 proc near
188
189;@@@PH similar to NT4
190 mov ecx, dword ptr [esp + 12]
191 mov edx, dword ptr [esp + 8]
192 mov eax, dword ptr [esp + 4]
193_ice_1:
194 nop
195 lock cmpxchg dword ptr [ecx], edx
196 retn 12
197
198
199; @@@PH 1999/12/06 old implementation from WINE
200; push ebp
201; mov ebp, esp
202; push edx
203; push ebx
204;
205; mov ebx, dword ptr [ebp+8] ;PVOID *Destination, /* Address of 32-bit value to exchange */
206; push dword ptr [ebx] ;save old *Destination
207; mov eax, [ebp+16] ;PVOID Comperand /* value to compare, 32 bits */
208; mov edx, [ebp+12] ;PVOID Exchange, /* change value, 32 bits */
209; lock cmpxchg dword ptr [ebx],edx
210; pop eax
211;
212; pop ebx
213; pop edx
214; pop ebp
215; ret 12
216_InterlockedCompareExchange@12 endp
217
218
219;************************************************************************
220;* InterlockedExchangeAdd [KERNEL32.880]
221;*
222;* Atomically adds Increment to Addend and returns the previous value of
223;* Addend
224;*
225;* RETURNS
226;* Prior value of value pointed to by cwAddendTarget
227;*
228;************************************************************************
229 public _InterlockedExchangeAdd@8
230_InterlockedExchangeAdd@8 proc near
231
232;@@@PH similar to NT4
233 mov ecx, dword ptr [esp + 4]
234 mov eax, dword ptr [esp + 8]
235 nop
236 lock xadd dword ptr [ecx], eax
237 retn 8
238
239; @@@PH 1999/12/06 old implementation from WINE
240;
241; push edx
242; mov eax, dword ptr [esp+12] ;LONG Increment /* Value to add */
243; mov edx, dword ptr [esp+8] ;PLONG Addend, /* Address of 32-bit value to exchange */
244; lock xadd dword ptr [edx], eax
245; pop edx
246; ret 8
247_InterlockedExchangeAdd@8 endp
248
249CODE32 ENDS
250
251 END
Note: See TracBrowser for help on using the repository browser.