Line data Source code
1 : #ifndef HEADER_fd_src_waltz_mib_fd_seqlock_h 2 : #define HEADER_fd_src_waltz_mib_fd_seqlock_h 3 : 4 : #include "../../util/fd_util_base.h" 5 : #include <stdatomic.h> 6 : 7 : static inline void 8 0 : fd_seqlock_init( atomic_ulong * lock ) { 9 0 : atomic_store_explicit( lock, 0UL, memory_order_release ); 10 0 : } 11 : 12 : static inline void 13 0 : fd_seqlock_write_lock( atomic_ulong * lock ) { 14 0 : for(;;) { 15 0 : ulong seq = atomic_load_explicit( lock, memory_order_relaxed ); 16 0 : if( FD_UNLIKELY( seq & 1UL ) ) continue; 17 0 : if( FD_LIKELY( atomic_compare_exchange_weak_explicit( lock, &seq, seq+1UL, memory_order_acquire, memory_order_relaxed ) ) ) { 18 0 : return; 19 0 : } 20 0 : } 21 0 : } 22 : 23 : static inline void 24 0 : fd_seqlock_write_unlock( atomic_ulong * lock ) { 25 0 : atomic_fetch_add_explicit( lock, 1UL, memory_order_release ); 26 0 : } 27 : 28 : static inline ulong 29 0 : fd_seqlock_read_try( atomic_ulong const * lock ) { 30 0 : for(;;) { 31 0 : ulong seq = atomic_load_explicit( lock, memory_order_acquire ); 32 0 : if( FD_LIKELY( !(seq & 1UL) ) ) return seq; 33 0 : } 34 0 : } 35 : 36 : static inline int 37 : fd_seqlock_read_test( atomic_ulong const * lock, 38 0 : ulong seq ) { 39 0 : atomic_thread_fence( memory_order_acquire ); 40 0 : return atomic_load_explicit( lock, memory_order_acquire )==seq; 41 0 : } 42 : 43 : static inline int 44 0 : fd_seqlock_locked_hint( atomic_ulong const * lock ) { 45 : return atomic_load_explicit( lock, memory_order_relaxed ) & 1UL; 46 0 : } 47 : 48 : #endif /* HEADER_fd_src_waltz_mib_fd_seqlock_h */