Updated MSA file for EBC.
authoryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 3 Apr 2007 07:13:38 +0000 (07:13 +0000)
committeryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 3 Apr 2007 07:13:38 +0000 (07:13 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2526 6f19259b-4bc3-4df7-8a09-765794883524

MdePkg/Library/BaseLib/BaseLib.msa
MdePkg/Library/BaseLib/Synchronization.c [new file with mode: 0644]
MdePkg/Library/BaseLib/SynchronizationGcc.c
MdePkg/Library/BaseLib/SynchronizationMsc.c

index 7e1690fefad75102ce044f77cbfc7386efaea174..274cf2a7672545e489864373d84715e63f031764 100644 (file)
     <Filename>SwapBytes64.c</Filename>
     <Filename>SwitchStack.c</Filename>
     <Filename>CheckSum.c</Filename>
-    <Filename ToolChainFamily="GCC">SynchronizationGcc.c</Filename>
-    <Filename ToolChainFamily="MSFT">SynchronizationMsc.c</Filename>
+    <Filename SupArchList="IA32 X64 IPF" ToolChainFamily="GCC">SynchronizationGcc.c</Filename>
+    <Filename SupArchList="IA32 X64 IPF" ToolChainFamily="MSFT">SynchronizationMsc.c</Filename>
+    <Filename SupArchList="IA32 X64 IPF" ToolChainFamily="ICC">Synchronization.c</Filename>
+
     <Filename SupArchList="IA32">x86DisablePaging32.c</Filename>
     <Filename SupArchList="IA32">x86DisablePaging64.c</Filename>
     <Filename SupArchList="IA32">x86EnablePaging32.c</Filename>
     <Filename SupArchList="EBC">Ebc/SetJumpLongJump.c</Filename>
     <Filename SupArchList="EBC">Ebc/CpuBreakpoint.c</Filename>
     <Filename SupArchList="EBC">Ebc/Synchronization.c</Filename>
+    <Filename SupArchList="EBC">Synchronization.c</Filename>
     <Filename>CheckSum.c</Filename>
   </SourceFiles>
   <NonProcessedFiles>
diff --git a/MdePkg/Library/BaseLib/Synchronization.c b/MdePkg/Library/BaseLib/Synchronization.c
new file mode 100644 (file)
index 0000000..a4aa3fb
--- /dev/null
@@ -0,0 +1,358 @@
+/** @file\r
+  Implementation of synchronization functions.\r
+\r
+  Copyright (c) 2006, Intel Corporation<BR>\r
+  All rights reserved. This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  Module Name:  Synchronization.c\r
+\r
+**/\r
+\r
+#include "BaseLibInternals.h"\r
+\r
+#define SPIN_LOCK_RELEASED          ((SPIN_LOCK)1)\r
+#define SPIN_LOCK_ACQUIRED          ((SPIN_LOCK)2)\r
+\r
+/**\r
+  Retrieves the architecture specific spin lock alignment requirements for\r
+  optimal spin lock performance.\r
+\r
+  This function retrieves the spin lock alignment requirements for optimal\r
+  performance on a given CPU architecture. The spin lock alignment must be a\r
+  power of two and is returned by this function. If there are no alignment\r
+  requirements, then 1 must be returned. The spin lock synchronization\r
+  functions must function correctly if the spin lock size and alignment values\r
+  returned by this function are not used at all. These values are hints to the\r
+  consumers of the spin lock synchronization functions to obtain optimal spin\r
+  lock performance.\r
+\r
+  @return The architecture specific spin lock alignment.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+GetSpinLockProperties (\r
+  VOID\r
+  )\r
+{\r
+  // @bug May use a PCD entry to determine this alignment.\r
+  return 32;\r
+}\r
+\r
+/**\r
+  Initializes a spin lock to the released state and returns the spin lock.\r
+\r
+  This function initializes the spin lock specified by SpinLock to the released\r
+  state, and returns SpinLock. Optimal performance can be achieved by calling\r
+  GetSpinLockProperties() to determine the size and alignment requirements for\r
+  SpinLock.\r
+\r
+  If SpinLock is NULL, then ASSERT().\r
+\r
+  @param  SpinLock  A pointer to the spin lock to initialize to the released\r
+                    state.\r
+\r
+  @return SpinLock\r
+\r
+**/\r
+SPIN_LOCK *\r
+EFIAPI\r
+InitializeSpinLock (\r
+  OUT     SPIN_LOCK                 *SpinLock\r
+  )\r
+{\r
+  ASSERT (SpinLock != NULL);\r
+  *SpinLock = SPIN_LOCK_RELEASED;\r
+  return SpinLock;\r
+}\r
+\r
+/**\r
+  Waits until a spin lock can be placed in the acquired state.\r
+\r
+  This function checks the state of the spin lock specified by SpinLock. If\r
+  SpinLock is in the released state, then this function places SpinLock in the\r
+  acquired state and returns SpinLock. Otherwise, this function waits\r
+  indefinitely for the spin lock to be released, and then places it in the\r
+  acquired state and returns SpinLock. All state transitions of SpinLock must\r
+  be performed using MP safe mechanisms.\r
+\r
+  If SpinLock is NULL, then ASSERT().\r
+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().\r
+  If PcdSpinLockTimeout is not zero, and SpinLock is can not be acquired in\r
+  PcdSpinLockTimeout microseconds, then ASSERT().\r
+\r
+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.\r
+\r
+  @return SpinLock\r
+\r
+**/\r
+SPIN_LOCK *\r
+EFIAPI\r
+AcquireSpinLock (\r
+  IN OUT  SPIN_LOCK                 *SpinLock\r
+  )\r
+{\r
+  UINT64                            Tick;\r
+  UINT64                            Start, End;\r
+  UINT64                            Timeout;\r
+\r
+  Tick = 0;\r
+  Start = 0;\r
+  End = 0;\r
+  if (PcdGet32 (PcdSpinLockTimeout) > 0) {\r
+    Tick = GetPerformanceCounter ();\r
+    Timeout = DivU64x32 (\r
+                MultU64x32 (\r
+                  GetPerformanceCounterProperties (&Start, &End),\r
+                  PcdGet32 (PcdSpinLockTimeout)\r
+                  ),\r
+                1000000\r
+                );\r
+    if (Start < End) {\r
+      Tick += Timeout;\r
+    } else {\r
+      Tick -= Timeout;\r
+    }\r
+  }\r
+\r
+  while (!AcquireSpinLockOrFail (SpinLock)) {\r
+    CpuPause ();\r
+    ASSERT ((Start < End) ^ (Tick <= GetPerformanceCounter ()));\r
+  }\r
+  return SpinLock;\r
+}\r
+\r
+/**\r
+  Attempts to place a spin lock in the acquired state.\r
+\r
+  This function checks the state of the spin lock specified by SpinLock. If\r
+  SpinLock is in the released state, then this function places SpinLock in the\r
+  acquired state and returns TRUE. Otherwise, FALSE is returned. All state\r
+  transitions of SpinLock must be performed using MP safe mechanisms.\r
+\r
+  If SpinLock is NULL, then ASSERT().\r
+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().\r
+\r
+  @param  SpinLock  A pointer to the spin lock to place in the acquired state.\r
+\r
+  @retval TRUE  SpinLock was placed in the acquired state.\r
+  @retval FALSE SpinLock could not be acquired.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+AcquireSpinLockOrFail (\r
+  IN OUT  SPIN_LOCK                 *SpinLock\r
+  )\r
+{\r
+  SPIN_LOCK    LockValue;\r
+\r
+  ASSERT (SpinLock != NULL);\r
+\r
+  LockValue = *SpinLock;\r
+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);\r
+\r
+  return (BOOLEAN)(\r
+           InterlockedCompareExchangePointer (\r
+             (VOID**)SpinLock,\r
+             (VOID*)SPIN_LOCK_RELEASED,\r
+             (VOID*)SPIN_LOCK_ACQUIRED\r
+             ) == (VOID*)SPIN_LOCK_RELEASED\r
+           );\r
+}\r
+\r
+/**\r
+  Releases a spin lock.\r
+\r
+  This function places the spin lock specified by SpinLock in the release state\r
+  and returns SpinLock.\r
+\r
+  If SpinLock is NULL, then ASSERT().\r
+  If SpinLock was not initialized with InitializeSpinLock(), then ASSERT().\r
+\r
+  @param  SpinLock  A pointer to the spin lock to release.\r
+\r
+  @return SpinLock\r
+\r
+**/\r
+SPIN_LOCK *\r
+EFIAPI\r
+ReleaseSpinLock (\r
+  IN OUT  SPIN_LOCK                 *SpinLock\r
+  )\r
+{\r
+  SPIN_LOCK    LockValue;\r
+\r
+  ASSERT (SpinLock != NULL);\r
+\r
+  LockValue = *SpinLock;\r
+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);\r
+\r
+  *SpinLock = SPIN_LOCK_RELEASED;\r
+  return SpinLock;\r
+}\r
+\r
+/**\r
+  Performs an atomic increment of an 32-bit unsigned integer.\r
+\r
+  Performs an atomic increment of the 32-bit unsigned integer specified by\r
+  Value and returns the incremented value. The increment operation must be\r
+  performed using MP safe mechanisms. The state of the return value is not\r
+  guaranteed to be MP safe.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value A pointer to the 32-bit value to increment.\r
+\r
+  @return The incremented value.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+InterlockedIncrement (\r
+  IN      UINT32                    *Value\r
+  )\r
+{\r
+  ASSERT (Value != NULL);\r
+  return InternalSyncIncrement (Value);\r
+}\r
+\r
+/**\r
+  Performs an atomic decrement of an 32-bit unsigned integer.\r
+\r
+  Performs an atomic decrement of the 32-bit unsigned integer specified by\r
+  Value and returns the decremented value. The decrement operation must be\r
+  performed using MP safe mechanisms. The state of the return value is not\r
+  guaranteed to be MP safe.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value A pointer to the 32-bit value to decrement.\r
+\r
+  @return The decremented value.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+InterlockedDecrement (\r
+  IN      UINT32                    *Value\r
+  )\r
+{\r
+  ASSERT (Value != NULL);\r
+  return InternalSyncDecrement (Value);\r
+}\r
+\r
+/**\r
+  Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 32-bit unsigned integer\r
+  specified by Value.  If Value is equal to CompareValue, then Value is set to \r
+  ExchangeValue and CompareValue is returned.  If Value is not equal to CompareValue,\r
+  then Value is returned.  The compare exchange operation must be performed using \r
+  MP safe mechanisms.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value         A pointer to the 32-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  32-bit value used in compare operation.\r
+  @param  ExchangeValue 32-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+InterlockedCompareExchange32 (\r
+  IN OUT  UINT32                    *Value,\r
+  IN      UINT32                    CompareValue,\r
+  IN      UINT32                    ExchangeValue\r
+  )\r
+{\r
+  ASSERT (Value != NULL);\r
+  return InternalSyncCompareExchange32 (Value, CompareValue, ExchangeValue);\r
+}\r
+\r
+/**\r
+  Performs an atomic compare exchange operation on a 64-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 64-bit unsigned integer specified \r
+  by Value.  If Value is equal to CompareValue, then Value is set to ExchangeValue and \r
+  CompareValue is returned.  If Value is not equal to CompareValue, then Value is returned. \r
+  The compare exchange operation must be performed using MP safe mechanisms.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value         A pointer to the 64-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  64-bit value used in compare operation.\r
+  @param  ExchangeValue 64-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InterlockedCompareExchange64 (\r
+  IN OUT  UINT64                    *Value,\r
+  IN      UINT64                    CompareValue,\r
+  IN      UINT64                    ExchangeValue\r
+  )\r
+{\r
+  ASSERT (Value != NULL);\r
+  return InternalSyncCompareExchange64 (Value, CompareValue, ExchangeValue);\r
+}\r
+\r
+/**\r
+  Performs an atomic compare exchange operation on a pointer value.\r
+\r
+  Performs an atomic compare exchange operation on the pointer value specified\r
+  by Value. If Value is equal to CompareValue, then Value is set to\r
+  ExchangeValue and CompareValue is returned. If Value is not equal to\r
+  CompareValue, then Value is returned. The compare exchange operation must be\r
+  performed using MP safe mechanisms.\r
+\r
+  If Value is NULL, then ASSERT().\r
+\r
+  @param  Value         A pointer to the pointer value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  Pointer value used in compare operation.\r
+  @param  ExchangeValue Pointer value used in exchange operation.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+InterlockedCompareExchangePointer (\r
+  IN OUT  VOID                      **Value,\r
+  IN      VOID                      *CompareValue,\r
+  IN      VOID                      *ExchangeValue\r
+  )\r
+{\r
+  UINT8  SizeOfValue;\r
+\r
+  SizeOfValue = sizeof (*Value);\r
+\r
+  switch (SizeOfValue) {\r
+    case sizeof (UINT32):\r
+      return (VOID*)(UINTN)InterlockedCompareExchange32 (\r
+                             (UINT32*)Value,\r
+                             (UINT32)(UINTN)CompareValue,\r
+                             (UINT32)(UINTN)ExchangeValue\r
+                             );\r
+    case sizeof (UINT64):\r
+      return (VOID*)(UINTN)InterlockedCompareExchange64 (\r
+                             (UINT64*)Value,\r
+                             (UINT64)(UINTN)CompareValue,\r
+                             (UINT64)(UINTN)ExchangeValue\r
+                             );\r
+    default:\r
+      ASSERT (FALSE);\r
+      return NULL;\r
+  }\r
+}\r
index 9d57a1f34d3b36a8c0df1d5e5659696e595902ed..40b1e4a36b303fb83b3c3785118d4c42a8c7db1e 100644 (file)
@@ -160,10 +160,13 @@ AcquireSpinLockOrFail (
   IN OUT  SPIN_LOCK                 *SpinLock\r
   )\r
 {\r
-  VOID  *Result;\r
+  SPIN_LOCK   LockValue;\r
+  VOID        *Result;\r
   \r
   ASSERT (SpinLock != NULL);\r
-  ASSERT (*SpinLock == SPIN_LOCK_ACQUIRED || *SpinLock == SPIN_LOCK_RELEASED);\r
+\r
+  LockValue = *SpinLock;\r
+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);\r
 \r
   _ReadWriteBarrier ();\r
   Result = InterlockedCompareExchangePointer (\r
@@ -196,8 +199,12 @@ ReleaseSpinLock (
   IN OUT  SPIN_LOCK                 *SpinLock\r
   )\r
 {\r
+  SPIN_LOCK    LockValue;\r
+\r
   ASSERT (SpinLock != NULL);\r
-  ASSERT (*SpinLock == SPIN_LOCK_ACQUIRED || *SpinLock == SPIN_LOCK_RELEASED);\r
+\r
+  LockValue = *SpinLock;\r
+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);\r
 \r
   _ReadWriteBarrier ();\r
   *SpinLock = SPIN_LOCK_RELEASED;\r
index fb10b5d01b59fceff5e0377e8a26c3653c3aa290..ce330aed880669d6a58412bd3f6feccb7bb4b67b 100644 (file)
@@ -162,10 +162,13 @@ AcquireSpinLockOrFail (
   IN OUT  SPIN_LOCK                 *SpinLock\r
   )\r
 {\r
-  VOID  *Result;\r
+  SPIN_LOCK   LockValue;\r
+  VOID        *Result;\r
   \r
   ASSERT (SpinLock != NULL);\r
-  ASSERT (*SpinLock == SPIN_LOCK_ACQUIRED || *SpinLock == SPIN_LOCK_RELEASED);\r
+\r
+  LockValue = *SpinLock;\r
+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);\r
 \r
   _ReadWriteBarrier ();\r
   Result = InterlockedCompareExchangePointer (\r
@@ -198,8 +201,12 @@ ReleaseSpinLock (
   IN OUT  SPIN_LOCK                 *SpinLock\r
   )\r
 {\r
+  SPIN_LOCK    LockValue;\r
+\r
   ASSERT (SpinLock != NULL);\r
-  ASSERT (*SpinLock == SPIN_LOCK_ACQUIRED || *SpinLock == SPIN_LOCK_RELEASED);\r
+\r
+  LockValue = *SpinLock;\r
+  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);\r
 \r
   _ReadWriteBarrier ();\r
   *SpinLock = SPIN_LOCK_RELEASED;\r