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