Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_progcache_fd_progcache_h 2 : #define HEADER_fd_src_flamenco_progcache_fd_progcache_h 3 : 4 : /* fd_progcache.h provides program cache data structures. 5 : 6 : Lock ordering: 7 : global txn lock, txn lock, clock lock, recm chain_lock, rec.lock */ 8 : 9 : #include "fd_progcache_rec.h" /* includes fd_progcache_base.h fd_funk_base.h */ 10 : #include "fd_progcache_clock.h" 11 : #include "../fd_rwlock.h" 12 : #include "../runtime/fd_runtime_const.h" 13 : 14 : /* fd_progcache_shmem_t is the top-level shared memory data structure 15 : of the progcache. */ 16 : 17 153 : #define FD_PROGCACHE_SHMEM_MAGIC (0xf17eda2ce7fc2c03UL) 18 : 19 : #define FD_PROGCACHE_DEPTH_MAX (8192UL) 20 : 21 : #define FD_PROGCACHE_SPAD_MAX (FD_MAX_INSTRUCTION_STACK_DEPTH * (20UL<<20)) 22 : 23 : struct fd_progcache_shmem { 24 : 25 : ulong magic; 26 : ulong wksp_tag; 27 : ulong seed; 28 : 29 : ulong alloc_gaddr; 30 : 31 : struct { 32 : uint max; 33 : ulong map_gaddr; 34 : ulong pool_gaddr; 35 : ulong ele_gaddr; 36 : } rec; 37 : 38 : struct __attribute__((aligned(64))) { 39 : fd_rwlock_t rwlock; 40 : ulong max; 41 : ulong map_gaddr; 42 : ulong pool_gaddr; 43 : ulong ele_gaddr; 44 : uint child_head_idx; 45 : uint child_tail_idx; 46 : fd_xid_t last_publish[1]; /* root XID (initially ULONG_MAX:ULONG_MAX) */ 47 : } txn; 48 : 49 : struct { 50 : fd_rwlock_t lock; 51 : fd_progcache_rec_t rec[ FD_MAX_INSTRUCTION_STACK_DEPTH ]; 52 : uint rec_used; 53 : uint spad_used; 54 : uint spad_off[ FD_MAX_INSTRUCTION_STACK_DEPTH ]; 55 : uchar spad[ FD_PROGCACHE_SPAD_MAX ] __attribute__((aligned(64UL))); 56 : } spill; 57 : 58 : struct { 59 : fd_rwlock_t lock; 60 : ulong head; 61 : ulong cbits_gaddr; 62 : } clock; 63 : 64 : }; 65 : 66 : FD_STATIC_ASSERT( FD_PROGCACHE_SPAD_MAX<=UINT_MAX, "layout" ); 67 : 68 : /* Declare a separately-chained concurrent hash map for cache entries */ 69 : 70 : #define POOL_NAME fd_prog_recp 71 : #define POOL_ELE_T fd_progcache_rec_t 72 : #define POOL_IDX_T uint 73 : #define POOL_NEXT map_next 74 : #define POOL_IMPL_STYLE 1 75 : #include "../../util/tmpl/fd_pool_para.c" 76 : 77 : #define MAP_NAME fd_prog_recm 78 48 : #define MAP_ELE_T fd_progcache_rec_t 79 : #define MAP_KEY_T fd_funk_xid_key_pair_t 80 : #define MAP_KEY pair 81 156 : #define MAP_KEY_EQ(k0,k1) fd_funk_xid_key_pair_eq((k0),(k1)) 82 372 : #define MAP_KEY_HASH(k0,seed) fd_funk_xid_key_pair_hash((k0),(seed)) 83 : #define MAP_IDX_T uint 84 48 : #define MAP_NEXT map_next 85 : #define MAP_MAGIC (0xf173da2ce77ecdb8UL) 86 : #define MAP_IMPL_STYLE 1 87 : #include "../../util/tmpl/fd_map_chain_para.c" 88 : 89 : /* Declare a tree / hash map hybrid of fork graph nodes (externally 90 : synchronized) */ 91 : 92 : struct __attribute__((aligned(64))) fd_progcache_txn { 93 : fd_xid_t xid; 94 : uint map_next; 95 : fd_rwlock_t lock; 96 : ushort tag : 2; 97 : 98 : uint parent_idx; 99 : uint child_head_idx; 100 : uint child_tail_idx; 101 : uint sibling_prev_idx; 102 : uint sibling_next_idx; 103 : 104 : uint rec_head_idx; 105 : uint rec_tail_idx; 106 : }; 107 : 108 : #define POOL_NAME fd_prog_txnp 109 : #define POOL_T fd_progcache_txn_t 110 : #define POOL_IDX_T uint 111 447 : #define POOL_NEXT map_next 112 : #define POOL_IMPL_STYLE 1 113 : #include "../../util/tmpl/fd_pool.c" 114 : 115 : #define MAP_NAME fd_prog_txnm 116 : #define MAP_ELE_T fd_progcache_txn_t 117 : #define MAP_KEY_T fd_xid_t 118 : #define MAP_KEY xid 119 609 : #define MAP_KEY_EQ(k0,k1) fd_funk_txn_xid_eq((k0),(k1)) 120 1152 : #define MAP_KEY_HASH(k0,seed) fd_funk_txn_xid_hash((k0),(seed)) 121 : #define MAP_IDX_T uint 122 : #define MAP_NEXT map_next 123 : #define MAP_MAGIC (0xf173da2ce77ecdb9UL) 124 : #define MAP_IMPL_STYLE 1 125 : #include "../../util/tmpl/fd_map_chain.c" 126 : 127 : /* Declare fd_progcache_join_t now that we have all dependencies */ 128 : 129 : typedef struct fd_prog_clock fd_prog_clock_t; 130 : 131 : struct fd_progcache_join { 132 : 133 : fd_progcache_shmem_t * shmem; 134 : 135 : struct { 136 : fd_prog_recm_t map[1]; 137 : fd_prog_recp_t pool[1]; 138 : uint reclaim_head; 139 : } rec; 140 : 141 : struct { 142 : fd_prog_txnm_t * map; 143 : fd_progcache_txn_t * pool; 144 : } txn; 145 : 146 : void * data_base; 147 : fd_alloc_t * alloc; 148 : 149 : struct { 150 : atomic_ulong * bits; 151 : } clock; 152 : 153 : }; 154 : 155 : FD_PROTOTYPES_BEGIN 156 : 157 : FD_FN_CONST ulong 158 : fd_progcache_shmem_align( void ); 159 : 160 : FD_FN_CONST ulong 161 : fd_progcache_shmem_footprint( ulong txn_max, 162 : ulong rec_max ); 163 : 164 : fd_progcache_shmem_t * 165 : fd_progcache_shmem_new( void * shmem, 166 : ulong wksp_tag, 167 : ulong seed, 168 : ulong txn_max, 169 : ulong rec_max ); 170 : 171 : fd_progcache_join_t * 172 : fd_progcache_shmem_join( fd_progcache_join_t * ljoin, 173 : fd_progcache_shmem_t * shmem ); 174 : 175 : void * 176 : fd_progcache_shmem_leave( fd_progcache_join_t * ljoin, 177 : fd_progcache_shmem_t ** opt_shmem ); 178 : 179 : void * 180 : fd_progcache_shmem_delete( fd_progcache_shmem_t * shmem ); 181 : 182 : void * 183 : fd_progcache_shmem_delete_fast( fd_progcache_shmem_t * shmem ); 184 : 185 : /* fd_progcache_rec_unlink removes a record from a transaction's record 186 : list. */ 187 : 188 : static inline void 189 : fd_progcache_rec_unlink( fd_progcache_rec_t * rec0, 190 : fd_progcache_rec_t * rec, 191 : fd_progcache_txn_t * txn, /* requires write lock */ 192 3 : ulong rec_max ) { 193 3 : if( FD_UNLIKELY( rec->next_idx!=UINT_MAX && (ulong)rec->next_idx>=rec_max ) ) 194 0 : FD_LOG_CRIT(( "progcache: corruption detected (rec_unlink next_idx=%u rec_max=%lu)", rec->next_idx, rec_max )); 195 3 : if( FD_UNLIKELY( rec->prev_idx!=UINT_MAX && (ulong)rec->prev_idx>=rec_max ) ) 196 0 : FD_LOG_CRIT(( "progcache: corruption detected (rec_unlink prev_idx=%u rec_max=%lu)", rec->prev_idx, rec_max )); 197 : 198 3 : *fd_ptr_if( rec->next_idx!=UINT_MAX, &rec0[ rec->next_idx ].prev_idx, &txn->rec_tail_idx ) = 199 3 : rec->prev_idx; 200 : 201 3 : *fd_ptr_if( rec->prev_idx!=UINT_MAX, &rec0[ rec->prev_idx ].next_idx, &txn->rec_head_idx ) = 202 3 : rec->next_idx; 203 3 : } 204 : 205 : FD_PROTOTYPES_END 206 : 207 : #endif /* HEADER_fd_src_flamenco_progcache_fd_progcache_h */