85a6c4b4c586413d11560685a74f2139f1464a8b
[reactos.git] / reactos / lib / kernel32 / synch / intrlck.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/sync/intrlck.c
5 * PURPOSE: Inter lock increments
6 * UPDATE HISTORY:
7 * Created 30/09/99
8 */
9
10 /*
11 * Win32 kernel functions
12 *
13 * Copyright 1995 Martin von Loewis
14 * Copyright 1997 Onno Hovers
15 */
16
17
18 /************************************************************************
19 * InterlockedIncrement *
20 * *
21 * InterlockedIncrement adds 1 to a long variable and returns *
22 * - a negative number if the result < 0 *
23 * - zero if the result == 0 *
24 * - a positive number if the result > 0 *
25 * *
26 * The returned number need not be equal to the result!!!! *
27 * note: *
28 * *
29 ************************************************************************/
30
31 #include <k32.h>
32
33 LONG
34 STDCALL
35 InterlockedIncrement(PLONG Addend)
36 {
37 long ret = 0;
38 __asm__
39 (
40 "\tlock\n" /* for SMP systems */
41 "\tincl (%1)\n"
42 "\tje 2f\n"
43 "\tjl 1f\n"
44 "\tincl %0\n"
45 "\tjmp 2f\n"
46 "1:\tdec %0\n"
47 "2:\n"
48 :"=r" (ret):"r" (Addend), "0" (0): "memory"
49 );
50 return ret;
51 }
52
53 /************************************************************************
54 * InterlockedDecrement *
55 * *
56 * InterlockedIncrement adds 1 to a long variable and returns *
57 * - a negative number if the result < 0 *
58 * - zero if the result == 0 *
59 * - a positive number if the result > 0 *
60 * *
61 * The returned number need not be equal to the result!!!! *
62 ************************************************************************/
63
64 LONG
65 STDCALL
66 InterlockedDecrement(LPLONG lpAddend)
67 {
68 long ret;
69 __asm__
70 (
71 "\tlock\n" /* for SMP systems */
72 "\tdecl (%1)\n"
73 "\tje 2f\n"
74 "\tjl 1f\n"
75 "\tincl %0\n"
76 "\tjmp 2f\n"
77 "1:\tdec %0\n"
78 "2:\n"
79 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
80 );
81 return ret;
82
83
84 }
85
86 /************************************************************************
87 * InterlockedExchange
88 *
89 * Atomically exchanges a pair of values.
90 *
91 * RETURNS
92 * Prior value of value pointed to by Target
93 */
94
95 LONG
96 STDCALL
97 InterlockedExchange(LPLONG target, LONG value )
98 {
99
100 long ret;
101 __asm__ ( /* lock for SMP systems */
102 "lock\n\txchgl %0,(%1)"
103 :"=r" (ret):"r" (target), "0" (value):"memory" );
104 return ret;
105
106
107 }
108
109 /************************************************************************
110 * InterlockedCompareExchange
111 *
112 * Atomically compares Destination and Comperand, and if found equal exchanges
113 * the value of Destination with Exchange
114 *
115 * RETURNS
116 * Prior value of value pointed to by Destination
117 */
118 PVOID
119 STDCALL
120 InterlockedCompareExchange(
121 PVOID *Destination,
122 PVOID Exchange,
123 PVOID Comperand )
124 {
125 PVOID ret;
126 __asm__ ( /* lock for SMP systems */
127 "lock\n\t"
128 "cmpxchgl %2,(%1)"
129 :"=r" (ret)
130 :"r" (Destination),"r" (Exchange), "0" (Comperand)
131 :"memory" );
132 return ret;
133
134 }
135
136 /************************************************************************
137 * InterlockedExchangeAdd
138 *
139 * Atomically adds Increment to Addend and returns the previous value of
140 * Addend
141 *
142 * RETURNS
143 * Prior value of value pointed to by Addend
144 */
145 LONG
146 STDCALL
147 InterlockedExchangeAdd(
148 PLONG Addend,
149 LONG Increment
150 )
151 {
152
153 LONG ret;
154 __asm__ ( /* lock for SMP systems */
155 "lock\n\t"
156 "xaddl %0,(%1)"
157 :"=r" (ret)
158 :"r" (Addend), "0" (Increment)
159 :"memory" );
160 return ret;
161
162 }