Line data Source code
1 : #include "fd_mcache_private.h" 2 : 3 : ulong 4 10785 : fd_mcache_align( void ) { 5 10785 : return FD_MCACHE_ALIGN; 6 10785 : } 7 : 8 : ulong 9 : fd_mcache_footprint( ulong depth, 10 3018027 : ulong app_sz ) { 11 : 12 3018027 : if( FD_UNLIKELY( depth<FD_MCACHE_BLOCK ) ) return 0UL; /* too small depth */ 13 3014919 : if( FD_UNLIKELY( depth>ULONG_MAX/sizeof(fd_frag_meta_t) ) ) return 0UL; /* too large depth */ 14 3014916 : if( FD_UNLIKELY( !fd_ulong_is_pow2( depth ) ) ) return 0UL; /* non-power-of-two depth */ 15 50691 : ulong meta_footprint = depth*sizeof( fd_frag_meta_t ); /* no overflow */ 16 50691 : if( FD_UNLIKELY( fd_ulong_align_up( meta_footprint, FD_MCACHE_ALIGN )<meta_footprint ) ) return 0UL; /* too large depth */ 17 50691 : meta_footprint = fd_ulong_align_up( meta_footprint, FD_MCACHE_ALIGN ); 18 : 19 50691 : ulong app_footprint = fd_ulong_align_up( app_sz, FD_MCACHE_ALIGN ); 20 50691 : if( FD_UNLIKELY( app_footprint<app_sz ) ) return 0UL; /* overflow */ 21 : 22 50688 : ulong footprint = meta_footprint + app_footprint; /* meta and app */ 23 50688 : if( footprint<meta_footprint ) return 0UL; /* overflow */ 24 : 25 50688 : footprint += sizeof(fd_mcache_private_hdr_t); /* header and seq */ 26 50688 : if( FD_UNLIKELY( footprint<sizeof(fd_mcache_private_hdr_t) ) ) return 0UL; /* overflow */ 27 : 28 50688 : return footprint; 29 50688 : } 30 : 31 : void * 32 : fd_mcache_new( void * shmem, 33 : ulong depth, 34 : ulong app_sz, 35 2313 : ulong seq0 ) { 36 : 37 2313 : if( FD_UNLIKELY( !shmem ) ) { 38 3 : FD_LOG_WARNING(( "NULL shmem" )); 39 3 : return NULL; 40 3 : } 41 : 42 2310 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_mcache_align() ) ) ) { 43 3 : FD_LOG_WARNING(( "misaligned shmem" )); 44 3 : return NULL; 45 3 : } 46 : 47 2307 : ulong footprint = fd_mcache_footprint( depth, app_sz ); 48 2307 : if( FD_UNLIKELY( !footprint ) ) { 49 3 : FD_LOG_WARNING(( "bad depth (%lu) or app_sz (%lu)", depth, app_sz )); 50 3 : return NULL; 51 3 : } 52 : 53 2304 : fd_memset( shmem, 0, footprint ); 54 : 55 2304 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmem; 56 : 57 2304 : hdr->depth = depth; 58 2304 : hdr->app_sz = app_sz; 59 2304 : hdr->seq0 = seq0; 60 2304 : hdr->app_off = sizeof(fd_mcache_private_hdr_t) + fd_ulong_align_up( depth*sizeof(fd_frag_meta_t), FD_MCACHE_ALIGN ); 61 : 62 2304 : hdr->seq[0] = seq0; 63 : 64 2304 : fd_frag_meta_t * mcache = fd_mcache_private_mcache( hdr ); 65 : 66 2304 : ulong seq1 = fd_seq_inc( seq0, depth ); 67 1643931 : for( ulong seq=seq0; seq!=seq1; seq=fd_seq_inc(seq,1UL) ) { 68 1641627 : ulong line = fd_mcache_line_idx( seq, depth ); 69 1641627 : mcache[line].seq = fd_seq_dec( seq, 1UL ); 70 1641627 : mcache[line].ctl = (ushort)fd_frag_meta_ctl( 0UL /*orig*/, 1 /*som*/, 1 /*eom*/, 1 /*err*/ ); 71 1641627 : } 72 : 73 2304 : FD_COMPILER_MFENCE(); 74 2304 : FD_VOLATILE( hdr->magic ) = FD_MCACHE_MAGIC; 75 2304 : FD_COMPILER_MFENCE(); 76 : 77 2304 : return shmem; 78 2307 : } 79 : 80 : fd_frag_meta_t * 81 5811 : fd_mcache_join( void * shmcache ) { 82 : 83 5811 : if( FD_UNLIKELY( !shmcache ) ) { 84 3 : FD_LOG_WARNING(( "NULL shmcache" )); 85 3 : return NULL; 86 3 : } 87 : 88 5808 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmcache, fd_mcache_align() ) ) ) { 89 3 : FD_LOG_WARNING(( "misaligned shmcache" )); 90 3 : return NULL; 91 3 : } 92 : 93 5805 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmcache; 94 5805 : if( FD_UNLIKELY( hdr->magic!=FD_MCACHE_MAGIC ) ) { 95 3 : FD_LOG_WARNING(( "bad magic" )); 96 3 : return NULL; 97 3 : } 98 : 99 5802 : return fd_mcache_private_mcache( hdr ); 100 5805 : } 101 : 102 : void * 103 171 : fd_mcache_leave( fd_frag_meta_t const * mcache ) { 104 : 105 171 : if( FD_UNLIKELY( !mcache ) ) { 106 3 : FD_LOG_WARNING(( "NULL mcache" )); 107 3 : return NULL; 108 3 : } 109 : 110 168 : return (void *)fd_mcache_private_hdr_const( mcache ); /* Kinda ugly const cast */ 111 171 : } 112 : 113 : void * 114 2211 : fd_mcache_delete( void * shmcache ) { 115 : 116 2211 : if( FD_UNLIKELY( !shmcache ) ) { 117 3 : FD_LOG_WARNING(( "NULL shmcache" )); 118 3 : return NULL; 119 3 : } 120 : 121 2208 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmcache, fd_mcache_align() ) ) ) { 122 3 : FD_LOG_WARNING(( "misaligned shmcache" )); 123 3 : return NULL; 124 3 : } 125 : 126 2205 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmcache; 127 2205 : if( FD_UNLIKELY( hdr->magic != FD_MCACHE_MAGIC ) ) { 128 6 : FD_LOG_WARNING(( "bad magic" )); 129 6 : return NULL; 130 6 : } 131 : 132 2199 : FD_COMPILER_MFENCE(); 133 2199 : FD_VOLATILE( hdr->magic ) = 0UL; 134 2199 : FD_COMPILER_MFENCE(); 135 : 136 2199 : return shmcache; 137 2205 : } 138 : 139 : ulong 140 250263 : fd_mcache_depth( fd_frag_meta_t const * mcache ) { 141 250263 : return fd_mcache_private_hdr_const( mcache )->depth; 142 250263 : } 143 : 144 : ulong 145 6 : fd_mcache_app_sz( fd_frag_meta_t const * mcache ) { 146 6 : return fd_mcache_private_hdr_const( mcache )->app_sz; 147 6 : } 148 : 149 : ulong 150 9 : fd_mcache_seq0( fd_frag_meta_t const * mcache ) { 151 9 : return fd_mcache_private_hdr_const( mcache )->seq0; 152 9 : } 153 : 154 : ulong const * 155 108 : fd_mcache_seq_laddr_const( fd_frag_meta_t const * mcache ) { 156 108 : return fd_mcache_private_hdr_const( mcache )->seq; 157 108 : } 158 : 159 : ulong * 160 5562 : fd_mcache_seq_laddr( fd_frag_meta_t * mcache ) { 161 5562 : return fd_mcache_private_hdr( mcache )->seq; 162 5562 : } 163 : 164 : uchar const * 165 9 : fd_mcache_app_laddr_const( fd_frag_meta_t const * mcache ) { 166 9 : fd_mcache_private_hdr_t const * hdr = fd_mcache_private_hdr_const( mcache ); 167 9 : return (uchar const *)(((ulong)hdr) + hdr->app_off); 168 9 : } 169 : 170 : uchar * 171 6 : fd_mcache_app_laddr( fd_frag_meta_t * mcache ) { 172 6 : fd_mcache_private_hdr_t * hdr = fd_mcache_private_hdr( mcache ); 173 6 : return (uchar *)(((ulong)hdr) + hdr->app_off); 174 6 : } 175 :