Files
TheRock/compiler/amd-llvm/orc-rt/unittests/LockedAccessTest.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

152 lines
3.6 KiB
C++

//===- LockedAccessTest.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, 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
//
//===----------------------------------------------------------------------===//
//
// Tests for orc-rt's LockedAccess.h APIs.
//
//===----------------------------------------------------------------------===//
#include "orc-rt/LockedAccess.h"
#include "gtest/gtest.h"
#include <mutex>
#include <thread>
#include <type_traits>
using namespace orc_rt;
namespace {
template <typename T> struct Foo {
std::mutex M;
T Val{};
Foo() = default;
Foo(T Val) : Val(std::move(Val)) {}
auto get() { return LockedAccess(Val, M); }
auto getConst() { return LockedAccess(std::as_const(Val), M); }
};
} // anonymous namespace
TEST(LockedAccessTest, ArrowRead) {
Foo<std::pair<int, int>> F({42, 7});
EXPECT_EQ(F.get()->first, 42);
EXPECT_EQ(F.get()->second, 7);
}
TEST(LockedAccessTest, ArrowWrite) {
Foo<std::pair<int, int>> F;
F.get()->first = 10;
F.get()->second = 20;
EXPECT_EQ(F.Val.first, 10);
EXPECT_EQ(F.Val.second, 20);
}
TEST(LockedAccessTest, ConstArrowReturnsConstPtr) {
Foo<int> F(42);
static_assert(std::is_const_v<
std::remove_pointer_t<decltype(F.getConst().operator->())>>,
"const overload should return const pointer");
}
TEST(LockedAccessTest, DerefRead) {
Foo<int> F(42);
EXPECT_EQ(*F.get(), 42);
}
TEST(LockedAccessTest, DerefWrite) {
Foo<int> F;
*F.get() = 7;
EXPECT_EQ(F.Val, 7);
}
TEST(LockedAccessTest, DerefPassToFunction) {
Foo<int> F(42);
auto timesTwo = [](int &X) { return X * 2; };
EXPECT_EQ(timesTwo(*F.get()), 84);
}
TEST(LockedAccessTest, ConstDerefReturnsConstRef) {
Foo<int> F(42);
static_assert(
std::is_const_v<std::remove_reference_t<decltype(*F.getConst())>>,
"const overload should return const reference");
}
TEST(LockedAccessTest, WithRefRead) {
Foo<int> F(42);
F.get().with_ref([](int &Y) { EXPECT_EQ(Y, 42); });
}
TEST(LockedAccessTest, WithRefWrite) {
Foo<int> F;
F.get().with_ref([](int &Y) { Y = 7; });
EXPECT_EQ(F.Val, 7);
}
TEST(LockedAccessTest, WithRefReturnValue) {
Foo<int> F(42);
int Result = F.get().with_ref([](int &Y) { return Y + 1; });
EXPECT_EQ(Result, 43);
}
TEST(LockedAccessTest, WithRefReturnReference) {
Foo<std::pair<int, int>> F({1, 2});
int &Ref = F.get().with_ref(
[](std::pair<int, int> &P) -> int & { return P.second; });
EXPECT_EQ(&Ref, &F.Val.second);
}
TEST(LockedAccessTest, ConstWithRefGetsConstReference) {
Foo<int> F(42);
F.getConst().with_ref([](const int &Y) { EXPECT_EQ(Y, 42); });
}
TEST(LockedAccessTest, WithRefMultiStatement) {
Foo<std::pair<int, int>> F;
F.get().with_ref([](std::pair<int, int> &P) {
P.first = 10;
P.second = P.first + 5;
});
EXPECT_EQ(F.Val.first, 10);
EXPECT_EQ(F.Val.second, 15);
}
TEST(LockedAccessTest, HoldsLockDuringArrow) {
struct Checker {
Foo<Checker> *F;
bool isLocked() { return !F->M.try_lock(); }
};
Foo<Checker> F({&F});
EXPECT_TRUE(F.get()->isLocked());
}
TEST(LockedAccessTest, HoldsLockDuringWithRef) {
Foo<int> F;
EXPECT_TRUE(F.get().with_ref([&](int &) { return !F.M.try_lock(); }));
}
TEST(LockedAccessTest, ProtectsAcrossThreads) {
Foo<int> F;
const int Iters = 10000;
auto Increment = [&]() {
for (int I = 0; I < Iters; ++I)
F.get().with_ref([](int &C) { ++C; });
};
std::thread T1(Increment);
std::thread T2(Increment);
T1.join();
T2.join();
EXPECT_EQ(F.Val, 2 * Iters);
}