Agora C++ API Reference for All Platforms
Loading...
Searching...
No Matches
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
21namespace agora {
22
23class 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
Definition AgoraAtomicOps.h:23
static int CompareAndSwap(volatile int *i, int old_value, int new_value)
Definition AgoraAtomicOps.h:35
static T * AcquireLoadPtr(T *volatile *ptr)
Definition AgoraAtomicOps.h:41
static void ReleaseStore(volatile int *i, int value)
Definition AgoraAtomicOps.h:34
static T * CompareAndSwapPtr(T *volatile *ptr, T *old_value, T *new_value)
Definition AgoraAtomicOps.h:45
static int Increment(volatile int *i)
Definition AgoraAtomicOps.h:27
static int AcquireLoad(volatile const int *i)
Definition AgoraAtomicOps.h:33
static int Decrement(volatile int *i)
Definition AgoraAtomicOps.h:30
Definition AgoraAtomicOps.h:21