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