xref: /llvm-project/libc/test/src/__support/RPC/rpc_smoke_test.cpp (revision f879ac0385d4c5f7b2b9f4807cd7bd4a78556c1c)
185c66f5dSJon Chesterfield //===-- smoke tests for RPC -----------------------------------------------===//
285c66f5dSJon Chesterfield //
385c66f5dSJon Chesterfield // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
485c66f5dSJon Chesterfield // See https://llvm.org/LICENSE.txt for license information.
585c66f5dSJon Chesterfield // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
685c66f5dSJon Chesterfield //
785c66f5dSJon Chesterfield //===----------------------------------------------------------------------===//
885c66f5dSJon Chesterfield 
985c66f5dSJon Chesterfield #include "src/__support/RPC/rpc.h"
1085c66f5dSJon Chesterfield 
1185c66f5dSJon Chesterfield #include "test/UnitTest/Test.h"
1285c66f5dSJon Chesterfield 
1385c66f5dSJon Chesterfield namespace {
1485c66f5dSJon Chesterfield enum { lane_size = 8, port_count = 4 };
1585c66f5dSJon Chesterfield 
16*f879ac03SJoseph Huber using ProcAType = LIBC_NAMESPACE::rpc::Process<false>;
17*f879ac03SJoseph Huber using ProcBType = LIBC_NAMESPACE::rpc::Process<true>;
1885c66f5dSJon Chesterfield 
1985c66f5dSJon Chesterfield static_assert(ProcAType::inbox_offset(port_count) ==
2085c66f5dSJon Chesterfield               ProcBType::outbox_offset(port_count));
2185c66f5dSJon Chesterfield 
2285c66f5dSJon Chesterfield static_assert(ProcAType::outbox_offset(port_count) ==
2385c66f5dSJon Chesterfield               ProcBType::inbox_offset(port_count));
2485c66f5dSJon Chesterfield 
25*f879ac03SJoseph Huber enum { alloc_size = ProcAType::allocation_size(port_count, 1) };
2685c66f5dSJon Chesterfield 
2785c66f5dSJon Chesterfield alignas(64) char buffer[alloc_size] = {0};
2885c66f5dSJon Chesterfield } // namespace
2985c66f5dSJon Chesterfield 
TEST(LlvmLibcRPCSmoke,SanityCheck)3085c66f5dSJon Chesterfield TEST(LlvmLibcRPCSmoke, SanityCheck) {
3185c66f5dSJon Chesterfield 
3259896c16SJoseph Huber   ProcAType ProcA(port_count, buffer);
3359896c16SJoseph Huber   ProcBType ProcB(port_count, buffer);
3485c66f5dSJon Chesterfield 
3585c66f5dSJon Chesterfield   uint64_t index = 0; // any < port_count
3685c66f5dSJon Chesterfield   uint64_t lane_mask = 1;
3785c66f5dSJon Chesterfield 
3885c66f5dSJon Chesterfield   // Each process has its own local lock for index
3985c66f5dSJon Chesterfield   EXPECT_TRUE(ProcA.try_lock(lane_mask, index));
4085c66f5dSJon Chesterfield   EXPECT_TRUE(ProcB.try_lock(lane_mask, index));
4185c66f5dSJon Chesterfield 
4285c66f5dSJon Chesterfield   // All zero to begin with
431143da22SJon Chesterfield   EXPECT_EQ(ProcA.load_inbox(lane_mask, index), 0u);
441143da22SJon Chesterfield   EXPECT_EQ(ProcB.load_inbox(lane_mask, index), 0u);
451143da22SJon Chesterfield   EXPECT_EQ(ProcA.load_outbox(lane_mask, index), 0u);
461143da22SJon Chesterfield   EXPECT_EQ(ProcB.load_outbox(lane_mask, index), 0u);
4785c66f5dSJon Chesterfield 
4885c66f5dSJon Chesterfield   // Available for ProcA and not for ProcB
491143da22SJon Chesterfield   EXPECT_FALSE(ProcA.buffer_unavailable(ProcA.load_inbox(lane_mask, index),
501143da22SJon Chesterfield                                         ProcA.load_outbox(lane_mask, index)));
511143da22SJon Chesterfield   EXPECT_TRUE(ProcB.buffer_unavailable(ProcB.load_inbox(lane_mask, index),
521143da22SJon Chesterfield                                        ProcB.load_outbox(lane_mask, index)));
5385c66f5dSJon Chesterfield 
5485c66f5dSJon Chesterfield   // ProcA write to outbox
551143da22SJon Chesterfield   uint32_t ProcAOutbox = ProcA.load_outbox(lane_mask, index);
5685c66f5dSJon Chesterfield   EXPECT_EQ(ProcAOutbox, 0u);
5785c66f5dSJon Chesterfield   ProcAOutbox = ProcA.invert_outbox(index, ProcAOutbox);
5885c66f5dSJon Chesterfield   EXPECT_EQ(ProcAOutbox, 1u);
5985c66f5dSJon Chesterfield 
6085c66f5dSJon Chesterfield   // No longer available for ProcA
611143da22SJon Chesterfield   EXPECT_TRUE(ProcA.buffer_unavailable(ProcA.load_inbox(lane_mask, index),
621143da22SJon Chesterfield                                        ProcAOutbox));
6385c66f5dSJon Chesterfield 
6485c66f5dSJon Chesterfield   // Outbox is still zero, hasn't been written to
651143da22SJon Chesterfield   EXPECT_EQ(ProcB.load_outbox(lane_mask, index), 0u);
6685c66f5dSJon Chesterfield 
6785c66f5dSJon Chesterfield   // Wait for ownership will terminate because load_inbox returns 1
681143da22SJon Chesterfield   EXPECT_EQ(ProcB.load_inbox(lane_mask, index), 1u);
691143da22SJon Chesterfield   ProcB.wait_for_ownership(lane_mask, index, 0u, 0u);
7085c66f5dSJon Chesterfield 
7185c66f5dSJon Chesterfield   // and B now has the buffer available
721143da22SJon Chesterfield   EXPECT_FALSE(ProcB.buffer_unavailable(ProcB.load_inbox(lane_mask, index),
731143da22SJon Chesterfield                                         ProcB.load_outbox(lane_mask, index)));
7485c66f5dSJon Chesterfield 
7585c66f5dSJon Chesterfield   // Enough checks for one test, close the locks
7685c66f5dSJon Chesterfield   ProcA.unlock(lane_mask, index);
7785c66f5dSJon Chesterfield   ProcB.unlock(lane_mask, index);
7885c66f5dSJon Chesterfield }
79