LCOV - code coverage report
Current view: top level - flamenco - fd_rwlock.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 25 33 75.8 %
Date: 2025-07-01 05:00:49 Functions: 6 540 1.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_rwlock_h
       2             : #define HEADER_fd_src_flamenco_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 void
      19          48 : fd_rwlock_write( fd_rwlock_t * lock ) {
      20          48 : # if FD_HAS_THREADS
      21          48 :   for(;;) {
      22          48 :     ushort value = lock->value;
      23          48 :     if( FD_LIKELY( !value ) ) {
      24          48 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, 0, 0xFFFF )==0 ) ) return;
      25          48 :     }
      26           0 :     FD_SPIN_PAUSE();
      27           0 :   }
      28             : # else
      29             :   lock->value = 0xFFFF;
      30             : # endif
      31           0 :   FD_COMPILER_MFENCE();
      32           0 : }
      33             : 
      34             : static inline void
      35         342 : fd_rwlock_unwrite( fd_rwlock_t * lock ) {
      36         342 :   FD_COMPILER_MFENCE();
      37         342 :   lock->value = 0;
      38         342 : }
      39             : 
      40             : static inline void
      41          15 : fd_rwlock_read( fd_rwlock_t * lock ) {
      42          15 : # if FD_HAS_THREADS
      43          15 :   for(;;) {
      44          15 :     ushort value = lock->value;
      45          15 :     if( FD_UNLIKELY( value<0xFFFE ) ) {
      46          15 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, value, value+1 )==value ) ) {
      47          15 :         return;
      48          15 :       }
      49          15 :     }
      50           0 :     FD_SPIN_PAUSE();
      51           0 :   }
      52             : # else
      53             :   lock->value++;
      54             : # endif
      55           0 :   FD_COMPILER_MFENCE();
      56           0 : }
      57             : 
      58             : static inline void
      59           9 : fd_rwlock_unread( fd_rwlock_t * lock ) {
      60           9 :   FD_COMPILER_MFENCE();
      61           9 : # if FD_HAS_THREADS
      62           9 :   FD_ATOMIC_FETCH_AND_SUB( &lock->value, 1 );
      63             : # else
      64             :   lock->value--;
      65             : # endif
      66           9 : }
      67             : 
      68             : #endif /* HEADER_fd_src_flamenco_rwlock_h */

Generated by: LCOV version 1.14