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 {
18 namespace seqarb_detail {
22 template <
bool THREADSAFE>
23 inline __attribute__ ((always_inline))
25 my__sync_synchronize() {
26 if (THREADSAFE) __sync_synchronize();
29 template <
bool THREADSAFE,
typename T>
30 inline __attribute__ ((always_inline))
32 my__sync_bool_compare_and_swap(volatile T* var, T compVal, T newVal) {
33 if (THREADSAFE)
return __sync_bool_compare_and_swap(var, compVal, newVal);
34 if (*var == compVal) {
41 template <
bool THREADSAFE,
typename T>
42 inline __attribute__ ((always_inline))
44 my__sync_val_compare_and_swap(volatile T* var, T compVal, T newVal) {
45 if (THREADSAFE)
return __sync_val_compare_and_swap(var, compVal, newVal);
47 if (*var == compVal) {
54 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t,
bool THREADSAFE = true>
56 explicit SeqArb(Seq startSeq = 0)
57 : missedInit_(~((1ul << PARTICIPANT_COUNT) - 1u))
60 static_assert(PARTICIPANT_COUNT <= 64u,
"too many participants");
66 template <
typename HitFunc,
typename GapFunc>
67 inline __attribute__ ((always_inline))
68 bool operator()(uint16_t participantIndex, Seq seq, HitFunc&& h, GapFunc&& g) HMBDC_RESTRICT {
69 j_[participantIndex].seq = seq;
71 auto old = my__sync_val_compare_and_swap<THREADSAFE>(&seq_, seq, std::numeric_limits<Seq>::max());
75 my__sync_synchronize<THREADSAFE>();
78 }
else if (old == std::numeric_limits<Seq>::max()) {
80 }
else if (seq < old) {
84 if (hmbdc_unlikely((low > old && seq_ == old &&
85 my__sync_bool_compare_and_swap<THREADSAFE>(&seq_, old, std::numeric_limits<Seq>::max())))) {
87 my__sync_synchronize<THREADSAFE>();
94 template <
typename SeqGen,
typename HitFunc,
typename GapFunc>
95 inline __attribute__ ((always_inline))
96 size_t operator()(uint16_t participantIndex, SeqGen&& seqGen
97 ,
size_t seqSize, HitFunc&& h, GapFunc&& g) HMBDC_RESTRICT {
99 j_[participantIndex].seq = seq;
101 auto old = my__sync_val_compare_and_swap<THREADSAFE>(
102 &seq_, seq, std::numeric_limits<Seq>::max());
108 for (; s < seqSize; ++s) {
110 if (seq - 1 == preSeq) {
117 j_[participantIndex].seq = seq;
118 my__sync_synchronize<THREADSAFE>();
121 }
else if (old == std::numeric_limits<Seq>::max()) {
123 }
else if (seq < old) {
127 if (hmbdc_unlikely((low > old && seq_ == old &&
128 my__sync_bool_compare_and_swap<THREADSAFE>(
129 &seq_, old, std::numeric_limits<Seq>::max())))) {
131 my__sync_synchronize<THREADSAFE>();
138 volatile Seq
const& expectingSeq()
const {
142 volatile Seq& expectingSeq() {
147 inline __attribute__ ((always_inline))
148 Seq jLow()
const HMBDC_RESTRICT {
149 auto res = j_[0].seq;
150 for (
auto i = 1u; i < PARTICIPANT_COUNT; ++i)
151 if (res > j_[i].seq) res = j_[i].seq;
155 uint64_t
const missedInit_;
157 volatile Seq seq_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
158 uint64_t missed_ __attribute__((__aligned__(SMP_CACHE_BYTES)));
162 } __attribute__((__aligned__(SMP_CACHE_BYTES)));
163 J j_[PARTICIPANT_COUNT];
166 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t>
171 template <
typename GapFunc>
172 int operator()(uint16_t participantIndex, Seq seq, GapFunc&& gapFunc) {
174 if (!arb_(participantIndex, seq
178 , forward<GapFunc>(gapFunc)
186 volatile Seq& expectingSeq() {
187 return arb_.expectingSeq();
190 volatile Seq
const& expectingSeq()
const {
191 return arb_.expectingSeq();
200 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t,
bool THREADSAFE = true>
203 template <u
int16_t PARTICIPANT_COUNT,
typename Seq = u
int64_t>
Definition: SeqArb.hpp:159
Definition: SeqArb.hpp:167
Definition: TypedString.hpp:74
Definition: SeqArb.hpp:55