diff options
author | mdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-11-30 02:33:37 +0000 |
---|---|---|
committer | mdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-11-30 02:33:37 +0000 |
commit | a82da388bfd838ba141d3643689de68e6c48e900 (patch) | |
tree | 794ac24567e59f9cdfcdcb636546c5e6f8dfb509 /MdePkg/Library/BaseLib | |
parent | 9a6b83a4adae9947d95df22cee8b16ae6ebe024d (diff) | |
download | edk2-a82da388bfd838ba141d3643689de68e6c48e900.tar.gz edk2-a82da388bfd838ba141d3643689de68e6c48e900.tar.bz2 edk2-a82da388bfd838ba141d3643689de68e6c48e900.zip |
Fix timeout logic in AcquireSpinLock(). It could fail if the end time computed was larger than the roll over value of the performance counter. The timeout logic now accumulates the total time elapsed to determine if the timeout has been exceeded.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4345 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdePkg/Library/BaseLib')
-rw-r--r-- | MdePkg/Library/BaseLib/Synchronization.c | 63 | ||||
-rw-r--r-- | MdePkg/Library/BaseLib/SynchronizationGcc.c | 63 | ||||
-rw-r--r-- | MdePkg/Library/BaseLib/SynchronizationMsc.c | 63 |
3 files changed, 141 insertions, 48 deletions
diff --git a/MdePkg/Library/BaseLib/Synchronization.c b/MdePkg/Library/BaseLib/Synchronization.c index b7c89732e0..f1565db3fd 100644 --- a/MdePkg/Library/BaseLib/Synchronization.c +++ b/MdePkg/Library/BaseLib/Synchronization.c @@ -101,15 +101,32 @@ AcquireSpinLock ( IN OUT SPIN_LOCK *SpinLock
)
{
- UINT64 Tick;
- UINT64 Start, End;
- UINT64 Timeout;
+ UINT64 Current;
+ UINT64 Previous;
+ UINT64 Total;
+ UINT64 Start;
+ UINT64 End;
+ UINT64 Timeout;
+ INT64 Cycle;
+ INT64 Delta;
- Tick = 0;
- Start = 0;
- End = 0;
if (PcdGet32 (PcdSpinLockTimeout) > 0) {
- Tick = GetPerformanceCounter ();
+ //
+ // Get the current timer value
+ //
+ Current = GetPerformanceCounter();
+
+ //
+ // Initialize local variables
+ //
+ Start = 0;
+ End = 0;
+ Total = 0;
+
+ //
+ // Retrieve the performance counter properties and compute the number of performance
+ // counter ticks required to reach the timeout
+ //
Timeout = DivU64x32 (
MultU64x32 (
GetPerformanceCounterProperties (&Start, &End),
@@ -117,16 +134,30 @@ AcquireSpinLock ( ),
1000000
);
- if (Start < End) {
- Tick += Timeout;
- } else {
- Tick -= Timeout;
+ Cycle = End - Start;
+ if (Cycle < 0) {
+ Cycle = -Cycle;
+ }
+ Cycle++;
+
+ while (!AcquireSpinLockOrFail (SpinLock)) {
+ CpuPause ();
+ Previous = Current;
+ Current = GetPerformanceCounter();
+ Delta = (INT64) (Current - Previous);
+ if (Start > End) {
+ Delta = -Delta;
+ }
+ if (Delta < 0) {
+ Delta += Cycle;
+ }
+ Total += Delta;
+ ASSERT (Total < Timeout);
+ }
+ } else {
+ while (!AcquireSpinLockOrFail (SpinLock)) {
+ CpuPause ();
}
- }
-
- while (!AcquireSpinLockOrFail (SpinLock)) {
- CpuPause ();
- ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));
}
return SpinLock;
}
diff --git a/MdePkg/Library/BaseLib/SynchronizationGcc.c b/MdePkg/Library/BaseLib/SynchronizationGcc.c index 1681b4cf44..4c30dbc4b1 100644 --- a/MdePkg/Library/BaseLib/SynchronizationGcc.c +++ b/MdePkg/Library/BaseLib/SynchronizationGcc.c @@ -110,15 +110,32 @@ AcquireSpinLock ( IN OUT SPIN_LOCK *SpinLock
)
{
- UINT64 Tick;
- UINT64 Start, End;
- UINT64 Timeout;
+ UINT64 Current;
+ UINT64 Previous;
+ UINT64 Total;
+ UINT64 Start;
+ UINT64 End;
+ UINT64 Timeout;
+ INT64 Cycle;
+ INT64 Delta;
- Tick = 0;
- Start = 0;
- End = 0;
if (PcdGet32 (PcdSpinLockTimeout) > 0) {
- Tick = GetPerformanceCounter ();
+ //
+ // Get the current timer value
+ //
+ Current = GetPerformanceCounter();
+
+ //
+ // Initialize local variables
+ //
+ Start = 0;
+ End = 0;
+ Total = 0;
+
+ //
+ // Retrieve the performance counter properties and compute the number of performance
+ // counter ticks required to reach the timeout
+ //
Timeout = DivU64x32 (
MultU64x32 (
GetPerformanceCounterProperties (&Start, &End),
@@ -126,16 +143,30 @@ AcquireSpinLock ( ),
1000000
);
- if (Start < End) {
- Tick += Timeout;
- } else {
- Tick -= Timeout;
+ Cycle = End - Start;
+ if (Cycle < 0) {
+ Cycle = -Cycle;
+ }
+ Cycle++;
+
+ while (!AcquireSpinLockOrFail (SpinLock)) {
+ CpuPause ();
+ Previous = Current;
+ Current = GetPerformanceCounter();
+ Delta = (INT64) (Current - Previous);
+ if (Start > End) {
+ Delta = -Delta;
+ }
+ if (Delta < 0) {
+ Delta += Cycle;
+ }
+ Total += Delta;
+ ASSERT (Total < Timeout);
+ }
+ } else {
+ while (!AcquireSpinLockOrFail (SpinLock)) {
+ CpuPause ();
}
- }
-
- while (!AcquireSpinLockOrFail (SpinLock)) {
- CpuPause ();
- ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));
}
return SpinLock;
}
diff --git a/MdePkg/Library/BaseLib/SynchronizationMsc.c b/MdePkg/Library/BaseLib/SynchronizationMsc.c index 9f1ec19383..0bc60259b1 100644 --- a/MdePkg/Library/BaseLib/SynchronizationMsc.c +++ b/MdePkg/Library/BaseLib/SynchronizationMsc.c @@ -112,15 +112,32 @@ AcquireSpinLock ( IN OUT SPIN_LOCK *SpinLock
)
{
- UINT64 Tick;
- UINT64 Start, End;
- UINT64 Timeout;
+ UINT64 Current;
+ UINT64 Previous;
+ UINT64 Total;
+ UINT64 Start;
+ UINT64 End;
+ UINT64 Timeout;
+ INT64 Cycle;
+ INT64 Delta;
- Tick = 0;
- Start = 0;
- End = 0;
if (PcdGet32 (PcdSpinLockTimeout) > 0) {
- Tick = GetPerformanceCounter ();
+ //
+ // Get the current timer value
+ //
+ Current = GetPerformanceCounter();
+
+ //
+ // Initialize local variables
+ //
+ Start = 0;
+ End = 0;
+ Total = 0;
+
+ //
+ // Retrieve the performance counter properties and compute the number of performance
+ // counter ticks required to reach the timeout
+ //
Timeout = DivU64x32 (
MultU64x32 (
GetPerformanceCounterProperties (&Start, &End),
@@ -128,16 +145,30 @@ AcquireSpinLock ( ),
1000000
);
- if (Start < End) {
- Tick += Timeout;
- } else {
- Tick -= Timeout;
+ Cycle = End - Start;
+ if (Cycle < 0) {
+ Cycle = -Cycle;
+ }
+ Cycle++;
+
+ while (!AcquireSpinLockOrFail (SpinLock)) {
+ CpuPause ();
+ Previous = Current;
+ Current = GetPerformanceCounter();
+ Delta = (INT64) (Current - Previous);
+ if (Start > End) {
+ Delta = -Delta;
+ }
+ if (Delta < 0) {
+ Delta += Cycle;
+ }
+ Total += Delta;
+ ASSERT (Total < Timeout);
+ }
+ } else {
+ while (!AcquireSpinLockOrFail (SpinLock)) {
+ CpuPause ();
}
- }
-
- while (!AcquireSpinLockOrFail (SpinLock)) {
- CpuPause ();
- ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));
}
return SpinLock;
}
|