Line data Source code
1 : #include "fd_groove_volume.h" 2 : 3 : #define POOL_NAME fd_groove_volume_pool 4 1499211 : #define POOL_ELE_T fd_groove_volume_t 5 0 : #define POOL_IDX_WIDTH (34) 6 6 : #define POOL_MAGIC (0xfd67007e70190010UL) /* fd groove vol pool version 0 */ 7 : #define POOL_IMPL_STYLE 2 8 : #include "../util/tmpl/fd_pool_para.c" 9 : 10 : int 11 : fd_groove_volume_pool_add( fd_groove_volume_pool_t * pool, 12 : void * shmem, 13 : ulong footprint, 14 : void const * info, 15 300027 : ulong info_sz ) { 16 : 17 300027 : if( FD_UNLIKELY( !footprint ) ) return FD_GROOVE_SUCCESS; /* Nothing to do */ 18 : 19 300024 : if( FD_UNLIKELY( !pool ) ) { 20 6 : FD_LOG_WARNING(( "NULL pool" )); 21 6 : return FD_GROOVE_ERR_INVAL; 22 6 : } 23 : 24 300018 : fd_groove_volume_t * _volume0 = (fd_groove_volume_t *)fd_groove_volume_pool_shele( pool ); 25 300018 : fd_groove_volume_t * _volume1 = _volume0 + fd_groove_volume_pool_ele_max( pool ); 26 : 27 300018 : fd_groove_volume_t * _va = (fd_groove_volume_t *)shmem; 28 300018 : fd_groove_volume_t * _vb = (fd_groove_volume_t *)((ulong)shmem + footprint); 29 : 30 300018 : if( FD_UNLIKELY( !( (_volume0<=_va) & (_va<_vb) & (_vb<=_volume1) & 31 300018 : fd_ulong_is_aligned( (ulong)_va-(ulong)_volume0, FD_GROOVE_VOLUME_FOOTPRINT ) & 32 300018 : fd_ulong_is_aligned( (ulong)_vb-(ulong)_volume0, FD_GROOVE_VOLUME_FOOTPRINT ) ) ) ) { 33 12 : FD_LOG_WARNING(( "Invalid region" )); 34 12 : return FD_GROOVE_ERR_INVAL; 35 12 : } 36 : 37 300006 : info_sz = fd_ulong_min( fd_ulong_if( !!info, info_sz, 0UL ), FD_GROOVE_VOLUME_INFO_MAX ); 38 : 39 : /* Format the volumes as empty and push into the free pool. We push 40 : them in reverse order so the volumes will be preferentially used 41 : from lowest to highest in future allocations. */ 42 : 43 300006 : fd_groove_volume_t * _volume = _vb; 44 449583 : do { 45 449583 : _volume--; 46 : 47 449583 : _volume->idx = (ulong)(_volume - _volume0); 48 : //_volume->next initialized when released into the pool 49 449583 : _volume->info_sz = info_sz; 50 : 51 449583 : memset( _volume->info, 0, FD_GROOVE_VOLUME_INFO_MAX ); 52 449583 : if( info_sz ) memcpy( _volume->info, info, info_sz ); 53 : 54 : //_volume->data initialized by caller 55 : 56 449583 : FD_COMPILER_MFENCE(); 57 449583 : _volume->magic = ~FD_GROOVE_VOLUME_MAGIC; /* Mark groove volume as containing no data allocations */ 58 449583 : FD_COMPILER_MFENCE(); 59 : 60 449583 : fd_groove_volume_pool_release( pool, _volume ); 61 : 62 449583 : } while( _volume>_va ); 63 : 64 300006 : return FD_GROOVE_SUCCESS; 65 300018 : } 66 : 67 : void * 68 749592 : fd_groove_volume_pool_remove( fd_groove_volume_pool_t * pool ) { 69 : 70 749592 : if( FD_UNLIKELY( !pool ) ) { 71 6 : FD_LOG_WARNING(( "NULL pool" )); 72 6 : return NULL; 73 6 : } 74 : 75 749586 : fd_groove_volume_t * _volume = fd_groove_volume_pool_acquire( pool ); 76 : 77 749586 : if( FD_LIKELY( _volume ) ) { 78 : 79 449580 : # if FD_GROOVE_PARANOID 80 449580 : fd_groove_volume_t * _volume0 = fd_groove_volume_pool_shele( pool ); 81 449580 : fd_groove_volume_t * _volume1 = _volume0 + fd_groove_volume_pool_ele_max( pool ); 82 : 83 449580 : ulong volume_off = (ulong)_volume - (ulong)_volume0; 84 : 85 449580 : if( FD_UNLIKELY( !( (_volume0<=_volume) & (_volume<_volume1) & 86 449580 : fd_ulong_is_aligned( volume_off, FD_GROOVE_VOLUME_FOOTPRINT ) ) ) ) { 87 0 : FD_LOG_WARNING(( "volume not at a valid groove data local address" )); 88 0 : return NULL; 89 0 : } 90 : 91 449580 : if( FD_UNLIKELY( !( (_volume->magic ==~FD_GROOVE_VOLUME_MAGIC ) & 92 449580 : (_volume->idx*FD_GROOVE_VOLUME_FOOTPRINT==volume_off ) & 93 449580 : (_volume->info_sz <=FD_GROOVE_VOLUME_INFO_MAX) ) ) ) { 94 0 : FD_LOG_WARNING(( "unexpected volume header" )); 95 0 : return NULL; 96 0 : } 97 449580 : # endif 98 : 99 449580 : FD_COMPILER_MFENCE(); 100 449580 : _volume->magic = 0UL; /* mark as no longer a groove volume */ 101 449580 : FD_COMPILER_MFENCE(); 102 : 103 449580 : } 104 : 105 749586 : return (void *)_volume; 106 749586 : }