]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
MdePkg/BaseSynchronizationLib: Add volatile Interlocked*() APIs
[mirror_edk2.git] / MdePkg / Library / BaseSynchronizationLib / X64 / GccInline.c
index ceb80aed94f8aeba8e02bda19e41384d4a607178..6347073fee510c2fb9f14ee9440ac34dad9bfcc0 100644 (file)
@@ -88,6 +88,50 @@ InternalSyncDecrement (
 }\r
 \r
 \r
+/**\r
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.\r
+\r
+  Performs an atomic compare exchange operation on the 16-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
+\r
+  @param  Value         A pointer to the 16-bit value for the compare exchange\r
+                        operation.\r
+  @param  CompareValue  16-bit value used in compare operation.\r
+  @param  ExchangeValue 16-bit value used in exchange operation.\r
+\r
+  @return The original *Value before exchange.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+InternalSyncCompareExchange16 (\r
+  IN OUT volatile  UINT16           *Value,\r
+  IN      UINT16                    CompareValue,\r
+  IN      UINT16                    ExchangeValue\r
+  )\r
+{\r
+\r
+\r
+  __asm__ __volatile__ (\r
+    "lock                 \n\t"\r
+    "cmpxchgw    %3, %1       "\r
+    : "=a" (CompareValue),\r
+      "=m" (*Value)\r
+    : "a"  (CompareValue),\r
+      "r"  (ExchangeValue),\r
+      "m"  (*Value)\r
+    : "memory",\r
+      "cc"\r
+    );\r
+\r
+  return CompareValue;\r
+}\r
+\r
+\r
 /**\r
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.\r
 \r