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 : int err = fd_groove_volume_pool_release( pool, _volume, 1 /* blocking */ ); 61 449583 : if( FD_UNLIKELY( err ) ) { 62 0 : FD_LOG_WARNING(( "fd_groove_volume_pool_release failed (%i-%s)", err, fd_groove_volume_pool_strerror( err ) )); 63 0 : return err; 64 0 : } 65 : 66 449583 : } while( _volume>_va ); 67 : 68 300006 : return FD_GROOVE_SUCCESS; 69 300006 : } 70 : 71 : void * 72 749592 : fd_groove_volume_pool_remove( fd_groove_volume_pool_t * pool ) { 73 : 74 749592 : if( FD_UNLIKELY( !pool ) ) { 75 6 : FD_LOG_WARNING(( "NULL pool" )); 76 6 : return NULL; 77 6 : } 78 : 79 749586 : int err; 80 749586 : fd_groove_volume_t * _volume = fd_groove_volume_pool_acquire( pool, NULL, 1 /* blocking */, &err ); 81 : 82 749586 : if( FD_LIKELY( _volume ) ) { 83 : 84 449580 : # if FD_GROOVE_PARANOID 85 449580 : fd_groove_volume_t * _volume0 = fd_groove_volume_pool_shele( pool ); 86 449580 : fd_groove_volume_t * _volume1 = _volume0 + fd_groove_volume_pool_ele_max( pool ); 87 : 88 449580 : ulong volume_off = (ulong)_volume - (ulong)_volume0; 89 : 90 449580 : if( FD_UNLIKELY( !( (_volume0<=_volume) & (_volume<_volume1) & 91 449580 : fd_ulong_is_aligned( volume_off, FD_GROOVE_VOLUME_FOOTPRINT ) ) ) ) { 92 0 : FD_LOG_WARNING(( "volume not at a valid groove data local address" )); 93 0 : return NULL; 94 0 : } 95 : 96 449580 : if( FD_UNLIKELY( !( (_volume->magic ==~FD_GROOVE_VOLUME_MAGIC ) & 97 449580 : (_volume->idx*FD_GROOVE_VOLUME_FOOTPRINT==volume_off ) & 98 449580 : (_volume->info_sz <=FD_GROOVE_VOLUME_INFO_MAX) ) ) ) { 99 0 : FD_LOG_WARNING(( "unexpected volume header" )); 100 0 : return NULL; 101 0 : } 102 449580 : # endif 103 : 104 449580 : FD_COMPILER_MFENCE(); 105 449580 : _volume->magic = 0UL; /* mark as no longer a groove volume */ 106 449580 : FD_COMPILER_MFENCE(); 107 : 108 449580 : } else if( FD_UNLIKELY( err!=FD_POOL_ERR_EMPTY ) ) { 109 : 110 0 : FD_LOG_WARNING(( "fd_groove_volume_pool_acquire failed (%i-%s)", err, fd_groove_volume_pool_strerror( err ) )); 111 : 112 0 : } 113 : 114 749586 : return (void *)_volume; 115 749586 : }