Line data Source code
1 : #include "fd_replay.h" 2 : 3 : void * 4 0 : fd_replay_new( void * shmem, ulong fec_max, ulong slice_max, ulong block_max ) { 5 0 : int lg_fec_max = fd_ulong_find_msb( fd_ulong_pow2_up( fec_max ) ); 6 0 : int lg_block_max = fd_ulong_find_msb( fd_ulong_pow2_up( block_max ) ); 7 : 8 0 : FD_SCRATCH_ALLOC_INIT( l, shmem ); 9 0 : fd_replay_t * replay = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_align(), sizeof(fd_replay_t) ); 10 0 : void * fec_map = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_fec_map_align(), fd_replay_fec_map_footprint( lg_fec_max ) ); 11 0 : void * fec_deque = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_fec_deque_align(), fd_replay_fec_deque_footprint( fec_max ) ); 12 0 : void * slice_buf = FD_SCRATCH_ALLOC_APPEND( l, 128UL, FD_SLICE_MAX ); 13 0 : void * slice_map = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_slice_map_align(), fd_replay_slice_map_footprint( lg_block_max ) ); 14 0 : for( ulong i = 0UL; i < block_max; i++ ) { 15 0 : void * slice_deque = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_slice_deque_align(), fd_replay_slice_deque_footprint( slice_max ) ); 16 0 : fd_replay_slice_deque_new( slice_deque, slice_max ); 17 0 : } 18 0 : ulong top = FD_SCRATCH_ALLOC_FINI( l, fd_replay_align() ); 19 0 : FD_TEST( top == (ulong)shmem + fd_replay_footprint( fec_max, slice_max, block_max ) ); 20 : 21 0 : fd_replay_fec_map_new( fec_map, lg_fec_max ); 22 0 : fd_replay_fec_deque_new( fec_deque, fec_max ); 23 0 : fd_replay_slice_map_new( slice_map, lg_block_max ); 24 : 25 0 : replay->block_max = block_max; 26 0 : replay->fec_max = fec_max; 27 0 : replay->slice_max = slice_max; 28 : 29 0 : FD_COMPILER_MFENCE(); 30 0 : replay->magic = FD_REPLAY_MAGIC; 31 0 : FD_COMPILER_MFENCE(); 32 : 33 0 : (void)slice_buf; 34 : 35 0 : return replay; 36 0 : } 37 : 38 : fd_replay_t * 39 0 : fd_replay_join( void * shreplay ) { 40 0 : fd_replay_t * replay = (fd_replay_t *)shreplay; 41 0 : FD_TEST( replay->magic==FD_REPLAY_MAGIC ); 42 : 43 0 : int lg_fec_max = fd_ulong_find_msb( fd_ulong_pow2_up( replay->fec_max ) ); 44 0 : int lg_block_max = fd_ulong_find_msb( fd_ulong_pow2_up( replay->block_max ) ); 45 : 46 0 : FD_SCRATCH_ALLOC_INIT( l, shreplay ); 47 0 : replay = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_align(), sizeof(fd_replay_t) ); 48 0 : void * fec_map = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_fec_map_align(), fd_replay_fec_map_footprint( lg_fec_max ) ); 49 0 : void * fec_deque = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_fec_deque_align(), fd_replay_fec_deque_footprint( replay->fec_max ) ); 50 0 : void * slice_buf = FD_SCRATCH_ALLOC_APPEND( l, 128UL, FD_SLICE_MAX ); 51 0 : void * slice_map = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_slice_map_align(), fd_replay_slice_map_footprint( lg_block_max ) ); 52 : 53 0 : replay->fec_map = fd_replay_fec_map_join( fec_map ); 54 0 : replay->fec_deque = fd_replay_fec_deque_join( fec_deque ); 55 0 : (void)slice_buf; 56 0 : replay->slice_map = fd_replay_slice_map_join( slice_map ); 57 : 58 : /* Initialize each map slot to point to a deque. Each slot should 59 : always have a valid pointer that points to the head of deque in the 60 : replay mem. When a map entry is moved/evicted, map move does a 61 : shallow copy, and the correct deque pointer will move along with 62 : the key to the new map slot location. On insert, only the map->key 63 : is set. Thus the map deque pointer should be valid always, and each 64 : map slot should have a unique deque pointer always. */ 65 : 66 0 : for( ulong i = 0UL; i < replay->block_max; i++ ) { 67 0 : fd_replay_slice_t * slice = &replay->slice_map[i]; 68 0 : void * slice_deque = FD_SCRATCH_ALLOC_APPEND( l, fd_replay_slice_deque_align(), fd_replay_slice_deque_footprint( replay->slice_max ) ); 69 0 : slice->deque = fd_replay_slice_deque_join( slice_deque ); 70 0 : } 71 0 : FD_SCRATCH_ALLOC_FINI( l, fd_replay_align() ); 72 : 73 0 : return replay; 74 0 : } 75 : 76 : //void 77 : //fd_replay_init( fd_replay_t * replay ) { 78 : /* set map pointer slot whatever the hecks */ 79 : //} 80 : 81 : void * 82 0 : fd_replay_leave( fd_replay_t const * replay ) { 83 : 84 0 : if( FD_UNLIKELY( !replay ) ) { 85 0 : FD_LOG_WARNING(( "NULL replay" )); 86 0 : return NULL; 87 0 : } 88 : 89 0 : return (void *)replay; 90 0 : } 91 : 92 : void * 93 0 : fd_replay_delete( void * shmem ) { 94 0 : fd_replay_t * replay = (fd_replay_t *)shmem; 95 : 96 0 : if( FD_UNLIKELY( !replay ) ) { 97 0 : FD_LOG_WARNING(( "NULL replay" )); 98 0 : return NULL; 99 0 : } 100 : 101 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned((ulong)replay, fd_replay_align() ) ) ) { 102 0 : FD_LOG_WARNING(( "misaligned replay" )); 103 0 : return NULL; 104 0 : } 105 : 106 0 : FD_COMPILER_MFENCE(); 107 0 : replay->magic = 0UL; 108 0 : FD_COMPILER_MFENCE(); 109 : 110 : // TODO: zero out mem? 111 : 112 0 : return replay; 113 0 : }