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-09-20 04:42:25 Functions: 8 344 2.3 %

          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         648 : fd_rwlock_write( fd_rwlock_t * lock ) {
      20         648 : # if FD_HAS_THREADS
      21         648 :   for(;;) {
      22         648 :     ushort value = lock->value;
      23         648 :     if( FD_LIKELY( !value ) ) {
      24         648 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, 0, 0xFFFF )==0 ) ) return;
      25         648 :     }
      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        1248 : fd_rwlock_unwrite( fd_rwlock_t * lock ) {
      36        1248 :   FD_COMPILER_MFENCE();
      37        1248 :   lock->value = 0;
      38        1248 : }
      39             : 
      40             : static inline void
      41         150 : fd_rwlock_read( fd_rwlock_t * lock ) {
      42         150 : # if FD_HAS_THREADS
      43         150 :   for(;;) {
      44         150 :     ushort value = lock->value;
      45         150 :     if( FD_UNLIKELY( value<0xFFFE ) ) {
      46         150 :       if( FD_LIKELY( FD_ATOMIC_CAS( &lock->value, value, value+1 )==value ) ) {
      47         150 :         return;
      48         150 :       }
      49         150 :     }
      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         150 : fd_rwlock_unread( fd_rwlock_t * lock ) {
      60         150 :   FD_COMPILER_MFENCE();
      61         150 : # if FD_HAS_THREADS
      62         150 :   FD_ATOMIC_FETCH_AND_SUB( &lock->value, 1 );
      63             : # else
      64             :   lock->value--;
      65             : # endif
      66         150 : }
      67             : 
      68             : #endif /* HEADER_fd_src_flamenco_rwlock_h */

Generated by: LCOV version 1.14