blob: a9fce2f2173e04a86344cc2c92f03223f6840d83 [file] [log] [blame]
// Copyright 2021 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "iree/base/internal/atomics.h"
#include <cstddef>
#include <cstdint>
#include "iree/testing/gtest.h"
namespace {
// NOTE: these tests are just to ensure we correctly compile the macros across
// our supported toolchains: they don't verify that the memory semantics are
// correct (as that would be difficult and is really the toolchain's job).
TEST(AtomicPtr, LoadStore) {
intptr_t ptr_0 = 0x0;
intptr_t ptr_1 = 0x1;
iree_atomic_intptr_t value = IREE_ATOMIC_VAR_INIT(ptr_0);
EXPECT_EQ(ptr_0, iree_atomic_load_intptr(&value, iree_memory_order_seq_cst));
iree_atomic_store_intptr(&value, ptr_1, iree_memory_order_seq_cst);
EXPECT_EQ(ptr_1, iree_atomic_load_intptr(&value, iree_memory_order_seq_cst));
}
TEST(AtomicPtr, AddSub) {
intptr_t ptr_0 = 0x0;
intptr_t ptr_1 = 0x1;
intptr_t ptr_2 = 0x2;
iree_atomic_intptr_t value = IREE_ATOMIC_VAR_INIT(ptr_0);
EXPECT_EQ(ptr_0, iree_atomic_fetch_add_intptr(&value, ptr_1,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_1, iree_atomic_fetch_add_intptr(&value, ptr_1,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_2, iree_atomic_fetch_sub_intptr(&value, ptr_1,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_1, iree_atomic_fetch_sub_intptr(&value, ptr_1,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_0, iree_atomic_load_intptr(&value, iree_memory_order_seq_cst));
}
TEST(AtomicPtr, Exchange) {
intptr_t ptr_0 = 0x0;
intptr_t ptr_1 = 0x1;
intptr_t ptr_2 = 0x2;
iree_atomic_intptr_t value = IREE_ATOMIC_VAR_INIT(ptr_0);
EXPECT_EQ(ptr_0, iree_atomic_exchange_intptr(&value, ptr_1,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_1, iree_atomic_exchange_intptr(&value, ptr_2,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_2, iree_atomic_load_intptr(&value, iree_memory_order_seq_cst));
}
TEST(AtomicPtr, CompareExchange) {
intptr_t ptr_0 = 0x0;
intptr_t ptr_1 = 0x1;
intptr_t ptr_2 = 0x2;
iree_atomic_intptr_t value = IREE_ATOMIC_VAR_INIT(ptr_0);
intptr_t ptr_expected = 0;
// OK: value == ptr_0, CAS(ptr_0 -> ptr_1)
iree_atomic_store_intptr(&value, ptr_0, iree_memory_order_seq_cst);
ptr_expected = ptr_0;
EXPECT_TRUE(iree_atomic_compare_exchange_strong_intptr(
&value, &ptr_expected, ptr_1, iree_memory_order_seq_cst,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_0, ptr_expected);
EXPECT_EQ(ptr_1, iree_atomic_load_intptr(&value, iree_memory_order_seq_cst));
// OK: value == ptr_1, CAS(ptr_1 -> ptr_2)
iree_atomic_store_intptr(&value, ptr_1, iree_memory_order_seq_cst);
ptr_expected = ptr_1;
EXPECT_TRUE(iree_atomic_compare_exchange_strong_intptr(
&value, &ptr_expected, ptr_2, iree_memory_order_seq_cst,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_1, ptr_expected);
EXPECT_EQ(ptr_2, iree_atomic_load_intptr(&value, iree_memory_order_seq_cst));
// FAIL: value == ptr_0, CAS(ptr_1 -> ptr_2)
iree_atomic_store_intptr(&value, ptr_0, iree_memory_order_seq_cst);
ptr_expected = ptr_1;
EXPECT_FALSE(iree_atomic_compare_exchange_strong_intptr(
&value, &ptr_expected, ptr_2, iree_memory_order_seq_cst,
iree_memory_order_seq_cst));
EXPECT_EQ(ptr_0, ptr_expected);
EXPECT_EQ(ptr_0, iree_atomic_load_intptr(&value, iree_memory_order_seq_cst));
}
TEST(AtomicRefCount, IncDec) {
iree_atomic_ref_count_t count;
iree_atomic_ref_count_init(&count);
iree_atomic_ref_count_inc(&count);
iree_atomic_ref_count_inc(&count);
EXPECT_EQ(3, iree_atomic_ref_count_dec(&count));
EXPECT_EQ(2, iree_atomic_ref_count_dec(&count));
EXPECT_EQ(1, iree_atomic_ref_count_dec(&count));
}
} // namespace