[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.
This commit is contained in:
parent
9f85fa2a52
commit
39f2ce3685
@ -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.
|
||||
|
||||
@ -138,8 +138,8 @@ template <bool Invert> 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 <bool Invert> 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
|
||||
|
||||
@ -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<rpc::tuple<Ts...>> : tuple_bytes<Ts...> {};
|
||||
template <uint64_t Idx, typename Tuple>
|
||||
RPC_ATTRS constexpr void prepare_arg(rpc::Client::Port &port, Tuple &t) {
|
||||
using ArgTy = rpc::tuple_element_t<Idx, Tuple>;
|
||||
if constexpr (rpc::is_pointer_v<ArgTy> &&
|
||||
!rpc::is_void_v<rpc::remove_pointer_t<ArgTy>>) {
|
||||
using ElemTy = rpc::remove_pointer_t<ArgTy>;
|
||||
if constexpr (rpc::is_pointer_v<ArgTy> && rpc::is_complete_v<ElemTy> &&
|
||||
!rpc::is_void_v<ElemTy>) {
|
||||
// We assume all constant character arrays are C-strings.
|
||||
uint64_t size{};
|
||||
if constexpr (rpc::is_same_v<ArgTy, const char *>)
|
||||
@ -77,8 +78,9 @@ RPC_ATTRS constexpr void prepare_arg(rpc::Client::Port &port, Tuple &t) {
|
||||
template <uint32_t NUM_LANES, typename Tuple, uint64_t Idx>
|
||||
RPC_ATTRS constexpr void prepare_arg(rpc::Server::Port &port) {
|
||||
using ArgTy = rpc::tuple_element_t<Idx, Tuple>;
|
||||
if constexpr (rpc::is_pointer_v<ArgTy> &&
|
||||
!rpc::is_void_v<rpc::remove_pointer_t<ArgTy>>) {
|
||||
using ElemTy = rpc::remove_pointer_t<ArgTy>;
|
||||
if constexpr (rpc::is_pointer_v<ArgTy> && rpc::is_complete_v<ElemTy> &&
|
||||
!rpc::is_void_v<ElemTy>) {
|
||||
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<Idx, Tuple>;
|
||||
using MemoryTy = rpc::remove_const_t<rpc::remove_pointer_t<ArgTy>> *;
|
||||
if constexpr (rpc::is_pointer_v<ArgTy> && !rpc::is_const_v<ArgTy> &&
|
||||
!rpc::is_void_v<rpc::remove_pointer_t<ArgTy>>) {
|
||||
rpc::is_complete_v<MemoryTy> && !rpc::is_void_v<MemoryTy>) {
|
||||
uint64_t size{};
|
||||
void *buf{};
|
||||
port.recv_n(&buf, &size, [&](uint64_t) {
|
||||
@ -118,8 +120,9 @@ template <uint32_t NUM_LANES, uint64_t Idx, typename Tuple>
|
||||
RPC_ATTRS constexpr void finish_arg(rpc::Server::Port &port,
|
||||
Tuple (&t)[NUM_LANES]) {
|
||||
using ArgTy = rpc::tuple_element_t<Idx, Tuple>;
|
||||
using ElemTy = rpc::remove_pointer_t<ArgTy>;
|
||||
if constexpr (rpc::is_pointer_v<ArgTy> && !rpc::is_const_v<ArgTy> &&
|
||||
!rpc::is_void_v<rpc::remove_pointer_t<ArgTy>>) {
|
||||
rpc::is_complete_v<ElemTy> && !rpc::is_void_v<ElemTy>) {
|
||||
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<ArgTy> &&
|
||||
!rpc::is_void_v<rpc::remove_pointer_t<ArgTy>>) {
|
||||
if constexpr (rpc::is_pointer_v<ArgTy> && rpc::is_complete_v<ElemTy> &&
|
||||
!rpc::is_void_v<ElemTy>) {
|
||||
for (uint32_t id = 0; id < NUM_LANES; ++id) {
|
||||
if (port.get_lane_mask() & (uint64_t(1) << id))
|
||||
free(const_cast<void *>(
|
||||
|
||||
@ -38,32 +38,32 @@ template <typename T> struct type_identity {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template <class T, T v> struct type_constant {
|
||||
template <typename T, T v> struct type_constant {
|
||||
static inline constexpr T value = v;
|
||||
};
|
||||
|
||||
/// Freestanding type trait helpers.
|
||||
template <class T> struct remove_cv : type_identity<T> {};
|
||||
template <class T> struct remove_cv<const T> : type_identity<T> {};
|
||||
template <class T> using remove_cv_t = typename remove_cv<T>::type;
|
||||
template <typename T> struct remove_cv : type_identity<T> {};
|
||||
template <typename T> struct remove_cv<const T> : type_identity<T> {};
|
||||
template <typename T> using remove_cv_t = typename remove_cv<T>::type;
|
||||
|
||||
template <class T> struct remove_pointer : type_identity<T> {};
|
||||
template <class T> struct remove_pointer<T *> : type_identity<T> {};
|
||||
template <class T> using remove_pointer_t = typename remove_pointer<T>::type;
|
||||
template <typename T> struct remove_pointer : type_identity<T> {};
|
||||
template <typename T> struct remove_pointer<T *> : type_identity<T> {};
|
||||
template <typename T> using remove_pointer_t = typename remove_pointer<T>::type;
|
||||
|
||||
template <class T> struct remove_const : type_identity<T> {};
|
||||
template <class T> struct remove_const<const T> : type_identity<T> {};
|
||||
template <class T> using remove_const_t = typename remove_const<T>::type;
|
||||
template <typename T> struct remove_const : type_identity<T> {};
|
||||
template <typename T> struct remove_const<const T> : type_identity<T> {};
|
||||
template <typename T> using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
template <class T> struct remove_reference : type_identity<T> {};
|
||||
template <class T> struct remove_reference<T &> : type_identity<T> {};
|
||||
template <class T> struct remove_reference<T &&> : type_identity<T> {};
|
||||
template <class T>
|
||||
template <typename T> struct remove_reference : type_identity<T> {};
|
||||
template <typename T> struct remove_reference<T &> : type_identity<T> {};
|
||||
template <typename T> struct remove_reference<T &&> : type_identity<T> {};
|
||||
template <typename T>
|
||||
using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
template <class T> struct is_const : type_constant<bool, false> {};
|
||||
template <class T> struct is_const<const T> : type_constant<bool, true> {};
|
||||
template <class T> RPC_ATTRS constexpr bool is_const_v = is_const<T>::value;
|
||||
template <typename T> struct is_const : type_constant<bool, false> {};
|
||||
template <typename T> struct is_const<const T> : type_constant<bool, true> {};
|
||||
template <typename T> RPC_ATTRS constexpr bool is_const_v = is_const<T>::value;
|
||||
|
||||
template <typename T> struct is_pointer : type_constant<bool, false> {};
|
||||
template <typename T> struct is_pointer<T *> : type_constant<bool, true> {};
|
||||
@ -78,32 +78,42 @@ template <typename T> struct is_same<T, T> : type_constant<bool, true> {};
|
||||
template <typename T, typename U>
|
||||
RPC_ATTRS constexpr bool is_same_v = is_same<T, U>::value;
|
||||
|
||||
template <class T> struct is_void : type_constant<bool, false> {};
|
||||
template <typename T> struct is_void : type_constant<bool, false> {};
|
||||
template <> struct is_void<void> : type_constant<bool, true> {};
|
||||
template <typename T> RPC_ATTRS constexpr bool is_void_v = is_void<T>::value;
|
||||
|
||||
template <class T>
|
||||
template <typename...> using void_t = void;
|
||||
template <typename T, typename = void>
|
||||
struct is_complete : type_constant<bool, false> {};
|
||||
template <typename T>
|
||||
struct is_complete<T, void_t<decltype(sizeof(T))>> : type_constant<bool, true> {
|
||||
};
|
||||
template <typename T>
|
||||
inline constexpr bool is_complete_v = is_complete<T>::value;
|
||||
|
||||
template <typename T>
|
||||
struct is_trivially_copyable
|
||||
: public type_constant<bool, __is_trivially_copyable(T)> {};
|
||||
template <class T>
|
||||
template <typename T>
|
||||
RPC_ATTRS constexpr bool is_trivially_copyable_v =
|
||||
is_trivially_copyable<T>::value;
|
||||
|
||||
template <class T, class... Args>
|
||||
template <typename T, typename... Args>
|
||||
struct is_trivially_constructible
|
||||
: type_constant<bool, __is_trivially_constructible(T, Args...)> {};
|
||||
template <class T, class... Args>
|
||||
template <typename T, typename... Args>
|
||||
RPC_ATTRS constexpr bool is_trivially_constructible_v =
|
||||
is_trivially_constructible<T>::value;
|
||||
|
||||
template <bool B, class T, class F> struct conditional : type_identity<T> {};
|
||||
template <class T, class F>
|
||||
template <bool B, typename T, typename F>
|
||||
struct conditional : type_identity<T> {};
|
||||
template <typename T, typename F>
|
||||
struct conditional<false, T, F> : type_identity<F> {};
|
||||
template <bool B, class T, class F>
|
||||
template <bool B, typename T, typename F>
|
||||
using conditional_t = typename conditional<B, T, F>::type;
|
||||
|
||||
/// Freestanding implementation of std::move.
|
||||
template <class T>
|
||||
template <typename T>
|
||||
RPC_ATTRS constexpr typename remove_reference<T>::type &&move(T &&t) {
|
||||
return static_cast<typename remove_reference<T>::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 <typename T> class optional {
|
||||
template <typename T> struct optional {
|
||||
template <typename U> struct OptionalStorage {
|
||||
union {
|
||||
char empty;
|
||||
@ -437,11 +447,13 @@ template <typename R, typename... Args> struct function_traits<R (*)(Args...)> {
|
||||
static constexpr uint64_t ARITY = sizeof...(Args);
|
||||
};
|
||||
|
||||
template <class T, class U> RPC_ATTRS constexpr T max(const T &a, const U &b) {
|
||||
template <typename T, typename U>
|
||||
RPC_ATTRS constexpr T max(const T &a, const U &b) {
|
||||
return (a < b) ? b : a;
|
||||
}
|
||||
|
||||
template <class T, class U> RPC_ATTRS constexpr T min(const T &a, const U &b) {
|
||||
template <typename T, typename U>
|
||||
RPC_ATTRS constexpr T min(const T &a, const U &b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user