43#include <sys/atomic.h>
52template <
typename U
intSingle,
typename U
intDouble,
typename T1,
typename T2>
53UintDouble packPair(T1 a, T2 b)
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;
64 return (r2 << shift) | r1;
69struct AtomicOperations<1>
71 template <
typename T>
inline
72 static T LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
75 reinterpret_cast<volatile uint8_t*
>(&dest),
76 *
reinterpret_cast<uint8_t*
>(&expectedValue),
77 *
reinterpret_cast<uint8_t*
>(&newValue));
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)
84 const uint16_t expected = packPair<uint8_t, uint16_t>(expected1, expected2);
86 reinterpret_cast<volatile uint16_t*
>(&dest1),
88 packPair<uint8_t, uint16_t>(new1, new2)) == expected;
91 template <
typename T>
inline
92 static void LASS_CALL increment(
volatile T& value)
94 atomic_inc_8(
reinterpret_cast<volatile uint8_t*
>(&value));
97 template <
typename T>
inline
98 static void LASS_CALL decrement(
volatile T& value)
100 atomic_dec_8(
reinterpret_cast<volatile uint8_t*
>(&value));
107struct AtomicOperations<2>
109 template <
typename T>
inline
110 static T LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
112 return atomic_cas_16(
113 reinterpret_cast<volatile uint16_t*
>(&dest),
114 *
reinterpret_cast<uint16_t*
>(&expectedValue),
115 *
reinterpret_cast<uint16_t*
>(&newValue));
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)
122 const uint32_t expected = packPair<uint16_t, uint32_t>(expected1, expected2);
123 return atomic_cas_32(
124 reinterpret_cast<volatile uint32_t*
>(&dest1),
126 packPair<uint16_t, uint32_t>(new1, new2)) == expected;
129 template <
typename T>
inline
130 static void LASS_CALL increment(
volatile T& value)
132 atomic_inc_16(
reinterpret_cast<volatile uint16_t*
>(&value));
135 template <
typename T>
inline
136 static void LASS_CALL decrement(
volatile T& value)
138 atomic_dec_16(
reinterpret_cast<volatile uint16_t*
>(&value));
145struct AtomicOperations<4>
147 template <
typename T>
inline
148 static T LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
150 return atomic_cas_32(
151 reinterpret_cast<volatile uint32_t*
>(&dest),
152 *
reinterpret_cast<uint32_t*
>(&expectedValue),
153 *
reinterpret_cast<uint32_t*
>(&newValue));
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)
160 const uint64_t expected = packPair<uint32_t, uint64_t>(expected1, expected2);
161 return atomic_cas_64(
162 reinterpret_cast<volatile uint64_t*
>(&dest1),
164 packPair<uint32_t, uint64_t>(new1, new2)) == expected;
167 template <
typename T>
inline
168 static void LASS_CALL increment(
volatile T& value)
170 atomic_inc_32(
reinterpret_cast<volatile uint32_t*
>(&value));
173 template <
typename T>
inline
174 static void LASS_CALL decrement(
volatile T& value)
176 atomic_dec_32(
reinterpret_cast<volatile uint32_t*
>(&value));
183struct AtomicOperations<8>
185 template <
typename T>
inline
186 static T LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
188 return atomic_cas_64(
189 reinterpret_cast<volatile uint64_t*
>(&dest),
190 *
reinterpret_cast<uint64_t*
>(&expectedValue),
191 *
reinterpret_cast<uint64_t*
>(&newValue));
194 template <
typename T>
inline
195 static void LASS_CALL increment(
volatile T& value)
197 atomic_inc_64(
reinterpret_cast<volatile uint64_t*
>(&value));
200 template <
typename T>
inline
201 static void LASS_CALL decrement(
volatile T& value)
203 atomic_dec_64(
reinterpret_cast<volatile uint64_t*
>(&value));
general utility, debug facilities, ...
Library for Assembled Shared Sources.