49f8b76ed9316e9b0a64c43e51ca95dca28a3fc6
[reactos.git] / reactos / lib / ntdll / rtl / intrlck.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/ntdll/rtl/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 * Copied from kernel32
16 */
17
18
19 /************************************************************************
20 * InterlockedIncrement *
21 * *
22 * InterlockedIncrement adds 1 to a long variable and returns *
23 * - a negative number if the result < 0 *
24 * - zero if the result == 0 *
25 * - a positive number if the result > 0 *
26 * *
27 * The returned number need not be equal to the result!!!! *
28 * note: *
29 * *
30 ************************************************************************/
31
32 #include <windows.h>
33
34 LONG
35 STDCALL
36 InterlockedIncrement(PLONG Addend)
37 {
38 long ret = 0;
39 __asm__
40 (
41 "\tlock\n" /* for SMP systems */
42 "\tincl (%1)\n"
43 "\tje 2f\n"
44 "\tjl 1f\n"
45 "\tincl %0\n"
46 "\tjmp 2f\n"
47 "1:\tdec %0\n"
48 "2:\n"
49 :"=r" (ret):"r" (Addend), "0" (0): "memory"
50 );
51 return ret;
52 }
53
54 /************************************************************************
55 * InterlockedDecrement *
56 * *
57 * InterlockedIncrement adds 1 to a long variable and returns *
58 * - a negative number if the result < 0 *
59 * - zero if the result == 0 *
60 * - a positive number if the result > 0 *
61 * *
62 * The returned number need not be equal to the result!!!! *
63 ************************************************************************/
64
65 LONG
66 STDCALL
67 InterlockedDecrement(LPLONG lpAddend)
68 {
69 long ret;
70 __asm__
71 (
72 "\tlock\n" /* for SMP systems */
73 "\tdecl (%1)\n"
74 "\tje 2f\n"
75 "\tjl 1f\n"
76 "\tincl %0\n"
77 "\tjmp 2f\n"
78 "1:\tdec %0\n"
79 "2:\n"
80 :"=r" (ret):"r" (lpAddend), "0" (0): "memory"
81 );
82 return ret;
83
84
85 }
86
87 /************************************************************************
88 * InterlockedExchange
89 *
90 * Atomically exchanges a pair of values.
91 *
92 * RETURNS
93 * Prior value of value pointed to by Target
94 */
95
96 LONG
97 STDCALL
98 InterlockedExchange(LPLONG target, LONG value )
99 {
100
101 long ret;
102 __asm__ ( /* lock for SMP systems */
103 "lock\n\txchgl %0,(%1)"
104 :"=r" (ret):"r" (target), "0" (value):"memory" );
105 return ret;
106
107
108 }
109
110 /************************************************************************
111 * InterlockedCompareExchange
112 *
113 * Atomically compares Destination and Comperand, and if found equal exchanges
114 * the value of Destination with Exchange
115 *
116 * RETURNS
117 * Prior value of value pointed to by Destination
118 */
119 LONG
120 STDCALL
121 InterlockedCompareExchange(PLONG Destination,
122 LONG Exchange,
123 LONG 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 }