]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Add Atomic_ReadIfEqualWrite128
authorOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:19 +0000 (11:23 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:19 +0000 (11:23 -0700)
This enables atomic CAS of a 128 bit entity. As gcc >= 4.6 already
provides intristics for it, the funciton is just a simple wrapper,
and built only for those compliers.

open-vm-tools/lib/include/vm_atomic.h

index e76e13b743459c65505351acb64c98303966658e..d104d70c92688f0ff7bcaef54d7bade3af6d910a 100644 (file)
@@ -246,6 +246,13 @@ typedef struct  Atomic_uint64 {
    volatile uint64 value;
 } Atomic_uint64 ALIGNED(8);
 
+#if (__GNUC__ > 4 || (__GNUC__ ==  4 && __GNUC_MINOR__ >= 6)) && \
+                                (defined(VM_X86_64) || defined(VM_ARM_64))
+typedef struct Atomic_uint128 {
+   volatile __int128 value;
+} Atomic_uint128 ALIGNED(16);
+#endif
+
 /*
  * Prototypes for msft atomics.  These are defined & inlined by the
  * compiler so no function definition is needed.  The prototypes are
@@ -458,6 +465,41 @@ CMPXCHG1B(volatile uint8 *ptr, // IN/OUT
 }
 #endif
 
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Atomic_ReadIfEqualWrite128 --
+ *
+ *      Compare and exchange a 16 byte tuple.
+ *
+ * Results:
+ *      old value
+ *
+ * Side effects:
+ *      None
+ *
+ *-----------------------------------------------------------------------------
+ */
+#if (__GNUC__ > 4 || (__GNUC__ ==  4 && __GNUC_MINOR__ >= 6)) && \
+                                (defined(VM_X86_64) || defined(VM_ARM_64))
+static INLINE __int128
+Atomic_ReadIfEqualWrite128(Atomic_uint128 *ptr,   // IN/OUT
+                           __int128       oldVal, // IN
+                           __int128       newVal) // IN
+{
+   __int128 res;
+#ifdef VM_ARM_64
+   LDST_LDST_MEM_BARRIER();
+#endif
+   res = __sync_val_compare_and_swap(&ptr->value, oldVal, newVal);
+#ifdef VM_ARM_64
+   LDST_LDST_MEM_BARRIER();
+#endif
+   return res;
+}
+#endif
+
 /*
  *-----------------------------------------------------------------------------
  *