LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_acc_pool.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 79 109 72.5 %
Date: 2026-02-01 06:05:50 Functions: 9 9 100.0 %

          Line data    Source code
       1             : #include "fd_acc_pool.h"
       2             : #include "fd_runtime_const.h"
       3             : #include "../fd_rwlock.h"
       4             : 
       5         723 : #define FD_ACC_POOL_MAGIC (0xF17EDA2CEACC6001UL) /* FIREDANCE ACC POOL */
       6             : 
       7             : struct fd_acc_entry {
       8             :   uchar account[ sizeof(fd_account_meta_t) + FD_RUNTIME_ACC_SZ_MAX ] __attribute__((aligned(FD_ACCOUNT_REC_ALIGN)));
       9             :   ulong magic;
      10             :   ulong next_;
      11             : };
      12             : typedef struct fd_acc_entry fd_acc_entry_t;
      13             : 
      14             : #define POOL_NAME fd_acc_entry_pool
      15         417 : #define POOL_T    fd_acc_entry_t
      16        1212 : #define POOL_NEXT next_
      17             : #include "../../util/tmpl/fd_pool.c"
      18             : 
      19             : struct fd_acc_pool {
      20             :   fd_rwlock_t lock_;
      21             :   ulong       pool_offset;
      22             :   ulong       magic;
      23             : };
      24             : typedef struct fd_acc_pool fd_acc_pool_t;
      25             : 
      26             : static inline fd_acc_entry_t *
      27         363 : fd_acc_pool( fd_acc_pool_t * acc_pool ) {
      28         363 :   return fd_acc_entry_pool_join( (uchar *)acc_pool + acc_pool->pool_offset );
      29         363 : }
      30             : 
      31             : ulong
      32         270 : fd_acc_pool_align( void ) {
      33         270 :   return 128UL;
      34         270 : }
      35             : 
      36             : ulong
      37          27 : fd_acc_pool_footprint( ulong account_cnt ) {
      38             : 
      39          27 :   ulong l = FD_LAYOUT_INIT;
      40          27 :   l = FD_LAYOUT_APPEND( l,  fd_acc_pool_align(),       sizeof(fd_acc_pool_t) );
      41          27 :   l = FD_LAYOUT_APPEND( l,  fd_acc_entry_pool_align(), fd_acc_entry_pool_footprint( account_cnt ) );
      42          27 :   return FD_LAYOUT_FINI( l, fd_acc_pool_align() );
      43          27 : }
      44             : 
      45             : void *
      46             : fd_acc_pool_new( void * shmem,
      47          27 :                  ulong  account_cnt ) {
      48          27 :   if( FD_UNLIKELY( !shmem ) ) {
      49           0 :     FD_LOG_WARNING(( "NULL shmem" ));
      50           0 :     return NULL;
      51           0 :   }
      52             : 
      53          27 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_acc_pool_align() ) ) ) {
      54           0 :     FD_LOG_WARNING(( "misaligned shmem" ));
      55           0 :     return NULL;
      56           0 :   }
      57             : 
      58          27 :   if( FD_UNLIKELY( account_cnt==0UL ) ) {
      59           0 :     FD_LOG_WARNING(( "account_cnt is 0" ));
      60           0 :     return NULL;
      61           0 :   }
      62             : 
      63          27 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      64          27 :   fd_acc_pool_t * acc_pool = FD_SCRATCH_ALLOC_APPEND( l, fd_acc_pool_align(),       sizeof(fd_acc_pool_t) );
      65          27 :   void *          pool     = FD_SCRATCH_ALLOC_APPEND( l, fd_acc_entry_pool_align(), fd_acc_entry_pool_footprint( account_cnt ) );
      66          27 :   FD_SCRATCH_ALLOC_FINI( l, fd_acc_pool_align() );
      67             : 
      68          27 :   fd_acc_entry_t * fd_acc_entry_pool = fd_acc_entry_pool_join( fd_acc_entry_pool_new( pool, account_cnt ) );
      69          27 :   if( FD_UNLIKELY( !fd_acc_entry_pool ) ) {
      70           0 :     FD_LOG_WARNING(( "Failed to create acc pool" ));
      71           0 :     return NULL;
      72           0 :   }
      73             : 
      74          27 :   acc_pool->pool_offset = (ulong)pool-(ulong)acc_pool;
      75             : 
      76          27 :   fd_rwlock_new( &acc_pool->lock_ );
      77             : 
      78          27 :   FD_COMPILER_MFENCE();
      79          27 :   FD_VOLATILE( acc_pool->magic ) = FD_ACC_POOL_MAGIC;
      80         723 :   for( ulong i=0UL; i<account_cnt; i++ ) {
      81         696 :     fd_acc_entry_t * ele = fd_acc_entry_pool_ele( fd_acc_entry_pool, i );
      82         696 :     ele->magic = FD_ACC_POOL_MAGIC;
      83         696 :   }
      84          27 :   FD_COMPILER_MFENCE();
      85             : 
      86          27 :   return shmem;
      87          27 : }
      88             : 
      89             : 
      90             : fd_acc_pool_t *
      91          27 : fd_acc_pool_join( void * mem ) {
      92             : 
      93          27 :   fd_acc_pool_t * acc_pool = (fd_acc_pool_t *)mem;
      94             : 
      95          27 :   if( FD_UNLIKELY( !mem ) ) {
      96           0 :     FD_LOG_WARNING(( "NULL mem" ));
      97           0 :     return NULL;
      98           0 :   }
      99             : 
     100          27 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_acc_pool_align() ) ) ) {
     101           0 :     FD_LOG_WARNING(( "misaligned mem" ));
     102           0 :     return NULL;
     103           0 :   }
     104             : 
     105          27 :   fd_acc_entry_t * fd_acc_entry_pool = fd_acc_pool( acc_pool );
     106          27 :   if( FD_UNLIKELY( !fd_acc_entry_pool ) ) {
     107           0 :     FD_LOG_WARNING(( "Failed to join acc entry pool" ));
     108           0 :     return NULL;
     109           0 :   }
     110             : 
     111         723 :   for( ulong i=0UL; i<fd_acc_entry_pool_max( fd_acc_entry_pool ); i++ ) {
     112         696 :     fd_acc_entry_t * ele = fd_acc_entry_pool_ele( fd_acc_entry_pool, i );
     113         696 :     if( FD_UNLIKELY( ele->magic!=FD_ACC_POOL_MAGIC ) ) {
     114           0 :       FD_LOG_WARNING(( "Invalid acc entry magic" ));
     115           0 :       return NULL;
     116           0 :     }
     117         696 :   }
     118             : 
     119          27 :   if( FD_UNLIKELY( acc_pool->magic!=FD_ACC_POOL_MAGIC ) ) {
     120           0 :     FD_LOG_WARNING(( "Invalid acc pool magic" ));
     121           0 :     return NULL;
     122           0 :   }
     123             : 
     124          27 :   return acc_pool;
     125          27 : }
     126             : 
     127             : int
     128             : fd_acc_pool_try_acquire( fd_acc_pool_t * acc_pool,
     129             :                          ulong           request_cnt,
     130          66 :                          uchar * *       accounts_out ) {
     131          66 :   fd_rwlock_write( &acc_pool->lock_ );
     132             : 
     133          66 :   fd_acc_entry_t * pool = fd_acc_pool( acc_pool );
     134             : 
     135          66 :   if( FD_UNLIKELY( fd_acc_entry_pool_free( pool )<request_cnt ) ) {
     136           0 :     fd_rwlock_unwrite( &acc_pool->lock_ );
     137           0 :     return 1;
     138           0 :   }
     139             : 
     140         333 :   for( ulong i=0UL; i<request_cnt; i++ ) {
     141         267 :     fd_acc_entry_t * ele = fd_acc_entry_pool_ele_acquire( pool );
     142         267 :     accounts_out[ i ] = (uchar *)ele;
     143         267 :   }
     144             : 
     145          66 :   fd_rwlock_unwrite( &acc_pool->lock_ );
     146             : 
     147          66 :   return 0;
     148          66 : }
     149             : 
     150             : void
     151             : fd_acc_pool_acquire( fd_acc_pool_t * acc_pool,
     152             :                      ulong           request_cnt,
     153          66 :                      uchar * *       accounts_out ) {
     154          66 :   for( ;; ) {
     155          66 :     int err = fd_acc_pool_try_acquire( acc_pool, request_cnt, accounts_out );
     156          66 :     if( FD_LIKELY( err==0 ) ) break;
     157          66 :   }
     158          66 : }
     159             : 
     160             : void
     161             : fd_acc_pool_release( fd_acc_pool_t * acc_pool,
     162         249 :                      uchar *         account ) {
     163         249 :   fd_rwlock_write( &acc_pool->lock_ );
     164             : 
     165         249 :   fd_acc_entry_t * pool = fd_acc_pool( acc_pool );
     166             : 
     167         249 :   fd_acc_entry_t * ele = fd_type_pun( account );
     168         249 :   fd_acc_entry_pool_ele_release( pool, ele );
     169             : 
     170         249 :   fd_rwlock_unwrite( &acc_pool->lock_ );
     171         249 : }
     172             : 
     173             : ulong
     174          21 : fd_acc_pool_free( fd_acc_pool_t * acc_pool ) {
     175          21 :   fd_rwlock_read( &acc_pool->lock_ );
     176          21 :   ulong free = fd_acc_entry_pool_free( fd_acc_pool( acc_pool ) );
     177          21 :   fd_rwlock_unread( &acc_pool->lock_ );
     178          21 :   return free;
     179          21 : }

Generated by: LCOV version 1.14