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 (); - ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ())); + 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 (); + } } 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 (); - ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ())); + 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 (); + } } 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 (); - ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ())); + 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 (); + } } return SpinLock; }