Remove `include/grpc/impl/codegen/atm.h` (#31673)

pull/31611/head
Cheng-Yu Chung 2 years ago committed by GitHub
parent a1dc498356
commit e69592d29c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 74
      include/grpc/impl/codegen/atm.h
  2. 61
      include/grpc/impl/codegen/atm_gcc_atomic.h
  3. 62
      include/grpc/impl/codegen/atm_gcc_sync.h
  4. 109
      include/grpc/impl/codegen/atm_windows.h
  5. 71
      include/grpc/support/atm.h
  6. 60
      include/grpc/support/atm_gcc_atomic.h
  7. 59
      include/grpc/support/atm_gcc_sync.h
  8. 106
      include/grpc/support/atm_windows.h
  9. 2
      include/grpcpp/completion_queue.h
  10. 3
      src/core/BUILD
  11. 2
      test/cpp/interop/server_helper.h

@ -21,77 +21,9 @@
// IWYU pragma: private, include <grpc/support/atm.h> // IWYU pragma: private, include <grpc/support/atm.h>
/** This interface provides atomic operations and barriers. #include <grpc/support/port_platform.h>
It is internal to gpr support code and should not be used outside it.
If an operation with acquire semantics precedes another memory access by the /// TODO(chengyuc): Remove this file after solving compatibility.
same thread, the operation will precede that other access as seen by other #include <grpc/support/atm.h>
threads.
If an operation with release semantics follows another memory access by the
same thread, the operation will follow that other access as seen by other
threads.
Routines with "acq" or "full" in the name have acquire semantics. Routines
with "rel" or "full" in the name have release semantics. Routines with
"no_barrier" in the name have neither acquire not release semantics.
The routines may be implemented as macros.
// Atomic operations act on an intergral_type gpr_atm that is guaranteed to
// be the same size as a pointer.
typedef intptr_t gpr_atm;
// A memory barrier, providing both acquire and release semantics, but not
// otherwise acting on memory.
void gpr_atm_full_barrier(void);
// Atomically return *p, with acquire semantics.
gpr_atm gpr_atm_acq_load(gpr_atm *p);
gpr_atm gpr_atm_no_barrier_load(gpr_atm *p);
// Atomically set *p = value, with release semantics.
void gpr_atm_rel_store(gpr_atm *p, gpr_atm value);
// Atomically add delta to *p, and return the old value of *p, with
// the barriers specified.
gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p, gpr_atm delta);
gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta);
// Atomically, if *p==o, set *p=n and return non-zero otherwise return 0,
// with the barriers specified if the operation succeeds.
int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
// Atomically, set *p=n and return the old value of *p
gpr_atm gpr_atm_full_xchg(gpr_atm *p, gpr_atm n);
*/
#include <grpc/impl/codegen/port_platform.h>
#if defined(GPR_GCC_ATOMIC)
#include <grpc/impl/codegen/atm_gcc_atomic.h> // IWYU pragma: export
#elif defined(GPR_GCC_SYNC)
#include <grpc/impl/codegen/atm_gcc_sync.h> // IWYU pragma: export
#elif defined(GPR_WINDOWS_ATOMIC)
#include <grpc/impl/codegen/atm_windows.h> // IWYU pragma: export
#else
#error could not determine platform for atm
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** Adds \a delta to \a *value, clamping the result to the range specified
by \a min and \a max. Returns the new value. */
gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm* value, gpr_atm delta,
gpr_atm min, gpr_atm max);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_ATM_H */ #endif /* GRPC_IMPL_CODEGEN_ATM_H */

@ -21,64 +21,9 @@
// IWYU pragma: private, include <grpc/support/atm.h> // IWYU pragma: private, include <grpc/support/atm.h>
/* atm_platform.h for gcc and gcc-like compilers with the #include <grpc/support/port_platform.h>
__atomic_* interface. */
#include <grpc/impl/codegen/port_platform.h>
#ifdef __cplusplus /// TODO(chengyuc): Remove this file after solving compatibility.
extern "C" { #include <grpc/support/atm_gcc_atomic.h>
#endif
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
#define gpr_atm_full_barrier() (__atomic_thread_fence(__ATOMIC_SEQ_CST))
#define gpr_atm_acq_load(p) (__atomic_load_n((p), __ATOMIC_ACQUIRE))
#define gpr_atm_no_barrier_load(p) (__atomic_load_n((p), __ATOMIC_RELAXED))
#define gpr_atm_rel_store(p, value) \
(__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELEASE))
#define gpr_atm_no_barrier_store(p, value) \
(__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELAXED))
#define gpr_atm_no_barrier_fetch_add(p, delta) \
__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_RELAXED)
#define gpr_atm_full_fetch_add(p, delta) \
__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_ACQ_REL)
static __inline int gpr_atm_no_barrier_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELAXED,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_acq_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_ACQUIRE,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_rel_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELEASE,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_full_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED);
}
#define gpr_atm_full_xchg(p, n) __atomic_exchange_n((p), (n), __ATOMIC_ACQ_REL)
#ifdef __cplusplus
}
#endif
#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H */ #endif /* GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H */

@ -21,65 +21,9 @@
// IWYU pragma: private, include <grpc/support/atm.h> // IWYU pragma: private, include <grpc/support/atm.h>
/* variant of atm_platform.h for gcc and gcc-like compiers with __sync_* #include <grpc/support/port_platform.h>
interface */
#include <grpc/impl/codegen/port_platform.h>
typedef intptr_t gpr_atm; /// TODO(chengyuc): Remove this file after solving compatibility.
#define GPR_ATM_MAX INTPTR_MAX #include <grpc/support/atm_gcc_sync.h>
#define GPR_ATM_MIN INTPTR_MIN
#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
#if defined(__i386) || defined(__x86_64__)
/* All loads are acquire loads and all stores are release stores. */
#define GPR_ATM_LS_BARRIER_() GPR_ATM_COMPILE_BARRIER_()
#else
#define GPR_ATM_LS_BARRIER_() gpr_atm_full_barrier()
#endif
#define gpr_atm_full_barrier() (__sync_synchronize())
static __inline gpr_atm gpr_atm_acq_load(const gpr_atm* p) {
gpr_atm value = *p;
GPR_ATM_LS_BARRIER_();
return value;
}
static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm* p) {
gpr_atm value = *p;
GPR_ATM_COMPILE_BARRIER_();
return value;
}
static __inline void gpr_atm_rel_store(gpr_atm* p, gpr_atm value) {
GPR_ATM_LS_BARRIER_();
*p = value;
}
static __inline void gpr_atm_no_barrier_store(gpr_atm* p, gpr_atm value) {
GPR_ATM_COMPILE_BARRIER_();
*p = value;
}
#undef GPR_ATM_LS_BARRIER_
#undef GPR_ATM_COMPILE_BARRIER_
#define gpr_atm_no_barrier_fetch_add(p, delta) \
gpr_atm_full_fetch_add((p), (delta))
#define gpr_atm_full_fetch_add(p, delta) (__sync_fetch_and_add((p), (delta)))
#define gpr_atm_no_barrier_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
#define gpr_atm_acq_cas(p, o, n) (__sync_bool_compare_and_swap((p), (o), (n)))
#define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
#define gpr_atm_full_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
static __inline gpr_atm gpr_atm_full_xchg(gpr_atm* p, gpr_atm n) {
gpr_atm cur;
do {
cur = gpr_atm_acq_load(p);
} while (!gpr_atm_rel_cas(p, cur, n));
return cur;
}
#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_SYNC_H */ #endif /* GRPC_IMPL_CODEGEN_ATM_GCC_SYNC_H */

@ -21,112 +21,9 @@
// IWYU pragma: private, include <grpc/support/atm.h> // IWYU pragma: private, include <grpc/support/atm.h>
/** Win32 variant of atm_platform.h */ #include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/port_platform.h>
#ifdef GPR_WINDOWS /// TODO(chengyuc): Remove this file after solving compatibility.
#include <grpc/support/atm_windows.h>
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
#define gpr_atm_full_barrier MemoryBarrier
static __inline gpr_atm gpr_atm_acq_load(const gpr_atm* p) {
gpr_atm result = *p;
gpr_atm_full_barrier();
return result;
}
static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm* p) {
/* TODO(dklempner): Can we implement something better here? */
return gpr_atm_acq_load(p);
}
static __inline void gpr_atm_rel_store(gpr_atm* p, gpr_atm value) {
gpr_atm_full_barrier();
*p = value;
}
static __inline void gpr_atm_no_barrier_store(gpr_atm* p, gpr_atm value) {
/* TODO(ctiller): Can we implement something better here? */
gpr_atm_rel_store(p, value);
}
static __inline int gpr_atm_no_barrier_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
/** InterlockedCompareExchangePointerNoFence() not available on vista or
windows7 */
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
(volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_acq_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
(volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_rel_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeRelease64(
(volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeRelease((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_full_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG*)p,
(LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchange((volatile LONG*)p, (LONG)n,
(LONG)o);
#endif
}
static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm* p,
gpr_atm delta) {
/** Use the CAS operation to get pointer-sized fetch and add */
gpr_atm old;
do {
old = *p;
} while (!gpr_atm_no_barrier_cas(p, old, old + delta));
return old;
}
static __inline gpr_atm gpr_atm_full_fetch_add(gpr_atm* p, gpr_atm delta) {
/** Use a CAS operation to get pointer-sized fetch and add */
gpr_atm old;
#ifdef GPR_ARCH_64
do {
old = *p;
} while (old != (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG*)p,
(LONGLONG)old + delta,
(LONGLONG)old));
#else
do {
old = *p;
} while (old != (gpr_atm)InterlockedCompareExchange(
(volatile LONG*)p, (LONG)old + delta, (LONG)old));
#endif
return old;
}
static __inline gpr_atm gpr_atm_full_xchg(gpr_atm* p, gpr_atm n) {
return (gpr_atm)InterlockedExchangePointer((PVOID*)p, (PVOID)n);
}
#endif /* GPR_WINDOWS */
#endif /* GRPC_IMPL_CODEGEN_ATM_WINDOWS_H */ #endif /* GRPC_IMPL_CODEGEN_ATM_WINDOWS_H */

@ -19,8 +19,77 @@
#ifndef GRPC_SUPPORT_ATM_H #ifndef GRPC_SUPPORT_ATM_H
#define GRPC_SUPPORT_ATM_H #define GRPC_SUPPORT_ATM_H
/** This interface provides atomic operations and barriers.
It is internal to gpr support code and should not be used outside it.
If an operation with acquire semantics precedes another memory access by the
same thread, the operation will precede that other access as seen by other
threads.
If an operation with release semantics follows another memory access by the
same thread, the operation will follow that other access as seen by other
threads.
Routines with "acq" or "full" in the name have acquire semantics. Routines
with "rel" or "full" in the name have release semantics. Routines with
"no_barrier" in the name have neither acquire not release semantics.
The routines may be implemented as macros.
// Atomic operations act on an integral_type gpr_atm that is guaranteed to
// be the same size as a pointer.
typedef intptr_t gpr_atm;
// A memory barrier, providing both acquire and release semantics, but not
// otherwise acting on memory.
void gpr_atm_full_barrier(void);
// Atomically return *p, with acquire semantics.
gpr_atm gpr_atm_acq_load(gpr_atm *p);
gpr_atm gpr_atm_no_barrier_load(gpr_atm *p);
// Atomically set *p = value, with release semantics.
void gpr_atm_rel_store(gpr_atm *p, gpr_atm value);
// Atomically add delta to *p, and return the old value of *p, with
// the barriers specified.
gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm *p, gpr_atm delta);
gpr_atm gpr_atm_full_fetch_add(gpr_atm *p, gpr_atm delta);
// Atomically, if *p==o, set *p=n and return non-zero otherwise return 0,
// with the barriers specified if the operation succeeds.
int gpr_atm_no_barrier_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_acq_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_rel_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
int gpr_atm_full_cas(gpr_atm *p, gpr_atm o, gpr_atm n);
// Atomically, set *p=n and return the old value of *p
gpr_atm gpr_atm_full_xchg(gpr_atm *p, gpr_atm n);
*/
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/atm.h> // IWYU pragma: export #if defined(GPR_GCC_ATOMIC)
#include <grpc/support/atm_gcc_atomic.h> // IWYU pragma: export
#elif defined(GPR_GCC_SYNC)
#include <grpc/support/atm_gcc_sync.h> // IWYU pragma: export
#elif defined(GPR_WINDOWS_ATOMIC)
#include <grpc/support/atm_windows.h> // IWYU pragma: export
#else
#error could not determine platform for atm
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** Adds \a delta to \a *value, clamping the result to the range specified
by \a min and \a max. Returns the new value. */
gpr_atm gpr_atm_no_barrier_clamped_add(gpr_atm* value, gpr_atm delta,
gpr_atm min, gpr_atm max);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_SUPPORT_ATM_H */ #endif /* GRPC_SUPPORT_ATM_H */

@ -19,8 +19,66 @@
#ifndef GRPC_SUPPORT_ATM_GCC_ATOMIC_H #ifndef GRPC_SUPPORT_ATM_GCC_ATOMIC_H
#define GRPC_SUPPORT_ATM_GCC_ATOMIC_H #define GRPC_SUPPORT_ATM_GCC_ATOMIC_H
// IWYU pragma: private, include <grpc/support/atm.h>
/* atm_platform.h for gcc and gcc-like compilers with the
__atomic_* interface. */
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/atm_gcc_atomic.h> // IWYU pragma: export #ifdef __cplusplus
extern "C" {
#endif
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
#define gpr_atm_full_barrier() (__atomic_thread_fence(__ATOMIC_SEQ_CST))
#define gpr_atm_acq_load(p) (__atomic_load_n((p), __ATOMIC_ACQUIRE))
#define gpr_atm_no_barrier_load(p) (__atomic_load_n((p), __ATOMIC_RELAXED))
#define gpr_atm_rel_store(p, value) \
(__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELEASE))
#define gpr_atm_no_barrier_store(p, value) \
(__atomic_store_n((p), (intptr_t)(value), __ATOMIC_RELAXED))
#define gpr_atm_no_barrier_fetch_add(p, delta) \
__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_RELAXED)
#define gpr_atm_full_fetch_add(p, delta) \
__atomic_fetch_add((p), (intptr_t)(delta), __ATOMIC_ACQ_REL)
static __inline int gpr_atm_no_barrier_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELAXED,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_acq_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_ACQUIRE,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_rel_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_RELEASE,
__ATOMIC_RELAXED);
}
static __inline int gpr_atm_full_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
// Need to be c89 compatible, so we can't use false for the fourth argument.
// NOLINTNEXTLINE(modernize-use-bool-literals)
return __atomic_compare_exchange_n(p, &o, n, 0, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED);
}
#define gpr_atm_full_xchg(p, n) __atomic_exchange_n((p), (n), __ATOMIC_ACQ_REL)
#ifdef __cplusplus
}
#endif
#endif /* GRPC_SUPPORT_ATM_GCC_ATOMIC_H */ #endif /* GRPC_SUPPORT_ATM_GCC_ATOMIC_H */

@ -19,8 +19,65 @@
#ifndef GRPC_SUPPORT_ATM_GCC_SYNC_H #ifndef GRPC_SUPPORT_ATM_GCC_SYNC_H
#define GRPC_SUPPORT_ATM_GCC_SYNC_H #define GRPC_SUPPORT_ATM_GCC_SYNC_H
/* variant of atm_platform.h for gcc and gcc-like compilers with __sync_*
interface */
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/atm_gcc_sync.h> // IWYU pragma: export typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
#if defined(__i386) || defined(__x86_64__)
/* All loads are acquire loads and all stores are release stores. */
#define GPR_ATM_LS_BARRIER_() GPR_ATM_COMPILE_BARRIER_()
#else
#define GPR_ATM_LS_BARRIER_() gpr_atm_full_barrier()
#endif
#define gpr_atm_full_barrier() (__sync_synchronize())
static __inline gpr_atm gpr_atm_acq_load(const gpr_atm* p) {
gpr_atm value = *p;
GPR_ATM_LS_BARRIER_();
return value;
}
static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm* p) {
gpr_atm value = *p;
GPR_ATM_COMPILE_BARRIER_();
return value;
}
static __inline void gpr_atm_rel_store(gpr_atm* p, gpr_atm value) {
GPR_ATM_LS_BARRIER_();
*p = value;
}
static __inline void gpr_atm_no_barrier_store(gpr_atm* p, gpr_atm value) {
GPR_ATM_COMPILE_BARRIER_();
*p = value;
}
#undef GPR_ATM_LS_BARRIER_
#undef GPR_ATM_COMPILE_BARRIER_
#define gpr_atm_no_barrier_fetch_add(p, delta) \
gpr_atm_full_fetch_add((p), (delta))
#define gpr_atm_full_fetch_add(p, delta) (__sync_fetch_and_add((p), (delta)))
#define gpr_atm_no_barrier_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
#define gpr_atm_acq_cas(p, o, n) (__sync_bool_compare_and_swap((p), (o), (n)))
#define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
#define gpr_atm_full_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
static __inline gpr_atm gpr_atm_full_xchg(gpr_atm* p, gpr_atm n) {
gpr_atm cur;
do {
cur = gpr_atm_acq_load(p);
} while (!gpr_atm_rel_cas(p, cur, n));
return cur;
}
#endif /* GRPC_SUPPORT_ATM_GCC_SYNC_H */ #endif /* GRPC_SUPPORT_ATM_GCC_SYNC_H */

@ -19,8 +19,112 @@
#ifndef GRPC_SUPPORT_ATM_WINDOWS_H #ifndef GRPC_SUPPORT_ATM_WINDOWS_H
#define GRPC_SUPPORT_ATM_WINDOWS_H #define GRPC_SUPPORT_ATM_WINDOWS_H
/** Win32 variant of atm_platform.h */
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include <grpc/impl/codegen/atm_windows.h> // IWYU pragma: export #ifdef GPR_WINDOWS
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
#define gpr_atm_full_barrier MemoryBarrier
static __inline gpr_atm gpr_atm_acq_load(const gpr_atm* p) {
gpr_atm result = *p;
gpr_atm_full_barrier();
return result;
}
static __inline gpr_atm gpr_atm_no_barrier_load(const gpr_atm* p) {
/* TODO(dklempner): Can we implement something better here? */
return gpr_atm_acq_load(p);
}
static __inline void gpr_atm_rel_store(gpr_atm* p, gpr_atm value) {
gpr_atm_full_barrier();
*p = value;
}
static __inline void gpr_atm_no_barrier_store(gpr_atm* p, gpr_atm value) {
/* TODO(ctiller): Can we implement something better here? */
gpr_atm_rel_store(p, value);
}
static __inline int gpr_atm_no_barrier_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
/** InterlockedCompareExchangePointerNoFence() not available on vista or
windows7 */
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
(volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_acq_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeAcquire64(
(volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeAcquire((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_rel_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchangeRelease64(
(volatile LONGLONG*)p, (LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchangeRelease((volatile LONG*)p,
(LONG)n, (LONG)o);
#endif
}
static __inline int gpr_atm_full_cas(gpr_atm* p, gpr_atm o, gpr_atm n) {
#ifdef GPR_ARCH_64
return o == (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG*)p,
(LONGLONG)n, (LONGLONG)o);
#else
return o == (gpr_atm)InterlockedCompareExchange((volatile LONG*)p, (LONG)n,
(LONG)o);
#endif
}
static __inline gpr_atm gpr_atm_no_barrier_fetch_add(gpr_atm* p,
gpr_atm delta) {
/** Use the CAS operation to get pointer-sized fetch and add */
gpr_atm old;
do {
old = *p;
} while (!gpr_atm_no_barrier_cas(p, old, old + delta));
return old;
}
static __inline gpr_atm gpr_atm_full_fetch_add(gpr_atm* p, gpr_atm delta) {
/** Use a CAS operation to get pointer-sized fetch and add */
gpr_atm old;
#ifdef GPR_ARCH_64
do {
old = *p;
} while (old != (gpr_atm)InterlockedCompareExchange64((volatile LONGLONG*)p,
(LONGLONG)old + delta,
(LONGLONG)old));
#else
do {
old = *p;
} while (old != (gpr_atm)InterlockedCompareExchange(
(volatile LONG*)p, (LONG)old + delta, (LONG)old));
#endif
return old;
}
static __inline gpr_atm gpr_atm_full_xchg(gpr_atm* p, gpr_atm n) {
return (gpr_atm)InterlockedExchangePointer((PVOID*)p, (PVOID)n);
}
#endif /* GPR_WINDOWS */
#endif /* GRPC_SUPPORT_ATM_WINDOWS_H */ #endif /* GRPC_SUPPORT_ATM_WINDOWS_H */

@ -34,7 +34,7 @@
#include <list> #include <list>
#include <grpc/impl/codegen/atm.h> #include <grpc/support/atm.h>
#include <grpcpp/impl/codegen/core_codegen_interface.h> #include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/rpc_service_method.h> #include <grpcpp/impl/codegen/rpc_service_method.h>
#include <grpcpp/impl/codegen/status.h> #include <grpcpp/impl/codegen/status.h>

@ -143,6 +143,9 @@ grpc_cc_library(
language = "c++", language = "c++",
public_hdrs = [ public_hdrs = [
"//:include/grpc/support/atm.h", "//:include/grpc/support/atm.h",
"//:include/grpc/support/atm_gcc_atomic.h",
"//:include/grpc/support/atm_gcc_sync.h",
"//:include/grpc/support/atm_windows.h",
"//:include/grpc/impl/codegen/atm.h", "//:include/grpc/impl/codegen/atm.h",
"//:include/grpc/impl/codegen/atm_gcc_atomic.h", "//:include/grpc/impl/codegen/atm_gcc_atomic.h",
"//:include/grpc/impl/codegen/atm_gcc_sync.h", "//:include/grpc/impl/codegen/atm_gcc_sync.h",

@ -23,7 +23,7 @@
#include <memory> #include <memory>
#include <grpc/compression.h> #include <grpc/compression.h>
#include <grpc/impl/codegen/atm.h> #include <grpc/support/atm.h>
#include <grpcpp/security/server_credentials.h> #include <grpcpp/security/server_credentials.h>
#include <grpcpp/server.h> #include <grpcpp/server.h>
#include <grpcpp/server_builder.h> #include <grpcpp/server_builder.h>

Loading…
Cancel
Save