From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- mfbt/tests/TestAtomics.cpp | 274 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 mfbt/tests/TestAtomics.cpp (limited to 'mfbt/tests/TestAtomics.cpp') diff --git a/mfbt/tests/TestAtomics.cpp b/mfbt/tests/TestAtomics.cpp new file mode 100644 index 0000000000..7d333d37c1 --- /dev/null +++ b/mfbt/tests/TestAtomics.cpp @@ -0,0 +1,274 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 + +using mozilla::Atomic; +using mozilla::MemoryOrdering; +using mozilla::Relaxed; +using mozilla::ReleaseAcquire; +using mozilla::SequentiallyConsistent; + +#define A(a, b) MOZ_RELEASE_ASSERT(a, b) + +template +static void TestTypeWithOrdering() { + Atomic atomic(5); + A(atomic == 5, "Atomic variable did not initialize"); + + // Test atomic increment + A(++atomic == T(6), "Atomic increment did not work"); + A(atomic++ == T(6), "Atomic post-increment did not work"); + A(atomic == T(7), "Atomic post-increment did not work"); + + // Test atomic decrement + A(--atomic == 6, "Atomic decrement did not work"); + A(atomic-- == 6, "Atomic post-decrement did not work"); + A(atomic == 5, "Atomic post-decrement did not work"); + + // Test other arithmetic. + T result; + result = (atomic += T(5)); + A(atomic == T(10), "Atomic += did not work"); + A(result == T(10), "Atomic += returned the wrong value"); + result = (atomic -= T(3)); + A(atomic == T(7), "Atomic -= did not work"); + A(result == T(7), "Atomic -= returned the wrong value"); + + // Test assignment + result = (atomic = T(5)); + A(atomic == T(5), "Atomic assignment failed"); + A(result == T(5), "Atomic assignment returned the wrong value"); + + // Test logical operations. + result = (atomic ^= T(2)); + A(atomic == T(7), "Atomic ^= did not work"); + A(result == T(7), "Atomic ^= returned the wrong value"); + result = (atomic ^= T(4)); + A(atomic == T(3), "Atomic ^= did not work"); + A(result == T(3), "Atomic ^= returned the wrong value"); + result = (atomic |= T(8)); + A(atomic == T(11), "Atomic |= did not work"); + A(result == T(11), "Atomic |= returned the wrong value"); + result = (atomic |= T(8)); + A(atomic == T(11), "Atomic |= did not work"); + A(result == T(11), "Atomic |= returned the wrong value"); + result = (atomic &= T(12)); + A(atomic == T(8), "Atomic &= did not work"); + A(result == T(8), "Atomic &= returned the wrong value"); + + // Test exchange. + atomic = T(30); + result = atomic.exchange(42); + A(atomic == T(42), "Atomic exchange did not work"); + A(result == T(30), "Atomic exchange returned the wrong value"); + + // Test CAS. + atomic = T(1); + bool boolResult = atomic.compareExchange(0, 2); + A(!boolResult, "CAS should have returned false."); + A(atomic == T(1), "CAS shouldn't have done anything."); + + boolResult = atomic.compareExchange(1, 42); + A(boolResult, "CAS should have succeeded."); + A(atomic == T(42), "CAS should have changed atomic's value."); +} + +template +static void TestPointerWithOrdering() { + T array1[10]; + Atomic atomic(array1); + A(atomic == array1, "Atomic variable did not initialize"); + + // Test atomic increment + A(++atomic == array1 + 1, "Atomic increment did not work"); + A(atomic++ == array1 + 1, "Atomic post-increment did not work"); + A(atomic == array1 + 2, "Atomic post-increment did not work"); + + // Test atomic decrement + A(--atomic == array1 + 1, "Atomic decrement did not work"); + A(atomic-- == array1 + 1, "Atomic post-decrement did not work"); + A(atomic == array1, "Atomic post-decrement did not work"); + + // Test other arithmetic operations + T* result; + result = (atomic += 2); + A(atomic == array1 + 2, "Atomic += did not work"); + A(result == array1 + 2, "Atomic += returned the wrong value"); + result = (atomic -= 1); + A(atomic == array1 + 1, "Atomic -= did not work"); + A(result == array1 + 1, "Atomic -= returned the wrong value"); + + // Test stores + result = (atomic = array1); + A(atomic == array1, "Atomic assignment did not work"); + A(result == array1, "Atomic assignment returned the wrong value"); + + // Test exchange + atomic = array1 + 2; + result = atomic.exchange(array1); + A(atomic == array1, "Atomic exchange did not work"); + A(result == array1 + 2, "Atomic exchange returned the wrong value"); + + atomic = array1; + bool boolResult = atomic.compareExchange(array1 + 1, array1 + 2); + A(!boolResult, "CAS should have returned false."); + A(atomic == array1, "CAS shouldn't have done anything."); + + boolResult = atomic.compareExchange(array1, array1 + 3); + A(boolResult, "CAS should have succeeded."); + A(atomic == array1 + 3, "CAS should have changed atomic's value."); +} + +enum EnumType { + EnumType_0 = 0, + EnumType_1 = 1, + EnumType_2 = 2, + EnumType_3 = 3 +}; + +template +static void TestEnumWithOrdering() { + Atomic atomic(EnumType_2); + A(atomic == EnumType_2, "Atomic variable did not initialize"); + + // Test assignment + EnumType result; + result = (atomic = EnumType_3); + A(atomic == EnumType_3, "Atomic assignment failed"); + A(result == EnumType_3, "Atomic assignment returned the wrong value"); + + // Test exchange. + atomic = EnumType_1; + result = atomic.exchange(EnumType_2); + A(atomic == EnumType_2, "Atomic exchange did not work"); + A(result == EnumType_1, "Atomic exchange returned the wrong value"); + + // Test CAS. + atomic = EnumType_1; + bool boolResult = atomic.compareExchange(EnumType_0, EnumType_2); + A(!boolResult, "CAS should have returned false."); + A(atomic == EnumType_1, "CAS shouldn't have done anything."); + + boolResult = atomic.compareExchange(EnumType_1, EnumType_3); + A(boolResult, "CAS should have succeeded."); + A(atomic == EnumType_3, "CAS should have changed atomic's value."); +} + +enum class EnumClass : uint32_t { + Value0 = 0, + Value1 = 1, + Value2 = 2, + Value3 = 3 +}; + +template +static void TestEnumClassWithOrdering() { + Atomic atomic(EnumClass::Value2); + A(atomic == EnumClass::Value2, "Atomic variable did not initialize"); + + // Test assignment + EnumClass result; + result = (atomic = EnumClass::Value3); + A(atomic == EnumClass::Value3, "Atomic assignment failed"); + A(result == EnumClass::Value3, "Atomic assignment returned the wrong value"); + + // Test exchange. + atomic = EnumClass::Value1; + result = atomic.exchange(EnumClass::Value2); + A(atomic == EnumClass::Value2, "Atomic exchange did not work"); + A(result == EnumClass::Value1, "Atomic exchange returned the wrong value"); + + // Test CAS. + atomic = EnumClass::Value1; + bool boolResult = + atomic.compareExchange(EnumClass::Value0, EnumClass::Value2); + A(!boolResult, "CAS should have returned false."); + A(atomic == EnumClass::Value1, "CAS shouldn't have done anything."); + + boolResult = atomic.compareExchange(EnumClass::Value1, EnumClass::Value3); + A(boolResult, "CAS should have succeeded."); + A(atomic == EnumClass::Value3, "CAS should have changed atomic's value."); +} + +template +static void TestBoolWithOrdering() { + Atomic atomic(false); + A(atomic == false, "Atomic variable did not initialize"); + + // Test assignment + bool result; + result = (atomic = true); + A(atomic == true, "Atomic assignment failed"); + A(result == true, "Atomic assignment returned the wrong value"); + + // Test exchange. + atomic = false; + result = atomic.exchange(true); + A(atomic == true, "Atomic exchange did not work"); + A(result == false, "Atomic exchange returned the wrong value"); + + // Test CAS. + atomic = false; + bool boolResult = atomic.compareExchange(true, false); + A(!boolResult, "CAS should have returned false."); + A(atomic == false, "CAS shouldn't have done anything."); + + boolResult = atomic.compareExchange(false, true); + A(boolResult, "CAS should have succeeded."); + A(atomic == true, "CAS should have changed atomic's value."); +} + +template +static void TestType() { + TestTypeWithOrdering(); + TestTypeWithOrdering(); + TestTypeWithOrdering(); +} + +template +static void TestPointer() { + TestPointerWithOrdering(); + TestPointerWithOrdering(); + TestPointerWithOrdering(); +} + +static void TestEnum() { + TestEnumWithOrdering(); + TestEnumWithOrdering(); + TestEnumWithOrdering(); + + TestEnumClassWithOrdering(); + TestEnumClassWithOrdering(); + TestEnumClassWithOrdering(); +} + +static void TestBool() { + TestBoolWithOrdering(); + TestBoolWithOrdering(); + TestBoolWithOrdering(); +} + +#undef A + +int main() { + TestType(); + TestType(); + TestType(); + TestType(); + TestType(); + TestType(); + TestPointer(); + TestPointer(); + TestPointer(); + TestPointer(); + TestEnum(); + TestBool(); + return 0; +} -- cgit v1.2.3