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