fix shared loop: in rare cases elements have been called twice

This commit is contained in:
Joachim Schoeberl 2022-04-30 10:39:26 +02:00
parent aa00749f97
commit bf22f8d4df

View File

@ -464,23 +464,26 @@ public:
bool PopFirst (size_t & first) bool PopFirst (size_t & first)
{ {
first = begin++; // first = begin++;
return first < end; // return first < end;
/*
// int oldbegin = begin;
size_t oldbegin = begin.load(std::memory_order_acquire);
if (oldbegin >= end) return false;
while (!begin.compare_exchange_weak (oldbegin, oldbegin+1,
std::memory_order_relaxed, std::memory_order_relaxed))
if (oldbegin >= end) return false;
first = oldbegin; first = begin;
return true;
*/ size_t nextfirst = first+1;
if (first >= end) nextfirst = std::numeric_limits<size_t>::max()-1;
while (!begin.compare_exchange_weak (first, nextfirst))
{
first = begin;
nextfirst = first+1;
if (nextfirst >= end) nextfirst = std::numeric_limits<size_t>::max()-1;
}
return first < end;
} }
bool PopHalf (IntRange & r) bool PopHalf (IntRange & r)
{ {
/*
// int oldbegin = begin; // int oldbegin = begin;
size_t oldbegin = begin.load(std::memory_order_acquire); size_t oldbegin = begin.load(std::memory_order_acquire);
size_t oldend = end.load(std::memory_order_acquire); size_t oldend = end.load(std::memory_order_acquire);
@ -496,6 +499,28 @@ public:
r = IntRange(oldbegin, (oldbegin+oldend+1)/2); r = IntRange(oldbegin, (oldbegin+oldend+1)/2);
return true; return true;
*/
size_t oldbegin = begin; // .load(std::memory_order_acquire);
size_t oldend = end; // .load(std::memory_order_acquire);
if (oldbegin >= oldend) return false;
size_t nextbegin = (oldbegin+oldend+1)/2;
if (nextbegin >= oldend) nextbegin = std::numeric_limits<size_t>::max()-1;
while (!begin.compare_exchange_weak (oldbegin, nextbegin))
// std::memory_order_relaxed, std::memory_order_relaxed))
{
oldend = end; // .load(std::memory_order_acquire);
if (oldbegin >= oldend) return false;
nextbegin = (oldbegin+oldend+1)/2;
if (nextbegin >= oldend) nextbegin = std::numeric_limits<size_t>::max()-1;
}
r = IntRange(oldbegin, (oldbegin+oldend+1)/2);
return true;
} }
}; };