1 //===-- smoke tests for RPC -----------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "src/__support/RPC/rpc.h"
10
11 #include "test/UnitTest/Test.h"
12
13 namespace {
14 enum { lane_size = 8, port_count = 4 };
15
16 using ProcAType = LIBC_NAMESPACE::rpc::Process<false>;
17 using ProcBType = LIBC_NAMESPACE::rpc::Process<true>;
18
19 static_assert(ProcAType::inbox_offset(port_count) ==
20 ProcBType::outbox_offset(port_count));
21
22 static_assert(ProcAType::outbox_offset(port_count) ==
23 ProcBType::inbox_offset(port_count));
24
25 enum { alloc_size = ProcAType::allocation_size(port_count, 1) };
26
27 alignas(64) char buffer[alloc_size] = {0};
28 } // namespace
29
TEST(LlvmLibcRPCSmoke,SanityCheck)30 TEST(LlvmLibcRPCSmoke, SanityCheck) {
31
32 ProcAType ProcA(port_count, buffer);
33 ProcBType ProcB(port_count, buffer);
34
35 uint64_t index = 0; // any < port_count
36 uint64_t lane_mask = 1;
37
38 // Each process has its own local lock for index
39 EXPECT_TRUE(ProcA.try_lock(lane_mask, index));
40 EXPECT_TRUE(ProcB.try_lock(lane_mask, index));
41
42 // All zero to begin with
43 EXPECT_EQ(ProcA.load_inbox(lane_mask, index), 0u);
44 EXPECT_EQ(ProcB.load_inbox(lane_mask, index), 0u);
45 EXPECT_EQ(ProcA.load_outbox(lane_mask, index), 0u);
46 EXPECT_EQ(ProcB.load_outbox(lane_mask, index), 0u);
47
48 // Available for ProcA and not for ProcB
49 EXPECT_FALSE(ProcA.buffer_unavailable(ProcA.load_inbox(lane_mask, index),
50 ProcA.load_outbox(lane_mask, index)));
51 EXPECT_TRUE(ProcB.buffer_unavailable(ProcB.load_inbox(lane_mask, index),
52 ProcB.load_outbox(lane_mask, index)));
53
54 // ProcA write to outbox
55 uint32_t ProcAOutbox = ProcA.load_outbox(lane_mask, index);
56 EXPECT_EQ(ProcAOutbox, 0u);
57 ProcAOutbox = ProcA.invert_outbox(index, ProcAOutbox);
58 EXPECT_EQ(ProcAOutbox, 1u);
59
60 // No longer available for ProcA
61 EXPECT_TRUE(ProcA.buffer_unavailable(ProcA.load_inbox(lane_mask, index),
62 ProcAOutbox));
63
64 // Outbox is still zero, hasn't been written to
65 EXPECT_EQ(ProcB.load_outbox(lane_mask, index), 0u);
66
67 // Wait for ownership will terminate because load_inbox returns 1
68 EXPECT_EQ(ProcB.load_inbox(lane_mask, index), 1u);
69 ProcB.wait_for_ownership(lane_mask, index, 0u, 0u);
70
71 // and B now has the buffer available
72 EXPECT_FALSE(ProcB.buffer_unavailable(ProcB.load_inbox(lane_mask, index),
73 ProcB.load_outbox(lane_mask, index)));
74
75 // Enough checks for one test, close the locks
76 ProcA.unlock(lane_mask, index);
77 ProcB.unlock(lane_mask, index);
78 }
79