Line data Source code
1 : #include "fd_inflight.h" 2 : 3 : void * 4 0 : fd_inflights_new( void * shmem ) { 5 0 : if( FD_UNLIKELY( !shmem ) ) { 6 0 : FD_LOG_WARNING(( "NULL mem" )); 7 0 : return NULL; 8 0 : } 9 : 10 0 : ulong footprint = fd_inflights_footprint(); 11 : 12 0 : FD_SCRATCH_ALLOC_INIT( l, shmem ); 13 0 : fd_inflights_t * table = FD_SCRATCH_ALLOC_APPEND( l, fd_inflights_align(), sizeof(fd_inflights_t) ); 14 0 : void * pool = FD_SCRATCH_ALLOC_APPEND( l, fd_inflight_pool_align(), fd_inflight_pool_footprint(FD_INFLIGHT_REQ_MAX) ); 15 0 : void * map = FD_SCRATCH_ALLOC_APPEND( l, fd_inflight_map_align(), fd_inflight_map_footprint(FD_INFLIGHT_REQ_MAX) ); 16 0 : void * dlist = FD_SCRATCH_ALLOC_APPEND( l, fd_inflight_dlist_align(), fd_inflight_dlist_footprint() ); 17 0 : FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_inflights_align() ) == (ulong)shmem + footprint ); 18 : 19 0 : table->pool = fd_inflight_pool_join ( fd_inflight_pool_new ( pool, FD_INFLIGHT_REQ_MAX ) ); 20 0 : table->map = fd_inflight_map_join ( fd_inflight_map_new ( map, FD_INFLIGHT_REQ_MAX, 0 ) ); 21 0 : table->dlist = fd_inflight_dlist_join( fd_inflight_dlist_new( dlist ) ); 22 : 23 0 : FD_TEST( table->pool ); 24 0 : FD_TEST( table->map ); 25 0 : FD_TEST( table->dlist ); 26 : 27 0 : return shmem; 28 0 : } 29 : 30 : fd_inflights_t * 31 0 : fd_inflights_join( void * shmem ) { 32 0 : fd_inflights_t * table = (fd_inflights_t *)shmem; 33 : 34 0 : if( FD_UNLIKELY( !table ) ) { 35 0 : FD_LOG_WARNING(( "NULL inflight table" )); 36 0 : return NULL; 37 0 : } 38 : 39 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)table, fd_inflights_align() ) ) ) { 40 0 : FD_LOG_WARNING(( "misaligned inflighttable" )); 41 0 : return NULL; 42 0 : } 43 : 44 0 : fd_wksp_t * wksp = fd_wksp_containing( table ); 45 0 : if( FD_UNLIKELY( !wksp ) ) { 46 0 : FD_LOG_WARNING(( "inflight table must be part of a workspace" )); 47 0 : return NULL; 48 0 : } 49 : 50 0 : return (fd_inflights_t *)shmem; 51 0 : } 52 : 53 : void 54 0 : fd_inflights_request_insert( fd_inflights_t * table, ulong nonce, fd_pubkey_t const * pubkey ) { 55 0 : if( FD_UNLIKELY( !fd_inflight_pool_free( table->pool ) ) ) { 56 0 : fd_inflight_t * evict = fd_inflight_dlist_ele_pop_head( table->dlist, table->pool ); 57 0 : fd_inflight_map_ele_remove( table->map, &evict->nonce, NULL, table->pool ); 58 0 : fd_inflight_pool_ele_release( table->pool, evict ); 59 0 : } 60 : 61 0 : fd_inflight_t * inflight_req = fd_inflight_pool_ele_acquire( table->pool ); 62 0 : inflight_req->nonce = nonce; 63 0 : inflight_req->timestamp_ns = fd_log_wallclock(); 64 0 : inflight_req->pubkey = *pubkey; 65 : 66 0 : fd_inflight_map_ele_insert( table->map, inflight_req, table->pool ); 67 0 : fd_inflight_dlist_ele_push_tail( table->dlist, inflight_req, table->pool ); 68 0 : } 69 : 70 : long 71 0 : fd_inflights_request_remove( fd_inflights_t * table, ulong nonce, fd_pubkey_t * peer_out ) { 72 0 : fd_inflight_t * inflight_req = fd_inflight_map_ele_remove( table->map, &nonce, NULL, table->pool ); 73 0 : if( FD_LIKELY( inflight_req ) ) { 74 0 : long now = fd_log_wallclock(); 75 0 : long rtt = now - inflight_req->timestamp_ns; 76 : 77 0 : *peer_out = inflight_req->pubkey; 78 : /* Remove the element from the inflight table */ 79 0 : fd_inflight_map_ele_remove ( table->map, &nonce, NULL, table->pool ); 80 0 : fd_inflight_dlist_ele_remove( table->dlist, inflight_req, table->pool ); 81 0 : fd_inflight_pool_ele_release( table->pool, inflight_req ); 82 0 : return rtt; 83 0 : } 84 0 : return 0; 85 0 : } 86 : 87 : fd_inflight_t * 88 0 : fd_inflights_request_query( fd_inflights_t * table, ulong nonce ) { 89 : return fd_inflight_map_ele_query( table->map, &nonce, NULL, table->pool ); 90 0 : }