Chris@102
|
1 /*
|
Chris@102
|
2 * Distributed under the Boost Software License, Version 1.0.
|
Chris@102
|
3 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@102
|
4 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
5 *
|
Chris@102
|
6 * Copyright (c) 2014 Andrey Semashev
|
Chris@102
|
7 */
|
Chris@102
|
8 /*!
|
Chris@102
|
9 * \file atomic/detail/ops_cas_based.hpp
|
Chris@102
|
10 *
|
Chris@102
|
11 * This header contains CAS-based implementation of the \c operations template.
|
Chris@102
|
12 */
|
Chris@102
|
13
|
Chris@102
|
14 #ifndef BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_
|
Chris@102
|
15 #define BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_
|
Chris@102
|
16
|
Chris@102
|
17 #include <boost/memory_order.hpp>
|
Chris@102
|
18 #include <boost/atomic/detail/config.hpp>
|
Chris@102
|
19
|
Chris@102
|
20 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@102
|
21 #pragma once
|
Chris@102
|
22 #endif
|
Chris@102
|
23
|
Chris@102
|
24 namespace boost {
|
Chris@102
|
25 namespace atomics {
|
Chris@102
|
26 namespace detail {
|
Chris@102
|
27
|
Chris@102
|
28 template< typename Base >
|
Chris@102
|
29 struct cas_based_operations :
|
Chris@102
|
30 public Base
|
Chris@102
|
31 {
|
Chris@102
|
32 typedef typename Base::storage_type storage_type;
|
Chris@102
|
33
|
Chris@102
|
34 static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
35 {
|
Chris@102
|
36 storage_type old_val = Base::load(storage, memory_order_relaxed);
|
Chris@102
|
37 while (!Base::compare_exchange_weak(storage, old_val, old_val + v, order, memory_order_relaxed)) {}
|
Chris@102
|
38 return old_val;
|
Chris@102
|
39 }
|
Chris@102
|
40
|
Chris@102
|
41 static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
42 {
|
Chris@102
|
43 storage_type old_val = Base::load(storage, memory_order_relaxed);
|
Chris@102
|
44 while (!Base::compare_exchange_weak(storage, old_val, old_val - v, order, memory_order_relaxed)) {}
|
Chris@102
|
45 return old_val;
|
Chris@102
|
46 }
|
Chris@102
|
47
|
Chris@102
|
48 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
49 {
|
Chris@102
|
50 storage_type old_val = Base::load(storage, memory_order_relaxed);
|
Chris@102
|
51 while (!Base::compare_exchange_weak(storage, old_val, v, order, memory_order_relaxed)) {}
|
Chris@102
|
52 return old_val;
|
Chris@102
|
53 }
|
Chris@102
|
54
|
Chris@102
|
55 static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
56 {
|
Chris@102
|
57 storage_type old_val = Base::load(storage, memory_order_relaxed);
|
Chris@102
|
58 while (!Base::compare_exchange_weak(storage, old_val, old_val & v, order, memory_order_relaxed)) {}
|
Chris@102
|
59 return old_val;
|
Chris@102
|
60 }
|
Chris@102
|
61
|
Chris@102
|
62 static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
63 {
|
Chris@102
|
64 storage_type old_val = Base::load(storage, memory_order_relaxed);
|
Chris@102
|
65 while (!Base::compare_exchange_weak(storage, old_val, old_val | v, order, memory_order_relaxed)) {}
|
Chris@102
|
66 return old_val;
|
Chris@102
|
67 }
|
Chris@102
|
68
|
Chris@102
|
69 static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
70 {
|
Chris@102
|
71 storage_type old_val = Base::load(storage, memory_order_relaxed);
|
Chris@102
|
72 while (!Base::compare_exchange_weak(storage, old_val, old_val ^ v, order, memory_order_relaxed)) {}
|
Chris@102
|
73 return old_val;
|
Chris@102
|
74 }
|
Chris@102
|
75
|
Chris@102
|
76 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
77 {
|
Chris@102
|
78 return !!exchange(storage, (storage_type)1, order);
|
Chris@102
|
79 }
|
Chris@102
|
80
|
Chris@102
|
81 static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
82 {
|
Chris@102
|
83 Base::store(storage, (storage_type)0, order);
|
Chris@102
|
84 }
|
Chris@102
|
85 };
|
Chris@102
|
86
|
Chris@102
|
87 } // namespace detail
|
Chris@102
|
88 } // namespace atomics
|
Chris@102
|
89 } // namespace boost
|
Chris@102
|
90
|
Chris@102
|
91 #endif // BOOST_ATOMIC_DETAIL_OPS_CAS_BASED_HPP_INCLUDED_
|