Bug 888548 - Part 3: Add enum support to mozilla::Atomic<T>. r=froydnj

Due to a bug in GCC, the compareExchange function is not available with enum types.
This commit is contained in:
Birunthan Mohanathas 2013-07-31 21:15:25 -04:00
parent 70a5f02910
commit 99ffeabe6b
2 changed files with 67 additions and 0 deletions

View File

@ -983,6 +983,27 @@ class Atomic<T*, Order> : public detail::AtomicBaseIncDec<T*, Order>
Atomic(Atomic<T*, Order>& aOther) MOZ_DELETE;
};
/**
* Atomic<T> implementation for enum types.
*
* The atomic store and load operations and the atomic swap method is provided.
*/
template<typename T, MemoryOrdering Order>
class Atomic<T, Order, typename EnableIf<IsEnum<T>::value>::Type>
: public detail::AtomicBase<T, Order>
{
typedef typename detail::AtomicBase<T, Order> Base;
public:
Atomic() : Base() {}
Atomic(T aInit) : Base(aInit) {}
using Base::operator=;
private:
Atomic(Atomic<T, Order>& aOther) MOZ_DELETE;
};
} // namespace mozilla
#endif /* mozilla_Atomics_h */

View File

@ -128,6 +128,43 @@ TestPointerWithOrdering()
MOZ_ASSERT(atomic == array1 + 3, "CAS should have changed atomic's value.");
}
template<MemoryOrdering Order>
static void
TestEnumWithOrdering()
{
enum EnumType {
EnumType_0 = 0,
EnumType_1 = 1,
EnumType_2 = 2,
EnumType_3 = 3
};
Atomic<EnumType, Order> atomic(EnumType_2);
MOZ_ASSERT(atomic == EnumType_2, "Atomic variable did not initialize");
// Test assignment
DebugOnly<EnumType> result;
result = (atomic = EnumType_3);
MOZ_ASSERT(atomic == EnumType_3, "Atomic assignment failed");
MOZ_ASSERT(result == EnumType_3, "Atomic assignment returned the wrong value");
// Test exchange.
atomic = EnumType_1;
result = atomic.exchange(EnumType_2);
MOZ_ASSERT(atomic == EnumType_2, "Atomic exchange did not work");
MOZ_ASSERT(result == EnumType_1, "Atomic exchange returned the wrong value");
// Test CAS.
atomic = EnumType_1;
DebugOnly<bool> boolResult = atomic.compareExchange(EnumType_0, EnumType_2);
MOZ_ASSERT(!boolResult, "CAS should have returned false.");
MOZ_ASSERT(atomic == EnumType_1, "CAS shouldn't have done anything.");
boolResult = atomic.compareExchange(EnumType_1, EnumType_3);
MOZ_ASSERT(boolResult, "CAS should have succeeded.");
MOZ_ASSERT(atomic == EnumType_3, "CAS should have changed atomic's value.");
}
template <typename T>
static void
TestType()
@ -146,6 +183,14 @@ TestPointer()
TestPointerWithOrdering<T, Relaxed>();
}
static void
TestEnum()
{
TestEnumWithOrdering<SequentiallyConsistent>();
TestEnumWithOrdering<ReleaseAcquire>();
TestEnumWithOrdering<Relaxed>();
}
int main()
{
TestType<uint32_t>();
@ -156,4 +201,5 @@ int main()
TestPointer<float>();
TestPointer<uint16_t*>();
TestPointer<uint32_t*>();
TestEnum();
}