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
13namespace {
14enum { lane_size = 8, port_count = 4 };
15
16using ProcAType = LIBC_NAMESPACE::rpc::Process<false>;
17using ProcBType = LIBC_NAMESPACE::rpc::Process<true>;
18
19static_assert(ProcAType::inbox_offset(port_count) ==
20 ProcBType::outbox_offset(port_count));
21
22static_assert(ProcAType::outbox_offset(port_count) ==
23 ProcBType::inbox_offset(port_count));
24
25enum { alloc_size = ProcAType::allocation_size(port_count, lane_size: 1) };
26
27alignas(64) char buffer[alloc_size] = {0};
28} // namespace
29
30TEST(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, current_outbox: 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, outbox: 0u, in: 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

source code of libc/test/src/__support/RPC/rpc_smoke_test.cpp