Line data Source code
1 : #include "fd_tcache.h" 2 : 3 : ulong 4 33 : fd_tcache_align( void ) { 5 33 : return FD_TCACHE_ALIGN; 6 33 : } 7 : 8 : ulong 9 : fd_tcache_footprint( ulong depth, 10 3000057 : ulong map_cnt ) { 11 3000057 : if( !map_cnt ) map_cnt = fd_tcache_map_cnt_default( depth ); /* use default */ 12 : 13 3000057 : if( FD_UNLIKELY( (!depth) | (map_cnt<(depth+2UL)) | (!fd_ulong_is_pow2( map_cnt )) ) ) return 0UL; /* Invalid depth / max_cnt */ 14 : 15 700497 : ulong cnt = 4UL+depth; if( FD_UNLIKELY( cnt<depth ) ) return 0UL; /* overflow */ 16 700494 : cnt += map_cnt; if( FD_UNLIKELY( cnt<map_cnt ) ) return 0UL; /* overflow */ 17 700494 : if( FD_UNLIKELY( cnt>(ULONG_MAX/sizeof(ulong)) ) ) return 0UL; /* overflow */ 18 700494 : cnt *= sizeof(ulong); /* no overflow */ 19 700494 : ulong footprint = fd_ulong_align_up( cnt, FD_TCACHE_ALIGN ); if( FD_UNLIKELY( footprint<cnt ) ) return 0UL; /* overflow */ 20 700494 : return footprint; 21 700494 : } 22 : 23 : void * 24 : fd_tcache_new( void * shmem, 25 : ulong depth, 26 18 : ulong map_cnt ) { 27 18 : if( !map_cnt ) map_cnt = fd_tcache_map_cnt_default( depth ); /* use default */ 28 : 29 18 : if( FD_UNLIKELY( !shmem ) ) { 30 0 : FD_LOG_WARNING(( "NULL shmem" )); 31 0 : return NULL; 32 0 : } 33 : 34 18 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_tcache_align() ) ) ) { 35 0 : FD_LOG_WARNING(( "misaligned shmem" )); 36 0 : return NULL; 37 0 : } 38 : 39 18 : ulong footprint = fd_tcache_footprint( depth, map_cnt ); 40 18 : if( FD_UNLIKELY( !footprint ) ) { 41 0 : FD_LOG_WARNING(( "bad depth (%lu) and/or map_cnt (%lu)", depth, map_cnt )); 42 0 : return NULL; 43 0 : } 44 : 45 18 : fd_memset( shmem, 0, footprint ); 46 : 47 18 : fd_tcache_t * tcache = (fd_tcache_t *)shmem; 48 : 49 18 : tcache->depth = depth; 50 18 : tcache->map_cnt = map_cnt; 51 18 : tcache->oldest = fd_tcache_reset( fd_tcache_ring_laddr( tcache ), depth, fd_tcache_map_laddr( tcache ), map_cnt ); 52 : 53 18 : FD_COMPILER_MFENCE(); 54 18 : FD_VOLATILE( tcache->magic ) = FD_TCACHE_MAGIC; 55 18 : FD_COMPILER_MFENCE(); 56 : 57 18 : return shmem; 58 18 : } 59 : 60 : fd_tcache_t * 61 24 : fd_tcache_join( void * _tcache ) { 62 : 63 24 : if( FD_UNLIKELY( !_tcache ) ) { 64 0 : FD_LOG_WARNING(( "NULL _tcache" )); 65 0 : return NULL; 66 0 : } 67 : 68 24 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)_tcache, fd_tcache_align() ) ) ) { 69 0 : FD_LOG_WARNING(( "misaligned _tcache" )); 70 0 : return NULL; 71 0 : } 72 : 73 24 : fd_tcache_t * tcache = (fd_tcache_t *)_tcache; 74 24 : if( FD_UNLIKELY( tcache->magic!=FD_TCACHE_MAGIC ) ) { 75 0 : FD_LOG_WARNING(( "bad magic" )); 76 0 : return NULL; 77 0 : } 78 : 79 24 : return tcache; 80 24 : } 81 : 82 : void * 83 12 : fd_tcache_leave( fd_tcache_t * tcache ) { 84 : 85 12 : if( FD_UNLIKELY( !tcache ) ) { 86 0 : FD_LOG_WARNING(( "NULL tcache" )); 87 0 : return NULL; 88 0 : } 89 : 90 12 : return (void *)tcache; 91 12 : } 92 : 93 : void * 94 6 : fd_tcache_delete( void * _tcache ) { 95 : 96 6 : if( FD_UNLIKELY( !_tcache ) ) { 97 0 : FD_LOG_WARNING(( "NULL _tcache" )); 98 0 : return NULL; 99 0 : } 100 : 101 6 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)_tcache, fd_tcache_align() ) ) ) { 102 0 : FD_LOG_WARNING(( "misaligned _tcache" )); 103 0 : return NULL; 104 0 : } 105 : 106 6 : fd_tcache_t * tcache = (fd_tcache_t *)_tcache; 107 6 : if( FD_UNLIKELY( tcache->magic != FD_TCACHE_MAGIC ) ) { 108 0 : FD_LOG_WARNING(( "bad magic" )); 109 0 : return NULL; 110 0 : } 111 : 112 6 : FD_COMPILER_MFENCE(); 113 6 : FD_VOLATILE( tcache->magic ) = 0UL; 114 6 : FD_COMPILER_MFENCE(); 115 : 116 6 : return _tcache; 117 6 : } 118 :