Agora C++ API Reference for All Platforms
AgoraAtomicOps.h
1 // Copyright (c) 2020 Agora.io. All rights reserved
2 
3 // This program is confidential and proprietary to Agora.io.
4 // And may not be copied, reproduced, modified, disclosed to others, published
5 // or used, in whole or in part, without the express prior written permission
6 // of Agora.io.
7 #pragma once
8 
9 #if defined(_WIN32)
10 // clang-format off
11 // clang formating would change include order.
12 
13 // Include WinSock2.h before including <Windows.h> to maintain consistency with
14 // win32.h. To include win32.h directly, it must be broken out into its own
15 // build target.
16 #include <WinSock2.h>
17 #include <Windows.h>
18 // clang-format on
19 #endif // _WIN32
20 
21 namespace agora {
22 
23 class AtomicOps {
24  public:
25 #if defined(_WIN32)
26  // Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
27  static int Increment(volatile int* i) {
28  return ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(i));
29  }
30  static int Decrement(volatile int* i) {
31  return ::InterlockedDecrement(reinterpret_cast<volatile LONG*>(i));
32  }
33  static int AcquireLoad(volatile const int* i) { return *i; }
34  static void ReleaseStore(volatile int* i, int value) { *i = value; }
35  static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
36  return ::InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(i),
37  new_value, old_value);
38  }
39  // Pointer variants.
40  template <typename T>
41  static T* AcquireLoadPtr(T* volatile* ptr) {
42  return *ptr;
43  }
44  template <typename T>
45  static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
46  return static_cast<T*>(::InterlockedCompareExchangePointer(
47  reinterpret_cast<PVOID volatile*>(ptr), new_value, old_value));
48  }
49 #else
50  static int Increment(volatile int* i) { return __sync_add_and_fetch(i, 1); }
51  static int Decrement(volatile int* i) { return __sync_sub_and_fetch(i, 1); }
52  static int AcquireLoad(volatile const int* i) {
53  return __atomic_load_n(i, __ATOMIC_ACQUIRE);
54  }
55  static void ReleaseStore(volatile int* i, int value) {
56  __atomic_store_n(i, value, __ATOMIC_RELEASE);
57  }
58  static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
59  return __sync_val_compare_and_swap(i, old_value, new_value);
60  }
61  // Pointer variants.
62  template <typename T>
63  static T* AcquireLoadPtr(T* volatile* ptr) {
64  return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
65  }
66  template <typename T>
67  static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
68  return __sync_val_compare_and_swap(ptr, old_value, new_value);
69  }
70 #endif // _WIN32
71 };
72 
73 } // namespace agora
agora::AtomicOps::AcquireLoad
static int AcquireLoad(volatile const int *i)
Definition: AgoraAtomicOps.h:33
agora::AtomicOps::Decrement
static int Decrement(volatile int *i)
Definition: AgoraAtomicOps.h:30
agora::AtomicOps::ReleaseStore
static void ReleaseStore(volatile int *i, int value)
Definition: AgoraAtomicOps.h:34
agora
Definition: AgoraAtomicOps.h:21
agora::AtomicOps::Increment
static int Increment(volatile int *i)
Definition: AgoraAtomicOps.h:27
agora::AtomicOps::CompareAndSwapPtr
static T * CompareAndSwapPtr(T *volatile *ptr, T *old_value, T *new_value)
Definition: AgoraAtomicOps.h:45
agora::AtomicOps
Definition: AgoraAtomicOps.h:23
agora::AtomicOps::CompareAndSwap
static int CompareAndSwap(volatile int *i, int old_value, int new_value)
Definition: AgoraAtomicOps.h:35
agora::AtomicOps::AcquireLoadPtr
static T * AcquireLoadPtr(T *volatile *ptr)
Definition: AgoraAtomicOps.h:41