#endif
-/* Basic atomic types: 8, 16, 32, 64 and 128 bits */
-typedef struct Atomic_uint8 {
- volatile uint8 value;
-} Atomic_uint8 ALIGNED(1);
-
+/* Basic atomic types: 16, 32 and 64 bits */
typedef struct Atomic_uint16 {
volatile uint16 value;
} Atomic_uint16 ALIGNED(2);
*/
#if defined _MSC_VER && _MSC_VER < 1600 && defined __x86_64__
-uint8 VMWInterlockedExchange8(uint8 volatile *ptr,
- uint8 val);
+Bool VMWInterlockedExchangeBool(Bool volatile *ptr,
+ Bool val);
-uint8 VMWInterlockedCompareExchange8(uint8 volatile *ptr,
- uint8 newVal,
- uint8 oldVal);
+Bool VMWInterlockedCompareExchangeBool(Bool volatile *ptr,
+ Bool newVal,
+ Bool oldVal);
#endif
-#if defined __GNUC__ && defined VM_ARM_32
-/* Force the link step to fail for unimplemented functions. */
-extern int AtomicUndefined(void *);
+/* The ARM32 team is expected to provide an implementation real soon now. */
+#if defined VM_ARM_32
+extern Bool AtomicUndefined(void);
+#endif
+
+typedef struct Atomic_Bool {
+ volatile Bool value;
+} Atomic_Bool;
+
+/* This should be enforced on all architectures not just ARM... */
+#if defined VM_ARM_ANY
+MY_ASSERTS(AtomicBoolSize,
+ ASSERT_ON_COMPILE(sizeof (Atomic_Bool) == sizeof (uint8));
+)
+#endif
+
+#if defined VMKERNEL || defined VMM
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CMPXCHG1B --
+ *
+ * Compare and exchange a single byte.
+ *
+ * Results:
+ * The value read from ptr.
+ *
+ * Side effects:
+ * None
+ *
+ *-----------------------------------------------------------------------------
+ */
+static INLINE uint8
+CMPXCHG1B(volatile uint8 *ptr, // IN/OUT
+ uint8 oldVal, // IN
+ uint8 newVal) // IN
+{
+ uint8 val;
+
+#if defined VM_ARM_64
+ val = _VMATOM_X(RIFEQW, 8, TRUE, ptr, oldVal, newVal);
+#else
+ __asm__ __volatile__("lock; cmpxchgb %b2, %1"
+ : "=a" (val),
+ "+m" (*ptr)
+ : "r" (newVal),
+ "0" (oldVal)
+ : "cc");
+
+#endif
+ return val;
+}
#endif
}
#endif
-
/*
*-----------------------------------------------------------------------------
*
- * Atomic_Read8 --
+ * Atomic_ReadBool --
*
* Read the value of the specified object atomically.
*
*-----------------------------------------------------------------------------
*/
-static INLINE uint8
-Atomic_Read8(Atomic_uint8 const *var) // IN:
+static INLINE Bool
+Atomic_ReadBool(Atomic_Bool const *var) // IN:
{
- uint8 val;
+ Bool val;
#if defined __GNUC__ && defined VM_ARM_32
- val = AtomicUndefined(var);
+ val = AtomicUndefined();
#elif defined VM_ARM_64
val = _VMATOM_X(R, 8, &var->value);
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
#elif defined _MSC_VER
val = var->value;
#else
-#error No compiler defined for Atomic_Read8
+#error No compiler defined for Atomic_ReadBool
#endif
return val;
/*
*-----------------------------------------------------------------------------
*
- * Atomic_ReadWrite8 --
+ * Atomic_ReadWriteBool --
*
* Read followed by write.
*
*-----------------------------------------------------------------------------
*/
-static INLINE uint8
-Atomic_ReadWrite8(Atomic_uint8 *var, // IN/OUT:
- uint8 val) // IN:
+static INLINE Bool
+Atomic_ReadWriteBool(Atomic_Bool *var, // IN/OUT:
+ Bool val) // IN:
{
#if defined __GNUC__ && defined VM_ARM_32
- return AtomicUndefined(var + val);
+ return AtomicUndefined();
#elif defined VM_ARM_64
return _VMATOM_X(RW, 8, TRUE, &var->value, val);
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
{
__asm movzx eax, val
__asm mov ebx, var
- __asm xchg [ebx]Atomic_uint8.value, al
+ __asm xchg [ebx]Atomic_Bool.value, al
}
#pragma warning(pop)
#elif defined _MSC_VER && defined __x86_64__
- return VMWInterlockedExchange8(&var->value, val);
+ return VMWInterlockedExchangeBool(&var->value, val);
#else
-#error No compiler defined for Atomic_ReadWrite8
+#error No compiler defined for Atomic_ReadBool
#endif
}
/*
*-----------------------------------------------------------------------------
*
- * Atomic_Write8 --
+ * Atomic_WriteBool --
*
* Write the specified value to the specified object atomically.
*
*/
static INLINE void
-Atomic_Write8(Atomic_uint8 *var, // IN/OUT:
- uint8 val) // IN:
+Atomic_WriteBool(Atomic_Bool *var, // IN/OUT:
+ Bool val) // IN:
{
#if defined __GNUC__ && defined VM_ARM_32
- AtomicUndefined(var + val);
+ AtomicUndefined();
#elif defined VM_ARM_64
_VMATOM_X(W, 8, &var->value, val);
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
#elif defined _MSC_VER
var->value = val;
#else
-#error No compiler defined for Atomic_Write8
+#error No compiler defined for Atomic_WriteBool
#endif
}
/*
*-----------------------------------------------------------------------------
*
- * Atomic_ReadIfEqualWrite8 --
+ * Atomic_ReadIfEqualWriteBool --
*
* Compare exchange: Read variable, if equal to oldVal, write newVal.
*
*-----------------------------------------------------------------------------
*/
-static INLINE uint8
-Atomic_ReadIfEqualWrite8(Atomic_uint8 *var, // IN/OUT:
- uint8 oldVal, // IN:
- uint8 newVal) // IN:
+static INLINE Bool
+Atomic_ReadIfEqualWriteBool(Atomic_Bool *var, // IN/OUT:
+ Bool oldVal, // IN:
+ Bool newVal) // IN:
{
#if defined __GNUC__ && defined VM_ARM_32
- return AtomicUndefined(var + oldVal + newVal);
+ return AtomicUndefined();
#elif defined VM_ARM_64
return _VMATOM_X(RIFEQW, 8, TRUE, &var->value, oldVal, newVal);
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
- uint8 val;
+ Bool val;
__asm__ __volatile__(
"lock; cmpxchgb %2, %1"
__asm mov al, oldVal
__asm mov ebx, var
__asm mov cl, newVal
- __asm lock cmpxchg [ebx]Atomic_uint8.value, cl
+ __asm lock cmpxchg [ebx]Atomic_Bool.value, cl
__asm movzx eax, al
// eax is the return value, this is documented to work - edward
}
#pragma warning(pop)
#elif defined _MSC_VER && defined __x86_64__
- return VMWInterlockedCompareExchange8(&var->value, newVal, oldVal);
-#else
-#error No compiler defined for Atomic_ReadIfEqualWrite8
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadAnd8 --
- *
- * Atomic read (returned), bitwise AND with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint8
-Atomic_ReadAnd8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
- uint8 res;
-
-#if defined VM_ARM_64
- res = _VMATOM_X(ROP, 8, TRUE, &var->value, and, val);
-#else
- do {
- res = Atomic_Read8(var);
- } while (res != Atomic_ReadIfEqualWrite8(var, res, res & val));
-#endif
-
- return res;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_And8 --
- *
- * Atomic read, bitwise AND with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_And8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
-#if defined VM_ARM_64
- _VMATOM_X(OP, 8, TRUE, &var->value, and, val);
-#else
- (void)Atomic_ReadAnd8(var, val);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadOr8 --
- *
- * Atomic read (returned), bitwise OR with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint8
-Atomic_ReadOr8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
- uint8 res;
-
-#if defined VM_ARM_64
- res = _VMATOM_X(ROP, 8, TRUE, &var->value, orr, val);
-#else
- do {
- res = Atomic_Read8(var);
- } while (res != Atomic_ReadIfEqualWrite8(var, res, res | val));
-#endif
-
- return res;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Or8 --
- *
- * Atomic read, bitwise OR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Or8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
-#if defined VM_ARM_64
- _VMATOM_X(OP, 8, TRUE, &var->value, orr, val);
-#else
- (void)Atomic_ReadOr8(var, val);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadXor8 --
- *
- * Atomic read (returned), bitwise XOR with a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint8
-Atomic_ReadXor8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
- uint8 res;
-
-#if defined VM_ARM_64
- res = _VMATOM_X(ROP, 8, TRUE, &var->value, eor, val);
+ return VMWInterlockedCompareExchangeBool(&var->value, newVal, oldVal);
#else
- do {
- res = Atomic_Read8(var);
- } while (res != Atomic_ReadIfEqualWrite8(var, res, res ^ val));
+#error No compiler defined for Atomic_ReadIfEqualWriteBool
#endif
-
- return res;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Xor8 --
- *
- * Atomic read, bitwise XOR with a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Xor8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
-#if defined VM_ARM_64
- _VMATOM_X(OP, 8, TRUE, &var->value, eor, val);
-#else
- (void)Atomic_ReadXor8(var, val);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadAdd8 --
- *
- * Atomic read (returned), add a value, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint8
-Atomic_ReadAdd8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
- uint8 res;
-
-#if defined VM_ARM_64
- res = _VMATOM_X(ROP, 8, TRUE, &var->value, add, val);
-#else
- do {
- res = Atomic_Read8(var);
- } while (res != Atomic_ReadIfEqualWrite8(var, res, res + val));
-#endif
-
- return res;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Add8 --
- *
- * Atomic read, add a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Add8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
-#if defined VM_ARM_64
- _VMATOM_X(OP, 8, TRUE, &var->value, add, val);
-#else
- (void)Atomic_ReadAdd8(var, val);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Sub8 --
- *
- * Atomic read, subtract a value, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Sub8(Atomic_uint8 *var, // IN/OUT
- uint8 val) // IN
-{
-#if defined VM_ARM_64
- _VMATOM_X(OP, 8, TRUE, &var->value, sub, val);
-#else
- Atomic_Add8(var, -val);
-#endif
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Inc8 --
- *
- * Atomic read, increment, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Inc8(Atomic_uint8 *var) // IN/OUT
-{
- Atomic_Add8(var, 1);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_Dec8 --
- *
- * Atomic read, decrement, write.
- *
- * Results:
- * None
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE void
-Atomic_Dec8(Atomic_uint8 *var) // IN/OUT
-{
- Atomic_Sub8(var, 1);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadInc8 --
- *
- * Atomic read (returned), increment, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint8
-Atomic_ReadInc8(Atomic_uint8 *var) // IN/OUT
-{
- return Atomic_ReadAdd8(var, 1);
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Atomic_ReadDec8 --
- *
- * Atomic read (returned), decrement, write.
- *
- * Results:
- * The value of the variable before the operation.
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-static INLINE uint8
-Atomic_ReadDec8(Atomic_uint8 *var) // IN/OUT
-{
- return Atomic_ReadAdd8(var, (uint8)-1);
}
* Atomic_ReadAddInt --
* Atomic_ReadIncInt --
* Atomic_ReadDecInt --
- *
- * Atomic_Bool
- * Atomic_ReadBool --
- * Atomic_WriteBool --
- * Atomic_ReadWriteBool --
- * Atomic_ReadIfEqualWriteBool --
- * Atomic_AndBool --
- * Atomic_OrBool --
- * Atomic_XorBool --
- * Atomic_AddBool --
- * Atomic_SubBool --
- * Atomic_IncBool --
- * Atomic_DecBool --
- * Atomic_ReadOrBool --
- * Atomic_ReadAddBool --
- * Atomic_ReadIncBool --
- * Atomic_ReadDecBool --
*/
#if defined VM_64BIT
MAKE_ATOMIC_TYPE(Ptr, 64, void const *, void *, uintptr_t)
MAKE_ATOMIC_TYPE(Ptr, 32, void const *, void *, uintptr_t)
#endif
MAKE_ATOMIC_TYPE(Int, 32, int, int, int)
-MAKE_ATOMIC_TYPE(Bool, 8, Bool, Bool, Bool)
#if defined VM_ARM_64 && defined VMKERNEL \