]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Fix timeout logic in AcquireSpinLock(). It could fail if the end time computed was...
authormdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 30 Nov 2007 02:33:37 +0000 (02:33 +0000)
committermdkinney <mdkinney@6f19259b-4bc3-4df7-8a09-765794883524>
Fri, 30 Nov 2007 02:33:37 +0000 (02:33 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4345 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Library/BaseLib/Synchronization.c
MdePkg/Library/BaseLib/SynchronizationGcc.c
MdePkg/Library/BaseLib/SynchronizationMsc.c

index b7c89732e0f19b5d8daf7f6fa056dafed5e104ca..f1565db3fdab7eb665328cce2f6bc4b3132f635d 100644 (file)
@@ -101,15 +101,32 @@ AcquireSpinLock (
   IN OUT  SPIN_LOCK                 *SpinLock\r
   )\r
 {\r
-  UINT64                            Tick;\r
-  UINT64                            Start, End;\r
-  UINT64                            Timeout;\r
+  UINT64  Current;\r
+  UINT64  Previous;\r
+  UINT64  Total;\r
+  UINT64  Start;\r
+  UINT64  End;\r
+  UINT64  Timeout;\r
+  INT64   Cycle;\r
+  INT64   Delta;\r
 \r
-  Tick = 0;\r
-  Start = 0;\r
-  End = 0;\r
   if (PcdGet32 (PcdSpinLockTimeout) > 0) {\r
-    Tick = GetPerformanceCounter ();\r
+    //\r
+    // Get the current timer value\r
+    //\r
+    Current = GetPerformanceCounter();\r
+\r
+    //\r
+    // Initialize local variables\r
+    //\r
+    Start = 0;\r
+    End   = 0;\r
+    Total = 0;\r
+\r
+    //\r
+    // Retrieve the performance counter properties and compute the number of performance\r
+    // counter ticks required to reach the timeout\r
+    //\r
     Timeout = DivU64x32 (\r
                 MultU64x32 (\r
                   GetPerformanceCounterProperties (&Start, &End),\r
@@ -117,16 +134,30 @@ AcquireSpinLock (
                   ),\r
                 1000000\r
                 );\r
-    if (Start < End) {\r
-      Tick += Timeout;\r
-    } else {\r
-      Tick -= Timeout;\r
+    Cycle = End - Start;\r
+    if (Cycle < 0) {\r
+      Cycle = -Cycle;\r
+    }\r
+    Cycle++;\r
+\r
+    while (!AcquireSpinLockOrFail (SpinLock)) {\r
+      CpuPause ();\r
+      Previous = Current;\r
+      Current  = GetPerformanceCounter();\r
+      Delta = (INT64) (Current - Previous);\r
+      if (Start > End) {\r
+        Delta = -Delta;\r
+      }\r
+      if (Delta < 0) {\r
+        Delta += Cycle;\r
+      }\r
+      Total += Delta;\r
+      ASSERT (Total < Timeout);\r
+    }\r
+  } else {\r
+    while (!AcquireSpinLockOrFail (SpinLock)) {\r
+      CpuPause ();\r
     }\r
-  }\r
-\r
-  while (!AcquireSpinLockOrFail (SpinLock)) {\r
-    CpuPause ();\r
-    ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));\r
   }\r
   return SpinLock;\r
 }\r
index 1681b4cf442934a0eb51bb6f2d9cec08b2f6f440..4c30dbc4b15b6dcd6899c16152394100913d2341 100644 (file)
@@ -110,15 +110,32 @@ AcquireSpinLock (
   IN OUT  SPIN_LOCK                 *SpinLock\r
   )\r
 {\r
-  UINT64                            Tick;\r
-  UINT64                            Start, End;\r
-  UINT64                            Timeout;\r
+  UINT64  Current;\r
+  UINT64  Previous;\r
+  UINT64  Total;\r
+  UINT64  Start;\r
+  UINT64  End;\r
+  UINT64  Timeout;\r
+  INT64   Cycle;\r
+  INT64   Delta;\r
 \r
-  Tick = 0;\r
-  Start = 0;\r
-  End = 0;\r
   if (PcdGet32 (PcdSpinLockTimeout) > 0) {\r
-    Tick = GetPerformanceCounter ();\r
+    //\r
+    // Get the current timer value\r
+    //\r
+    Current = GetPerformanceCounter();\r
+\r
+    //\r
+    // Initialize local variables\r
+    //\r
+    Start = 0;\r
+    End   = 0;\r
+    Total = 0;\r
+\r
+    //\r
+    // Retrieve the performance counter properties and compute the number of performance\r
+    // counter ticks required to reach the timeout\r
+    //\r
     Timeout = DivU64x32 (\r
                 MultU64x32 (\r
                   GetPerformanceCounterProperties (&Start, &End),\r
@@ -126,16 +143,30 @@ AcquireSpinLock (
                   ),\r
                 1000000\r
                 );\r
-    if (Start < End) {\r
-      Tick += Timeout;\r
-    } else {\r
-      Tick -= Timeout;\r
+    Cycle = End - Start;\r
+    if (Cycle < 0) {\r
+      Cycle = -Cycle;\r
+    }\r
+    Cycle++;\r
+\r
+    while (!AcquireSpinLockOrFail (SpinLock)) {\r
+      CpuPause ();\r
+      Previous = Current;\r
+      Current  = GetPerformanceCounter();\r
+      Delta = (INT64) (Current - Previous);\r
+      if (Start > End) {\r
+        Delta = -Delta;\r
+      }\r
+      if (Delta < 0) {\r
+        Delta += Cycle;\r
+      }\r
+      Total += Delta;\r
+      ASSERT (Total < Timeout);\r
+    }\r
+  } else {\r
+    while (!AcquireSpinLockOrFail (SpinLock)) {\r
+      CpuPause ();\r
     }\r
-  }\r
-\r
-  while (!AcquireSpinLockOrFail (SpinLock)) {\r
-    CpuPause ();\r
-    ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));\r
   }\r
   return SpinLock;\r
 }\r
index 9f1ec193833569b6119ad1185ba6e4ebb43fd3fd..0bc60259b170bc6cd0517df8751d1a30386f9d74 100644 (file)
@@ -112,15 +112,32 @@ AcquireSpinLock (
   IN OUT  SPIN_LOCK                 *SpinLock\r
   )\r
 {\r
-  UINT64                            Tick;\r
-  UINT64                            Start, End;\r
-  UINT64                            Timeout;\r
+  UINT64  Current;\r
+  UINT64  Previous;\r
+  UINT64  Total;\r
+  UINT64  Start;\r
+  UINT64  End;\r
+  UINT64  Timeout;\r
+  INT64   Cycle;\r
+  INT64   Delta;\r
 \r
-  Tick = 0;\r
-  Start = 0;\r
-  End = 0;\r
   if (PcdGet32 (PcdSpinLockTimeout) > 0) {\r
-    Tick = GetPerformanceCounter ();\r
+    //\r
+    // Get the current timer value\r
+    //\r
+    Current = GetPerformanceCounter();\r
+\r
+    //\r
+    // Initialize local variables\r
+    //\r
+    Start = 0;\r
+    End   = 0;\r
+    Total = 0;\r
+\r
+    //\r
+    // Retrieve the performance counter properties and compute the number of performance\r
+    // counter ticks required to reach the timeout\r
+    //\r
     Timeout = DivU64x32 (\r
                 MultU64x32 (\r
                   GetPerformanceCounterProperties (&Start, &End),\r
@@ -128,16 +145,30 @@ AcquireSpinLock (
                   ),\r
                 1000000\r
                 );\r
-    if (Start < End) {\r
-      Tick += Timeout;\r
-    } else {\r
-      Tick -= Timeout;\r
+    Cycle = End - Start;\r
+    if (Cycle < 0) {\r
+      Cycle = -Cycle;\r
+    }\r
+    Cycle++;\r
+\r
+    while (!AcquireSpinLockOrFail (SpinLock)) {\r
+      CpuPause ();\r
+      Previous = Current;\r
+      Current  = GetPerformanceCounter();\r
+      Delta = (INT64) (Current - Previous);\r
+      if (Start > End) {\r
+        Delta = -Delta;\r
+      }\r
+      if (Delta < 0) {\r
+        Delta += Cycle;\r
+      }\r
+      Total += Delta;\r
+      ASSERT (Total < Timeout);\r
+    }\r
+  } else {\r
+    while (!AcquireSpinLockOrFail (SpinLock)) {\r
+      CpuPause ();\r
     }\r
-  }\r
-\r
-  while (!AcquireSpinLockOrFail (SpinLock)) {\r
-    CpuPause ();\r
-    ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));\r
   }\r
   return SpinLock;\r
 }\r