Library of Assembled Shared Sources
atomic_solaris.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43#include <sys/atomic.h>
44
45namespace lass
46{
47namespace util
48{
49namespace impl
50{
51
52template <typename UintSingle, typename UintDouble, typename T1, typename T2>
53UintDouble packPair(T1 a, T2 b)
54{
55 LASS_META_ASSERT(sizeof(UintDouble) == 2 * sizeof(UintSingle), UintDouble_must_be_twice_as_wide_as_UintSingle);
56 LASS_META_ASSERT(sizeof(T1) == sizeof(UintSingle), T1_must_have_same_wide_as_UintSingle);
57 LASS_META_ASSERT(sizeof(T2) == sizeof(UintSingle), T2_must_have_same_wide_as_UintSingle);
58 enum { shift = bitsPerByte * sizeof(UintSingle) };
59 const UintDouble r1 = *reinterpret_cast<UintSingle*>(&a);
60 const UintDouble r2 = *reinterpret_cast<UintSingle*>(&b);
61#if LASS_HAVE_BIG_ENDIAN
62 return (r1 << shift) | r2;
63#else
64 return (r2 << shift) | r1;
65#endif
66}
67
68template <>
69struct AtomicOperations<1>
70{
71 template <typename T> inline
72 static T LASS_CALL compareAndSwap(volatile T& dest, T expectedValue, T newValue)
73 {
74 return atomic_cas_8(
75 reinterpret_cast<volatile uint8_t*>(&dest),
76 *reinterpret_cast<uint8_t*>(&expectedValue),
77 *reinterpret_cast<uint8_t*>(&newValue));
78 }
79
80 template <typename T1, typename T2> inline
81 static bool LASS_CALL compareAndSwap(
82 volatile T1& dest1, T1 expected1, T2 expected2, T1 new1, T2 new2)
83 {
84 const uint16_t expected = packPair<uint8_t, uint16_t>(expected1, expected2);
85 return atomic_cas_16(
86 reinterpret_cast<volatile uint16_t*>(&dest1),
87 expected,
88 packPair<uint8_t, uint16_t>(new1, new2)) == expected;
89 }
90
91 template <typename T> inline
92 static void LASS_CALL increment(volatile T& value)
93 {
94 atomic_inc_8(reinterpret_cast<volatile uint8_t*>(&value));
95 }
96
97 template <typename T> inline
98 static void LASS_CALL decrement(volatile T& value)
99 {
100 atomic_dec_8(reinterpret_cast<volatile uint8_t*>(&value));
101 }
102};
103
104
105
106template <>
107struct AtomicOperations<2>
108{
109 template <typename T> inline
110 static T LASS_CALL compareAndSwap(volatile T& dest, T expectedValue, T newValue)
111 {
112 return atomic_cas_16(
113 reinterpret_cast<volatile uint16_t*>(&dest),
114 *reinterpret_cast<uint16_t*>(&expectedValue),
115 *reinterpret_cast<uint16_t*>(&newValue));
116 }
117
118 template <typename T1, typename T2> inline
119 static bool LASS_CALL compareAndSwap(
120 volatile T1& dest1, T1 expected1, T2 expected2, T1 new1, T2 new2)
121 {
122 const uint32_t expected = packPair<uint16_t, uint32_t>(expected1, expected2);
123 return atomic_cas_32(
124 reinterpret_cast<volatile uint32_t*>(&dest1),
125 expected,
126 packPair<uint16_t, uint32_t>(new1, new2)) == expected;
127 }
128
129 template <typename T> inline
130 static void LASS_CALL increment(volatile T& value)
131 {
132 atomic_inc_16(reinterpret_cast<volatile uint16_t*>(&value));
133 }
134
135 template <typename T> inline
136 static void LASS_CALL decrement(volatile T& value)
137 {
138 atomic_dec_16(reinterpret_cast<volatile uint16_t*>(&value));
139 }
140};
141
142
143
144template <>
145struct AtomicOperations<4>
146{
147 template <typename T> inline
148 static T LASS_CALL compareAndSwap(volatile T& dest, T expectedValue, T newValue)
149 {
150 return atomic_cas_32(
151 reinterpret_cast<volatile uint32_t*>(&dest),
152 *reinterpret_cast<uint32_t*>(&expectedValue),
153 *reinterpret_cast<uint32_t*>(&newValue));
154 }
155
156 template <typename T1, typename T2> inline
157 static bool LASS_CALL compareAndSwap(
158 volatile T1& dest1, T1 expected1, T2 expected2, T1 new1, T2 new2)
159 {
160 const uint64_t expected = packPair<uint32_t, uint64_t>(expected1, expected2);
161 return atomic_cas_64(
162 reinterpret_cast<volatile uint64_t*>(&dest1),
163 expected,
164 packPair<uint32_t, uint64_t>(new1, new2)) == expected;
165 }
166
167 template <typename T> inline
168 static void LASS_CALL increment(volatile T& value)
169 {
170 atomic_inc_32(reinterpret_cast<volatile uint32_t*>(&value));
171 }
172
173 template <typename T> inline
174 static void LASS_CALL decrement(volatile T& value)
175 {
176 atomic_dec_32(reinterpret_cast<volatile uint32_t*>(&value));
177 }
178};
179
180
181
182template <>
183struct AtomicOperations<8>
184{
185 template <typename T> inline
186 static T LASS_CALL compareAndSwap(volatile T& dest, T expectedValue, T newValue)
187 {
188 return atomic_cas_64(
189 reinterpret_cast<volatile uint64_t*>(&dest),
190 *reinterpret_cast<uint64_t*>(&expectedValue),
191 *reinterpret_cast<uint64_t*>(&newValue));
192 }
193
194 template <typename T> inline
195 static void LASS_CALL increment(volatile T& value)
196 {
197 atomic_inc_64(reinterpret_cast<volatile uint64_t*>(&value));
198 }
199
200 template <typename T> inline
201 static void LASS_CALL decrement(volatile T& value)
202 {
203 atomic_dec_64(reinterpret_cast<volatile uint64_t*>(&value));
204 }
205};
206
207}
208}
209}
210
211// EOF
#define LASS_META_ASSERT(expression, message)
complite time static check
general utility, debug facilities, ...
Library for Assembled Shared Sources.
Definition config.h:53