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) 2010 Helge Bahmann
|
Chris@102
|
7 * Copyright (c) 2013 Tim Blechmann
|
Chris@102
|
8 * Copyright (c) 2014 Andrey Semashev
|
Chris@102
|
9 */
|
Chris@102
|
10 /*!
|
Chris@102
|
11 * \file atomic/detail/ops_gcc_sparc.hpp
|
Chris@102
|
12 *
|
Chris@102
|
13 * This header contains implementation of the \c operations template.
|
Chris@102
|
14 */
|
Chris@102
|
15
|
Chris@102
|
16 #ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_
|
Chris@102
|
17 #define BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_
|
Chris@102
|
18
|
Chris@102
|
19 #include <boost/memory_order.hpp>
|
Chris@102
|
20 #include <boost/atomic/detail/config.hpp>
|
Chris@102
|
21 #include <boost/atomic/detail/storage_type.hpp>
|
Chris@102
|
22 #include <boost/atomic/detail/operations_fwd.hpp>
|
Chris@102
|
23 #include <boost/atomic/capabilities.hpp>
|
Chris@102
|
24 #include <boost/atomic/detail/ops_cas_based.hpp>
|
Chris@102
|
25 #include <boost/atomic/detail/ops_extending_cas_based.hpp>
|
Chris@102
|
26
|
Chris@102
|
27 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@102
|
28 #pragma once
|
Chris@102
|
29 #endif
|
Chris@102
|
30
|
Chris@102
|
31 namespace boost {
|
Chris@102
|
32 namespace atomics {
|
Chris@102
|
33 namespace detail {
|
Chris@102
|
34
|
Chris@102
|
35 struct gcc_sparc_cas_base
|
Chris@102
|
36 {
|
Chris@102
|
37 static BOOST_FORCEINLINE void fence_before(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
38 {
|
Chris@102
|
39 if (order == memory_order_seq_cst)
|
Chris@102
|
40 __asm__ __volatile__ ("membar #Sync" ::: "memory");
|
Chris@102
|
41 else if ((order & memory_order_release) != 0)
|
Chris@102
|
42 __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
|
Chris@102
|
43 }
|
Chris@102
|
44
|
Chris@102
|
45 static BOOST_FORCEINLINE void fence_after(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
46 {
|
Chris@102
|
47 if (order == memory_order_seq_cst)
|
Chris@102
|
48 __asm__ __volatile__ ("membar #Sync" ::: "memory");
|
Chris@102
|
49 else if ((order & (memory_order_consume | memory_order_acquire)) != 0)
|
Chris@102
|
50 __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
|
Chris@102
|
51 }
|
Chris@102
|
52
|
Chris@102
|
53 static BOOST_FORCEINLINE void fence_after_store(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
54 {
|
Chris@102
|
55 if (order == memory_order_seq_cst)
|
Chris@102
|
56 __asm__ __volatile__ ("membar #Sync" ::: "memory");
|
Chris@102
|
57 }
|
Chris@102
|
58 };
|
Chris@102
|
59
|
Chris@102
|
60 template< bool Signed >
|
Chris@102
|
61 struct gcc_sparc_cas32 :
|
Chris@102
|
62 public gcc_sparc_cas_base
|
Chris@102
|
63 {
|
Chris@102
|
64 typedef typename make_storage_type< 4u, Signed >::type storage_type;
|
Chris@102
|
65
|
Chris@102
|
66 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
67 {
|
Chris@102
|
68 fence_before_store(order);
|
Chris@102
|
69 storage = v;
|
Chris@102
|
70 fence_after_store(order);
|
Chris@102
|
71 }
|
Chris@102
|
72
|
Chris@102
|
73 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
74 {
|
Chris@102
|
75 storage_type v = storage;
|
Chris@102
|
76 fence_after(order);
|
Chris@102
|
77 return v;
|
Chris@102
|
78 }
|
Chris@102
|
79
|
Chris@102
|
80 static BOOST_FORCEINLINE bool compare_exchange_strong(
|
Chris@102
|
81 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
82 {
|
Chris@102
|
83 fence_before(success_order);
|
Chris@102
|
84 storage_type previous = expected;
|
Chris@102
|
85 __asm__ __volatile__
|
Chris@102
|
86 (
|
Chris@102
|
87 "cas [%1], %2, %0"
|
Chris@102
|
88 : "+r" (desired)
|
Chris@102
|
89 : "r" (&storage), "r" (previous)
|
Chris@102
|
90 : "memory"
|
Chris@102
|
91 );
|
Chris@102
|
92 const bool success = (desired == previous);
|
Chris@102
|
93 if (success)
|
Chris@102
|
94 fence_after(success_order);
|
Chris@102
|
95 else
|
Chris@102
|
96 fence_after(failure_order);
|
Chris@102
|
97 expected = desired;
|
Chris@102
|
98 return success;
|
Chris@102
|
99 }
|
Chris@102
|
100
|
Chris@102
|
101 static BOOST_FORCEINLINE bool compare_exchange_weak(
|
Chris@102
|
102 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
103 {
|
Chris@102
|
104 return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
|
Chris@102
|
105 }
|
Chris@102
|
106
|
Chris@102
|
107 static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
|
Chris@102
|
108 {
|
Chris@102
|
109 return true;
|
Chris@102
|
110 }
|
Chris@102
|
111 };
|
Chris@102
|
112
|
Chris@102
|
113 template< bool Signed >
|
Chris@102
|
114 struct operations< 4u, Signed > :
|
Chris@102
|
115 public cas_based_operations< gcc_sparc_cas32< Signed > >
|
Chris@102
|
116 {
|
Chris@102
|
117 typedef cas_based_operations< gcc_sparc_cas32< Signed > > base_type;
|
Chris@102
|
118 typedef typename base_type::storage_type storage_type;
|
Chris@102
|
119
|
Chris@102
|
120 static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
121 {
|
Chris@102
|
122 base_type::fence_before(order);
|
Chris@102
|
123 __asm__ __volatile__
|
Chris@102
|
124 (
|
Chris@102
|
125 "swap [%1], %0"
|
Chris@102
|
126 : "+r" (v)
|
Chris@102
|
127 : "r" (&storage)
|
Chris@102
|
128 : "memory"
|
Chris@102
|
129 );
|
Chris@102
|
130 base_type::fence_after(order);
|
Chris@102
|
131 return v;
|
Chris@102
|
132 }
|
Chris@102
|
133
|
Chris@102
|
134 static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
135 {
|
Chris@102
|
136 return !!exchange(storage, (storage_type)1, order);
|
Chris@102
|
137 }
|
Chris@102
|
138 };
|
Chris@102
|
139
|
Chris@102
|
140 template< bool Signed >
|
Chris@102
|
141 struct operations< 1u, Signed > :
|
Chris@102
|
142 public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
|
Chris@102
|
143 {
|
Chris@102
|
144 };
|
Chris@102
|
145
|
Chris@102
|
146 template< bool Signed >
|
Chris@102
|
147 struct operations< 2u, Signed > :
|
Chris@102
|
148 public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
|
Chris@102
|
149 {
|
Chris@102
|
150 };
|
Chris@102
|
151
|
Chris@102
|
152 template< bool Signed >
|
Chris@102
|
153 struct gcc_sparc_cas64 :
|
Chris@102
|
154 public gcc_sparc_cas_base
|
Chris@102
|
155 {
|
Chris@102
|
156 typedef typename make_storage_type< 8u, Signed >::type storage_type;
|
Chris@102
|
157
|
Chris@102
|
158 static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
159 {
|
Chris@102
|
160 fence_before_store(order);
|
Chris@102
|
161 storage = v;
|
Chris@102
|
162 fence_after_store(order);
|
Chris@102
|
163 }
|
Chris@102
|
164
|
Chris@102
|
165 static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
166 {
|
Chris@102
|
167 storage_type v = storage;
|
Chris@102
|
168 fence_after(order);
|
Chris@102
|
169 return v;
|
Chris@102
|
170 }
|
Chris@102
|
171
|
Chris@102
|
172 static BOOST_FORCEINLINE bool compare_exchange_strong(
|
Chris@102
|
173 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
174 {
|
Chris@102
|
175 fence_before(success_order);
|
Chris@102
|
176 storage_type previous = expected;
|
Chris@102
|
177 __asm__ __volatile__
|
Chris@102
|
178 (
|
Chris@102
|
179 "casx [%1], %2, %0"
|
Chris@102
|
180 : "+r" (desired)
|
Chris@102
|
181 : "r" (&storage), "r" (previous)
|
Chris@102
|
182 : "memory"
|
Chris@102
|
183 );
|
Chris@102
|
184 const bool success = (desired == previous);
|
Chris@102
|
185 if (success)
|
Chris@102
|
186 fence_after(success_order);
|
Chris@102
|
187 else
|
Chris@102
|
188 fence_after(failure_order);
|
Chris@102
|
189 expected = desired;
|
Chris@102
|
190 return success;
|
Chris@102
|
191 }
|
Chris@102
|
192
|
Chris@102
|
193 static BOOST_FORCEINLINE bool compare_exchange_weak(
|
Chris@102
|
194 storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
|
Chris@102
|
195 {
|
Chris@102
|
196 return compare_exchange_strong(storage, expected, desired, success_order, failure_order);
|
Chris@102
|
197 }
|
Chris@102
|
198
|
Chris@102
|
199 static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile&) BOOST_NOEXCEPT
|
Chris@102
|
200 {
|
Chris@102
|
201 return true;
|
Chris@102
|
202 }
|
Chris@102
|
203 };
|
Chris@102
|
204
|
Chris@102
|
205 template< bool Signed >
|
Chris@102
|
206 struct operations< 8u, Signed > :
|
Chris@102
|
207 public cas_based_operations< gcc_sparc_cas64< Signed > >
|
Chris@102
|
208 {
|
Chris@102
|
209 };
|
Chris@102
|
210
|
Chris@102
|
211
|
Chris@102
|
212 BOOST_FORCEINLINE void thread_fence(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
213 {
|
Chris@102
|
214 switch (order)
|
Chris@102
|
215 {
|
Chris@102
|
216 case memory_order_release:
|
Chris@102
|
217 __asm__ __volatile__ ("membar #StoreStore | #LoadStore" ::: "memory");
|
Chris@102
|
218 break;
|
Chris@102
|
219 case memory_order_consume:
|
Chris@102
|
220 case memory_order_acquire:
|
Chris@102
|
221 __asm__ __volatile__ ("membar #LoadLoad | #LoadStore" ::: "memory");
|
Chris@102
|
222 break;
|
Chris@102
|
223 case memory_order_acq_rel:
|
Chris@102
|
224 __asm__ __volatile__ ("membar #LoadLoad | #LoadStore | #StoreStore" ::: "memory");
|
Chris@102
|
225 break;
|
Chris@102
|
226 case memory_order_seq_cst:
|
Chris@102
|
227 __asm__ __volatile__ ("membar #Sync" ::: "memory");
|
Chris@102
|
228 break;
|
Chris@102
|
229 case memory_order_relaxed:
|
Chris@102
|
230 default:
|
Chris@102
|
231 break;
|
Chris@102
|
232 }
|
Chris@102
|
233 }
|
Chris@102
|
234
|
Chris@102
|
235 BOOST_FORCEINLINE void signal_fence(memory_order order) BOOST_NOEXCEPT
|
Chris@102
|
236 {
|
Chris@102
|
237 if (order != memory_order_relaxed)
|
Chris@102
|
238 __asm__ __volatile__ ("" ::: "memory");
|
Chris@102
|
239 }
|
Chris@102
|
240
|
Chris@102
|
241 } // namespace detail
|
Chris@102
|
242 } // namespace atomics
|
Chris@102
|
243 } // namespace boost
|
Chris@102
|
244
|
Chris@102
|
245 #endif // BOOST_ATOMIC_DETAIL_OPS_GCC_SPARC_HPP_INCLUDED_
|