Line data Source code
1 : #include "fd_mcache_private.h" 2 : 3 : ulong 4 90 : fd_mcache_align( void ) { 5 90 : return FD_MCACHE_ALIGN; 6 90 : } 7 : 8 : ulong 9 : fd_mcache_footprint( ulong depth, 10 3000105 : ulong app_sz ) { 11 : 12 3000105 : if( FD_UNLIKELY( depth<FD_MCACHE_BLOCK ) ) return 0UL; /* too small depth */ 13 2624784 : if( FD_UNLIKELY( depth>ULONG_MAX/sizeof(fd_frag_meta_t) ) ) return 0UL; /* too large depth */ 14 2624784 : if( FD_UNLIKELY( !fd_ulong_is_pow2( depth ) ) ) return 0UL; /* non-power-of-two depth */ 15 12168 : ulong meta_footprint = depth*sizeof( fd_frag_meta_t ); /* no overflow */ 16 : 17 12168 : ulong app_footprint = fd_ulong_align_up( app_sz, FD_MCACHE_ALIGN ); 18 12168 : if( FD_UNLIKELY( app_footprint<app_sz ) ) return 0UL; /* overflow */ 19 : 20 12168 : ulong footprint = meta_footprint + app_footprint; /* meta and app */ 21 12168 : if( footprint<meta_footprint ) return 0UL; /* overflow */ 22 : 23 12168 : footprint += sizeof(fd_mcache_private_hdr_t); /* header and seq */ 24 12168 : if( FD_UNLIKELY( footprint<sizeof(fd_mcache_private_hdr_t) ) ) return 0UL; /* overflow */ 25 : 26 12168 : return footprint; 27 12168 : } 28 : 29 : void * 30 : fd_mcache_new( void * shmem, 31 : ulong depth, 32 : ulong app_sz, 33 24 : ulong seq0 ) { 34 : 35 24 : if( FD_UNLIKELY( !shmem ) ) { 36 3 : FD_LOG_WARNING(( "NULL shmem" )); 37 3 : return NULL; 38 3 : } 39 : 40 21 : 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 18 : ulong footprint = fd_mcache_footprint( depth, app_sz ); 46 18 : 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 15 : fd_memset( shmem, 0, footprint ); 52 : 53 15 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmem; 54 : 55 15 : hdr->depth = depth; 56 15 : hdr->app_sz = app_sz; 57 15 : hdr->seq0 = seq0; 58 15 : hdr->app_off = sizeof(fd_mcache_private_hdr_t) + fd_ulong_align_up( depth*sizeof(fd_frag_meta_t), FD_MCACHE_ALIGN ); 59 : 60 15 : hdr->seq[0] = seq0; 61 : 62 15 : fd_frag_meta_t * mcache = fd_mcache_private_mcache( hdr ); 63 : 64 15 : ulong seq1 = fd_seq_inc( seq0, depth ); 65 106383 : for( ulong seq=seq0; seq!=seq1; seq=fd_seq_inc(seq,1UL) ) { 66 106368 : ulong line = fd_mcache_line_idx( seq, depth ); 67 106368 : mcache[line].seq = fd_seq_dec( seq, 1UL ); 68 106368 : mcache[line].ctl = (ushort)fd_frag_meta_ctl( 0UL /*orig*/, 1 /*som*/, 1 /*eom*/, 1 /*err*/ ); 69 106368 : } 70 : 71 15 : FD_COMPILER_MFENCE(); 72 15 : FD_VOLATILE( hdr->magic ) = FD_MCACHE_MAGIC; 73 15 : FD_COMPILER_MFENCE(); 74 : 75 15 : return shmem; 76 18 : } 77 : 78 : fd_frag_meta_t * 79 126 : fd_mcache_join( void * shmcache ) { 80 : 81 126 : if( FD_UNLIKELY( !shmcache ) ) { 82 3 : FD_LOG_WARNING(( "NULL shmcache" )); 83 3 : return NULL; 84 3 : } 85 : 86 123 : 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 120 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmcache; 92 120 : if( FD_UNLIKELY( hdr->magic!=FD_MCACHE_MAGIC ) ) { 93 3 : FD_LOG_WARNING(( "bad magic" )); 94 3 : return NULL; 95 3 : } 96 : 97 117 : return fd_mcache_private_mcache( hdr ); 98 120 : } 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 21 : fd_mcache_delete( void * shmcache ) { 113 : 114 21 : if( FD_UNLIKELY( !shmcache ) ) { 115 3 : FD_LOG_WARNING(( "NULL shmcache" )); 116 3 : return NULL; 117 3 : } 118 : 119 18 : 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 15 : fd_mcache_private_hdr_t * hdr = (fd_mcache_private_hdr_t *)shmcache; 125 15 : if( FD_UNLIKELY( hdr->magic != FD_MCACHE_MAGIC ) ) { 126 3 : FD_LOG_WARNING(( "bad magic" )); 127 3 : return NULL; 128 3 : } 129 : 130 12 : FD_COMPILER_MFENCE(); 131 12 : FD_VOLATILE( hdr->magic ) = 0UL; 132 12 : FD_COMPILER_MFENCE(); 133 : 134 12 : return shmcache; 135 15 : } 136 : 137 : ulong 138 1206913 : fd_mcache_depth( fd_frag_meta_t const * mcache ) { 139 1206913 : return fd_mcache_private_hdr_const( mcache )->depth; 140 1206913 : } 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 99 : fd_mcache_seq_laddr_const( fd_frag_meta_t const * mcache ) { 154 99 : return fd_mcache_private_hdr_const( mcache )->seq; 155 99 : } 156 : 157 : ulong * 158 9 : fd_mcache_seq_laddr( fd_frag_meta_t * mcache ) { 159 9 : return fd_mcache_private_hdr( mcache )->seq; 160 9 : } 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 :