LCOV - code coverage report
Current view: top level - flamenco - fd_rwlock.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 29 37 78.4 %
Date: 2025-12-28 05:17:03 Functions: 15 725 2.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_fd_rwlock_h
       2             : #define HEADER_fd_src_flamenco_fd_rwlock_h
       3             : 
       4             : /* A very simple read-write spin lock. */
       5             : 
       6             : #include "../util/fd_util_base.h"
       7             : 
       8             : struct fd_rwlock {
       9             :   ushort value; /* Bits 0..16 are
      10             : 
      11             :                     0: Unlocked
      12             :                     1..=0xFFFE: Locked by N readers
      13             :                     0xFFFF: Write locked */
      14             : };
      15             : 
      16             : typedef struct fd_rwlock fd_rwlock_t;
      17             : 
      18             : static inline fd_rwlock_t *
      19     1574514 : fd_rwlock_new( fd_rwlock_t * lock ) {
      20     1574514 :   lock->value = 0;
      21     1574514 :   return 0;
      22     1574514 : }
      23             : 
      24             : static inline void
      25      573489 : fd_rwlock_write( fd_rwlock_t * lock ) {
      26      573489 : # if FD_HAS_THREADS
      27      573489 :   for(;;) {
      28      573489 :     ushort value = lock->value;
      29      573489 :     if( FD_LIKELY( !value ) ) {
      30      573489 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, 0, 0xFFFF )==0 ) ) return;
      31      573489 :     }
      32           0 :     FD_SPIN_PAUSE();
      33           0 :   }
      34             : # else
      35             :   lock->value = 0xFFFF;
      36             : # endif
      37           0 :   FD_COMPILER_MFENCE();
      38           0 : }
      39             : 
      40             : static inline void
      41      574284 : fd_rwlock_unwrite( fd_rwlock_t * lock ) {
      42      574284 :   FD_COMPILER_MFENCE();
      43      574284 :   lock->value = 0;
      44      574284 : }
      45             : 
      46             : static inline void
      47         144 : fd_rwlock_read( fd_rwlock_t * lock ) {
      48         144 : # if FD_HAS_THREADS
      49         144 :   for(;;) {
      50         144 :     ushort value = lock->value;
      51         144 :     if( FD_UNLIKELY( value<0xFFFE ) ) {
      52         144 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, value, value+1 )==value ) ) {
      53         144 :         return;
      54         144 :       }
      55         144 :     }
      56           0 :     FD_SPIN_PAUSE();
      57           0 :   }
      58             : # else
      59             :   lock->value++;
      60             : # endif
      61           0 :   FD_COMPILER_MFENCE();
      62           0 : }
      63             : 
      64             : static inline void
      65         213 : fd_rwlock_unread( fd_rwlock_t * lock ) {
      66         213 :   FD_COMPILER_MFENCE();
      67         213 : # if FD_HAS_THREADS
      68         213 :   FD_ATOMIC_FETCH_AND_SUB( &lock->value, 1 );
      69             : # else
      70             :   lock->value--;
      71             : # endif
      72         213 : }
      73             : 
      74             : #endif /* HEADER_fd_src_flamenco_fd_rwlock_h */

Generated by: LCOV version 1.14