Line data Source code
1 : #include "fd_gossip_txbuild.h" 2 : 3 : struct push_set_entry { 4 : fd_gossip_txbuild_t txbuild[1]; 5 : 6 : /* We use fd_pool APIs because fd_dlist doesn't work without it and 7 : there are no suitable linked list APIs. However, because we want 8 : to track the active set indices, we also need to bypass the native 9 : acquire/release mechanism provided by fd_pool and use it as an 10 : array instead. */ 11 : 12 : struct { 13 : ulong next; 14 : uchar in_use; 15 : } pool; 16 : 17 : struct{ 18 : long wallclock_nanos; 19 : ulong prev; 20 : ulong next; 21 : } last_hit; 22 : }; 23 : 24 : typedef struct push_set_entry push_set_entry_t; 25 : 26 : #define POOL_NAME pset_entry_pool 27 0 : #define POOL_T push_set_entry_t 28 0 : #define POOL_NEXT pool.next 29 : #include "../../util/tmpl/fd_pool.c" 30 : 31 : #define DLIST_NAME pset_last_hit 32 : #define DLIST_ELE_T push_set_entry_t 33 0 : #define DLIST_PREV last_hit.prev 34 0 : #define DLIST_NEXT last_hit.next 35 : 36 : #include "../../util/tmpl/fd_dlist.c" 37 : 38 : struct push_set { 39 : push_set_entry_t * pool; 40 : pset_last_hit_t * last_hit; 41 : }; 42 : 43 : typedef struct push_set push_set_t; 44 : 45 : ulong 46 0 : push_set_align( void ) { 47 0 : return pset_entry_pool_align(); 48 0 : } 49 : 50 : ulong 51 0 : push_set_footprint( ulong ele_max ) { 52 0 : ulong l; 53 0 : l = FD_LAYOUT_INIT; 54 0 : l = FD_LAYOUT_APPEND( l, pset_entry_pool_align(), pset_entry_pool_footprint( ele_max ) ); 55 0 : l = FD_LAYOUT_APPEND( l, pset_last_hit_align(), pset_last_hit_footprint() ); 56 0 : l = FD_LAYOUT_APPEND( l, alignof(push_set_t), sizeof(push_set_t) ); 57 0 : l = FD_LAYOUT_FINI( l, push_set_align() ); 58 0 : return l; 59 0 : } 60 : 61 : void * 62 : push_set_new( void * shmem, 63 0 : ulong ele_max ) { 64 0 : if( FD_UNLIKELY( !shmem ) ) { 65 0 : FD_LOG_ERR(( "NULL shmem" )); 66 0 : } 67 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, push_set_align() ) ) ) { 68 0 : FD_LOG_ERR(( "misaligned shmem" )); 69 0 : } 70 : 71 0 : FD_SCRATCH_ALLOC_INIT( l, shmem ); 72 0 : void * _pool = FD_SCRATCH_ALLOC_APPEND( l, pset_entry_pool_align(), pset_entry_pool_footprint( ele_max ) ); 73 0 : void * _last_appended = FD_SCRATCH_ALLOC_APPEND( l, pset_last_hit_align(), pset_last_hit_footprint() ); 74 0 : push_set_t * push_set = FD_SCRATCH_ALLOC_APPEND( l, alignof(push_set_t), sizeof(push_set_t) ); 75 : 76 0 : push_set->pool = pset_entry_pool_join( pset_entry_pool_new( _pool, ele_max ) ); 77 0 : push_set->last_hit = pset_last_hit_join( pset_last_hit_new( _last_appended ) ); 78 : 79 0 : for( ulong i=0UL; i<ele_max; i++ ) { 80 0 : push_set_entry_t * entry = pset_entry_pool_ele( push_set->pool, i ); 81 0 : entry->pool.in_use = 0U; 82 0 : } 83 : 84 0 : return (void *)push_set; 85 0 : } 86 : 87 : push_set_t * 88 0 : push_set_join( void * shpool ) { 89 0 : if( FD_UNLIKELY( !shpool ) ) { 90 0 : FD_LOG_ERR(( "NULL shpool" )); 91 0 : } 92 0 : return (push_set_t *)shpool; 93 0 : } 94 : 95 : void 96 : push_set_pop_append( push_set_t * pset, 97 : push_set_entry_t * state, 98 0 : long now ) { 99 0 : state->last_hit.wallclock_nanos = now; 100 0 : pset_last_hit_ele_remove( pset->last_hit, state, pset->pool ); 101 0 : pset_last_hit_ele_push_tail( pset->last_hit, state, pset->pool ); 102 0 : }