Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_progcache_fd_progcache_cache_h 2 : #define HEADER_fd_src_flamenco_progcache_fd_progcache_cache_h 3 : 4 : /* fd_progcache_cache.h defines the program cache. 5 : value memory is split in classes, each dedicated to programs of 6 : a certain size, and each class has a fixed number of slots. 7 : 8 : The classes cover the mainnet program size distribution: 9 : 10 : class 0: <= 128 KiB 11 : class 1: <= 512 KiB 12 : class 2: <= 1 MiB 13 : class 3: <= 2 MiB 14 : class 4: <= 4 MiB 15 : class 5: <= ~10 MiB (FD_RUNTIME_ACC_SZ_MAX + a margin) */ 16 : 17 : #include "../../util/fd_util_base.h" 18 : #include "../runtime/fd_runtime_const.h" /* FD_RUNTIME_ACC_SZ_MAX */ 19 : #include "../../ballet/sbpf/fd_sbpf_loader.h" /* FD_SBPF_PROGRAM_FOOTPRINT */ 20 : 21 3648058 : #define FD_PROGCACHE_CACHE_DATA_CLASS_CNT (6UL) 22 3650110 : #define FD_PROGCACHE_CACHE_CLASS_CNT (FD_PROGCACHE_CACHE_DATA_CLASS_CNT) 23 : 24 : /* FD_PROGCACHE_CACHE_SLOT_TOP_SZ is the slot size of the largest class. 25 : It must be >= FD_RUNTIME_ACC_SZ_MAX (10 MiB) + ~160 KiB calldests + alignment. 26 : 11 MiB gives comfortable margin. */ 27 : #define FD_PROGCACHE_CACHE_SLOT_TOP_SZ (FD_RUNTIME_ACC_SZ_MAX + (1UL<<20)) 28 : 29 : /* The worst case value is a max-size account that is all text, so it carries a 30 : full calldests bitmap; FD_SBPF_PROGRAM_FOOTPRINT bounds that bitmap, and 8 covers 31 : the alignment between the two regions. Asserting the load buffer alone would 32 : leave the bitmap unaccounted. */ 33 : 34 : FD_STATIC_ASSERT( FD_SBPF_PROGRAM_FOOTPRINT + FD_RUNTIME_ACC_SZ_MAX + 8UL 35 : <= FD_PROGCACHE_CACHE_SLOT_TOP_SZ, progcache_top_class_too_small ); 36 : 37 : /* fd_progcache_cache_slot_sz[c] is the maximum value footprint that class 38 : c can store (and, since values are stored raw, the byte size of one 39 : slot in that class). */ 40 : static const ulong fd_progcache_cache_slot_sz[ FD_PROGCACHE_CACHE_CLASS_CNT ] = { 41 : 128UL << 10, /* class 0: <= 128 KiB */ 42 : 512UL << 10, /* class 1: <= 512 KiB */ 43 : 1UL << 20, /* class 2: <= 1 MiB */ 44 : 2UL << 20, /* class 3: <= 2 MiB */ 45 : 4UL << 20, /* class 4: <= 4 MiB */ 46 : FD_PROGCACHE_CACHE_SLOT_TOP_SZ, /* class 5: <= ~10 MiB */ 47 : }; 48 : 49 : /* fd_progcache_cache_class maps a program_sz to its class. Returns 50 : FD_PROGCACHE_CACHE_CLASS_CNT if no class can hold it. */ 51 : FD_FN_CONST static inline ulong 52 3620668 : fd_progcache_cache_class( ulong program_sz ) { 53 3620776 : for( ulong c=0UL; c<FD_PROGCACHE_CACHE_CLASS_CNT; c++ ) { 54 3620773 : if( program_sz<=fd_progcache_cache_slot_sz[c] ) return c; 55 3620773 : } 56 3 : return FD_PROGCACHE_CACHE_CLASS_CNT; 57 3620668 : } 58 : 59 : /* Guaranteed minimum slots per class; derives the minimum progcache footprint. */ 60 : static const ulong fd_progcache_cache_class_min_tbl[ FD_PROGCACHE_CACHE_CLASS_CNT ] = { 61 : 50UL, 50UL, 30UL, 30UL, 10UL, 3UL 62 : }; 63 : 64 : FD_FN_CONST static inline ulong 65 11844 : fd_progcache_cache_class_min( ulong c ) { 66 11844 : return fd_progcache_cache_class_min_tbl[ c ]; 67 11844 : } 68 : 69 : 70 : FD_PROTOTYPES_BEGIN 71 : 72 : /* fd_progcache_setup_slots provisions progcache_sz across the classes, populating 73 : slot_cnt with each class's slot count. Every data class gets at least 74 : fd_progcache_cache_class_min slots. 75 : Returns the record capacity (== sum(slot_cnt)), or 0 if progcache_sz is below 76 : fd_progcache_shmem_min_sz( txn_max ). */ 77 : ulong 78 : fd_progcache_setup_slots( ulong txn_max, 79 : ulong progcache_sz, 80 : ulong * slot_cnt ); 81 : 82 : FD_PROTOTYPES_END 83 : 84 : #endif /* HEADER_fd_src_flamenco_progcache_fd_progcache_cache_h */