GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
atomic_ops.hpp
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 
24 #ifndef GRAPHLAB_ATOMIC_OPS_HPP
25 #define GRAPHLAB_ATOMIC_OPS_HPP
26 
27 #include <stdint.h>
28 
29 
30 namespace graphlab {
31  /**
32  * \ingroup util
33  atomic instruction that is equivalent to the following:
34  \code
35  if (a==oldval) {
36  a = newval;
37  return true;
38  }
39  else {
40  return false;
41  }
42  \endcode
43  */
44  template<typename T>
45  bool atomic_compare_and_swap(T& a, T oldval, T newval) {
46  return __sync_bool_compare_and_swap(&a, oldval, newval);
47  };
48 
49  /**
50  * \ingroup util
51  atomic instruction that is equivalent to the following:
52  \code
53  if (a==oldval) {
54  a = newval;
55  return true;
56  }
57  else {
58  return false;
59  }
60  \endcode
61  */
62  template<typename T>
63  bool atomic_compare_and_swap(volatile T& a,
64  T oldval,
65  T newval) {
66  return __sync_bool_compare_and_swap(&a, oldval, newval);
67  };
68 
69  /**
70  * \ingroup util
71  atomic instruction that is equivalent to the following:
72  \code
73  if (a==oldval) {
74  a = newval;
75  return true;
76  }
77  else {
78  return false;
79  }
80  \endcode
81  */
82  template <>
83  inline bool atomic_compare_and_swap(volatile double& a,
84  double oldval,
85  double newval) {
86  volatile uint64_t* a_ptr = reinterpret_cast<volatile uint64_t*>(&a);
87  const uint64_t* oldval_ptr = reinterpret_cast<const uint64_t*>(&oldval);
88  const uint64_t* newval_ptr = reinterpret_cast<const uint64_t*>(&newval);
89  return __sync_bool_compare_and_swap(a_ptr, *oldval_ptr, *newval_ptr);
90  };
91 
92  /**
93  * \ingroup util
94  atomic instruction that is equivalent to the following:
95  \code
96  if (a==oldval) {
97  a = newval;
98  return true;
99  }
100  else {
101  return false;
102  }
103  \endcode
104  */
105  template <>
106  inline bool atomic_compare_and_swap(volatile float& a,
107  float oldval,
108  float newval) {
109  volatile uint32_t* a_ptr = reinterpret_cast<volatile uint32_t*>(&a);
110  const uint32_t* oldval_ptr = reinterpret_cast<const uint32_t*>(&oldval);
111  const uint32_t* newval_ptr = reinterpret_cast<const uint32_t*>(&newval);
112  return __sync_bool_compare_and_swap(a_ptr, *oldval_ptr, *newval_ptr);
113  };
114 
115  /**
116  * \ingroup util
117  * \brief Atomically exchanges the values of a and b.
118  * \warning This is not a full atomic exchange. Read of a,
119  * and the write of b into a is atomic. But the write into b is not.
120  */
121  template<typename T>
122  void atomic_exchange(T& a, T& b) {
123  b = __sync_lock_test_and_set(&a, b);
124  };
125 
126  /**
127  * \ingroup util
128  * \brief Atomically exchanges the values of a and b.
129  * \warning This is not a full atomic exchange. Read of a,
130  * and the write of b into a is atomic. But the write into b is not.
131  */
132  template<typename T>
133  void atomic_exchange(volatile T& a, T& b) {
134  b = __sync_lock_test_and_set(&a, b);
135  };
136 
137  /**
138  * \ingroup util
139  * \brief Atomically sets a to the newval, returning the old value
140  */
141  template<typename T>
142  T fetch_and_store(T& a, const T& newval) {
143  return __sync_lock_test_and_set(&a, newval);
144  };
145 
146 }
147 #endif
148