Line data Source code
1 : /*
2 : * Copyright 2011 The WebRTC Project Authors. All rights reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #ifndef WEBRTC_BASE_ATOMICOPS_H_
12 : #define WEBRTC_BASE_ATOMICOPS_H_
13 :
14 : #if defined(WEBRTC_WIN)
15 : // Include winsock2.h before including <windows.h> to maintain consistency with
16 : // win32.h. We can't include win32.h directly here since it pulls in
17 : // headers such as basictypes.h which causes problems in Chromium where webrtc
18 : // exists as two separate projects, webrtc and libjingle.
19 : #include <winsock2.h>
20 : #include <windows.h>
21 : #endif // defined(WEBRTC_WIN)
22 :
23 : namespace rtc {
24 : class AtomicOps {
25 : public:
26 : #if defined(WEBRTC_WIN)
27 : // Assumes sizeof(int) == sizeof(LONG), which it is on Win32 and Win64.
28 : static int Increment(volatile int* i) {
29 : return ::InterlockedIncrement(reinterpret_cast<volatile LONG*>(i));
30 : }
31 : static int Decrement(volatile int* i) {
32 : return ::InterlockedDecrement(reinterpret_cast<volatile LONG*>(i));
33 : }
34 : static int AcquireLoad(volatile const int* i) {
35 : return *i;
36 : }
37 : static void ReleaseStore(volatile int* i, int value) {
38 : *i = value;
39 : }
40 : static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
41 : return ::InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(i),
42 : new_value,
43 : old_value);
44 : }
45 : // Pointer variants.
46 : template <typename T>
47 : static T* AcquireLoadPtr(T* volatile* ptr) {
48 : return *ptr;
49 : }
50 : template <typename T>
51 : static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
52 : return static_cast<T*>(::InterlockedCompareExchangePointer(
53 : reinterpret_cast<PVOID volatile*>(ptr), new_value, old_value));
54 : }
55 : #else
56 0 : static int Increment(volatile int* i) {
57 0 : return __sync_add_and_fetch(i, 1);
58 : }
59 0 : static int Decrement(volatile int* i) {
60 0 : return __sync_sub_and_fetch(i, 1);
61 : }
62 0 : static int AcquireLoad(volatile const int* i) {
63 0 : return __atomic_load_n(i, __ATOMIC_ACQUIRE);
64 : }
65 0 : static void ReleaseStore(volatile int* i, int value) {
66 0 : __atomic_store_n(i, value, __ATOMIC_RELEASE);
67 0 : }
68 0 : static int CompareAndSwap(volatile int* i, int old_value, int new_value) {
69 0 : return __sync_val_compare_and_swap(i, old_value, new_value);
70 : }
71 : // Pointer variants.
72 : template <typename T>
73 0 : static T* AcquireLoadPtr(T* volatile* ptr) {
74 0 : return __atomic_load_n(ptr, __ATOMIC_ACQUIRE);
75 : }
76 : template <typename T>
77 0 : static T* CompareAndSwapPtr(T* volatile* ptr, T* old_value, T* new_value) {
78 0 : return __sync_val_compare_and_swap(ptr, old_value, new_value);
79 : }
80 : #endif
81 : };
82 :
83 :
84 :
85 : }
86 :
87 : #endif // WEBRTC_BASE_ATOMICOPS_H_
|