mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-14 19:27:30 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
295
mfbt/tests/TestAtomics.cpp
Normal file
295
mfbt/tests/TestAtomics.cpp
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
/* -*- 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 <stdint.h>
|
||||
|
||||
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 <typename T, MemoryOrdering Order>
|
||||
static void
|
||||
TestTypeWithOrdering()
|
||||
{
|
||||
Atomic<T, Order> 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<typename T, MemoryOrdering Order>
|
||||
static void
|
||||
TestPointerWithOrdering()
|
||||
{
|
||||
T array1[10];
|
||||
Atomic<T*, Order> 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<MemoryOrdering Order>
|
||||
static void
|
||||
TestEnumWithOrdering()
|
||||
{
|
||||
Atomic<EnumType, Order> 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<MemoryOrdering Order>
|
||||
static void
|
||||
TestEnumClassWithOrdering()
|
||||
{
|
||||
Atomic<EnumClass, Order> 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 <MemoryOrdering Order>
|
||||
static void
|
||||
TestBoolWithOrdering()
|
||||
{
|
||||
Atomic<bool, Order> 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 <typename T>
|
||||
static void
|
||||
TestType()
|
||||
{
|
||||
TestTypeWithOrdering<T, SequentiallyConsistent>();
|
||||
TestTypeWithOrdering<T, ReleaseAcquire>();
|
||||
TestTypeWithOrdering<T, Relaxed>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void
|
||||
TestPointer()
|
||||
{
|
||||
TestPointerWithOrdering<T, SequentiallyConsistent>();
|
||||
TestPointerWithOrdering<T, ReleaseAcquire>();
|
||||
TestPointerWithOrdering<T, Relaxed>();
|
||||
}
|
||||
|
||||
static void
|
||||
TestEnum()
|
||||
{
|
||||
TestEnumWithOrdering<SequentiallyConsistent>();
|
||||
TestEnumWithOrdering<ReleaseAcquire>();
|
||||
TestEnumWithOrdering<Relaxed>();
|
||||
|
||||
TestEnumClassWithOrdering<SequentiallyConsistent>();
|
||||
TestEnumClassWithOrdering<ReleaseAcquire>();
|
||||
TestEnumClassWithOrdering<Relaxed>();
|
||||
}
|
||||
|
||||
static void
|
||||
TestBool()
|
||||
{
|
||||
TestBoolWithOrdering<SequentiallyConsistent>();
|
||||
TestBoolWithOrdering<ReleaseAcquire>();
|
||||
TestBoolWithOrdering<Relaxed>();
|
||||
}
|
||||
|
||||
#undef A
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
TestType<uint32_t>();
|
||||
TestType<int32_t>();
|
||||
TestType<uint64_t>();
|
||||
TestType<int64_t>();
|
||||
TestType<intptr_t>();
|
||||
TestType<uintptr_t>();
|
||||
TestPointer<int>();
|
||||
TestPointer<float>();
|
||||
TestPointer<uint16_t*>();
|
||||
TestPointer<uint32_t*>();
|
||||
TestEnum();
|
||||
TestBool();
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue