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 {
19 template <
bool THREADSAFE>
20 inline __attribute__ ((always_inline))
22 my__sync_synchronize() {
23 if (THREADSAFE) __sync_synchronize();
26 template <
bool THREADSAFE,
typename T>
27 inline __attribute__ ((always_inline))
29 my__sync_bool_compare_and_swap(
volatile T* var, T compVal, T newVal) {
30 if (THREADSAFE)
return __sync_bool_compare_and_swap(var, compVal, newVal);
31 if (*var == compVal) {
38 template <
bool THREADSAFE,
typename T>
39 inline __attribute__ ((always_inline))
41 my__sync_val_compare_and_swap(
volatile T* var, T compVal, T newVal) {
42 if (THREADSAFE)
return __sync_val_compare_and_swap(var, compVal, newVal);
44 if (*var == compVal) {
51 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t,
bool THREADSAFE = true>
53 explicit SeqArb(Seq startSeq = 0)
54 : missedInit_(~((1ul << PARTICIPANT_COUNT) - 1u))
57 static_assert(PARTICIPANT_COUNT <= 64u,
"too many participants");
63 template <
typename HitFunc,
typename GapFunc>
64 inline __attribute__ ((always_inline))
65 bool operator()(uint16_t participantIndex, Seq seq, HitFunc&& h, GapFunc&& g) HMBDC_RESTRICT {
66 j_[participantIndex].seq = seq;
68 auto old = my__sync_val_compare_and_swap<THREADSAFE>(&seq_, seq, std::numeric_limits<Seq>::max());
72 my__sync_synchronize<THREADSAFE>();
75 }
else if (old == std::numeric_limits<Seq>::max()) {
77 }
else if (seq < old) {
81 if (hmbdc_unlikely((low > old && seq_ == old &&
82 my__sync_bool_compare_and_swap<THREADSAFE>(&seq_, old, std::numeric_limits<Seq>::max())))) {
84 my__sync_synchronize<THREADSAFE>();
91 template <
typename SeqGen,
typename HitFunc,
typename GapFunc>
92 inline __attribute__ ((always_inline))
93 size_t operator()(uint16_t participantIndex, SeqGen&& seqGen
94 ,
size_t seqSize, HitFunc&& h, GapFunc&& g) HMBDC_RESTRICT {
96 j_[participantIndex].seq = seq;
98 auto old = my__sync_val_compare_and_swap<THREADSAFE>(
99 &seq_, seq, std::numeric_limits<Seq>::max());
105 for (; s < seqSize; ++s) {
107 if (seq - 1 == preSeq) {
114 j_[participantIndex].seq = seq;
115 my__sync_synchronize<THREADSAFE>();
118 }
else if (old == std::numeric_limits<Seq>::max()) {
120 }
else if (seq < old) {
124 if (hmbdc_unlikely((low > old && seq_ == old &&
125 my__sync_bool_compare_and_swap<THREADSAFE>(
126 &seq_, old, std::numeric_limits<Seq>::max())))) {
128 my__sync_synchronize<THREADSAFE>();
135 volatile Seq
const& expectingSeq()
const {
139 volatile Seq& expectingSeq() {
144 inline __attribute__ ((always_inline))
145 Seq jLow()
const HMBDC_RESTRICT {
146 auto res = j_[0].seq;
147 for (
auto i = 1u; i < PARTICIPANT_COUNT; ++i)
148 if (res > j_[i].seq) res = j_[i].seq;
152 uint64_t
const missedInit_;
154 volatile Seq seq_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
155 uint64_t missed_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
159 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
160 J j_[PARTICIPANT_COUNT];
163 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t>
168 template <
typename GapFunc>
169 int operator()(uint16_t participantIndex, Seq seq, GapFunc&& gapFunc) {
171 if (!arb_(participantIndex, seq
175 , std::forward<GapFunc>(gapFunc)
183 volatile Seq& expectingSeq() {
184 return arb_.expectingSeq();
187 volatile Seq
const& expectingSeq()
const {
188 return arb_.expectingSeq();
197 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t,
bool THREADSAFE = true>
200 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t>
Definition: SeqArb.hpp:156
Definition: SeqArb.hpp:164
Definition: SeqArb.hpp:52