From 39f2ce368593e05dfc7411a65cf6073dcea4da64 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Wed, 11 Feb 2026 16:41:54 -0600 Subject: [PATCH] [libc] Cleanup RPC helpers and comments Summary: Mostly NFC, replaced some inconsistent comments and replaces `class` with `typename` to be consistent. Also fix incomplete type detection I forgot to merge in the RPC helper PR. --- libc/docs/configure.rst | 2 +- libc/shared/rpc.h | 11 +++--- libc/shared/rpc_dispatch.h | 21 +++++++----- libc/shared/rpc_util.h | 70 ++++++++++++++++++++++---------------- 4 files changed, 60 insertions(+), 44 deletions(-) diff --git a/libc/docs/configure.rst b/libc/docs/configure.rst index e6bf4b20ef59..1e91a1f14da5 100644 --- a/libc/docs/configure.rst +++ b/libc/docs/configure.rst @@ -36,7 +36,7 @@ to learn about the defaults for your platform and target. - ``LIBC_ADD_NULL_CHECKS``: Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior. * **"math" options** - ``LIBC_CONF_FREXP_INF_NAN_EXPONENT``: The value written back to the second parameter when calling frexp/frexpf/frexpl` with `+/-Inf`/`NaN` is unspecified. Configure an explicit exp value for Inf/NaN inputs. - - ``LIBC_CONF_MATH_OPTIMIZATIONS``: Configure optimizations for math functions. Values accepted are LIBC_MATH_SKIP_ACCURATE_PASS, LIBC_MATH_SMALL_TABLES, LIBC_MATH_NO_ERRNO, LIBC_MATH_NO_EXCEPT, and LIBC_MATH_FAST. + - ``LIBC_CONF_MATH_OPTIMIZATIONS``: Configure optimizations for math functions. Values accepted are LIBC_MATH_SKIP_ACCURATE_PASS, LIBC_MATH_SMALL_TABLES, LIBC_MATH_NO_ERRNO, LIBC_MATH_NO_EXCEPT, LIBC_MATH_FAST, and LIBC_MATH_INTERMEDIATE_COMP_IN_FLOAT. - ``LIBC_CONF_MATH_USE_SYSTEM_FENV``: Use C standard fenv.h calls from the system libc instead our internal fenv implementations. * **"printf" options** - ``LIBC_CONF_PRINTF_DISABLE_FIXED_POINT``: Disable printing fixed point values in printf and friends. diff --git a/libc/shared/rpc.h b/libc/shared/rpc.h index 89f716a0d1ac..1233f4c0bbdf 100644 --- a/libc/shared/rpc.h +++ b/libc/shared/rpc.h @@ -138,8 +138,8 @@ template struct Process { return inverted_outbox; } - // Given the current outbox and inbox values, wait until the inbox changes - // to indicate that this thread owns the buffer element. + /// Given the current outbox and inbox values, wait until the inbox changes + /// to indicate that this thread owns the buffer element. RPC_ATTRS void wait_for_ownership(uint64_t lane_mask, uint32_t index, uint32_t outbox, uint32_t in) { while (buffer_unavailable(in, outbox)) { @@ -169,9 +169,10 @@ template struct Process { /// single lock on success, e.g. the result of rpc::get_lane_mask() /// The lock is held when the n-th bit of the lock bitfield is set. RPC_ATTRS bool try_lock(uint64_t lane_mask, uint32_t index) { - // On amdgpu, test and set to the nth lock bit and a sync_lane would suffice - // On volta, need to handle differences between the threads running and - // the threads that were detected in the previous call to get_lane_mask() + // On AMDGPU, test and set to the n-th lock bit and a sync_lane would + // suffice On NVIDIA with ITS we need to handle differences between the + // threads running and the threads that were detected in the previous call + // to get_lane_mask() // // All threads in lane_mask try to claim the lock. At most one can succeed. // There may be threads active which are not in lane mask which must not diff --git a/libc/shared/rpc_dispatch.h b/libc/shared/rpc_dispatch.h index e95f82496522..b977faf56fdc 100644 --- a/libc/shared/rpc_dispatch.h +++ b/libc/shared/rpc_dispatch.h @@ -13,7 +13,7 @@ namespace rpc { namespace { // Forward declarations needed for the server, we assume these are present. -extern "C" void *malloc(uint64_t); +extern "C" void *malloc(__SIZE_TYPE__); extern "C" void free(void *); // Traits to convert between a tuple and binary representation of an argument @@ -57,8 +57,9 @@ struct tuple_bytes> : tuple_bytes {}; template RPC_ATTRS constexpr void prepare_arg(rpc::Client::Port &port, Tuple &t) { using ArgTy = rpc::tuple_element_t; - if constexpr (rpc::is_pointer_v && - !rpc::is_void_v>) { + using ElemTy = rpc::remove_pointer_t; + if constexpr (rpc::is_pointer_v && rpc::is_complete_v && + !rpc::is_void_v) { // We assume all constant character arrays are C-strings. uint64_t size{}; if constexpr (rpc::is_same_v) @@ -77,8 +78,9 @@ RPC_ATTRS constexpr void prepare_arg(rpc::Client::Port &port, Tuple &t) { template RPC_ATTRS constexpr void prepare_arg(rpc::Server::Port &port) { using ArgTy = rpc::tuple_element_t; - if constexpr (rpc::is_pointer_v && - !rpc::is_void_v>) { + using ElemTy = rpc::remove_pointer_t; + if constexpr (rpc::is_pointer_v && rpc::is_complete_v && + !rpc::is_void_v) { void *args[NUM_LANES]{}; uint64_t sizes[NUM_LANES]{}; port.recv_n(args, sizes, [](uint64_t size) { @@ -102,7 +104,7 @@ RPC_ATTRS constexpr void finish_arg(rpc::Client::Port &port, Tuple &t) { using ArgTy = rpc::tuple_element_t; using MemoryTy = rpc::remove_const_t> *; if constexpr (rpc::is_pointer_v && !rpc::is_const_v && - !rpc::is_void_v>) { + rpc::is_complete_v && !rpc::is_void_v) { uint64_t size{}; void *buf{}; port.recv_n(&buf, &size, [&](uint64_t) { @@ -118,8 +120,9 @@ template RPC_ATTRS constexpr void finish_arg(rpc::Server::Port &port, Tuple (&t)[NUM_LANES]) { using ArgTy = rpc::tuple_element_t; + using ElemTy = rpc::remove_pointer_t; if constexpr (rpc::is_pointer_v && !rpc::is_const_v && - !rpc::is_void_v>) { + rpc::is_complete_v && !rpc::is_void_v) { const void *buffer[NUM_LANES]{}; size_t sizes[NUM_LANES]{}; for (uint32_t id = 0; id < NUM_LANES; ++id) { @@ -131,8 +134,8 @@ RPC_ATTRS constexpr void finish_arg(rpc::Server::Port &port, port.send_n(buffer, sizes); } - if constexpr (rpc::is_pointer_v && - !rpc::is_void_v>) { + if constexpr (rpc::is_pointer_v && rpc::is_complete_v && + !rpc::is_void_v) { for (uint32_t id = 0; id < NUM_LANES; ++id) { if (port.get_lane_mask() & (uint64_t(1) << id)) free(const_cast( diff --git a/libc/shared/rpc_util.h b/libc/shared/rpc_util.h index 5e2299367845..b75dbad3d94f 100644 --- a/libc/shared/rpc_util.h +++ b/libc/shared/rpc_util.h @@ -38,32 +38,32 @@ template struct type_identity { using type = T; }; -template struct type_constant { +template struct type_constant { static inline constexpr T value = v; }; /// Freestanding type trait helpers. -template struct remove_cv : type_identity {}; -template struct remove_cv : type_identity {}; -template using remove_cv_t = typename remove_cv::type; +template struct remove_cv : type_identity {}; +template struct remove_cv : type_identity {}; +template using remove_cv_t = typename remove_cv::type; -template struct remove_pointer : type_identity {}; -template struct remove_pointer : type_identity {}; -template using remove_pointer_t = typename remove_pointer::type; +template struct remove_pointer : type_identity {}; +template struct remove_pointer : type_identity {}; +template using remove_pointer_t = typename remove_pointer::type; -template struct remove_const : type_identity {}; -template struct remove_const : type_identity {}; -template using remove_const_t = typename remove_const::type; +template struct remove_const : type_identity {}; +template struct remove_const : type_identity {}; +template using remove_const_t = typename remove_const::type; -template struct remove_reference : type_identity {}; -template struct remove_reference : type_identity {}; -template struct remove_reference : type_identity {}; -template +template struct remove_reference : type_identity {}; +template struct remove_reference : type_identity {}; +template struct remove_reference : type_identity {}; +template using remove_reference_t = typename remove_reference::type; -template struct is_const : type_constant {}; -template struct is_const : type_constant {}; -template RPC_ATTRS constexpr bool is_const_v = is_const::value; +template struct is_const : type_constant {}; +template struct is_const : type_constant {}; +template RPC_ATTRS constexpr bool is_const_v = is_const::value; template struct is_pointer : type_constant {}; template struct is_pointer : type_constant {}; @@ -78,32 +78,42 @@ template struct is_same : type_constant {}; template RPC_ATTRS constexpr bool is_same_v = is_same::value; -template struct is_void : type_constant {}; +template struct is_void : type_constant {}; template <> struct is_void : type_constant {}; template RPC_ATTRS constexpr bool is_void_v = is_void::value; -template +template using void_t = void; +template +struct is_complete : type_constant {}; +template +struct is_complete> : type_constant { +}; +template +inline constexpr bool is_complete_v = is_complete::value; + +template struct is_trivially_copyable : public type_constant {}; -template +template RPC_ATTRS constexpr bool is_trivially_copyable_v = is_trivially_copyable::value; -template +template struct is_trivially_constructible : type_constant {}; -template +template RPC_ATTRS constexpr bool is_trivially_constructible_v = is_trivially_constructible::value; -template struct conditional : type_identity {}; -template +template +struct conditional : type_identity {}; +template struct conditional : type_identity {}; -template +template using conditional_t = typename conditional::type; /// Freestanding implementation of std::move. -template +template RPC_ATTRS constexpr typename remove_reference::type &&move(T &&t) { return static_cast::type &&>(t); } @@ -153,7 +163,7 @@ constexpr inline in_place_t in_place{}; constexpr inline nullopt_t nullopt{}; /// Freestanding and minimal implementation of std::optional. -template class optional { +template struct optional { template struct OptionalStorage { union { char empty; @@ -437,11 +447,13 @@ template struct function_traits { static constexpr uint64_t ARITY = sizeof...(Args); }; -template RPC_ATTRS constexpr T max(const T &a, const U &b) { +template +RPC_ATTRS constexpr T max(const T &a, const U &b) { return (a < b) ? b : a; } -template RPC_ATTRS constexpr T min(const T &a, const U &b) { +template +RPC_ATTRS constexpr T min(const T &a, const U &b) { return (a < b) ? a : b; }