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 */ 10 : #include "fd_progcache_xid.h" 11 : #include "../fd_rwlock.h" 12 : #include "../runtime/fd_runtime_const.h" 13 : #include "fd_progcache_xid.h" 14 : 15 : /* fd_progcache_shmem_t is the top-level shared memory data structure 16 : of the progcache. */ 17 : 18 135 : #define FD_PROGCACHE_SHMEM_MAGIC (0xf17eda2ce7fc2c03UL) 19 : 20 : #define FD_PROGCACHE_SPAD_MAX (FD_MAX_INSTRUCTION_STACK_DEPTH * (20UL<<20)) 21 : 22 : struct fd_progcache_shmem { 23 : 24 : ulong magic; 25 : ulong wksp_tag; 26 : ulong seed; 27 : 28 : ulong alloc_gaddr; 29 : 30 : struct { 31 : uint max; 32 : ulong map_gaddr; 33 : ulong pool_gaddr; 34 : ulong ele_gaddr; 35 : } rec; 36 : 37 : struct __attribute__((aligned(64))) { 38 : fd_rwlock_t rwlock; 39 : ulong max; 40 : ulong map_gaddr; 41 : ulong pool_gaddr; 42 : ulong ele_gaddr; 43 : uint child_head_idx; 44 : uint child_tail_idx; 45 : fd_progcache_fork_id_t root; 46 : fd_progcache_fork_id_t seq; 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 18 : #define MAP_ELE_T fd_progcache_rec_t 79 : #define MAP_KEY_T fd_progcache_rec_key_t 80 : #define MAP_KEY pair 81 354 : #define MAP_KEY_EQ(k0,k1) fd_progcache_rec_key_eq((k0),(k1)) 82 651 : #define MAP_KEY_HASH(k0,seed) fd_progcache_rec_key_hash( &(k0)->prog, (seed) ) 83 : #define MAP_IDX_T uint 84 18 : #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_progcache_fork_id_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 7554 : #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 xid 118 : #define MAP_IDX_T uint 119 : #define MAP_NEXT map_next 120 : #define MAP_MAGIC (0xf173da2ce77ecdb9UL) 121 : #define MAP_IMPL_STYLE 1 122 : #include "../../util/tmpl/fd_map_chain.c" 123 : 124 : /* Declare fd_progcache_join_t now that we have all dependencies */ 125 : 126 : typedef struct fd_prog_clock fd_prog_clock_t; 127 : 128 : struct fd_progcache_join { 129 : 130 : fd_progcache_shmem_t * shmem; 131 : 132 : struct { 133 : fd_prog_recm_t map[1]; 134 : fd_prog_recp_t pool[1]; 135 : uint reclaim_head; 136 : } rec; 137 : 138 : struct { 139 : fd_prog_txnm_t * map; 140 : fd_progcache_txn_t * pool; 141 : } txn; 142 : 143 : void * data_base; 144 : fd_alloc_t * alloc; 145 : 146 : struct { 147 : atomic_ulong * bits; 148 : } clock; 149 : 150 : }; 151 : 152 : FD_PROTOTYPES_BEGIN 153 : 154 : FD_FN_CONST ulong 155 : fd_progcache_shmem_align( void ); 156 : 157 : FD_FN_CONST ulong 158 : fd_progcache_shmem_footprint( ulong txn_max, 159 : ulong rec_max ); 160 : 161 : fd_progcache_shmem_t * 162 : fd_progcache_shmem_new( void * shmem, 163 : ulong wksp_tag, 164 : ulong seed, 165 : ulong txn_max, 166 : ulong rec_max ); 167 : 168 : fd_progcache_join_t * 169 : fd_progcache_shmem_join( fd_progcache_join_t * ljoin, 170 : fd_progcache_shmem_t * shmem ); 171 : 172 : void * 173 : fd_progcache_shmem_leave( fd_progcache_join_t * ljoin, 174 : fd_progcache_shmem_t ** opt_shmem ); 175 : 176 : void * 177 : fd_progcache_shmem_delete( fd_progcache_shmem_t * shmem ); 178 : 179 : void * 180 : fd_progcache_shmem_delete_fast( fd_progcache_shmem_t * shmem ); 181 : 182 : /* fd_progcache_rec_unlink removes a record from a transaction's record 183 : list. */ 184 : 185 : static inline void 186 : fd_progcache_rec_unlink( fd_progcache_rec_t * rec0, 187 : fd_progcache_rec_t * rec, 188 : fd_progcache_txn_t * txn, /* requires write lock */ 189 36 : ulong rec_max ) { 190 36 : if( FD_UNLIKELY( rec->next_idx!=UINT_MAX && (ulong)rec->next_idx>=rec_max ) ) 191 0 : FD_LOG_CRIT(( "progcache: corruption detected (rec_unlink next_idx=%u rec_max=%lu)", rec->next_idx, rec_max )); 192 36 : if( FD_UNLIKELY( rec->prev_idx!=UINT_MAX && (ulong)rec->prev_idx>=rec_max ) ) 193 0 : FD_LOG_CRIT(( "progcache: corruption detected (rec_unlink prev_idx=%u rec_max=%lu)", rec->prev_idx, rec_max )); 194 : 195 36 : *fd_ptr_if( rec->next_idx!=UINT_MAX, &rec0[ rec->next_idx ].prev_idx, &txn->rec_tail_idx ) = 196 36 : rec->prev_idx; 197 : 198 36 : *fd_ptr_if( rec->prev_idx!=UINT_MAX, &rec0[ rec->prev_idx ].next_idx, &txn->rec_head_idx ) = 199 36 : rec->next_idx; 200 36 : } 201 : 202 : FD_FN_CONST static inline fd_progcache_fork_id_t 203 11106 : fd_progcache_fork_id_initial( void ) { 204 11106 : return 0UL; 205 11106 : } 206 : 207 : FD_PROTOTYPES_END 208 : 209 : #endif /* HEADER_fd_src_flamenco_progcache_fd_progcache_h */