1 #include "hmbdc/Copyright.hpp" 4 #ifndef SMP_CACHE_BYTES 5 #define SMP_CACHE_BYTES 64 8 #include "hmbdc/Exception.hpp" 9 #include "hmbdc/Compile.hpp" 16 namespace hmbdc {
namespace pattern {
21 template <
bool THREADSAFE>
22 inline __attribute__ ((always_inline))
24 my__sync_synchronize() {
25 if (THREADSAFE) __sync_synchronize();
28 template <
bool THREADSAFE,
typename T>
29 inline __attribute__ ((always_inline))
31 my__sync_bool_compare_and_swap(volatile T* var, T compVal, T newVal) {
32 if (THREADSAFE)
return __sync_bool_compare_and_swap(var, compVal, newVal);
33 if (*var == compVal) {
40 template <
bool THREADSAFE,
typename T>
41 inline __attribute__ ((always_inline))
43 my__sync_val_compare_and_swap(volatile T* var, T compVal, T newVal) {
44 if (THREADSAFE)
return __sync_val_compare_and_swap(var, compVal, newVal);
46 if (*var == compVal) {
53 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t,
bool THREADSAFE = true>
55 explicit SeqArb(Seq startSeq = 0)
56 : missedInit_(~((1ul << PARTICIPANT_COUNT) - 1u))
59 static_assert(PARTICIPANT_COUNT <= 64u,
"too many participants");
65 template <
typename HitFunc,
typename GapFunc>
66 inline __attribute__ ((always_inline))
67 bool operator()(uint16_t participantIndex, Seq seq, HitFunc&& h, GapFunc&& g) __restrict__ {
68 j_[participantIndex].seq = seq;
70 auto old = my__sync_val_compare_and_swap<THREADSAFE>(&seq_, seq, std::numeric_limits<Seq>::max());
74 my__sync_synchronize<THREADSAFE>();
77 }
else if (old == std::numeric_limits<Seq>::max()) {
79 }
else if (seq < old) {
83 if (unlikely((low > old && seq_ == old &&
84 my__sync_bool_compare_and_swap<THREADSAFE>(&seq_, old, std::numeric_limits<Seq>::max())))) {
86 my__sync_synchronize<THREADSAFE>();
93 template <
typename SeqGen,
typename HitFunc,
typename GapFunc>
94 inline __attribute__ ((always_inline))
95 size_t operator()(uint16_t participantIndex, SeqGen&& seqGen
96 ,
size_t seqSize, HitFunc&& h, GapFunc&& g) __restrict__ {
98 j_[participantIndex].seq = seq;
100 auto old = my__sync_val_compare_and_swap<THREADSAFE>(
101 &seq_, seq, std::numeric_limits<Seq>::max());
107 for (; s < seqSize; ++s) {
109 if (seq - 1 == preSeq) {
116 j_[participantIndex].seq = seq;
117 my__sync_synchronize<THREADSAFE>();
120 }
else if (old == std::numeric_limits<Seq>::max()) {
122 }
else if (seq < old) {
126 if (unlikely((low > old && seq_ == old &&
127 my__sync_bool_compare_and_swap<THREADSAFE>(
128 &seq_, old, std::numeric_limits<Seq>::max())))) {
130 my__sync_synchronize<THREADSAFE>();
137 volatile Seq
const& expectingSeq()
const {
141 volatile Seq& expectingSeq() {
146 inline __attribute__ ((always_inline))
147 Seq jLow()
const __restrict__ {
148 auto res = j_[0].seq;
149 for (
auto i = 1u; i < PARTICIPANT_COUNT; ++i)
150 if (res > j_[i].seq) res = j_[i].seq;
154 uint64_t
const missedInit_;
156 volatile Seq seq_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
157 uint64_t missed_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
161 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
162 J j_[PARTICIPANT_COUNT];
165 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t>
170 template <
typename GapFunc>
171 int operator()(uint16_t participantIndex, Seq seq, GapFunc&& gapFunc) {
173 if (!arb_(participantIndex, seq
177 , forward<GapFunc>(gapFunc)
185 volatile Seq& expectingSeq() {
186 return arb_.expectingSeq();
189 volatile Seq
const& expectingSeq()
const {
190 return arb_.expectingSeq();
Definition: TypedString.hpp:74
Definition: SeqArb.hpp:166
Definition: SeqArb.hpp:54
Definition: Client.hpp:11