Line data Source code
1 : #include "fd_lru.h" 2 : #include "fd_list.h" 3 : 4 : #define DEPTH_OFFSET (2UL) 5 : 6 : ulong 7 3 : fd_lru_align( void ) { 8 3 : return FD_LRU_ALIGN; 9 3 : } 10 : 11 : ulong 12 : fd_lru_footprint( ulong depth, 13 12 : ulong map_cnt ) { 14 12 : if( !map_cnt ) map_cnt = fd_lru_map_cnt_default( depth ); /* use default */ 15 : 16 12 : if( FD_UNLIKELY( (!depth) | (map_cnt<(depth+2UL)) | (!fd_ulong_is_pow2( map_cnt )) ) ) return 0UL; /* Invalid depth / max_cnt */ 17 : 18 9 : ulong depth_mul = (depth + 1) * (sizeof(fd_list_t) / sizeof(ulong)); 19 9 : ulong cnt = 4UL+depth_mul * sizeof(ulong); if( FD_UNLIKELY( cnt<depth ) ) return 0UL; /* overflow */ 20 6 : cnt += map_cnt; if( FD_UNLIKELY( cnt<map_cnt ) ) return 0UL; /* overflow */ 21 6 : if( FD_UNLIKELY( cnt>(ULONG_MAX/sizeof(ulong)) ) ) return 0UL; /* overflow */ 22 6 : cnt *= sizeof(ulong); /* no overflow */ 23 6 : ulong footprint = fd_ulong_align_up( cnt, FD_LRU_ALIGN ); if( FD_UNLIKELY( footprint<cnt ) ) return 0UL; /* overflow */ 24 6 : return footprint; 25 6 : } 26 : 27 : void * 28 : fd_lru_new( void * shmem, 29 : ulong depth, 30 3 : ulong map_cnt ) { 31 3 : if( !map_cnt ) map_cnt = fd_lru_map_cnt_default( depth ); /* use default */ 32 : 33 3 : if( FD_UNLIKELY( !shmem ) ) { 34 0 : FD_LOG_WARNING(( "NULL shmem" )); 35 0 : return NULL; 36 0 : } 37 : 38 3 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_lru_align() ) ) ) { 39 0 : FD_LOG_WARNING(( "misaligned shmem" )); 40 0 : return NULL; 41 0 : } 42 : 43 3 : ulong footprint = fd_lru_footprint( depth, map_cnt ); 44 3 : if( FD_UNLIKELY( !footprint ) ) { 45 0 : FD_LOG_WARNING(( "bad depth (%lu) and/or map_cnt (%lu)", depth, map_cnt )); 46 0 : return NULL; 47 0 : } 48 : 49 3 : fd_memset( shmem, 0, footprint ); 50 : 51 3 : fd_lru_t * lru = (fd_lru_t *)shmem; 52 : 53 3 : lru->depth = depth; 54 3 : lru->free_top = 1UL; 55 3 : lru->map_cnt = map_cnt; 56 3 : fd_list_new( fd_lru_list_laddr( lru ), depth ); 57 : 58 3 : FD_COMPILER_MFENCE(); 59 3 : FD_VOLATILE( lru->magic ) = FD_LRU_MAGIC; 60 3 : FD_COMPILER_MFENCE(); 61 : 62 3 : return shmem; 63 3 : } 64 : 65 : fd_lru_t * 66 3 : fd_lru_join( void * _lru ) { 67 : 68 3 : if( FD_UNLIKELY( !_lru ) ) { 69 0 : FD_LOG_WARNING(( "NULL _lru" )); 70 0 : return NULL; 71 0 : } 72 : 73 3 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)_lru, fd_lru_align() ) ) ) { 74 0 : FD_LOG_WARNING(( "misaligned _lru" )); 75 0 : return NULL; 76 0 : } 77 : 78 3 : fd_lru_t * lru = (fd_lru_t *)_lru; 79 3 : if( FD_UNLIKELY( lru->magic!=FD_LRU_MAGIC ) ) { 80 0 : FD_LOG_WARNING(( "bad magic" )); 81 0 : return NULL; 82 0 : } 83 : 84 3 : return lru; 85 3 : } 86 : 87 : void * 88 3 : fd_lru_leave( fd_lru_t * lru ) { 89 : 90 3 : if( FD_UNLIKELY( !lru ) ) { 91 0 : FD_LOG_WARNING(( "NULL lru" )); 92 0 : return NULL; 93 0 : } 94 : 95 3 : return (void *)lru; 96 3 : } 97 : 98 : void * 99 3 : fd_lru_delete( void * _lru ) { 100 : 101 3 : if( FD_UNLIKELY( !_lru ) ) { 102 0 : FD_LOG_WARNING(( "NULL _lru" )); 103 0 : return NULL; 104 0 : } 105 : 106 3 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)_lru, fd_lru_align() ) ) ) { 107 0 : FD_LOG_WARNING(( "misaligned _lru" )); 108 0 : return NULL; 109 0 : } 110 : 111 3 : fd_lru_t * lru = (fd_lru_t *)_lru; 112 3 : if( FD_UNLIKELY( lru->magic != FD_LRU_MAGIC ) ) { 113 0 : FD_LOG_WARNING(( "bad magic" )); 114 0 : return NULL; 115 0 : } 116 : 117 3 : FD_COMPILER_MFENCE(); 118 3 : FD_VOLATILE( lru->magic ) = 0UL; 119 3 : FD_COMPILER_MFENCE(); 120 : 121 3 : return _lru; 122 3 : }