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 15 : fd_seqlock_write_lock( atomic_ulong * lock ) { 14 15 : for(;;) { 15 15 : ulong seq = atomic_load_explicit( lock, memory_order_relaxed ); 16 15 : if( FD_UNLIKELY( seq & 1UL ) ) continue; 17 15 : if( FD_LIKELY( atomic_compare_exchange_weak_explicit( lock, &seq, seq+1UL, memory_order_acquire, memory_order_relaxed ) ) ) { 18 15 : return; 19 15 : } 20 15 : } 21 15 : } 22 : 23 : static inline void 24 15 : fd_seqlock_write_unlock( atomic_ulong * lock ) { 25 15 : atomic_fetch_add_explicit( lock, 1UL, memory_order_release ); 26 15 : } 27 : 28 : static inline ulong 29 33 : fd_seqlock_read_try( atomic_ulong const * lock ) { 30 33 : for(;;) { 31 33 : ulong seq = atomic_load_explicit( lock, memory_order_acquire ); 32 33 : if( FD_LIKELY( !(seq & 1UL) ) ) return seq; 33 33 : } 34 33 : } 35 : 36 : static inline int 37 : fd_seqlock_read_test( atomic_ulong const * lock, 38 33 : ulong seq ) { 39 33 : atomic_thread_fence( memory_order_acquire ); 40 33 : return atomic_load_explicit( lock, memory_order_acquire )==seq; 41 33 : } 42 : 43 : static inline int 44 0 : fd_seqlock_locked_hint( atomic_ulong const * lock ) { 45 0 : return atomic_load_explicit( lock, memory_order_relaxed ) & 1UL; 46 0 : } 47 : 48 : #endif /* HEADER_fd_src_waltz_mib_fd_seqlock_h */