:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / 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 PVOID 
120 STDCALL 
121 InterlockedCompareExchange(
122             PVOID *Destination, 
123             PVOID Exchange,     
124             PVOID Comperand     ) 
125 {       
126         PVOID ret;
127         __asm__ ( /* lock for SMP systems */
128                   "lock\n\t"
129                   "cmpxchgl %2,(%1)"
130                   :"=r" (ret)
131                   :"r" (Destination),"r" (Exchange), "0" (Comperand)
132                   :"memory" );
133         return ret;
134
135 }
136
137 /************************************************************************
138  *           InterlockedExchangeAdd                     
139  *
140  * Atomically adds Increment to Addend and returns the previous value of
141  * Addend
142  *
143  * RETURNS
144  *      Prior value of value pointed to by Addend
145  */
146 LONG 
147 STDCALL 
148 InterlockedExchangeAdd(
149             PLONG Addend, 
150             LONG Increment 
151
152 {
153
154         LONG ret;
155         __asm__ ( /* lock for SMP systems */
156                   "lock\n\t"
157                   "xaddl %0,(%1)"
158                   :"=r" (ret)
159                   :"r" (Addend), "0" (Increment)
160                   :"memory" );
161         return ret;
162
163 }