TianoCore EDK2 master
Synchronization.c
Go to the documentation of this file.
1
10
11#define SPIN_LOCK_RELEASED ((UINTN) 1)
12#define SPIN_LOCK_ACQUIRED ((UINTN) 2)
13
31EFIAPI
33 VOID
34 )
35{
36 return 32;
37}
38
56EFIAPI
58 OUT SPIN_LOCK *SpinLock
59 )
60{
61 ASSERT (SpinLock != NULL);
62 *SpinLock = SPIN_LOCK_RELEASED;
63 return SpinLock;
64}
65
87EFIAPI
89 IN OUT SPIN_LOCK *SpinLock
90 )
91{
92 UINT64 Current;
93 UINT64 Previous;
94 UINT64 Total;
95 UINT64 Start;
96 UINT64 End;
97 UINT64 Timeout;
98 INT64 Cycle;
99 INT64 Delta;
100
101 if (PcdGet32 (PcdSpinLockTimeout) == 0) {
102 while (!AcquireSpinLockOrFail (SpinLock)) {
103 CpuPause ();
104 }
105 } else if (!AcquireSpinLockOrFail (SpinLock)) {
106 //
107 // Get the current timer value
108 //
109 Current = GetPerformanceCounter ();
110
111 //
112 // Initialize local variables
113 //
114 Start = 0;
115 End = 0;
116 Total = 0;
117
118 //
119 // Retrieve the performance counter properties and compute the number of performance
120 // counter ticks required to reach the timeout
121 //
122 Timeout = DivU64x32 (
123 MultU64x32 (
124 GetPerformanceCounterProperties (&Start, &End),
125 PcdGet32 (PcdSpinLockTimeout)
126 ),
127 1000000
128 );
129 Cycle = End - Start;
130 if (Cycle < 0) {
131 Cycle = -Cycle;
132 }
133
134 Cycle++;
135
136 while (!AcquireSpinLockOrFail (SpinLock)) {
137 CpuPause ();
138 Previous = Current;
139 Current = GetPerformanceCounter ();
140 Delta = (INT64)(Current - Previous);
141 if (Start > End) {
142 Delta = -Delta;
143 }
144
145 if (Delta < 0) {
146 Delta += Cycle;
147 }
148
149 Total += Delta;
150 ASSERT (Total < Timeout);
151 }
152 }
153
154 return SpinLock;
155}
156
174BOOLEAN
175EFIAPI
177 IN OUT SPIN_LOCK *SpinLock
178 )
179{
180 SPIN_LOCK LockValue;
181
182 ASSERT (SpinLock != NULL);
183
184 LockValue = *SpinLock;
185 ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue);
186
187 return (BOOLEAN)(
189 (VOID **)SpinLock,
190 (VOID *)SPIN_LOCK_RELEASED,
191 (VOID *)SPIN_LOCK_ACQUIRED
192 ) == (VOID *)SPIN_LOCK_RELEASED
193 );
194}
195
210SPIN_LOCK *
211EFIAPI
213 IN OUT SPIN_LOCK *SpinLock
214 )
215{
216 SPIN_LOCK LockValue;
217
218 ASSERT (SpinLock != NULL);
219
220 LockValue = *SpinLock;
221 ASSERT (SPIN_LOCK_ACQUIRED == LockValue || SPIN_LOCK_RELEASED == LockValue);
222
223 *SpinLock = SPIN_LOCK_RELEASED;
224 return SpinLock;
225}
226
241UINT32
242EFIAPI
244 IN volatile UINT32 *Value
245 )
246{
247 ASSERT (Value != NULL);
248 return InternalSyncIncrement (Value);
249}
250
265UINT32
266EFIAPI
268 IN volatile UINT32 *Value
269 )
270{
271 ASSERT (Value != NULL);
272 return InternalSyncDecrement (Value);
273}
274
294UINT16
295EFIAPI
297 IN OUT volatile UINT16 *Value,
298 IN UINT16 CompareValue,
299 IN UINT16 ExchangeValue
300 )
301{
302 ASSERT (Value != NULL);
303 return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
304}
305
325UINT32
326EFIAPI
328 IN OUT volatile UINT32 *Value,
329 IN UINT32 CompareValue,
330 IN UINT32 ExchangeValue
331 )
332{
333 ASSERT (Value != NULL);
334 return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue);
335}
336
355UINT64
356EFIAPI
358 IN OUT volatile UINT64 *Value,
359 IN UINT64 CompareValue,
360 IN UINT64 ExchangeValue
361 )
362{
363 ASSERT (Value != NULL);
364 return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue);
365}
366
385VOID *
386EFIAPI
388 IN OUT VOID *volatile *Value,
389 IN VOID *CompareValue,
390 IN VOID *ExchangeValue
391 )
392{
393 UINT8 SizeOfValue;
394
395 SizeOfValue = sizeof (*Value);
396
397 switch (SizeOfValue) {
398 case sizeof (UINT32):
399 return (VOID *)(UINTN)InterlockedCompareExchange32 (
400 (volatile UINT32 *)Value,
401 (UINT32)(UINTN)CompareValue,
402 (UINT32)(UINTN)ExchangeValue
403 );
404 case sizeof (UINT64):
405 return (VOID *)(UINTN)InterlockedCompareExchange64 (
406 (volatile UINT64 *)Value,
407 (UINT64)(UINTN)CompareValue,
408 (UINT64)(UINTN)ExchangeValue
409 );
410 default:
411 ASSERT (FALSE);
412 return NULL;
413 }
414}
UINT64 UINTN
UINT64 EFIAPI GetPerformanceCounterProperties(OUT UINT64 *StartValue OPTIONAL, OUT UINT64 *EndValue OPTIONAL)
UINT64 EFIAPI GetPerformanceCounter(VOID)
#define NULL
Definition: Base.h:312
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
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
#define ASSERT(Expression)
Definition: DebugLib.h:391
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 PcdGet32(TokenName)
Definition: PcdLib.h:362
UINT32 EFIAPI InterlockedIncrement(IN volatile UINT32 *Value)
VOID *EFIAPI InterlockedCompareExchangePointer(IN OUT VOID *volatile *Value, IN VOID *CompareValue, IN VOID *ExchangeValue)
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)
volatile UINTN SPIN_LOCK