diff --git a/mfbt/tests/Makefile.in b/mfbt/tests/Makefile.in index 301078be50d..faac3bc0aa4 100644 --- a/mfbt/tests/Makefile.in +++ b/mfbt/tests/Makefile.in @@ -12,6 +12,7 @@ include $(DEPTH)/config/autoconf.mk STL_FLAGS = CPP_UNIT_TESTS = \ + TestAtomics.cpp \ TestBloomFilter.cpp \ TestCasting.cpp \ TestCheckedInt.cpp \ diff --git a/mfbt/tests/TestAtomics.cpp b/mfbt/tests/TestAtomics.cpp new file mode 100644 index 00000000000..fc5156a5174 --- /dev/null +++ b/mfbt/tests/TestAtomics.cpp @@ -0,0 +1,140 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/Assertions.h" +#include "mozilla/Atomics.h" +#include "mozilla/DebugOnly.h" + +#include + +using mozilla::Atomic; +using mozilla::DebugOnly; +using mozilla::MemoryOrdering; +using mozilla::Relaxed; +using mozilla::ReleaseAcquire; +using mozilla::SequentiallyConsistent; + +template +static void +TestTypeWithOrdering() +{ + Atomic atomic(5); + MOZ_ASSERT(atomic == 5, "Atomic variable did not initialize"); + + // Test atomic increment + MOZ_ASSERT(++atomic == T(6), "Atomic increment did not work"); + MOZ_ASSERT(atomic++ == T(6), "Atomic post-increment did not work"); + MOZ_ASSERT(atomic == T(7), "Atomic post-increment did not work"); + + // Test atomic decrement + MOZ_ASSERT(--atomic == 6, "Atomic decrement did not work"); + MOZ_ASSERT(atomic-- == 6, "Atomic post-decrement did not work"); + MOZ_ASSERT(atomic == 5, "Atomic post-decrement did not work"); + + // Test other arithmetic. + DebugOnly result; + result = (atomic += T(5)); + MOZ_ASSERT(atomic == T(10), "Atomic += did not work"); + MOZ_ASSERT(result == T(10), "Atomic += returned the wrong value"); + result = (atomic -= T(3)); + MOZ_ASSERT(atomic == T(7), "Atomic -= did not work"); + MOZ_ASSERT(result == T(7), "Atomic -= returned the wrong value"); + + // Test assignment + result = (atomic = T(5)); + MOZ_ASSERT(atomic == T(5), "Atomic assignment failed"); + MOZ_ASSERT(result == T(5), "Atomic assignment returned the wrong value"); + + // Test logical operations. + result = (atomic ^= T(2)); + MOZ_ASSERT(atomic == T(7), "Atomic ^= did not work"); + MOZ_ASSERT(result == T(7), "Atomic ^= returned the wrong value"); + result = (atomic ^= T(4)); + MOZ_ASSERT(atomic == T(3), "Atomic ^= did not work"); + MOZ_ASSERT(result == T(3), "Atomic ^= returned the wrong value"); + result = (atomic |= T(8)); + MOZ_ASSERT(atomic == T(11), "Atomic |= did not work"); + MOZ_ASSERT(result == T(11), "Atomic |= returned the wrong value"); + result = (atomic |= T(8)); + MOZ_ASSERT(atomic == T(11), "Atomic |= did not work"); + MOZ_ASSERT(result == T(11), "Atomic |= returned the wrong value"); + result = (atomic &= T(12)); + MOZ_ASSERT(atomic == T(8), "Atomic &= did not work"); + MOZ_ASSERT(result == T(8), "Atomic &= returned the wrong value"); + + // Test exchange. + atomic = T(30); + result = atomic.exchange(42); + MOZ_ASSERT(atomic == T(42), "Atomic exchange did not work"); + MOZ_ASSERT(result == T(30), "Atomic exchange returned the wrong value"); +} + +template +static void +TestPointerWithOrdering() +{ + T array1[10]; + Atomic atomic(array1); + MOZ_ASSERT(atomic == array1, "Atomic variable did not initialize"); + + // Test atomic increment + MOZ_ASSERT(++atomic == array1 + 1, "Atomic increment did not work"); + MOZ_ASSERT(atomic++ == array1 + 1, "Atomic post-increment did not work"); + MOZ_ASSERT(atomic == array1 + 2, "Atomic post-increment did not work"); + + // Test atomic decrement + MOZ_ASSERT(--atomic == array1 + 1, "Atomic decrement did not work"); + MOZ_ASSERT(atomic-- == array1 + 1, "Atomic post-decrement did not work"); + MOZ_ASSERT(atomic == array1, "Atomic post-decrement did not work"); + + // Test other arithmetic operations + DebugOnly result; + result = (atomic += 2); + MOZ_ASSERT(atomic == array1 + 2, "Atomic += did not work"); + MOZ_ASSERT(result == array1 + 2, "Atomic += returned the wrong value"); + result = (atomic -= 1); + MOZ_ASSERT(atomic == array1 + 1, "Atomic -= did not work"); + MOZ_ASSERT(result == array1 + 1, "Atomic -= returned the wrong value"); + + // Test stores + result = (atomic = array1); + MOZ_ASSERT(atomic == array1, "Atomic assignment did not work"); + MOZ_ASSERT(result == array1, "Atomic assignment returned the wrong value"); + + // Test exchange + atomic = array1 + 2; + result = atomic.exchange(array1); + MOZ_ASSERT(atomic == array1, "Atomic exchange did not work"); + MOZ_ASSERT(result == array1 + 2, "Atomic exchange returned the wrong value"); +} + +template +static void +TestType() +{ + TestTypeWithOrdering(); + TestTypeWithOrdering(); + TestTypeWithOrdering(); +} + +template +static void +TestPointer() +{ + TestPointerWithOrdering(); + TestPointerWithOrdering(); + TestPointerWithOrdering(); +} + +int main() +{ + TestType(); + TestType(); + TestType(); + TestType(); + TestPointer(); + TestPointer(); + TestPointer(); + TestPointer(); +}