:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / 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 <windows.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 }