1 #include "hmbdc/Copyright.hpp" 5 #include "hmbdc/Exception.hpp" 6 #include "hmbdc/Compile.hpp" 7 #include "hmbdc/Config.hpp" 14 namespace hmbdc {
namespace pattern {
16 namespace seqarb_detail {
20 template <
bool THREADSAFE>
21 inline __attribute__ ((always_inline))
23 my__sync_synchronize() {
24 if (THREADSAFE) __sync_synchronize();
27 template <
bool THREADSAFE,
typename T>
28 inline __attribute__ ((always_inline))
30 my__sync_bool_compare_and_swap(
volatile T* var, T compVal, T newVal) {
31 if (THREADSAFE)
return __sync_bool_compare_and_swap(var, compVal, newVal);
32 if (*var == compVal) {
39 template <
bool THREADSAFE,
typename T>
40 inline __attribute__ ((always_inline))
42 my__sync_val_compare_and_swap(
volatile T* var, T compVal, T newVal) {
43 if (THREADSAFE)
return __sync_val_compare_and_swap(var, compVal, newVal);
45 if (*var == compVal) {
52 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t,
bool THREADSAFE = true>
54 explicit SeqArb(Seq startSeq = 0)
55 : missedInit_(~((1ul << PARTICIPANT_COUNT) - 1u))
58 static_assert(PARTICIPANT_COUNT <= 64u,
"too many participants");
64 template <
typename HitFunc,
typename GapFunc>
65 inline __attribute__ ((always_inline))
66 bool operator()(uint16_t participantIndex, Seq seq, HitFunc&& h, GapFunc&& g) HMBDC_RESTRICT {
67 j_[participantIndex].seq = seq;
69 auto old = my__sync_val_compare_and_swap<THREADSAFE>(&seq_, seq, std::numeric_limits<Seq>::max());
73 my__sync_synchronize<THREADSAFE>();
76 }
else if (old == std::numeric_limits<Seq>::max()) {
78 }
else if (seq < old) {
82 if (hmbdc_unlikely((low > old && seq_ == old &&
83 my__sync_bool_compare_and_swap<THREADSAFE>(&seq_, old, std::numeric_limits<Seq>::max())))) {
85 my__sync_synchronize<THREADSAFE>();
92 template <
typename SeqGen,
typename HitFunc,
typename GapFunc>
93 inline __attribute__ ((always_inline))
94 size_t operator()(uint16_t participantIndex, SeqGen&& seqGen
95 ,
size_t seqSize, HitFunc&& h, GapFunc&& g) HMBDC_RESTRICT {
97 j_[participantIndex].seq = seq;
99 auto old = my__sync_val_compare_and_swap<THREADSAFE>(
100 &seq_, seq, std::numeric_limits<Seq>::max());
106 for (; s < seqSize; ++s) {
108 if (seq - 1 == preSeq) {
115 j_[participantIndex].seq = seq;
116 my__sync_synchronize<THREADSAFE>();
119 }
else if (old == std::numeric_limits<Seq>::max()) {
121 }
else if (seq < old) {
125 if (hmbdc_unlikely((low > old && seq_ == old &&
126 my__sync_bool_compare_and_swap<THREADSAFE>(
127 &seq_, old, std::numeric_limits<Seq>::max())))) {
129 my__sync_synchronize<THREADSAFE>();
136 volatile Seq
const& expectingSeq()
const {
140 volatile Seq& expectingSeq() {
145 inline __attribute__ ((always_inline))
146 Seq jLow()
const HMBDC_RESTRICT {
147 auto res = j_[0].seq;
148 for (
auto i = 1u; i < PARTICIPANT_COUNT; ++i)
149 if (res > j_[i].seq) res = j_[i].seq;
153 uint64_t
const missedInit_;
155 volatile Seq seq_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
156 uint64_t missed_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
160 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
161 J j_[PARTICIPANT_COUNT];
164 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t>
169 template <
typename GapFunc>
170 int operator()(uint16_t participantIndex, Seq seq, GapFunc&& gapFunc) {
172 if (!arb_(participantIndex, seq
176 , std::forward<GapFunc>(gapFunc)
184 volatile Seq& expectingSeq() {
185 return arb_.expectingSeq();
188 volatile Seq
const& expectingSeq()
const {
189 return arb_.expectingSeq();
198 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t,
bool THREADSAFE = true>
201 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t>
Definition: SeqArb.hpp:157
Definition: SeqArb.hpp:165
Definition: TypedString.hpp:84
Definition: SeqArb.hpp:53