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-11-26 04:52:47 Functions: 13 730 1.8 %

          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     1574424 : fd_rwlock_new( fd_rwlock_t * lock ) {
      20     1574424 :   lock->value = 0;
      21     1574424 :   return 0;
      22     1574424 : }
      23             : 
      24             : static inline void
      25      572916 : fd_rwlock_write( fd_rwlock_t * lock ) {
      26      572916 : # if FD_HAS_THREADS
      27      572916 :   for(;;) {
      28      572916 :     ushort value = lock->value;
      29      572916 :     if( FD_LIKELY( !value ) ) {
      30      572916 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, 0, 0xFFFF )==0 ) ) return;
      31      572916 :     }
      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      573522 : fd_rwlock_unwrite( fd_rwlock_t * lock ) {
      42      573522 :   FD_COMPILER_MFENCE();
      43      573522 :   lock->value = 0;
      44      573522 : }
      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         114 : fd_rwlock_unread( fd_rwlock_t * lock ) {
      66         114 :   FD_COMPILER_MFENCE();
      67         114 : # if FD_HAS_THREADS
      68         114 :   FD_ATOMIC_FETCH_AND_SUB( &lock->value, 1 );
      69             : # else
      70             :   lock->value--;
      71             : # endif
      72         114 : }
      73             : 
      74             : #endif /* HEADER_fd_src_flamenco_fd_rwlock_h */

Generated by: LCOV version 1.14