LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_acc_pool.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 66 103 64.1 %
Date: 2026-01-09 05:14:11 Functions: 7 8 87.5 %

          Line data    Source code
       1             : #include "fd_acc_pool.h"
       2             : #include "fd_runtime_const.h"
       3             : #include "../fd_rwlock.h"
       4             : 
       5          30 : #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          24 : #define POOL_T    fd_acc_entry_t
      16          42 : #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          12 : fd_acc_pool( fd_acc_pool_t * acc_pool ) {
      28          12 :   return fd_acc_entry_pool_join( (uchar *)acc_pool + acc_pool->pool_offset );
      29          12 : }
      30             : 
      31             : ulong
      32          60 : fd_acc_pool_align( void ) {
      33          60 :   return 128UL;
      34          60 : }
      35             : 
      36             : ulong
      37           6 : fd_acc_pool_footprint( ulong account_cnt ) {
      38             : 
      39           6 :   ulong l = FD_LAYOUT_INIT;
      40           6 :   l = FD_LAYOUT_APPEND( l,  fd_acc_pool_align(),       sizeof(fd_acc_pool_t) );
      41           6 :   l = FD_LAYOUT_APPEND( l,  fd_acc_entry_pool_align(), fd_acc_entry_pool_footprint( account_cnt ) );
      42           6 :   return FD_LAYOUT_FINI( l, fd_acc_pool_align() );
      43           6 : }
      44             : 
      45             : void *
      46             : fd_acc_pool_new( void * shmem,
      47           6 :                  ulong  account_cnt ) {
      48           6 :   if( FD_UNLIKELY( !shmem ) ) {
      49           0 :     FD_LOG_WARNING(( "NULL shmem" ));
      50           0 :     return NULL;
      51           0 :   }
      52             : 
      53           6 :   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           6 :   if( FD_UNLIKELY( account_cnt==0UL ) ) {
      59           0 :     FD_LOG_WARNING(( "account_cnt is 0" ));
      60           0 :     return NULL;
      61           0 :   }
      62             : 
      63           6 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      64           6 :   fd_acc_pool_t * acc_pool = FD_SCRATCH_ALLOC_APPEND( l, fd_acc_pool_align(),       sizeof(fd_acc_pool_t) );
      65           6 :   void *          pool     = FD_SCRATCH_ALLOC_APPEND( l, fd_acc_entry_pool_align(), fd_acc_entry_pool_footprint( account_cnt ) );
      66           6 :   FD_SCRATCH_ALLOC_FINI( l, fd_acc_pool_align() );
      67             : 
      68           6 :   fd_acc_entry_t * fd_acc_entry_pool = fd_acc_entry_pool_join( fd_acc_entry_pool_new( pool, account_cnt ) );
      69           6 :   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           6 :   acc_pool->pool_offset = (ulong)pool-(ulong)acc_pool;
      75             : 
      76           6 :   fd_rwlock_new( &acc_pool->lock_ );
      77             : 
      78           6 :   FD_COMPILER_MFENCE();
      79           6 :   FD_VOLATILE( acc_pool->magic ) = FD_ACC_POOL_MAGIC;
      80          30 :   for( ulong i=0UL; i<account_cnt; i++ ) {
      81          24 :     fd_acc_entry_t * ele = fd_acc_entry_pool_ele( fd_acc_entry_pool, i );
      82          24 :     ele->magic = FD_ACC_POOL_MAGIC;
      83          24 :   }
      84           6 :   FD_COMPILER_MFENCE();
      85             : 
      86           6 :   return shmem;
      87           6 : }
      88             : 
      89             : 
      90             : fd_acc_pool_t *
      91           6 : fd_acc_pool_join( void * mem ) {
      92             : 
      93           6 :   fd_acc_pool_t * acc_pool = (fd_acc_pool_t *)mem;
      94             : 
      95           6 :   if( FD_UNLIKELY( !mem ) ) {
      96           0 :     FD_LOG_WARNING(( "NULL mem" ));
      97           0 :     return NULL;
      98           0 :   }
      99             : 
     100           6 :   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           6 :   fd_acc_entry_t * fd_acc_entry_pool = fd_acc_pool( acc_pool );
     106           6 :   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          30 :   for( ulong i=0UL; i<fd_acc_entry_pool_max( fd_acc_entry_pool ); i++ ) {
     112          24 :     fd_acc_entry_t * ele = fd_acc_entry_pool_ele( fd_acc_entry_pool, i );
     113          24 :     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          24 :   }
     118             : 
     119           6 :   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           6 :   return acc_pool;
     125           6 : }
     126             : 
     127             : int
     128             : fd_acc_pool_try_acquire( fd_acc_pool_t * acc_pool,
     129             :                          ulong           request_cnt,
     130           6 :                          uchar * *       accounts_out ) {
     131           6 :   fd_rwlock_write( &acc_pool->lock_ );
     132             : 
     133           6 :   fd_acc_entry_t * pool = fd_acc_pool( acc_pool );
     134             : 
     135           6 :   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          24 :   for( ulong i=0UL; i<request_cnt; i++ ) {
     141          18 :     fd_acc_entry_t * ele = fd_acc_entry_pool_ele_acquire( pool );
     142          18 :     accounts_out[ i ] = (uchar *)ele;
     143          18 :   }
     144             : 
     145           6 :   fd_rwlock_unwrite( &acc_pool->lock_ );
     146             : 
     147           6 :   return 0;
     148           6 : }
     149             : 
     150             : void
     151             : fd_acc_pool_acquire( fd_acc_pool_t * acc_pool,
     152             :                      ulong           request_cnt,
     153           6 :                      uchar * *       accounts_out ) {
     154           6 :   for( ;; ) {
     155           6 :     int err = fd_acc_pool_try_acquire( acc_pool, request_cnt, accounts_out );
     156           6 :     if( FD_LIKELY( err==0 ) ) break;
     157           6 :   }
     158           6 : }
     159             : 
     160             : void
     161             : fd_acc_pool_release( fd_acc_pool_t * acc_pool,
     162           0 :                      uchar *         account ) {
     163           0 :   fd_rwlock_write( &acc_pool->lock_ );
     164             : 
     165           0 :   fd_acc_entry_t * pool = fd_acc_pool( acc_pool );
     166             : 
     167           0 :   fd_acc_entry_t * ele = fd_type_pun( account );
     168           0 :   fd_acc_entry_pool_ele_release( pool, ele );
     169             : 
     170           0 :   fd_rwlock_unwrite( &acc_pool->lock_ );
     171           0 : }

Generated by: LCOV version 1.14