Line data Source code
1 : #include "fd_mcache_private.h" 2 : 3 : ulong 4 4971 : fd_mcache_align( void ) { 5 4971 : return FD_MCACHE_ALIGN; 6 4971 : } 7 : 8 : ulong 9 : fd_mcache_footprint( ulong depth, 10 3003726 : ulong app_sz ) { 11 : 12 3003726 : if( FD_UNLIKELY( depth<FD_MCACHE_BLOCK ) ) return 0UL; /* too small depth */ 13 3000618 : if( FD_UNLIKELY( depth>ULONG_MAX/sizeof(fd_frag_meta_t) ) ) return 0UL; /* too large depth */ 14 3000615 : if( FD_UNLIKELY( !fd_ulong_is_pow2( depth ) ) ) return 0UL; /* non-power-of-two depth */ 15 36390 : ulong meta_footprint = depth*sizeof( fd_frag_meta_t ); /* no overflow */ 16 36390 : if( FD_UNLIKELY( fd_ulong_align_up( meta_footprint, FD_MCACHE_ALIGN )<meta_footprint ) ) return 0UL; /* too large depth */ 17 36390 : meta_footprint = fd_ulong_align_up( meta_footprint, FD_MCACHE_ALIGN ); 18 : 19 36390 : ulong app_footprint = fd_ulong_align_up( app_sz, FD_MCACHE_ALIGN ); 20 36390 : if( FD_UNLIKELY( app_footprint<app_sz ) ) return 0UL; /* overflow */ 21 : 22 36387 : ulong footprint = meta_footprint + app_footprint; /* meta and app */ 23 36387 : if( footprint<meta_footprint ) return 0UL; /* overflow */ 24 : 25 36387 : footprint += sizeof(fd_mcache_private_hdr_t); /* header and seq */ 26 36387 : if( FD_UNLIKELY( footprint<sizeof(fd_mcache_private_hdr_t) ) ) return 0UL; /* overflow */ 27 : 28 36387 : return footprint; 29 36387 : } 30 : 31 : void * 32 : fd_mcache_new( void * shmem, 33 : ulong depth, 34 : ulong app_sz, 35 1653 : ulong seq0 ) { 36 : 37 1653 : if( FD_UNLIKELY( !shmem ) ) { 38 3 : FD_LOG_WARNING(( "NULL shmem" )); 39 3 : return NULL; 40 3 : } 41 : 42 1650 : 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 1647 : ulong footprint = fd_mcache_footprint( depth, app_sz ); 48 1647 : 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 1644 : fd_memset( shmem, 0, footprint ); 54 : 55 1644 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmem; 56 : 57 1644 : hdr->depth = depth; 58 1644 : hdr->app_sz = app_sz; 59 1644 : hdr->seq0 = seq0; 60 1644 : hdr->app_off = sizeof(fd_mcache_private_hdr_t) + fd_ulong_align_up( depth*sizeof(fd_frag_meta_t), FD_MCACHE_ALIGN ); 61 : 62 1644 : hdr->seq[0] = seq0; 63 : 64 1644 : fd_frag_meta_t * mcache = fd_mcache_private_mcache( hdr ); 65 : 66 1644 : ulong seq1 = fd_seq_inc( seq0, depth ); 67 256359 : for( ulong seq=seq0; seq!=seq1; seq=fd_seq_inc(seq,1UL) ) { 68 254715 : ulong line = fd_mcache_line_idx( seq, depth ); 69 254715 : mcache[line].seq = fd_seq_dec( seq, 1UL ); 70 254715 : mcache[line].ctl = (ushort)fd_frag_meta_ctl( 0UL /*orig*/, 1 /*som*/, 1 /*eom*/, 1 /*err*/ ); 71 254715 : } 72 : 73 1644 : FD_COMPILER_MFENCE(); 74 1644 : FD_VOLATILE( hdr->magic ) = FD_MCACHE_MAGIC; 75 1644 : FD_COMPILER_MFENCE(); 76 : 77 1644 : return shmem; 78 1647 : } 79 : 80 : fd_frag_meta_t * 81 2226 : fd_mcache_join( void * shmcache ) { 82 : 83 2226 : if( FD_UNLIKELY( !shmcache ) ) { 84 3 : FD_LOG_WARNING(( "NULL shmcache" )); 85 3 : return NULL; 86 3 : } 87 : 88 2223 : 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 2220 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmcache; 94 2220 : if( FD_UNLIKELY( hdr->magic!=FD_MCACHE_MAGIC ) ) { 95 3 : FD_LOG_WARNING(( "bad magic" )); 96 3 : return NULL; 97 3 : } 98 : 99 2217 : return fd_mcache_private_mcache( hdr ); 100 2220 : } 101 : 102 : void * 103 237 : fd_mcache_leave( fd_frag_meta_t const * mcache ) { 104 : 105 237 : if( FD_UNLIKELY( !mcache ) ) { 106 3 : FD_LOG_WARNING(( "NULL mcache" )); 107 3 : return NULL; 108 3 : } 109 : 110 234 : return (void *)fd_mcache_private_hdr_const( mcache ); /* Kinda ugly const cast */ 111 237 : } 112 : 113 : void * 114 225 : fd_mcache_delete( void * shmcache ) { 115 : 116 225 : if( FD_UNLIKELY( !shmcache ) ) { 117 3 : FD_LOG_WARNING(( "NULL shmcache" )); 118 3 : return NULL; 119 3 : } 120 : 121 222 : 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 219 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmcache; 127 219 : if( FD_UNLIKELY( hdr->magic != FD_MCACHE_MAGIC ) ) { 128 6 : FD_LOG_WARNING(( "bad magic" )); 129 6 : return NULL; 130 6 : } 131 : 132 213 : FD_COMPILER_MFENCE(); 133 213 : FD_VOLATILE( hdr->magic ) = 0UL; 134 213 : FD_COMPILER_MFENCE(); 135 : 136 213 : return shmcache; 137 219 : } 138 : 139 : ulong 140 2031 : fd_mcache_depth( fd_frag_meta_t const * mcache ) { 141 2031 : return fd_mcache_private_hdr_const( mcache )->depth; 142 2031 : } 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 1635 : fd_mcache_seq_laddr_const( fd_frag_meta_t const * mcache ) { 156 1635 : return fd_mcache_private_hdr_const( mcache )->seq; 157 1635 : } 158 : 159 : ulong * 160 654 : fd_mcache_seq_laddr( fd_frag_meta_t * mcache ) { 161 654 : return fd_mcache_private_hdr( mcache )->seq; 162 654 : } 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 :