TianoCore EDK2 master
Loading...
Searching...
No Matches
SynchronizationMsc.c
Go to the documentation of this file.
1
10
15void
17 void
18 );
19
20#pragma intrinsic(_ReadWriteBarrier)
21
22#define SPIN_LOCK_RELEASED ((UINTN) 1)
23#define SPIN_LOCK_ACQUIRED ((UINTN) 2)
24
42EFIAPI
44 VOID
45 )
46{
48}
49
67EFIAPI
69 OUT SPIN_LOCK *SpinLock
70 )
71{
72 ASSERT (SpinLock != NULL);
73
75 *SpinLock = SPIN_LOCK_RELEASED;
77
78 return SpinLock;
79}
80
101SPIN_LOCK *
102EFIAPI
104 IN OUT SPIN_LOCK *SpinLock
105 )
106{
107 UINT64 Current;
108 UINT64 Previous;
109 UINT64 Total;
110 UINT64 Start;
111 UINT64 End;
112 UINT64 Timeout;
113 INT64 Cycle;
114 INT64 Delta;
115
116 if (PcdGet32 (PcdSpinLockTimeout) == 0) {
117 while (!AcquireSpinLockOrFail (SpinLock)) {
118 CpuPause ();
119 }
120 } else if (!AcquireSpinLockOrFail (SpinLock)) {
121 //
122 // Get the current timer value
123 //
124 Current = GetPerformanceCounter ();
125
126 //
127 // Initialize local variables
128 //
129 Start = 0;
130 End = 0;
131 Total = 0;
132
133 //
134 // Retrieve the performance counter properties and compute the number of performance
135 // counter ticks required to reach the timeout
136 //
137 Timeout = DivU64x32 (
138 MultU64x32 (
139 GetPerformanceCounterProperties (&Start, &End),
140 PcdGet32 (PcdSpinLockTimeout)
141 ),
142 1000000
143 );
144 Cycle = End - Start;
145 if (Cycle < 0) {
146 Cycle = -Cycle;
147 }
148
149 Cycle++;
150
151 while (!AcquireSpinLockOrFail (SpinLock)) {
152 CpuPause ();
153 Previous = Current;
154 Current = GetPerformanceCounter ();
155 Delta = (INT64)(Current - Previous);
156 if (Start > End) {
157 Delta = -Delta;
158 }
159
160 if (Delta < 0) {
161 Delta += Cycle;
162 }
163
164 Total += Delta;
165 ASSERT (Total < Timeout);
166 }
167 }
168
169 return SpinLock;
170}
171
189BOOLEAN
190EFIAPI
192 IN OUT SPIN_LOCK *SpinLock
193 )
194{
195 SPIN_LOCK LockValue;
196 VOID *Result;
197
198 ASSERT (SpinLock != NULL);
199
200 LockValue = *SpinLock;
201 ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);
202
205 (VOID **)SpinLock,
206 (VOID *)SPIN_LOCK_RELEASED,
207 (VOID *)SPIN_LOCK_ACQUIRED
208 );
209
211 return (BOOLEAN)(Result == (VOID *)SPIN_LOCK_RELEASED);
212}
213
228SPIN_LOCK *
229EFIAPI
231 IN OUT SPIN_LOCK *SpinLock
232 )
233{
234 SPIN_LOCK LockValue;
235
236 ASSERT (SpinLock != NULL);
237
238 LockValue = *SpinLock;
239 ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);
240
242 *SpinLock = SPIN_LOCK_RELEASED;
244
245 return SpinLock;
246}
247
262UINT32
263EFIAPI
265 IN volatile UINT32 *Value
266 )
267{
268 ASSERT (Value != NULL);
269 return InternalSyncIncrement (Value);
270}
271
286UINT32
287EFIAPI
289 IN volatile UINT32 *Value
290 )
291{
292 ASSERT (Value != NULL);
293 return InternalSyncDecrement (Value);
294}
295
315UINT16
316EFIAPI
318 IN OUT volatile UINT16 *Value,
319 IN UINT16 CompareValue,
320 IN UINT16 ExchangeValue
321 )
322{
323 ASSERT (Value != NULL);
324 return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
325}
326
346UINT32
347EFIAPI
349 IN OUT volatile UINT32 *Value,
350 IN UINT32 CompareValue,
351 IN UINT32 ExchangeValue
352 )
353{
354 ASSERT (Value != NULL);
355 return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue);
356}
357
376UINT64
377EFIAPI
379 IN OUT volatile UINT64 *Value,
380 IN UINT64 CompareValue,
381 IN UINT64 ExchangeValue
382 )
383{
384 ASSERT (Value != NULL);
385 return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue);
386}
387
406VOID *
407EFIAPI
409 IN OUT VOID *volatile *Value,
410 IN VOID *CompareValue,
411 IN VOID *ExchangeValue
412 )
413{
414 UINT8 SizeOfValue;
415
416 SizeOfValue = (UINT8)sizeof (*Value);
417
418 switch (SizeOfValue) {
419 case sizeof (UINT32):
420 return (VOID *)(UINTN)InterlockedCompareExchange32 (
421 (volatile UINT32 *)Value,
422 (UINT32)(UINTN)CompareValue,
423 (UINT32)(UINTN)ExchangeValue
424 );
425 case sizeof (UINT64):
426 return (VOID *)(UINTN)InterlockedCompareExchange64 (
427 (volatile UINT64 *)Value,
428 (UINT64)(UINTN)CompareValue,
429 (UINT64)(UINTN)ExchangeValue
430 );
431 default:
432 ASSERT (FALSE);
433 return NULL;
434 }
435}
UINT64 UINTN
UINT64 EFIAPI GetPerformanceCounterProperties(OUT UINT64 *StartValue OPTIONAL, OUT UINT64 *EndValue OPTIONAL)
UINT64 EFIAPI GetPerformanceCounter(VOID)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
VOID EFIAPI CpuPause(VOID)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINTN InternalGetSpinLockProperties(VOID)
UINT32 EFIAPI InternalSyncDecrement(IN volatile UINT32 *Value)
UINT32 EFIAPI InternalSyncIncrement(IN volatile UINT32 *Value)
UINT64 EFIAPI InternalSyncCompareExchange64(IN volatile UINT64 *Value, IN UINT64 CompareValue, IN UINT64 ExchangeValue)
UINT32 EFIAPI InternalSyncCompareExchange32(IN volatile UINT32 *Value, IN UINT32 CompareValue, IN UINT32 ExchangeValue)
UINT16 EFIAPI InternalSyncCompareExchange16(IN volatile UINT16 *Value, IN UINT16 CompareValue, IN UINT16 ExchangeValue)
#define NULL
Definition: Base.h:319
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
volatile UINTN SPIN_LOCK
UINT32 EFIAPI InterlockedIncrement(IN volatile UINT32 *Value)
VOID *EFIAPI InterlockedCompareExchangePointer(IN OUT VOID *volatile *Value, IN VOID *CompareValue, IN VOID *ExchangeValue)
void _ReadWriteBarrier(void)
SPIN_LOCK *EFIAPI AcquireSpinLock(IN OUT SPIN_LOCK *SpinLock)
UINTN EFIAPI GetSpinLockProperties(VOID)
UINT32 EFIAPI InterlockedCompareExchange32(IN OUT volatile UINT32 *Value, IN UINT32 CompareValue, IN UINT32 ExchangeValue)
UINT16 EFIAPI InterlockedCompareExchange16(IN OUT volatile UINT16 *Value, IN UINT16 CompareValue, IN UINT16 ExchangeValue)
UINT32 EFIAPI InterlockedDecrement(IN volatile UINT32 *Value)
SPIN_LOCK *EFIAPI InitializeSpinLock(OUT SPIN_LOCK *SpinLock)
SPIN_LOCK *EFIAPI ReleaseSpinLock(IN OUT SPIN_LOCK *SpinLock)
BOOLEAN EFIAPI AcquireSpinLockOrFail(IN OUT SPIN_LOCK *SpinLock)
UINT64 EFIAPI InterlockedCompareExchange64(IN OUT volatile UINT64 *Value, IN UINT64 CompareValue, IN UINT64 ExchangeValue)