xref: /llvm-project/libc/test/src/__support/RPC/rpc_smoke_test.cpp (revision f879ac0385d4c5f7b2b9f4807cd7bd4a78556c1c)
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