LCOV - code coverage report
Current view: top level - choreo/forks - fd_forks.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 138 0.0 %
Date: 2025-08-18 04:55:26 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #include "fd_forks.h"
       2             : 
       3             : #include "../../flamenco/runtime/context/fd_exec_slot_ctx.h"
       4             : #include "../../flamenco/runtime/fd_acc_mgr.h"
       5             : #include "../../flamenco/runtime/fd_borrowed_account.h"
       6             : #include "../../flamenco/runtime/fd_runtime.h"
       7             : #include "../../flamenco/runtime/program/fd_program_util.h"
       8             : #include "../../flamenco/runtime/program/fd_vote_program.h"
       9             : 
      10             : void *
      11           0 : fd_forks_new( void * shmem, ulong max, ulong seed ) {
      12             : 
      13           0 :   if( FD_UNLIKELY( !shmem ) ) {
      14           0 :     FD_LOG_WARNING( ( "NULL mem" ) );
      15           0 :     return NULL;
      16           0 :   }
      17             : 
      18           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_forks_align() ) ) ) {
      19           0 :     FD_LOG_WARNING( ( "misaligned mem" ) );
      20           0 :     return NULL;
      21           0 :   }
      22             : 
      23           0 :   ulong footprint = fd_forks_footprint( max );
      24           0 :   if( FD_UNLIKELY( !footprint ) ) {
      25           0 :     FD_LOG_WARNING( ( "bad mem" ) );
      26           0 :     return NULL;
      27           0 :   }
      28             : 
      29           0 :   fd_memset( shmem, 0, footprint );
      30           0 :   ulong laddr = (ulong)shmem;
      31             : 
      32           0 :   laddr = fd_ulong_align_up( laddr, alignof( fd_forks_t ) );
      33           0 :   laddr += sizeof( fd_forks_t );
      34             : 
      35           0 :   laddr = fd_ulong_align_up( laddr, fd_fork_pool_align() );
      36           0 :   fd_fork_pool_new( (void *)laddr, max );
      37           0 :   laddr += fd_fork_pool_footprint( max );
      38             : 
      39           0 :   laddr = fd_ulong_align_up( laddr, fd_fork_frontier_align() );
      40           0 :   fd_fork_frontier_new( (void *)laddr, max, seed );
      41           0 :   laddr += fd_fork_frontier_footprint( max );
      42             : 
      43           0 :   return shmem;
      44           0 : }
      45             : 
      46             : fd_forks_t *
      47           0 : fd_forks_join( void * shforks ) {
      48             : 
      49           0 :   if( FD_UNLIKELY( !shforks ) ) {
      50           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
      51           0 :     return NULL;
      52           0 :   }
      53             : 
      54           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shforks, fd_forks_align() ) ) ) {
      55           0 :     FD_LOG_WARNING( ( "misaligned forks" ) );
      56           0 :     return NULL;
      57           0 :   }
      58             : 
      59           0 :   ulong        laddr = (ulong)shforks;
      60           0 :   fd_forks_t * forks = (void *)laddr;
      61             : 
      62           0 :   laddr = fd_ulong_align_up( laddr, alignof( fd_forks_t ) );
      63           0 :   laddr += sizeof( fd_forks_t );
      64             : 
      65           0 :   laddr       = fd_ulong_align_up( laddr, fd_fork_pool_align() );
      66           0 :   forks->pool = fd_fork_pool_join( (void *)laddr );
      67           0 :   ulong max   = fd_fork_pool_max( forks->pool );
      68           0 :   laddr += fd_fork_pool_footprint( max );
      69             : 
      70           0 :   laddr           = fd_ulong_align_up( laddr, fd_fork_frontier_align() );
      71           0 :   forks->frontier = fd_fork_frontier_join( (void *)laddr );
      72           0 :   laddr += fd_fork_frontier_footprint( max );
      73             : 
      74           0 :   return (fd_forks_t *)shforks;
      75           0 : }
      76             : 
      77             : void *
      78           0 : fd_forks_leave( fd_forks_t const * forks ) {
      79             : 
      80           0 :   if( FD_UNLIKELY( !forks ) ) {
      81           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
      82           0 :     return NULL;
      83           0 :   }
      84             : 
      85           0 :   return (void *)forks;
      86           0 : }
      87             : 
      88             : void *
      89           0 : fd_forks_delete( void * forks ) {
      90             : 
      91           0 :   if( FD_UNLIKELY( !forks ) ) {
      92           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
      93           0 :     return NULL;
      94           0 :   }
      95             : 
      96           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)forks, fd_forks_align() ) ) ) {
      97           0 :     FD_LOG_WARNING( ( "misaligned forks" ) );
      98           0 :     return NULL;
      99           0 :   }
     100             : 
     101           0 :   return forks;
     102           0 : }
     103             : 
     104             : fd_fork_t *
     105           0 : fd_forks_init( fd_forks_t * forks, ulong slot ) {
     106             : 
     107           0 :   if( FD_UNLIKELY( !forks ) ) {
     108           0 :     FD_LOG_WARNING( ( "NULL forks" ) );
     109           0 :     return NULL;
     110           0 :   }
     111             : 
     112           0 :   fd_fork_t * fork = fd_fork_pool_ele_acquire( forks->pool );
     113           0 :   fork->slot       = slot;
     114           0 :   fork->prev       = fd_fork_pool_idx_null( forks->pool );
     115           0 :   fork->lock       = 0;
     116           0 :   if( FD_UNLIKELY( !fd_fork_frontier_ele_insert( forks->frontier, fork, forks->pool ) ) ) {
     117           0 :     FD_LOG_WARNING( ( "Failed to insert fork into frontier" ) );
     118           0 :   }
     119             : 
     120           0 :   return fork;
     121           0 : }
     122             : 
     123             : fd_fork_t *
     124           0 : fd_forks_query( fd_forks_t * forks, ulong slot ) {
     125           0 :   return fd_fork_frontier_ele_query( forks->frontier, &slot, NULL, forks->pool );
     126           0 : }
     127             : 
     128             : fd_fork_t const *
     129           0 : fd_forks_query_const( fd_forks_t const * forks, ulong slot ) {
     130           0 :   return fd_fork_frontier_ele_query_const( forks->frontier, &slot, NULL, forks->pool );
     131           0 : }
     132             : 
     133             : fd_fork_t *
     134           0 : fd_forks_prepare( fd_forks_t const * forks, ulong parent_slot ) {
     135             : 
     136             :   /* Query for parent_slot in the frontier. */
     137             : 
     138           0 :   fd_fork_t * fork = fd_fork_frontier_ele_query( forks->frontier, &parent_slot, NULL, forks->pool );
     139             : 
     140             :   /* If the parent block is both present and executed, but isn't in the
     141             :      frontier, that means this block is starting a new fork and needs to
     142             :      be added to the frontier. This requires recovering the slot_ctx
     143             :      as of that parent_slot by executing a funky rollback. */
     144             : 
     145           0 :   if( FD_UNLIKELY( !fork ) ) {
     146             : 
     147             :     /* Alloc a new slot_ctx */
     148             : 
     149           0 :     fork       = fd_fork_pool_ele_acquire( forks->pool );
     150           0 :     fork->prev = fd_fork_pool_idx_null( forks->pool );
     151           0 :     fork->slot = parent_slot;
     152           0 :     fork->lock = 1;
     153             : 
     154             :     /* Add to frontier */
     155             : 
     156           0 :     fd_fork_frontier_ele_insert( forks->frontier, fork, forks->pool );
     157           0 :   }
     158             : 
     159           0 :   return fork;
     160           0 : }
     161             : 
     162             : void
     163           0 : fd_forks_publish( fd_forks_t * forks, ulong slot ) {
     164           0 :   fd_fork_t * tail = NULL;
     165           0 :   fd_fork_t * curr = NULL;
     166             : 
     167           0 :   for( fd_fork_frontier_iter_t iter = fd_fork_frontier_iter_init( forks->frontier, forks->pool );
     168           0 :        !fd_fork_frontier_iter_done( iter, forks->frontier, forks->pool );
     169           0 :        iter = fd_fork_frontier_iter_next( iter, forks->frontier, forks->pool ) ) {
     170           0 :     fd_fork_t * fork = fd_fork_frontier_iter_ele( iter, forks->frontier, forks->pool );
     171             : 
     172             :     /* Prune any forks not in the ancestry from root.
     173             : 
     174             :        Optimize for unlikely because there is usually just one fork. */
     175             : 
     176           0 :     if( FD_UNLIKELY( !fork->lock && fork->slot < slot ) ) {
     177           0 :       if( FD_LIKELY( !curr ) ) {
     178           0 :         tail = fork;
     179           0 :         curr = fork;
     180           0 :       } else {
     181           0 :         curr->prev = fd_fork_pool_idx( forks->pool, fork );
     182           0 :         curr       = fd_fork_pool_ele( forks->pool, curr->prev );
     183           0 :       }
     184           0 :     }
     185           0 :   }
     186             : 
     187           0 :   while( FD_UNLIKELY( tail ) ) {
     188           0 :     ulong remove = fd_fork_frontier_idx_remove( forks->frontier,
     189           0 :                                                 &tail->slot,
     190           0 :                                                 fd_fork_pool_idx_null( forks->pool ),
     191           0 :                                                 forks->pool );
     192           0 : #if FD_FORKS_USE_HANDHOLDING
     193           0 :     if( FD_UNLIKELY( remove == fd_fork_pool_idx_null( forks->pool ) ) ) {
     194           0 :       FD_LOG_ERR( ( "failed to remove fork we added to prune." ) );
     195           0 :     }
     196           0 : #endif
     197             : 
     198             :     /* pool_idx_release cannot fail given we just removed this from the
     199             :       frontier directly above. */
     200           0 :     fd_fork_pool_idx_release( forks->pool, remove );
     201           0 :     tail = fd_ptr_if( tail->prev != fd_fork_pool_idx_null( forks->pool ),
     202           0 :                       fd_fork_pool_ele( forks->pool, tail->prev ),
     203           0 :                       NULL );
     204           0 :   }
     205           0 : }
     206             : 
     207             : #include <stdio.h>
     208             : 
     209             : void
     210           0 : fd_forks_print( fd_forks_t const * forks ) {
     211           0 :   FD_LOG_NOTICE( ( "\n\n[Forks]" ) );
     212           0 :   for( fd_fork_frontier_iter_t iter = fd_fork_frontier_iter_init( forks->frontier, forks->pool );
     213           0 :        !fd_fork_frontier_iter_done( iter, forks->frontier, forks->pool );
     214           0 :        iter = fd_fork_frontier_iter_next( iter, forks->frontier, forks->pool ) ) {
     215           0 :     printf( "%lu\n", fd_fork_frontier_iter_ele_const( iter, forks->frontier, forks->pool )->slot );
     216           0 :   }
     217             :   printf( "\n" );
     218           0 : }

Generated by: LCOV version 1.14