MongoDB C++ Driver  legacy-1.1.2
atomic_intrinsics_gcc_sync.h
1 /* Copyright 2014 10gen Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
21 #pragma once
22 
23 #include <boost/utility.hpp>
24 
25 namespace mongo {
26 
30 template <typename T, typename IsTLarge = void>
31 class AtomicIntrinsics {
32 public:
33  static T compareAndSwap(volatile T* dest, T expected, T newValue) {
34  return __sync_val_compare_and_swap(dest, expected, newValue);
35  }
36 
37  static T swap(volatile T* dest, T newValue) {
38  T currentValue = *dest;
39  while (true) {
40  const T result = compareAndSwap(dest, currentValue, newValue);
41  if (result == currentValue)
42  return result;
43  currentValue = result;
44  }
45  }
46 
47  static T load(volatile const T* value) {
48  __sync_synchronize();
49  T result = *value;
50  __sync_synchronize();
51  return result;
52  }
53 
54  static T loadRelaxed(volatile const T* value) {
55  asm volatile("" ::: "memory");
56  return *value;
57  }
58 
59  static void store(volatile T* dest, T newValue) {
60  __sync_synchronize();
61  *dest = newValue;
62  __sync_synchronize();
63  }
64 
65  static T fetchAndAdd(volatile T* dest, T increment) {
66  return __sync_fetch_and_add(dest, increment);
67  }
68 
69 private:
70  AtomicIntrinsics();
71  ~AtomicIntrinsics();
72 };
73 
74 template <typename T>
75 class AtomicIntrinsics<T, typename boost::disable_if_c<sizeof(T) <= sizeof(void*)>::type> {
76 public:
77  static T compareAndSwap(volatile T* dest, T expected, T newValue) {
78  return __sync_val_compare_and_swap(dest, expected, newValue);
79  }
80 
81  static T swap(volatile T* dest, T newValue) {
82  T currentValue = *dest;
83  while (true) {
84  const T result = compareAndSwap(dest, currentValue, newValue);
85  if (result == currentValue)
86  return result;
87  currentValue = result;
88  }
89  }
90 
91  static T load(volatile const T* value) {
92  return compareAndSwap(const_cast<volatile T*>(value), T(0), T(0));
93  }
94 
95  static void store(volatile T* dest, T newValue) {
96  swap(dest, newValue);
97  }
98 
99  static T fetchAndAdd(volatile T* dest, T increment) {
100  return __sync_fetch_and_add(dest, increment);
101  }
102 
103 private:
104  AtomicIntrinsics();
105  ~AtomicIntrinsics();
106 };
107 
108 } // namespace mongo
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20