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, ulong slot, ulong shred_idx ) {
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 0 : inflight_req->slot = slot;
66 0 : inflight_req->shred_idx = shred_idx;
67 :
68 0 : fd_inflight_map_ele_insert ( table->map, inflight_req, table->pool );
69 0 : fd_inflight_dlist_ele_push_tail( table->dlist, inflight_req, table->pool );
70 0 : }
71 :
72 : long
73 0 : fd_inflights_request_remove( fd_inflights_t * table, ulong nonce, fd_pubkey_t * peer_out ) {
74 0 : fd_inflight_t * inflight_req = fd_inflight_map_ele_remove( table->map, &nonce, NULL, table->pool );
75 0 : if( FD_LIKELY( inflight_req ) ) {
76 0 : long now = fd_log_wallclock();
77 0 : long rtt = now - inflight_req->timestamp_ns;
78 :
79 0 : *peer_out = inflight_req->pubkey;
80 : /* Remove the element from the inflight table */
81 0 : fd_inflight_map_ele_remove ( table->map, &nonce, NULL, table->pool );
82 0 : fd_inflight_dlist_ele_remove( table->dlist, inflight_req, table->pool );
83 0 : fd_inflight_pool_ele_release( table->pool, inflight_req );
84 0 : return rtt;
85 0 : }
86 0 : return 0;
87 0 : }
88 :
89 : void
90 0 : fd_inflights_request_pop( fd_inflights_t * table, ulong * nonce_out, ulong * slot_out, ulong * shred_idx_out ) {
91 0 : fd_inflight_t * inflight_req = fd_inflight_dlist_ele_pop_head( table->dlist, table->pool );
92 0 : fd_inflight_map_ele_remove( table->map, &inflight_req->nonce, NULL, table->pool );
93 0 : *nonce_out = inflight_req->nonce;
94 0 : *slot_out = inflight_req->slot;
95 0 : *shred_idx_out = inflight_req->shred_idx;
96 0 : fd_inflight_pool_ele_release( table->pool, inflight_req );
97 0 : }
98 :
99 : fd_inflight_t *
100 0 : fd_inflights_request_query( fd_inflights_t * table, ulong nonce ) {
101 0 : return fd_inflight_map_ele_query( table->map, &nonce, NULL, table->pool );
102 0 : }
103 :
104 : #include <stdio.h>
105 :
106 : void
107 0 : fd_inflights_print( fd_inflight_map_t * map, fd_inflight_t * pool ) {
108 0 : printf("%-15s %-8s %-15s %-44s\n", "Slot", "Idx", "Timestamp", "Peer");
109 0 : printf("%-15s %-8s %-15s %-44s\n",
110 0 : "---------------", "--------", "------------",
111 0 : "--------------------------------------------");
112 :
113 0 : for( fd_inflight_map_iter_t iter = fd_inflight_map_iter_init( map, pool );
114 0 : !fd_inflight_map_iter_done( iter, map, pool );
115 0 : iter = fd_inflight_map_iter_next( iter, map, pool ) ) {
116 0 : fd_inflight_t * inflight_req = fd_inflight_map_iter_ele( iter, map, pool );
117 0 : FD_BASE58_ENCODE_32_BYTES( inflight_req->pubkey.uc, peer );
118 :
119 0 : printf("%-15lu %-8lu %-15lu %-44.44s\n",
120 0 : inflight_req->slot,
121 0 : inflight_req->shred_idx,
122 0 : (ulong)inflight_req->timestamp_ns / (ulong)1e6,
123 0 : peer);
124 0 : }
125 : printf("\n");
126 0 : }
|