• 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)