[libc-commits] [libc] 85c66f5 - [libc] Instantiate and sanity check rpc class

Jon Chesterfield via libc-commits libc-commits at lists.llvm.org
Thu Jun 22 18:11:33 PDT 2023


Author: Jon Chesterfield
Date: 2023-06-23T02:11:18+01:00
New Revision: 85c66f5d18b3b4123eb9246a48ed5118219996d8

URL: https://github.com/llvm/llvm-project/commit/85c66f5d18b3b4123eb9246a48ed5118219996d8
DIFF: https://github.com/llvm/llvm-project/commit/85c66f5d18b3b4123eb9246a48ed5118219996d8.diff

LOG: [libc] Instantiate and sanity check rpc class

CMake plumbing cargo culted from other tests.
Minor changes to Process to allow statically allocating a buffer.

Reviewed By: jhuber6

Differential Revision: https://reviews.llvm.org/D153594

Added: 
    libc/test/src/__support/RPC/CMakeLists.txt
    libc/test/src/__support/RPC/rpc_smoke_test.cpp

Modified: 
    libc/src/__support/RPC/rpc.h
    libc/src/__support/RPC/rpc_util.h
    libc/test/src/__support/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/RPC/rpc.h b/libc/src/__support/RPC/rpc.h
index c96468ad005aa..a2f80822e4d49 100644
--- a/libc/src/__support/RPC/rpc.h
+++ b/libc/src/__support/RPC/rpc.h
@@ -116,11 +116,10 @@ template <bool Invert, uint32_t lane_size> struct Process {
   ///   Atomic<uint32_t> secondary[port_count];
   ///   Packet buffer[port_count];
   /// };
-  LIBC_INLINE static uint64_t allocation_size(uint64_t port_count) {
+  LIBC_INLINE static constexpr uint64_t allocation_size(uint64_t port_count) {
     return buffer_offset(port_count) + buffer_bytes(port_count);
   }
 
-protected:
   /// Retrieve the inbox state from memory shared between processes.
   LIBC_INLINE uint32_t load_inbox(uint64_t index) {
     return inbox[index].load(cpp::MemoryOrder::RELAXED);
@@ -251,27 +250,27 @@ template <bool Invert, uint32_t lane_size> struct Process {
   }
 
   /// Number of bytes to allocate for an inbox or outbox.
-  LIBC_INLINE static uint64_t mailbox_bytes(uint64_t port_count) {
+  LIBC_INLINE static constexpr uint64_t mailbox_bytes(uint64_t port_count) {
     return port_count * sizeof(cpp::Atomic<uint32_t>);
   }
 
   /// Number of bytes to allocate for the buffer containing the packets.
-  LIBC_INLINE static uint64_t buffer_bytes(uint64_t port_count) {
+  LIBC_INLINE static constexpr uint64_t buffer_bytes(uint64_t port_count) {
     return port_count * sizeof(Packet<lane_size>);
   }
 
   /// Offset of the inbox in memory. This is the same as the outbox if inverted.
-  LIBC_INLINE static uint64_t inbox_offset(uint64_t port_count) {
+  LIBC_INLINE static constexpr uint64_t inbox_offset(uint64_t port_count) {
     return Invert ? mailbox_bytes(port_count) : 0;
   }
 
   /// Offset of the outbox in memory. This is the same as the inbox if inverted.
-  LIBC_INLINE static uint64_t outbox_offset(uint64_t port_count) {
+  LIBC_INLINE static constexpr uint64_t outbox_offset(uint64_t port_count) {
     return Invert ? 0 : mailbox_bytes(port_count);
   }
 
   /// Offset of the buffer containing the packets after the inbox and outbox.
-  LIBC_INLINE static uint64_t buffer_offset(uint64_t port_count) {
+  LIBC_INLINE static constexpr uint64_t buffer_offset(uint64_t port_count) {
     return align_up(2 * mailbox_bytes(port_count), alignof(Packet<lane_size>));
   }
 };

diff  --git a/libc/src/__support/RPC/rpc_util.h b/libc/src/__support/RPC/rpc_util.h
index d8cb88d2a23fb..910eceece1288 100644
--- a/libc/src/__support/RPC/rpc_util.h
+++ b/libc/src/__support/RPC/rpc_util.h
@@ -51,7 +51,8 @@ LIBC_INLINE constexpr bool is_process_gpu() {
 }
 
 /// Return \p val aligned "upwards" according to \p align.
-template <typename V, typename A> LIBC_INLINE V align_up(V val, A align) {
+template <typename V, typename A>
+LIBC_INLINE constexpr V align_up(V val, A align) {
   return ((val + V(align) - 1) / V(align)) * V(align);
 }
 

diff  --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt
index 29fb25cc3cb27..5eabf9320ed40 100644
--- a/libc/test/src/__support/CMakeLists.txt
+++ b/libc/test/src/__support/CMakeLists.txt
@@ -126,5 +126,6 @@ add_custom_command(TARGET libc_str_to_float_comparison_test
 
 add_subdirectory(CPP)
 add_subdirectory(File)
+add_subdirectory(RPC)
 add_subdirectory(OSUtil)
 add_subdirectory(FPUtil)

diff  --git a/libc/test/src/__support/RPC/CMakeLists.txt b/libc/test/src/__support/RPC/CMakeLists.txt
new file mode 100644
index 0000000000000..8f79a49cec40c
--- /dev/null
+++ b/libc/test/src/__support/RPC/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_custom_target(libc-rpc-tests)
+
+add_libc_test(
+  rpc_smoke_test
+  SUITE
+    libc-rpc-tests
+  SRCS
+    rpc_smoke_test.cpp
+  DEPENDS
+   libc.src.__support.RPC.rpc
+)

diff  --git a/libc/test/src/__support/RPC/rpc_smoke_test.cpp b/libc/test/src/__support/RPC/rpc_smoke_test.cpp
new file mode 100644
index 0000000000000..3211c7f94723e
--- /dev/null
+++ b/libc/test/src/__support/RPC/rpc_smoke_test.cpp
@@ -0,0 +1,82 @@
+//===-- smoke tests for RPC -----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/RPC/rpc.h"
+
+#include "test/UnitTest/Test.h"
+
+namespace {
+enum { lane_size = 8, port_count = 4 };
+
+using ProcAType = __llvm_libc::rpc::Process<false, lane_size>;
+using ProcBType = __llvm_libc::rpc::Process<true, lane_size>;
+
+static_assert(ProcAType::inbox_offset(port_count) ==
+              ProcBType::outbox_offset(port_count));
+
+static_assert(ProcAType::outbox_offset(port_count) ==
+              ProcBType::inbox_offset(port_count));
+
+enum { alloc_size = ProcAType::allocation_size(port_count) };
+
+alignas(64) char buffer[alloc_size] = {0};
+} // namespace
+
+TEST(LlvmLibcRPCSmoke, SanityCheck) {
+
+  ProcAType ProcA;
+  ProcBType ProcB;
+
+  ProcA.reset(port_count, buffer);
+  ProcB.reset(port_count, buffer);
+
+  EXPECT_EQ(ProcA.get_buffer_start(), ProcB.get_buffer_start());
+
+  uint64_t index = 0; // any < port_count
+  uint64_t lane_mask = 1;
+
+  // Each process has its own local lock for index
+  EXPECT_TRUE(ProcA.try_lock(lane_mask, index));
+  EXPECT_TRUE(ProcB.try_lock(lane_mask, index));
+
+  // All zero to begin with
+  EXPECT_EQ(ProcA.load_inbox(index), 0u);
+  EXPECT_EQ(ProcB.load_inbox(index), 0u);
+  EXPECT_EQ(ProcA.load_outbox(index), 0u);
+  EXPECT_EQ(ProcB.load_outbox(index), 0u);
+
+  // Available for ProcA and not for ProcB
+  EXPECT_FALSE(ProcA.buffer_unavailable(ProcA.load_inbox(index),
+                                        ProcA.load_outbox(index)));
+  EXPECT_TRUE(ProcB.buffer_unavailable(ProcB.load_inbox(index),
+                                       ProcB.load_outbox(index)));
+
+  // ProcA write to outbox
+  uint32_t ProcAOutbox = ProcA.load_outbox(index);
+  EXPECT_EQ(ProcAOutbox, 0u);
+  ProcAOutbox = ProcA.invert_outbox(index, ProcAOutbox);
+  EXPECT_EQ(ProcAOutbox, 1u);
+
+  // No longer available for ProcA
+  EXPECT_TRUE(ProcA.buffer_unavailable(ProcA.load_inbox(index), ProcAOutbox));
+
+  // Outbox is still zero, hasn't been written to
+  EXPECT_EQ(ProcB.load_outbox(index), 0u);
+
+  // Wait for ownership will terminate because load_inbox returns 1
+  EXPECT_EQ(ProcB.load_inbox(index), 1u);
+  ProcB.wait_for_ownership(index, 0u, 0u);
+
+  // and B now has the buffer available
+  EXPECT_FALSE(ProcB.buffer_unavailable(ProcB.load_inbox(index),
+                                        ProcB.load_outbox(index)));
+
+  // Enough checks for one test, close the locks
+  ProcA.unlock(lane_mask, index);
+  ProcB.unlock(lane_mask, index);
+}


        


More information about the libc-commits mailing list