1*76559068SAndroid Build Coastguard Worker //===-- atomic_test.cpp -----------------------------------------*- C++ -*-===//
2*76559068SAndroid Build Coastguard Worker //
3*76559068SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*76559068SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information.
5*76559068SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*76559068SAndroid Build Coastguard Worker //
7*76559068SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
8*76559068SAndroid Build Coastguard Worker
9*76559068SAndroid Build Coastguard Worker #include "tests/scudo_unit_test.h"
10*76559068SAndroid Build Coastguard Worker
11*76559068SAndroid Build Coastguard Worker #include "atomic_helpers.h"
12*76559068SAndroid Build Coastguard Worker
13*76559068SAndroid Build Coastguard Worker namespace scudo {
14*76559068SAndroid Build Coastguard Worker
15*76559068SAndroid Build Coastguard Worker template <typename T> struct ValAndMagic {
16*76559068SAndroid Build Coastguard Worker typename T::Type Magic0;
17*76559068SAndroid Build Coastguard Worker T A;
18*76559068SAndroid Build Coastguard Worker typename T::Type Magic1;
19*76559068SAndroid Build Coastguard Worker
20*76559068SAndroid Build Coastguard Worker static ValAndMagic<T> *Sink;
21*76559068SAndroid Build Coastguard Worker };
22*76559068SAndroid Build Coastguard Worker
23*76559068SAndroid Build Coastguard Worker template <typename T> ValAndMagic<T> *ValAndMagic<T>::Sink;
24*76559068SAndroid Build Coastguard Worker
25*76559068SAndroid Build Coastguard Worker template <typename T, memory_order LoadMO, memory_order StoreMO>
checkStoreLoad()26*76559068SAndroid Build Coastguard Worker void checkStoreLoad() {
27*76559068SAndroid Build Coastguard Worker typedef typename T::Type Type;
28*76559068SAndroid Build Coastguard Worker ValAndMagic<T> Val;
29*76559068SAndroid Build Coastguard Worker // Prevent the compiler from scalarizing the struct.
30*76559068SAndroid Build Coastguard Worker ValAndMagic<T>::Sink = &Val;
31*76559068SAndroid Build Coastguard Worker // Ensure that surrounding memory is not overwritten.
32*76559068SAndroid Build Coastguard Worker Val.Magic0 = Val.Magic1 = (Type)-3;
33*76559068SAndroid Build Coastguard Worker for (u64 I = 0; I < 100; I++) {
34*76559068SAndroid Build Coastguard Worker // Generate A value that occupies all bytes of the variable.
35*76559068SAndroid Build Coastguard Worker u64 V = I;
36*76559068SAndroid Build Coastguard Worker V |= V << 8;
37*76559068SAndroid Build Coastguard Worker V |= V << 16;
38*76559068SAndroid Build Coastguard Worker V |= V << 32;
39*76559068SAndroid Build Coastguard Worker Val.A.ValDoNotUse = (Type)V;
40*76559068SAndroid Build Coastguard Worker EXPECT_EQ(atomic_load(&Val.A, LoadMO), (Type)V);
41*76559068SAndroid Build Coastguard Worker Val.A.ValDoNotUse = (Type)-1;
42*76559068SAndroid Build Coastguard Worker atomic_store(&Val.A, (Type)V, StoreMO);
43*76559068SAndroid Build Coastguard Worker EXPECT_EQ(Val.A.ValDoNotUse, (Type)V);
44*76559068SAndroid Build Coastguard Worker }
45*76559068SAndroid Build Coastguard Worker EXPECT_EQ(Val.Magic0, (Type)-3);
46*76559068SAndroid Build Coastguard Worker EXPECT_EQ(Val.Magic1, (Type)-3);
47*76559068SAndroid Build Coastguard Worker }
48*76559068SAndroid Build Coastguard Worker
TEST(ScudoAtomicTest,AtomicStoreLoad)49*76559068SAndroid Build Coastguard Worker TEST(ScudoAtomicTest, AtomicStoreLoad) {
50*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u8, memory_order_relaxed, memory_order_relaxed>();
51*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u8, memory_order_consume, memory_order_relaxed>();
52*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u8, memory_order_acquire, memory_order_relaxed>();
53*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u8, memory_order_relaxed, memory_order_release>();
54*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u8, memory_order_seq_cst, memory_order_seq_cst>();
55*76559068SAndroid Build Coastguard Worker
56*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u16, memory_order_relaxed, memory_order_relaxed>();
57*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u16, memory_order_consume, memory_order_relaxed>();
58*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u16, memory_order_acquire, memory_order_relaxed>();
59*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u16, memory_order_relaxed, memory_order_release>();
60*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u16, memory_order_seq_cst, memory_order_seq_cst>();
61*76559068SAndroid Build Coastguard Worker
62*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u32, memory_order_relaxed, memory_order_relaxed>();
63*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u32, memory_order_consume, memory_order_relaxed>();
64*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u32, memory_order_acquire, memory_order_relaxed>();
65*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u32, memory_order_relaxed, memory_order_release>();
66*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u32, memory_order_seq_cst, memory_order_seq_cst>();
67*76559068SAndroid Build Coastguard Worker
68*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u64, memory_order_relaxed, memory_order_relaxed>();
69*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u64, memory_order_consume, memory_order_relaxed>();
70*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u64, memory_order_acquire, memory_order_relaxed>();
71*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u64, memory_order_relaxed, memory_order_release>();
72*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_u64, memory_order_seq_cst, memory_order_seq_cst>();
73*76559068SAndroid Build Coastguard Worker
74*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_uptr, memory_order_relaxed, memory_order_relaxed>();
75*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_uptr, memory_order_consume, memory_order_relaxed>();
76*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_uptr, memory_order_acquire, memory_order_relaxed>();
77*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_uptr, memory_order_relaxed, memory_order_release>();
78*76559068SAndroid Build Coastguard Worker checkStoreLoad<atomic_uptr, memory_order_seq_cst, memory_order_seq_cst>();
79*76559068SAndroid Build Coastguard Worker }
80*76559068SAndroid Build Coastguard Worker
checkAtomicCompareExchange()81*76559068SAndroid Build Coastguard Worker template <typename T> void checkAtomicCompareExchange() {
82*76559068SAndroid Build Coastguard Worker typedef typename T::Type Type;
83*76559068SAndroid Build Coastguard Worker Type OldVal = 42;
84*76559068SAndroid Build Coastguard Worker Type NewVal = 24;
85*76559068SAndroid Build Coastguard Worker Type V = OldVal;
86*76559068SAndroid Build Coastguard Worker EXPECT_TRUE(atomic_compare_exchange_strong(reinterpret_cast<T *>(&V), &OldVal,
87*76559068SAndroid Build Coastguard Worker NewVal, memory_order_relaxed));
88*76559068SAndroid Build Coastguard Worker EXPECT_FALSE(atomic_compare_exchange_strong(
89*76559068SAndroid Build Coastguard Worker reinterpret_cast<T *>(&V), &OldVal, NewVal, memory_order_relaxed));
90*76559068SAndroid Build Coastguard Worker EXPECT_EQ(NewVal, OldVal);
91*76559068SAndroid Build Coastguard Worker }
92*76559068SAndroid Build Coastguard Worker
TEST(ScudoAtomicTest,AtomicCompareExchangeTest)93*76559068SAndroid Build Coastguard Worker TEST(ScudoAtomicTest, AtomicCompareExchangeTest) {
94*76559068SAndroid Build Coastguard Worker checkAtomicCompareExchange<atomic_u8>();
95*76559068SAndroid Build Coastguard Worker checkAtomicCompareExchange<atomic_u16>();
96*76559068SAndroid Build Coastguard Worker checkAtomicCompareExchange<atomic_u32>();
97*76559068SAndroid Build Coastguard Worker checkAtomicCompareExchange<atomic_u64>();
98*76559068SAndroid Build Coastguard Worker checkAtomicCompareExchange<atomic_uptr>();
99*76559068SAndroid Build Coastguard Worker }
100*76559068SAndroid Build Coastguard Worker
101*76559068SAndroid Build Coastguard Worker } // namespace scudo
102