summaryrefslogtreecommitdiff
path: root/MdePkg/Library
diff options
context:
space:
mode:
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>2007-11-30 02:33:37 +0000
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>2007-11-30 02:33:37 +0000
commita82da388bfd838ba141d3643689de68e6c48e900 (patch)
tree794ac24567e59f9cdfcdcb636546c5e6f8dfb509 /MdePkg/Library
parent9a6b83a4adae9947d95df22cee8b16ae6ebe024d (diff)
downloadedk2-platforms-a82da388bfd838ba141d3643689de68e6c48e900.tar.xz
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')
-rw-r--r--MdePkg/Library/BaseLib/Synchronization.c63
-rw-r--r--MdePkg/Library/BaseLib/SynchronizationGcc.c63
-rw-r--r--MdePkg/Library/BaseLib/SynchronizationMsc.c63
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;
}