Maybe not finished, just a first step
From
Bonita Montero@3:633/10 to
All on Wed Jan 14 15:14:50 2026
A "std::barrier" with a futex.
And aliasing, which shouldn't make problems with atomics.
#pragma once
#include <atomic>
#include <bit>
struct xbarrier
{
struct error : std::invalid_argument
{
error() : std::invalid_argument( nullptr ) {};
};
xbarrier( uint32_t initial );
xbarrier( const xbarrier & ) = delete;
xbarrier &operator =( const xbarrier & ) = delete;
void arrive_and_wait( uint32_t count = 1 );
void arrive( uint32_t count = 1 );
void arrive_and_drop( uint32_t count = 1 );
uint32_t max() noexcept;
private:
uint64_t arriveInternal( uint32_t n, bool drop );
std::atomic_uint64_t m_counters = 0;
};
xbarrier::xbarrier( uint32_t initial ) :
m_counters( [&]
{
if( initial && initial <= (uint32_t)std::numeric_limits<int32_t>::max() )
return (uint64_t)initial << 32;
else
throw error();
}() )
{
}
uint64_t xbarrier::arriveInternal( uint32_t n, bool drop )
{
using namespace std;
uint64_t ref = m_counters.load( memory_order_relaxed );
if( !n )
return ref;
for( ; ; )
{
uint32_t counter = (uint32_t)ref;
counter -= n <= counter ? n : counter;
uint32_t initial = ref >> 32;
if( drop && (int32_t)(initial -= drop) <= 0 )
throw error();
counter = counter ? counter : initial;
uint64_t niu = (uint64_t)initial << 32 | counter;
if( m_counters.compare_exchange_strong( ref, niu, memory_order_acquire, memory_order_relaxed ) )
{
if( (uint32_t)niu == initial )
m_counters.notify_all();
return niu;
}
}
}
void xbarrier::arrive_and_wait( uint32_t n )
{
using namespace std;
uint64_t ref = arriveInternal( n, false );
if( !(uint32_t)ref )
return;
atomic_uint32_t *base = (atomic_uint32_t *)&m_counters;
while( (uint32_t)ref )
{
if constexpr( endian::native == endian::little )
base[0].wait( 0, memory_order_relaxed );
else
base[1].wait( 0, memory_order_relaxed );
ref = m_counters.load( memory_order_acquire );
}
}
void xbarrier::arrive( uint32_t count )
{
arriveInternal( count, false );
}
void xbarrier::arrive_and_drop( uint32_t count )
{
arriveInternal( count, true );
}
uint32_t xbarrier::max() noexcept
{
return -1;
}
--- PyGate Linux v1.5.2
* Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)