1 /** @file
2   Provides synchronization functions.
3 
4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #ifndef __SYNCHRONIZATION_LIB__
16 #define __SYNCHRONIZATION_LIB__
17 
18 ///
19 /// Definitions for SPIN_LOCK
20 ///
21 typedef volatile UINTN              SPIN_LOCK;
22 
23 
24 /**
25   Retrieves the architecture-specific spin lock alignment requirements for
26   optimal spin lock performance.
27 
28   This function retrieves the spin lock alignment requirements for optimal
29   performance on a given CPU architecture. The spin lock alignment is byte alignment.
30   It must be a power of two and is returned by this function. If there are no alignment
31   requirements, then 1 must be returned. The spin lock synchronization
32   functions must function correctly if the spin lock size and alignment values
33   returned by this function are not used at all. These values are hints to the
34   consumers of the spin lock synchronization functions to obtain optimal spin
35   lock performance.
36 
37   @return The architecture-specific spin lock alignment.
38 
39 **/
40 UINTN
41 EFIAPI
42 GetSpinLockProperties (
43   VOID
44   );
45 
46 
47 /**
48   Initializes a spin lock to the released state and returns the spin lock.
49 
50   This function initializes the spin lock specified by SpinLock to the released
51   state, and returns SpinLock. Optimal performance can be achieved by calling
52   GetSpinLockProperties() to determine the size and alignment requirements for
53   SpinLock.
54 
55   If SpinLock is NULL, then ASSERT().
56 
57   @param  SpinLock  A pointer to the spin lock to initialize to the released
58                     state.
59 
60   @return SpinLock in release state.
61 
62 **/
63 SPIN_LOCK *
64 EFIAPI
65 InitializeSpinLock (
66   OUT      SPIN_LOCK                 *SpinLock
67   );
68 
69 
70 /**
71   Waits until a spin lock can be placed in the acquired state.
72 
73   This function checks the state of the spin lock specified by SpinLock. If
74   SpinLock is in the released state, then this function places SpinLock in the
75   acquired state and returns SpinLock. Otherwise, this function waits
76   indefinitely for the spin lock to be released, and then places it in the
77   acquired state and returns SpinLock. All state transitions of SpinLock must
78   be performed using MP safe mechanisms.
79 
80   If SpinLock is NULL, then ASSERT().
81   If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().
82   If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in
83   PcdSpinLockTimeout microseconds, then ASSERT().
84 
85   @param  SpinLock  A pointer to the spin lock to place in the acquired state.
86 
87   @return SpinLock acquired lock.
88 
89 **/
90 SPIN_LOCK *
91 EFIAPI
92 AcquireSpinLock (
93   IN OUT  SPIN_LOCK                 *SpinLock
94   );
95 
96 
97 /**
98   Attempts to place a spin lock in the acquired state.
99 
100   This function checks the state of the spin lock specified by SpinLock. If
101   SpinLock is in the released state, then this function places SpinLock in the
102   acquired state and returns TRUE. Otherwise, FALSE is returned. All state
103   transitions of SpinLock must be performed using MP safe mechanisms.
104 
105   If SpinLock is NULL, then ASSERT().
106   If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().
107 
108   @param  SpinLock  A pointer to the spin lock to place in the acquired state.
109 
110   @retval TRUE  SpinLock was placed in the acquired state.
111   @retval FALSE SpinLock could not be acquired.
112 
113 **/
114 BOOLEAN
115 EFIAPI
116 AcquireSpinLockOrFail (
117   IN OUT  SPIN_LOCK                 *SpinLock
118   );
119 
120 
121 /**
122   Releases a spin lock.
123 
124   This function places the spin lock specified by SpinLock in the release state
125   and returns SpinLock.
126 
127   If SpinLock is NULL, then ASSERT().
128   If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().
129 
130   @param  SpinLock  A pointer to the spin lock to release.
131 
132   @return SpinLock released lock.
133 
134 **/
135 SPIN_LOCK *
136 EFIAPI
137 ReleaseSpinLock (
138   IN OUT  SPIN_LOCK                 *SpinLock
139   );
140 
141 
142 /**
143   Performs an atomic increment of a 32-bit unsigned integer.
144 
145   Performs an atomic increment of the 32-bit unsigned integer specified by
146   Value and returns the incremented value. The increment operation must be
147   performed using MP safe mechanisms. The state of the return value is not
148   guaranteed to be MP safe.
149 
150   If Value is NULL, then ASSERT().
151 
152   @param  Value A pointer to the 32-bit value to increment.
153 
154   @return The incremented value.
155 
156 **/
157 UINT32
158 EFIAPI
159 InterlockedIncrement (
160   IN      volatile UINT32           *Value
161   );
162 
163 
164 /**
165   Performs an atomic decrement of a 32-bit unsigned integer.
166 
167   Performs an atomic decrement of the 32-bit unsigned integer specified by
168   Value and returns the decremented value. The decrement operation must be
169   performed using MP safe mechanisms. The state of the return value is not
170   guaranteed to be MP safe.
171 
172   If Value is NULL, then ASSERT().
173 
174   @param  Value A pointer to the 32-bit value to decrement.
175 
176   @return The decremented value.
177 
178 **/
179 UINT32
180 EFIAPI
181 InterlockedDecrement (
182   IN      volatile UINT32           *Value
183   );
184 
185 
186 /**
187   Performs an atomic compare exchange operation on a 16-bit unsigned integer.
188 
189   Performs an atomic compare exchange operation on the 16-bit unsigned integer
190   specified by Value.  If Value is equal to CompareValue, then Value is set to
191   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
192   then Value is returned.  The compare exchange operation must be performed using
193   MP safe mechanisms.
194 
195   If Value is NULL, then ASSERT().
196 
197   @param  Value         A pointer to the 16-bit value for the compare exchange
198                         operation.
199   @param  CompareValue  16-bit value used in compare operation.
200   @param  ExchangeValue 16-bit value used in exchange operation.
201 
202   @return The original *Value before exchange.
203 **/
204 UINT16
205 EFIAPI
206 InterlockedCompareExchange16 (
207   IN OUT  volatile UINT16           *Value,
208   IN      UINT16                    CompareValue,
209   IN      UINT16                    ExchangeValue
210   );
211 
212 /**
213   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
214 
215   Performs an atomic compare exchange operation on the 32-bit unsigned integer
216   specified by Value.  If Value is equal to CompareValue, then Value is set to
217   ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,
218   then Value is returned.  The compare exchange operation must be performed using
219   MP safe mechanisms.
220 
221   If Value is NULL, then ASSERT().
222 
223   @param  Value         A pointer to the 32-bit value for the compare exchange
224                         operation.
225   @param  CompareValue  32-bit value used in compare operation.
226   @param  ExchangeValue 32-bit value used in exchange operation.
227 
228   @return The original *Value before exchange.
229 
230 **/
231 UINT32
232 EFIAPI
233 InterlockedCompareExchange32 (
234   IN OUT  volatile UINT32           *Value,
235   IN      UINT32                    CompareValue,
236   IN      UINT32                    ExchangeValue
237   );
238 
239 
240 /**
241   Performs an atomic compare exchange operation on a 64-bit unsigned integer.
242 
243   Performs an atomic compare exchange operation on the 64-bit unsigned integer specified
244   by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and
245   CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned.
246   The compare exchange operation must be performed using MP safe mechanisms.
247 
248   If Value is NULL, then ASSERT().
249 
250   @param  Value         A pointer to the 64-bit value for the compare exchange
251                         operation.
252   @param  CompareValue  64-bit value used in compare operation.
253   @param  ExchangeValue 64-bit value used in exchange operation.
254 
255   @return The original *Value before exchange.
256 
257 **/
258 UINT64
259 EFIAPI
260 InterlockedCompareExchange64 (
261   IN OUT  volatile UINT64           *Value,
262   IN      UINT64                    CompareValue,
263   IN      UINT64                    ExchangeValue
264   );
265 
266 
267 /**
268   Performs an atomic compare exchange operation on a pointer value.
269 
270   Performs an atomic compare exchange operation on the pointer value specified
271   by Value. If Value is equal to CompareValue, then Value is set to
272   ExchangeValue and CompareValue is returned. If Value is not equal to
273   CompareValue, then Value is returned. The compare exchange operation must be
274   performed using MP safe mechanisms.
275 
276   If Value is NULL, then ASSERT().
277 
278   @param  Value         A pointer to the pointer value for the compare exchange
279                         operation.
280   @param  CompareValue  Pointer value used in compare operation.
281   @param  ExchangeValue Pointer value used in exchange operation.
282 
283   @return The original *Value before exchange.
284 **/
285 VOID *
286 EFIAPI
287 InterlockedCompareExchangePointer (
288   IN OUT  VOID                      * volatile *Value,
289   IN      VOID                      *CompareValue,
290   IN      VOID                      *ExchangeValue
291   );
292 
293 #endif
294 
295 
296