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-10-27 04:40:00 Functions: 12 785 1.5 %

          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     1577394 : fd_rwlock_new( fd_rwlock_t * lock ) {
      20     1577394 :   lock->value = 0;
      21     1577394 :   return 0;
      22     1577394 : }
      23             : 
      24             : static inline void
      25      572610 : fd_rwlock_write( fd_rwlock_t * lock ) {
      26      572610 : # if FD_HAS_THREADS
      27      572610 :   for(;;) {
      28      572610 :     ushort value = lock->value;
      29      572610 :     if( FD_LIKELY( !value ) ) {
      30      572610 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, 0, 0xFFFF )==0 ) ) return;
      31      572610 :     }
      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      573222 : fd_rwlock_unwrite( fd_rwlock_t * lock ) {
      42      573222 :   FD_COMPILER_MFENCE();
      43      573222 :   lock->value = 0;
      44      573222 : }
      45             : 
      46             : static inline void
      47          45 : fd_rwlock_read( fd_rwlock_t * lock ) {
      48          45 : # if FD_HAS_THREADS
      49          45 :   for(;;) {
      50          45 :     ushort value = lock->value;
      51          45 :     if( FD_UNLIKELY( value<0xFFFE ) ) {
      52          45 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, value, value+1 )==value ) ) {
      53          45 :         return;
      54          45 :       }
      55          45 :     }
      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         105 : fd_rwlock_unread( fd_rwlock_t * lock ) {
      66         105 :   FD_COMPILER_MFENCE();
      67         105 : # if FD_HAS_THREADS
      68         105 :   FD_ATOMIC_FETCH_AND_SUB( &lock->value, 1 );
      69             : # else
      70             :   lock->value--;
      71             : # endif
      72         105 : }
      73             : 
      74             : #endif /* HEADER_fd_src_flamenco_fd_rwlock_h */

Generated by: LCOV version 1.14