LCOV - code coverage report
Current view: top level - choreo/tower - fd_tower_lockos.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 73 106 68.9 %
Date: 2026-03-31 06:22:16 Functions: 4 6 66.7 %

          Line data    Source code
       1             : #include "fd_tower_lockos.h"
       2             : #include "fd_tower.h"
       3             : 
       4             : void *
       5             : fd_tower_lockos_new( void * shmem,
       6             :                      ulong  slot_max,
       7             :                      ulong  vtr_max,
       8          15 :                      ulong  seed ) {
       9             : 
      10          15 :   if( FD_UNLIKELY( !shmem ) ) {
      11           0 :     FD_LOG_WARNING(( "NULL mem" ));
      12           0 :     return NULL;
      13           0 :   }
      14             : 
      15          15 :   ulong footprint = fd_tower_lockos_footprint( slot_max, vtr_max );
      16          15 :   if( FD_UNLIKELY( !footprint ) ) {
      17           0 :     FD_LOG_WARNING(( "bad slot_max (%lu)", slot_max ));
      18           0 :     return NULL;
      19           0 :   }
      20             : 
      21          15 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_tower_lockos_align() ) ) ) {
      22           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      23           0 :     return NULL;
      24           0 :   }
      25             : 
      26          15 :   ulong interval_max = fd_ulong_pow2_up( FD_TOWER_LOCKOS_MAX*slot_max*vtr_max );
      27             : 
      28          15 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      29          15 :   fd_tower_lockos_t * lockos        = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_tower_lockos_t),            sizeof(fd_tower_lockos_t)                               );
      30          15 :   void *              slot_pool     = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_lockos_slot_pool_align(),     fd_tower_lockos_slot_pool_footprint( interval_max )     );
      31          15 :   void *              slot_map      = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_lockos_slot_map_align(),      fd_tower_lockos_slot_map_footprint ( slot_max )         );
      32          15 :   void *              interval_pool = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_lockos_interval_pool_align(), fd_tower_lockos_interval_pool_footprint( interval_max ) );
      33          15 :   void *              interval_map  = FD_SCRATCH_ALLOC_APPEND( l, fd_tower_lockos_interval_map_align(),  fd_tower_lockos_interval_map_footprint ( interval_max ) );
      34          15 :   FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_tower_lockos_align() )==(ulong)shmem + footprint );
      35             : 
      36          15 :   lockos->slot_pool     = fd_tower_lockos_slot_pool_new    ( slot_pool,     interval_max       );
      37          15 :   lockos->slot_map      = fd_tower_lockos_slot_map_new     ( slot_map,      slot_max,     seed );
      38          15 :   lockos->interval_pool = fd_tower_lockos_interval_pool_new( interval_pool, interval_max       );
      39          15 :   lockos->interval_map  = fd_tower_lockos_interval_map_new ( interval_map,  interval_max, seed );
      40             : 
      41          15 :   FD_TEST( lockos->slot_map );
      42          15 :   FD_TEST( lockos->slot_pool );
      43          15 :   FD_TEST( lockos->interval_map );
      44          15 :   FD_TEST( lockos->interval_pool );
      45             : 
      46          15 :   return shmem;
      47          15 : }
      48             : 
      49             : fd_tower_lockos_t *
      50          15 : fd_tower_lockos_join( void * shlockos ) {
      51             : 
      52          15 :   fd_tower_lockos_t * lockos = (fd_tower_lockos_t *)shlockos;
      53             : 
      54          15 :   if( FD_UNLIKELY( !lockos ) ) {
      55           0 :     FD_LOG_WARNING(( "NULL tower_lockos" ));
      56           0 :     return NULL;
      57           0 :   }
      58             : 
      59          15 :   if( FD_UNLIKELY( !fd_ulong_is_aligned((ulong)lockos, fd_tower_lockos_align() ) ) ) {
      60           0 :     FD_LOG_WARNING(( "misaligned tower_lockos" ));
      61           0 :     return NULL;
      62           0 :   }
      63             : 
      64          15 :   lockos->slot_map      = fd_tower_lockos_slot_map_join     ( lockos->slot_map      );
      65          15 :   lockos->slot_pool     = fd_tower_lockos_slot_pool_join    ( lockos->slot_pool     );
      66          15 :   lockos->interval_map  = fd_tower_lockos_interval_map_join ( lockos->interval_map  );
      67          15 :   lockos->interval_pool = fd_tower_lockos_interval_pool_join( lockos->interval_pool );
      68             : 
      69          15 :   FD_TEST( lockos->slot_map );
      70          15 :   FD_TEST( lockos->slot_pool );
      71          15 :   FD_TEST( lockos->interval_map );
      72          15 :   FD_TEST( lockos->interval_pool );
      73             : 
      74          15 :   return lockos;
      75          15 : }
      76             : 
      77             : void *
      78           0 : fd_tower_lockos_leave( fd_tower_lockos_t const * lockos ) {
      79             : 
      80           0 :   if( FD_UNLIKELY( !lockos ) ) {
      81           0 :     FD_LOG_WARNING(( "NULL lockos" ));
      82           0 :     return NULL;
      83           0 :   }
      84             : 
      85           0 :   return (void *)lockos;
      86           0 : }
      87             : 
      88             : void *
      89           0 : fd_tower_lockos_delete( void * lockos ) {
      90             : 
      91           0 :   if( FD_UNLIKELY( !lockos ) ) {
      92           0 :     FD_LOG_WARNING(( "NULL lockos" ));
      93           0 :     return NULL;
      94           0 :   }
      95             : 
      96           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned((ulong)lockos, fd_tower_lockos_align() ) ) ) {
      97           0 :     FD_LOG_WARNING(( "misaligned lockos" ));
      98           0 :     return NULL;
      99           0 :   }
     100             : 
     101           0 :   return lockos;
     102           0 : }
     103             : 
     104             : void
     105             : fd_tower_lockos_insert( fd_tower_lockos_t * lockos,
     106             :                         ulong               slot,
     107             :                         fd_hash_t const *   addr,
     108         138 :                         fd_tower_voters_t * voters ) {
     109             : 
     110         138 :   for( fd_tower_iter_t iter = fd_tower_iter_init( voters->tower );
     111         276 :                              !fd_tower_iter_done( voters->tower, iter );
     112         138 :                        iter = fd_tower_iter_next( voters->tower, iter ) ) {
     113         138 :     fd_tower_vote_t const * vote = fd_tower_iter_ele_const( voters->tower, iter );
     114         138 :     ulong        interval_start = vote->slot;
     115         138 :     ulong        interval_end   = vote->slot + ( 1UL << vote->conf );
     116         138 :     ulong        key            = fd_tower_lockos_interval_key( slot, interval_end );
     117             : 
     118         138 :     if( !fd_tower_lockos_interval_map_ele_query( lockos->interval_map, &key, NULL, lockos->interval_pool ) ) {
     119         129 :       FD_TEST( fd_tower_lockos_slot_pool_free( lockos->slot_pool ) ); /* [slot, interval_end] is a new vote interval. guaranteed to have space because we size slot pool to max voters * max slots. */
     120         129 :       fd_tower_lockos_slot_t * slot_ele = fd_tower_lockos_slot_pool_ele_acquire( lockos->slot_pool );
     121         129 :       slot_ele->fork_slot               = slot; /* map multi, multiple keys for the same fork_slot */
     122         129 :       slot_ele->interval_end            = interval_end;
     123         129 :       FD_TEST( fd_tower_lockos_slot_map_ele_insert( lockos->slot_map, slot_ele, lockos->slot_pool ) );
     124         129 :     }
     125             : 
     126         138 :     FD_TEST( fd_tower_lockos_interval_pool_free( lockos->interval_pool ) );
     127         138 :     fd_tower_lockos_interval_t * interval = fd_tower_lockos_interval_pool_ele_acquire( lockos->interval_pool );
     128         138 :     interval->key                         = key;
     129         138 :     interval->addr                        = *addr;
     130         138 :     interval->start                       = interval_start;
     131         138 :     FD_TEST( fd_tower_lockos_interval_map_ele_insert( lockos->interval_map, interval, lockos->interval_pool ) );
     132         138 :   }
     133         138 : }
     134             : 
     135             : void
     136             : fd_tower_lockos_remove( fd_tower_lockos_t * lockos,
     137          12 :                         ulong               slot ) {
     138             : 
     139          12 :   for( fd_tower_lockos_slot_t * sloti = fd_tower_lockos_slot_map_ele_remove( lockos->slot_map, &slot, NULL, lockos->slot_pool );
     140         114 :                                 sloti;
     141         102 :                                 sloti = fd_tower_lockos_slot_map_ele_remove( lockos->slot_map, &slot, NULL, lockos->slot_pool ) ) {
     142         102 :     ulong key = fd_tower_lockos_interval_key( slot, sloti->interval_end );
     143         102 :     for( fd_tower_lockos_interval_t * itrvl = fd_tower_lockos_interval_map_ele_remove( lockos->interval_map, &key, NULL, lockos->interval_pool );
     144         204 :                                       itrvl;
     145         102 :                                       itrvl = fd_tower_lockos_interval_map_ele_remove( lockos->interval_map, &key, NULL, lockos->interval_pool ) ) {
     146         102 :       fd_tower_lockos_interval_pool_ele_release( lockos->interval_pool, itrvl );
     147         102 :     }
     148         102 :     fd_tower_lockos_slot_pool_ele_release( lockos->slot_pool, sloti );
     149         102 :   }
     150          12 : }

Generated by: LCOV version 1.14