blob: 0663a86bee9edd9f691ae6675eee803defc06800 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fbl/atomic_ref.h>
#include <zxtest/zxtest.h>
namespace {
// Functional test of each member function of fbl::atomic_ref
TEST(AtomicRef, BasicTest) {
int val = 0;
fbl::atomic_ref<int> atomic_ref_1(val);
EXPECT_EQ(true, atomic_ref_1.is_always_lock_free);
atomic_ref_1 = 1;
EXPECT_EQ(true, atomic_ref_1.is_lock_free());
EXPECT_EQ(1, val); // Check that the underlying storage is updated
atomic_ref_1.store(2);
EXPECT_EQ(2, atomic_ref_1.load());
EXPECT_EQ(2, atomic_ref_1.exchange(0));
EXPECT_EQ(0, atomic_ref_1.exchange(2, fbl::memory_order_acq_rel));
atomic_ref_1 = 0;
int expected = 0;
EXPECT_EQ(true, atomic_ref_1.compare_exchange_strong(expected, 1));
EXPECT_EQ(1, atomic_ref_1.load());
EXPECT_EQ(0, expected);
EXPECT_EQ(false, atomic_ref_1.compare_exchange_strong(expected, 1));
EXPECT_EQ(1, expected);
atomic_ref_1 = 0;
EXPECT_EQ(0, atomic_ref_1.fetch_add(1));
EXPECT_EQ(1, atomic_ref_1.load());
atomic_ref_1 = 1;
EXPECT_EQ(1, atomic_ref_1.fetch_sub(1));
EXPECT_EQ(0, atomic_ref_1.load());
atomic_ref_1 = 2;
EXPECT_EQ(2, atomic_ref_1.fetch_and(1));
EXPECT_EQ(0, atomic_ref_1.load());
atomic_ref_1 = 2;
EXPECT_EQ(2, atomic_ref_1.fetch_or(1));
EXPECT_EQ(3, atomic_ref_1.load());
atomic_ref_1 = 2;
EXPECT_EQ(2, atomic_ref_1.fetch_xor(2));
EXPECT_EQ(0, atomic_ref_1.load());
atomic_ref_1 = 0;
EXPECT_EQ(0, atomic_ref_1++);
EXPECT_EQ(1, atomic_ref_1.load());
atomic_ref_1 = 0;
EXPECT_EQ(1, ++atomic_ref_1);
EXPECT_EQ(1, atomic_ref_1.load());
atomic_ref_1 = 1;
EXPECT_EQ(1, atomic_ref_1--);
EXPECT_EQ(0, atomic_ref_1.load());
atomic_ref_1 = 1;
EXPECT_EQ(0, --atomic_ref_1);
EXPECT_EQ(0, atomic_ref_1.load());
atomic_ref_1 = 0;
atomic_ref_1 += 2;
EXPECT_EQ(2, atomic_ref_1.load());
atomic_ref_1 = 2;
atomic_ref_1 -= 2;
EXPECT_EQ(0, atomic_ref_1.load());
atomic_ref_1 = 1;
atomic_ref_1 &= -1;
EXPECT_EQ(1, atomic_ref_1.load());
atomic_ref_1 = 1;
atomic_ref_1 |= 2;
EXPECT_EQ(3, atomic_ref_1.load());
atomic_ref_1 = 1;
atomic_ref_1 ^= 2;
EXPECT_EQ(3, atomic_ref_1.load());
atomic_ref_1.store(1);
fbl::atomic_ref<int> atomic_ref_2(atomic_ref_1);
EXPECT_EQ(1, atomic_ref_2.load());
}
// Basic test of qualified integral types
TEST(AtomicRef, BasicQualified) {
volatile uint32_t i = 0;
fbl::atomic_ref<volatile uint32_t> i_ref(i);
i_ref.store(1);
EXPECT_EQ(1, i_ref.load());
EXPECT_EQ(1, i_ref.exchange(2));
}
} // anonymous namespace