From 9b5c7d1f91964335b427b26fa43205c4143f87a1 Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Sun, 5 Apr 2026 09:05:55 -0500 Subject: [PATCH] [libc] Allow RPC interface to be compiled with MSVC (#190483) Summary: This should be portable to other compilers so it can support Windows infrastructure. I don't really use MSVC but godbolt seems happy: https://godbolt.org/z/Ysdx1Y1rq --- libc/shared/rpc.h | 26 ++++++++++++++++++++++++-- libc/shared/rpc_util.h | 5 +++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/libc/shared/rpc.h b/libc/shared/rpc.h index 9886c3851b25..a27b0676e595 100644 --- a/libc/shared/rpc.h +++ b/libc/shared/rpc.h @@ -20,10 +20,25 @@ #include "rpc_util.h" -namespace rpc { - /// Use scoped atomic variants if they are available for the target. #if !__has_builtin(__scoped_atomic_load_n) +#ifdef _MSC_VER // MSVC atomic support. +#include +#define __scoped_atomic_load_n(src, ord, scp) \ + (decltype(*(src)))__iso_volatile_load32((const volatile int32_t *)(src)) +#define __scoped_atomic_store_n(dst, src, ord, scp) \ + (sizeof(*(dst)) == 4 \ + ? __iso_volatile_store32((volatile int32_t *)(dst), (__int32)(src)) \ + : __iso_volatile_store64((volatile int64_t *)(dst), (__int64)(src))) +#define __scoped_atomic_fetch_or(src, val, ord, scp) \ + _InterlockedOr((volatile long *)(src), (long)(val)) +#define __scoped_atomic_fetch_and(src, val, ord, scp) \ + _InterlockedAnd((volatile long *)(src), (long)(val)) +#define __scoped_atomic_fetch_add(src, val, ord, scp) \ + _InterlockedExchangeAdd64((volatile long long *)(src), (long long)(val)) +#define __scoped_atomic_fetch_sub(src, val, ord, scp) \ + _InterlockedExchangeAdd64((volatile long long *)(src), -(long long)(val)) +#else // GNU atomic support. #define __scoped_atomic_load_n(src, ord, scp) __atomic_load_n(src, ord) #define __scoped_atomic_store_n(dst, src, ord, scp) \ __atomic_store_n(dst, src, ord) @@ -36,9 +51,16 @@ namespace rpc { #define __scoped_atomic_fetch_sub(src, val, ord, scp) \ __atomic_fetch_sub(src, val, ord) #endif +#endif #if !__has_builtin(__scoped_atomic_thread_fence) +#ifdef _MSC_VER +#define __scoped_atomic_thread_fence(ord, scp) _ReadWriteBarrier() +#else #define __scoped_atomic_thread_fence(ord, scp) __atomic_thread_fence(ord) #endif +#endif + +namespace rpc { /// Generic codes that can be used when implementing the server. enum RPCStatus { diff --git a/libc/shared/rpc_util.h b/libc/shared/rpc_util.h index c003db828fd7..09a97c63b562 100644 --- a/libc/shared/rpc_util.h +++ b/libc/shared/rpc_util.h @@ -453,8 +453,13 @@ template RPC_ATTRS T *advance(T *ptr, U bytes) { /// Wrapper around the optimal memory copy implementation for the target. RPC_ATTRS void rpc_memcpy(void *dst, const void *src, uint64_t count) { +#if __has_builtin(__builtin_memcpy) if (count) __builtin_memcpy(dst, src, count); +#else + for (uint64_t i = 0; i < count; ++i) + static_cast(dst)[i] = static_cast(src)[i]; +#endif } /// Minimal string length function.