[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
This commit is contained in:
Joseph Huber 2026-04-05 09:05:55 -05:00 committed by GitHub
parent 144c324380
commit 9b5c7d1f91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 2 deletions

View File

@ -20,10 +20,25 @@
#include "rpc_util.h" #include "rpc_util.h"
namespace rpc {
/// Use scoped atomic variants if they are available for the target. /// Use scoped atomic variants if they are available for the target.
#if !__has_builtin(__scoped_atomic_load_n) #if !__has_builtin(__scoped_atomic_load_n)
#ifdef _MSC_VER // MSVC atomic support.
#include <intrin.h>
#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_load_n(src, ord, scp) __atomic_load_n(src, ord)
#define __scoped_atomic_store_n(dst, src, ord, scp) \ #define __scoped_atomic_store_n(dst, src, ord, scp) \
__atomic_store_n(dst, src, ord) __atomic_store_n(dst, src, ord)
@ -36,9 +51,16 @@ namespace rpc {
#define __scoped_atomic_fetch_sub(src, val, ord, scp) \ #define __scoped_atomic_fetch_sub(src, val, ord, scp) \
__atomic_fetch_sub(src, val, ord) __atomic_fetch_sub(src, val, ord)
#endif #endif
#endif
#if !__has_builtin(__scoped_atomic_thread_fence) #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) #define __scoped_atomic_thread_fence(ord, scp) __atomic_thread_fence(ord)
#endif #endif
#endif
namespace rpc {
/// Generic codes that can be used when implementing the server. /// Generic codes that can be used when implementing the server.
enum RPCStatus { enum RPCStatus {

View File

@ -453,8 +453,13 @@ template <typename T, typename U> RPC_ATTRS T *advance(T *ptr, U bytes) {
/// Wrapper around the optimal memory copy implementation for the target. /// Wrapper around the optimal memory copy implementation for the target.
RPC_ATTRS void rpc_memcpy(void *dst, const void *src, uint64_t count) { RPC_ATTRS void rpc_memcpy(void *dst, const void *src, uint64_t count) {
#if __has_builtin(__builtin_memcpy)
if (count) if (count)
__builtin_memcpy(dst, src, count); __builtin_memcpy(dst, src, count);
#else
for (uint64_t i = 0; i < count; ++i)
static_cast<uint8_t *>(dst)[i] = static_cast<const uint8_t *>(src)[i];
#endif
} }
/// Minimal string length function. /// Minimal string length function.