LCOV - code coverage report
Current view: top level - app/firedancer/commands/monitor_gossip - gossip_diag.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 532 0.0 %
Date: 2026-09-17 04:28:31 Functions: 0 9 0.0 %

          Line data    Source code
       1             : #include "gossip_diag.h"
       2             : #include "../../../../disco/net/fd_net_tile.h"
       3             : 
       4             : #include <stdio.h>
       5             : #include <stdlib.h>
       6             : #include <string.h>
       7             : 
       8             : /* Formatting helpers *************************************************/
       9             : 
      10             : static char *
      11           0 : fmt_count( char buf[ static 64 ], ulong count ) {
      12           0 :   char tmp[ 64 ];
      13           0 :   if( FD_LIKELY( count<1000UL ) ) FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%lu", count ) );
      14           0 :   else if( FD_LIKELY( count<1000000UL ) ) FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%.1f K", (double)count/1000.0 ) );
      15           0 :   else if( FD_LIKELY( count<1000000000UL ) ) FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%.1f M", (double)count/1000000.0 ) );
      16           0 :   else FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%.1f G", (double)count/1000000000.0 ) );
      17             : 
      18           0 :   FD_TEST( fd_cstr_printf_check( buf, 64UL, NULL, "%12s", tmp ) );
      19           0 :   return buf;
      20           0 : }
      21             : 
      22             : static char *
      23           0 : fmt_bytes( char buf[ static 64 ], ulong bytes ) {
      24           0 :   char tmp[ 64 ];
      25           0 :   if( FD_LIKELY( 8UL*bytes<1000UL ) ) FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%lu bits", 8UL*bytes ) );
      26           0 :   else if( FD_LIKELY( 8UL*bytes<1000000UL ) ) FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%.1f Kbit", (double)(8UL*bytes)/1000.0 ) );
      27           0 :   else if( FD_LIKELY( 8UL*bytes<1000000000UL ) ) FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%.1f Mbit", (double)(8UL*bytes)/1000000.0 ) );
      28           0 :   else FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%.1f Gbit", (double)(8UL*bytes)/1000000000.0 ) );
      29             : 
      30           0 :   FD_TEST( fd_cstr_printf_check( buf, 64UL, NULL, "%12s", tmp ) );
      31           0 :   return buf;
      32           0 : }
      33             : 
      34             : static char *
      35           0 : fmt_pct( char buf[ static 64 ], double pct ) {
      36           0 :   char tmp[ 64 ];
      37           0 :   FD_TEST( fd_cstr_printf_check( tmp, 64UL, NULL, "%.1f %%", 100.0*pct ) );
      38           0 :   FD_TEST( fd_cstr_printf_check( buf, 64UL, NULL, "%12s", tmp ) );
      39           0 :   return buf;
      40           0 : }
      41             : 
      42             : /* Gossvf tile collection *********************************************/
      43             : 
      44             : static fd_gossip_diag_gossvf_t
      45           0 : collect_gossvf_tiles( fd_topo_t * topo ) {
      46           0 :   fd_gossip_diag_gossvf_t tiles = {0};
      47           0 :   tiles.tile_count = fd_topo_tile_name_cnt( topo, "gossvf" );
      48             : 
      49           0 :   if( FD_UNLIKELY( tiles.tile_count == 0UL ) ) {
      50           0 :     return tiles;
      51           0 :   }
      52             : 
      53           0 :   tiles.tiles = aligned_alloc( 8UL, tiles.tile_count * sizeof(fd_topo_tile_t*) );
      54           0 :   FD_TEST( tiles.tiles );
      55           0 :   tiles.metrics = aligned_alloc( 8UL, tiles.tile_count * sizeof(volatile ulong*) );
      56           0 :   FD_TEST( tiles.metrics );
      57           0 :   tiles.prev_metrics = aligned_alloc( 8UL, tiles.tile_count * sizeof(ulong*) );
      58           0 :   FD_TEST( tiles.prev_metrics );
      59           0 :   tiles.net_links = aligned_alloc( 8UL, tiles.tile_count * sizeof(volatile ulong*) );
      60           0 :   FD_TEST( tiles.net_links );
      61             : 
      62           0 :   for( ulong i = 0UL; i < tiles.tile_count; i++ ) {
      63           0 :     ulong tile_idx = fd_topo_find_tile( topo, "gossvf", i );
      64           0 :     FD_TEST( tile_idx != ULONG_MAX );
      65             : 
      66           0 :     tiles.tiles[i] = &topo->tiles[ tile_idx ];
      67           0 :     tiles.metrics[i] = fd_metrics_tile( tiles.tiles[i]->metrics );
      68           0 :     FD_TEST( tiles.metrics[i] );
      69             : 
      70           0 :     tiles.prev_metrics[i] = aligned_alloc( 8UL, FD_METRICS_TOTAL_SZ );
      71           0 :     FD_TEST( tiles.prev_metrics[i] );
      72           0 :     memset( tiles.prev_metrics[i], 0, FD_METRICS_TOTAL_SZ );
      73             : 
      74           0 :     tiles.net_links[i] = fd_metrics_link_in( tiles.tiles[i]->metrics, 0UL );
      75           0 :     FD_TEST( tiles.net_links[i] );
      76           0 :   }
      77             : 
      78           0 :   return tiles;
      79           0 : }
      80             : 
      81             : /* Aggregation helpers ************************************************/
      82             : 
      83             : static ulong
      84           0 : aggregate_gossvf_counter( fd_gossip_diag_gossvf_t * tiles, ulong metric_idx ) {
      85           0 :   ulong total = 0UL;
      86           0 :   for( ulong i = 0UL; i < tiles->tile_count; i++ ) {
      87           0 :     total += tiles->metrics[i][metric_idx];
      88           0 :   }
      89           0 :   return total;
      90           0 : }
      91             : 
      92             : static ulong
      93           0 : aggregate_gossvf_prev_counter( fd_gossip_diag_gossvf_t * tiles, ulong metric_idx ) {
      94           0 :   ulong total = 0UL;
      95           0 :   for( ulong i = 0UL; i < tiles->tile_count; i++ ) {
      96           0 :     total += tiles->prev_metrics[i][metric_idx];
      97           0 :   }
      98           0 :   return total;
      99           0 : }
     100             : 
     101             : /* rx_deltas computation **********************************************/
     102             : 
     103             : static rx_deltas_t
     104             : rx_deltas_aggregated( volatile ulong * gossip_metrics,
     105             :                       ulong *          gossip_prev,
     106           0 :                       fd_gossip_diag_gossvf_t * gossvf_tiles ) {
     107           0 :   rx_deltas_t deltas;
     108             : 
     109             :   /* Pull request metrics aggregated across all gossvf tiles */
     110           0 :   ulong pull_request_rx_current =
     111           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PULL_REQUEST ) ) +
     112           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_NOT_CONTACT_INFO ) ) +
     113           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_LOOPBACK ) ) +
     114           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_INACTIVE ) ) +
     115           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_WALLCLOCK ) ) +
     116           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SIGNATURE ) ) +
     117           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SHRED_VERSION ) ) +
     118           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_MASK_BITS ) );
     119             : 
     120           0 :   ulong pull_request_rx_prev =
     121           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PULL_REQUEST ) ) +
     122           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_NOT_CONTACT_INFO ) ) +
     123           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_LOOPBACK ) ) +
     124           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_INACTIVE ) ) +
     125           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_WALLCLOCK ) ) +
     126           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SIGNATURE ) ) +
     127           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SHRED_VERSION ) ) +
     128           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_MASK_BITS ) );
     129             : 
     130           0 :   deltas.pull_request_rx = pull_request_rx_current - pull_request_rx_prev;
     131             : 
     132           0 :   deltas.pull_request_rx_drop =
     133           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_NOT_CONTACT_INFO ) ) +
     134           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_LOOPBACK ) ) +
     135           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_INACTIVE ) ) +
     136           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_WALLCLOCK ) ) +
     137           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SIGNATURE ) ) +
     138           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SHRED_VERSION ) ) +
     139           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_MASK_BITS ) )) -
     140           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_NOT_CONTACT_INFO ) ) +
     141           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_LOOPBACK ) ) +
     142           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_INACTIVE ) ) +
     143           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_WALLCLOCK ) ) +
     144           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SIGNATURE ) ) +
     145           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_SHRED_VERSION ) ) +
     146           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_REQUEST_MASK_BITS ) ));
     147             : 
     148           0 :   deltas.pull_request_tx = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PULL_REQUEST ) ] -
     149           0 :                            gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PULL_REQUEST ) ];
     150           0 :   deltas.pull_request_tx_bytes = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PULL_REQUEST ) ] -
     151           0 :                                  gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PULL_REQUEST ) ];
     152             : 
     153           0 :   deltas.pull_request_rx_bytes =
     154           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PULL_REQUEST ) ) +
     155           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_NOT_CONTACT_INFO ) ) +
     156           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_LOOPBACK ) ) +
     157           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_INACTIVE ) ) +
     158           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_WALLCLOCK ) ) +
     159           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_SIGNATURE ) ) +
     160           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_SHRED_VERSION ) ) +
     161           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_MASK_BITS ) )) -
     162           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PULL_REQUEST ) ) +
     163           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_NOT_CONTACT_INFO ) ) +
     164           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_LOOPBACK ) ) +
     165           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_INACTIVE ) ) +
     166           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_WALLCLOCK ) ) +
     167           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_SIGNATURE ) ) +
     168           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_SHRED_VERSION ) ) +
     169           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_REQUEST_MASK_BITS ) ));
     170             : 
     171             :   /* Pull response metrics */
     172           0 :   deltas.pull_response_rx =
     173           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PULL_RESPONSE ) ) +
     174           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_LOOPBACK ) ) +
     175           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_NO_VALID_CRDS ) )) -
     176           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PULL_RESPONSE ) ) +
     177           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_LOOPBACK ) ) +
     178           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_NO_VALID_CRDS ) ));
     179             : 
     180           0 :   deltas.pull_response_rx_drop =
     181           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_LOOPBACK ) ) +
     182           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_NO_VALID_CRDS ) )) -
     183           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_LOOPBACK ) ) +
     184           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_NO_VALID_CRDS ) ));
     185             : 
     186           0 :   deltas.pull_response_tx = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PULL_RESPONSE ) ] -
     187           0 :                             gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PULL_RESPONSE ) ];
     188           0 :   deltas.pull_response_tx_bytes = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PULL_RESPONSE ) ] -
     189           0 :                                   gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PULL_RESPONSE ) ];
     190           0 :   deltas.pull_response_rx_bytes =
     191           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PULL_RESPONSE ) ) +
     192           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_RESPONSE_LOOPBACK ) ) +
     193           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_RESPONSE_NO_VALID_CRDS ) )) -
     194           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PULL_RESPONSE ) ) +
     195           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_RESPONSE_LOOPBACK ) ) +
     196           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PULL_RESPONSE_NO_VALID_CRDS ) ));
     197             : 
     198             :   /* Push metrics */
     199           0 :   deltas.push_rx =
     200           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PUSH ) ) +
     201           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_LOOPBACK ) ) +
     202           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_NO_VALID_CRDS ) )) -
     203           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PUSH ) ) +
     204           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_LOOPBACK ) ) +
     205           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_NO_VALID_CRDS ) ));
     206             : 
     207           0 :   deltas.push_rx_drop =
     208           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_LOOPBACK ) ) +
     209           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_NO_VALID_CRDS ) )) -
     210           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_LOOPBACK ) ) +
     211           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_NO_VALID_CRDS ) ));
     212             : 
     213           0 :   deltas.push_tx = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PUSH ) ] -
     214           0 :                    gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PUSH ) ];
     215           0 :   deltas.push_tx_bytes = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PUSH ) ] -
     216           0 :                          gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PUSH ) ];
     217           0 :   deltas.push_rx_bytes =
     218           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PUSH ) ) +
     219           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PUSH_LOOPBACK ) ) +
     220           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PUSH_NO_VALID_CRDS ) )) -
     221           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PUSH ) ) +
     222           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PUSH_LOOPBACK ) ) +
     223           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PUSH_NO_VALID_CRDS ) ));
     224             : 
     225             :   /* Prune metrics */
     226           0 :   deltas.prune_rx =
     227           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PRUNE ) ) +
     228           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_DESTINATION ) ) +
     229           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_WALLCLOCK ) ) +
     230           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_SIGNATURE ) )) -
     231           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PRUNE ) ) +
     232           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_DESTINATION ) ) +
     233           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_WALLCLOCK ) ) +
     234           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_SIGNATURE ) ));
     235             : 
     236           0 :   deltas.prune_rx_drop =
     237           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_DESTINATION ) ) +
     238           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_WALLCLOCK ) ) +
     239           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_SIGNATURE ) )) -
     240           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_DESTINATION ) ) +
     241           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_WALLCLOCK ) ) +
     242           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PRUNE_SIGNATURE ) ));
     243             : 
     244           0 :   deltas.prune_tx = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PRUNE ) ] -
     245           0 :                     gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PRUNE ) ];
     246           0 :   deltas.prune_tx_bytes = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PRUNE ) ] -
     247           0 :                           gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PRUNE ) ];
     248           0 :   deltas.prune_rx_bytes =
     249           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PRUNE ) ) +
     250           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PRUNE_DESTINATION ) ) +
     251           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PRUNE_WALLCLOCK ) ) +
     252           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PRUNE_SIGNATURE ) )) -
     253           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PRUNE ) ) +
     254           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PRUNE_DESTINATION ) ) +
     255           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PRUNE_WALLCLOCK ) ) +
     256           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PRUNE_SIGNATURE ) ));
     257             : 
     258             :   /* Ping metrics */
     259           0 :   deltas.ping_rx =
     260           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PING ) ) +
     261           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PING_SIGNATURE ) )) -
     262           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PING ) ) +
     263           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PING_SIGNATURE ) ));
     264             : 
     265           0 :   deltas.ping_rx_drop =
     266           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PING_SIGNATURE ) ) -
     267           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PING_SIGNATURE ) );
     268             : 
     269           0 :   deltas.ping_tx = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PING ) ] -
     270           0 :                    gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PING ) ];
     271           0 :   deltas.ping_tx_bytes = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PING ) ] -
     272           0 :                          gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PING ) ];
     273           0 :   deltas.ping_rx_bytes =
     274           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PING ) ) +
     275           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PING_SIGNATURE ) )) -
     276           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PING ) ) +
     277           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PING_SIGNATURE ) ));
     278             : 
     279             :   /* Pong metrics */
     280           0 :   deltas.pong_rx =
     281           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PONG ) ) +
     282           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PONG_SIGNATURE ) )) -
     283           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PONG ) ) +
     284           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PONG_SIGNATURE ) ));
     285             : 
     286           0 :   deltas.pong_rx_drop =
     287           0 :     aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PONG_SIGNATURE ) ) -
     288           0 :     aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PONG_SIGNATURE ) );
     289             : 
     290           0 :   deltas.pong_tx = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PONG ) ] -
     291           0 :                    gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_PONG ) ];
     292           0 :   deltas.pong_tx_bytes = gossip_metrics[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PONG ) ] -
     293           0 :                          gossip_prev[ MIDX( COUNTER, GOSSIP, MESSAGE_TX_BYTES_PONG ) ];
     294           0 :   deltas.pong_rx_bytes =
     295           0 :     (aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PONG ) ) +
     296           0 :      aggregate_gossvf_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PONG_SIGNATURE ) )) -
     297           0 :     (aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_SUCCESS_PONG ) ) +
     298           0 :      aggregate_gossvf_prev_counter( gossvf_tiles, MIDX( COUNTER, GOSSVF, MESSAGE_RX_BYTES_DROPPED_PONG_SIGNATURE ) ));
     299             : 
     300           0 :   return deltas;
     301           0 : }
     302             : 
     303             : /* Public API *********************************************************/
     304             : 
     305             : int
     306             : fd_gossip_diag_init( fd_gossip_diag_ctx_t * ctx,
     307             :                      fd_topo_t *            topo,
     308           0 :                      config_t *             config ) {
     309           0 :   memset( ctx, 0, sizeof(*ctx) );
     310           0 :   ctx->topo   = topo;
     311           0 :   ctx->config = config;
     312           0 :   if(      !strcmp( config->net.provider, "xdp"  ) ) ctx->net_provider = FD_GOSSIP_DIAG_NET_XDP;
     313           0 :   else if( !strcmp( config->net.provider, "mlx5" ) ) ctx->net_provider = FD_GOSSIP_DIAG_NET_MLX5;
     314           0 :   else                                               ctx->net_provider = FD_GOSSIP_DIAG_NET_SOCKET;
     315             : 
     316             :   /* Find gossip tile */
     317           0 :   ulong gossip_tile_idx = fd_topo_find_tile( topo, "gossip", 0UL );
     318           0 :   if( FD_UNLIKELY( gossip_tile_idx==ULONG_MAX ) ) {
     319           0 :     FD_LOG_WARNING(( "No gossip tile found in topology" ));
     320           0 :     return -1;
     321           0 :   }
     322           0 :   ctx->gossip_tile    = &topo->tiles[ gossip_tile_idx ];
     323           0 :   ctx->gossip_metrics = fd_metrics_tile( ctx->gossip_tile->metrics );
     324           0 :   if( FD_UNLIKELY( !ctx->gossip_metrics ) ) {
     325           0 :     FD_LOG_WARNING(( "Failed to get gossip tile metrics" ));
     326           0 :     return -1;
     327           0 :   }
     328             : 
     329           0 :   ctx->gossip_prev = aligned_alloc( 8UL, FD_METRICS_TOTAL_SZ );
     330           0 :   FD_TEST( ctx->gossip_prev );
     331           0 :   memset( ctx->gossip_prev, 0, FD_METRICS_TOTAL_SZ );
     332             : 
     333             :   /* Collect gossvf tiles */
     334           0 :   ctx->gossvf = collect_gossvf_tiles( topo );
     335           0 :   if( FD_UNLIKELY( ctx->gossvf.tile_count==0UL ) ) {
     336           0 :     FD_LOG_WARNING(( "No gossvf tiles found in topology" ));
     337           0 :     return -1;
     338           0 :   }
     339             : 
     340             :   /* Find net tiles */
     341           0 :   ctx->net_tile_cnt = config->layout.net_tile_count;
     342           0 :   ctx->net_metrics  = aligned_alloc( 8UL, ctx->net_tile_cnt * sizeof(volatile ulong const *) );
     343           0 :   FD_TEST( ctx->net_metrics );
     344           0 :   char const * net_tile_name = fd_net_tile_name( config->net.provider );
     345           0 :   for( ulong i=0UL; i<ctx->net_tile_cnt; i++ ) {
     346           0 :     ulong net_tile_idx = fd_topo_find_tile( topo, net_tile_name, i );
     347           0 :     if( FD_UNLIKELY( net_tile_idx==ULONG_MAX ) ) {
     348           0 :       FD_LOG_WARNING(( "Net tile %lu not found", i ));
     349           0 :       return -1;
     350           0 :     }
     351           0 :     fd_topo_tile_t * net_tile = &topo->tiles[ net_tile_idx ];
     352           0 :     ctx->net_metrics[ i ] = fd_metrics_tile( net_tile->metrics );
     353           0 :     FD_TEST( ctx->net_metrics[ i ] );
     354           0 :   }
     355             : 
     356           0 :   ctx->prev_net_tx_bytes = aligned_alloc( 8UL, ctx->net_tile_cnt * sizeof(ulong) );
     357           0 :   ctx->prev_net_rx_bytes = aligned_alloc( 8UL, ctx->net_tile_cnt * sizeof(ulong) );
     358           0 :   FD_TEST( ctx->prev_net_tx_bytes );
     359           0 :   FD_TEST( ctx->prev_net_rx_bytes );
     360           0 :   memset( ctx->prev_net_tx_bytes, 0, ctx->net_tile_cnt * sizeof(ulong) );
     361           0 :   memset( ctx->prev_net_rx_bytes, 0, ctx->net_tile_cnt * sizeof(ulong) );
     362             : 
     363           0 :   ctx->net0_link         = ctx->gossvf.net_links[0];
     364           0 :   ctx->prev_net0_rx_bytes = 0UL;
     365             : 
     366           0 :   return 0;
     367           0 : }
     368             : 
     369             : void
     370             : fd_gossip_diag_render( fd_gossip_diag_ctx_t * ctx,
     371           0 :                        int                    compact_mode ) {
     372           0 :   volatile ulong * gossip_metrics = ctx->gossip_metrics;
     373           0 :   ulong *          gossip_prev    = ctx->gossip_prev;
     374             : 
     375           0 :   ulong total_crds = 0UL;
     376           0 :   for( ulong i=0UL; i<FD_METRICS_ENUM_CRDS_VALUE_CNT; i++ ) total_crds += gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED )+i ];
     377           0 :   ulong total_contact_infos = gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_CONTACT_INFO_V2 ) ];
     378             : 
     379           0 :   ctx->last_total_crds          = total_crds;
     380           0 :   ctx->last_total_contact_infos = total_contact_infos;
     381             : 
     382           0 :   if( compact_mode ) {
     383           0 :     printf( "Table Size: %lu,\tContact Infos: %lu\n",
     384           0 :             total_crds,
     385           0 :             total_contact_infos );
     386           0 :     return;
     387           0 :   }
     388             : 
     389           0 :   char buf1[ 64 ], buf2[ 64 ], buf3[ 64 ], buf4[ 64 ], buf5[ 64 ];
     390             : 
     391           0 :   ulong total_overrun = 0UL;
     392           0 :   for( ulong i = 0UL; i < ctx->gossvf.tile_count; i++ ) {
     393           0 :     volatile ulong * net_vf_link = ctx->gossvf.net_links[i];
     394           0 :     ulong overrun_count = net_vf_link[ MIDX( COUNTER, LINK, FRAG_POLLING_OVERRUN ) ] +
     395           0 :                           net_vf_link[ MIDX( COUNTER, LINK, FRAG_READING_OVERRUN ) ];
     396           0 :     total_overrun += overrun_count;
     397           0 :   }
     398           0 :   printf( " Total Overrun: %s\n", fmt_count( buf1, total_overrun ) );
     399           0 :   printf( " Total ping tracked: %lu\n", gossip_metrics[ MIDX( COUNTER, GOSSIP, PING_TRACKER_ADDED ) ] );
     400             : 
     401           0 :   for( ulong i=0UL; i<ctx->net_tile_cnt; i++ ) {
     402           0 :     if( FD_LIKELY( ctx->net_provider==FD_GOSSIP_DIAG_NET_XDP ) ) {
     403           0 :       printf( " Net %lu RX bw %s, TX bw %s .. %s %s\n", i,
     404           0 :               fmt_bytes( buf1, ctx->net_metrics[ i ][ MIDX( COUNTER, NET,  PKT_RX_BYTES ) ] - ctx->prev_net_rx_bytes[ i ] ),
     405           0 :               fmt_bytes( buf2, ctx->net_metrics[ i ][ MIDX( COUNTER, NET,  PKT_TX_BYTES ) ] - ctx->prev_net_tx_bytes[ i ] ),
     406           0 :               fmt_count( buf3, ctx->net_metrics[ i ][ MIDX( COUNTER, NET, PKT_RX_FILL_RING_FULL ) ] ),
     407           0 :               fmt_count( buf4, ctx->net_metrics[ i ][ MIDX( COUNTER, NET,  PKT_RX_BACKPRESSURE ) ] ) );
     408           0 :       ctx->prev_net_rx_bytes[ i ] = ctx->net_metrics[ i ][ MIDX( COUNTER, NET,  PKT_RX_BYTES ) ];
     409           0 :       ctx->prev_net_tx_bytes[ i ] = ctx->net_metrics[ i ][ MIDX( COUNTER, NET,  PKT_TX_BYTES ) ];
     410           0 :     } else if( FD_LIKELY( ctx->net_provider==FD_GOSSIP_DIAG_NET_MLX5 ) ) {
     411           0 :       printf( " Net %lu RX bw %s, TX bw %s\n", i,
     412           0 :               fmt_bytes( buf1, ctx->net_metrics[ i ][ MIDX( COUNTER, MLX5, PKT_RX_BYTES ) ] - ctx->prev_net_rx_bytes[ i ] ),
     413           0 :               fmt_bytes( buf2, ctx->net_metrics[ i ][ MIDX( COUNTER, MLX5, PKT_TX_BYTES ) ] - ctx->prev_net_tx_bytes[ i ] ) );
     414           0 :       ctx->prev_net_rx_bytes[ i ] = ctx->net_metrics[ i ][ MIDX( COUNTER, MLX5, PKT_RX_BYTES ) ];
     415           0 :       ctx->prev_net_tx_bytes[ i ] = ctx->net_metrics[ i ][ MIDX( COUNTER, MLX5, PKT_TX_BYTES ) ];
     416           0 :     } else {
     417           0 :       printf( " Net %lu RX bw %s, TX bw %s\n", i,
     418           0 :               fmt_bytes( buf1, ctx->net_metrics[ i ][ MIDX( COUNTER, SOCK, PKT_RX_BYTES ) ] - ctx->prev_net_rx_bytes[ i ] ),
     419           0 :               fmt_bytes( buf2, ctx->net_metrics[ i ][ MIDX( COUNTER, SOCK, PKT_TX_BYTES ) ] - ctx->prev_net_tx_bytes[ i ] ) );
     420           0 :       ctx->prev_net_rx_bytes[ i ] = ctx->net_metrics[ i ][ MIDX( COUNTER, SOCK, PKT_RX_BYTES ) ];
     421           0 :       ctx->prev_net_tx_bytes[ i ] = ctx->net_metrics[ i ][ MIDX( COUNTER, SOCK, PKT_TX_BYTES ) ];
     422           0 :     }
     423           0 :   }
     424             : 
     425           0 :   printf( " Single Tile RX bw %s\n\n", fmt_bytes( buf1, ctx->net0_link[ MIDX( COUNTER, LINK, FRAG_CONSUMED_BYTES ) ] - ctx->prev_net0_rx_bytes ) );
     426           0 :   ctx->prev_net0_rx_bytes = ctx->net0_link[ MIDX( COUNTER, LINK, FRAG_CONSUMED_BYTES ) ];
     427             : 
     428           0 :   ulong message_unparseable = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_UNPARSEABLE ) );
     429           0 :   printf( " Message unparseable: %lu/??\n", message_unparseable );
     430             : 
     431           0 :   ulong pull_response_drops   = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PULL_RESPONSE_NO_VALID_CRDS ) );
     432           0 :   ulong pull_response_success = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PULL_RESPONSE ) );
     433           0 :   printf( " Pull response drops (no valid CRDS): %lu/%lu\n", pull_response_drops, pull_response_drops + pull_response_success );
     434             : 
     435           0 :   ulong crds_forwarded         = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PULL_RESPONSE ) )
     436           0 :                                + aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PULL_RESPONSE_DUPLICATE ) );
     437           0 :   ulong crds_signature         = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_SIGNATURE ) );
     438           0 :   ulong crds_origin_no_contact = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_ORIGIN_NO_CONTACT_INFO ) );
     439           0 :   ulong crds_origin_shred      = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_ORIGIN_SHRED_VERSION ) );
     440           0 :   ulong crds_inactive          = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_INACTIVE ) );
     441           0 :   ulong crds_wallclock         = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_WALLCLOCK ) );
     442             : 
     443           0 :   ulong pull_response_crds_total = crds_forwarded + crds_signature + crds_origin_no_contact + crds_origin_shred + crds_inactive + crds_wallclock;
     444             : 
     445           0 :   ulong prev_crds_forwarded         = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PULL_RESPONSE ) )
     446           0 :                                     + aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PULL_RESPONSE_DUPLICATE ) );
     447           0 :   ulong prev_crds_signature         = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_SIGNATURE ) );
     448           0 :   ulong prev_crds_origin_no_contact = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_ORIGIN_NO_CONTACT_INFO ) );
     449           0 :   ulong prev_crds_origin_shred      = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_ORIGIN_SHRED_VERSION ) );
     450           0 :   ulong prev_crds_inactive          = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_INACTIVE ) );
     451           0 :   ulong prev_crds_wallclock         = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PULL_RESPONSE_WALLCLOCK ) );
     452             : 
     453           0 :   ulong prev_pull_response_crds_total = prev_crds_forwarded + prev_crds_signature + prev_crds_origin_no_contact + prev_crds_origin_shred + prev_crds_inactive + prev_crds_wallclock;
     454             : 
     455           0 :   printf( " Pull response CRDS drops: (%lu/%lu) %.1f %% (%.1f %% signature, %.1f %% origin no contact info, %.1f %% origin shred version, %.1f %% inactive, %.1f %% wallclock)\n",
     456           0 :           pull_response_crds_total - crds_forwarded,
     457           0 :           pull_response_crds_total,
     458           0 :           ((double)pull_response_crds_total - (double)crds_forwarded ) / (double)pull_response_crds_total * 100.0,
     459           0 :           (double)crds_signature / (double)pull_response_crds_total * 100.0,
     460           0 :           (double)crds_origin_no_contact / (double)pull_response_crds_total * 100.0,
     461           0 :           (double)crds_origin_shred / (double)pull_response_crds_total * 100.0,
     462           0 :           (double)crds_inactive / (double)pull_response_crds_total * 100.0,
     463           0 :           (double)crds_wallclock / (double)pull_response_crds_total * 100.0 );
     464             : 
     465           0 :   printf( " Pull response CRDS inc drops: (%lu/%lu) %1.f %% (%.1f %% signature, %.1f %% origin no contact info, %.1f %% origin shred version, %.1f %% inactive, %.1f %% wallclock)\n\n",
     466           0 :           (pull_response_crds_total - prev_pull_response_crds_total) - (crds_forwarded - prev_crds_forwarded),
     467           0 :           pull_response_crds_total - prev_pull_response_crds_total,
     468           0 :           ((double)(pull_response_crds_total - prev_pull_response_crds_total) - (double)(crds_forwarded - prev_crds_forwarded) ) / (double)(pull_response_crds_total - prev_pull_response_crds_total) * 100.0,
     469           0 :           (double)(crds_signature - prev_crds_signature) / (double)(pull_response_crds_total - prev_pull_response_crds_total) * 100.0,
     470           0 :           (double)(crds_origin_no_contact - prev_crds_origin_no_contact) / (double)(pull_response_crds_total - prev_pull_response_crds_total) * 100.0,
     471           0 :           (double)(crds_origin_shred - prev_crds_origin_shred) / (double)(pull_response_crds_total - prev_pull_response_crds_total) * 100.0,
     472           0 :           (double)(crds_inactive - prev_crds_inactive) / (double)(pull_response_crds_total - prev_pull_response_crds_total) * 100.0,
     473           0 :           (double)(crds_wallclock - prev_crds_wallclock) / (double)(pull_response_crds_total - prev_pull_response_crds_total) * 100.0 );
     474             : 
     475           0 :   ulong pull_response_insertion_total = gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ] +
     476           0 :                                         gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_STALE ) ] +
     477           0 :                                         gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_DUPLICATE ) ];
     478           0 :   ulong prev_pull_response_insertion_total = gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ] +
     479           0 :                                              gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_STALE ) ] +
     480           0 :                                              gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_DUPLICATE ) ];
     481             : 
     482           0 :   printf( " Pull response CRDS insertion drops: (%lu/%lu) %.1f %% (%.1f %% no override, %.1f %% hash duplicate)\n",
     483           0 :           pull_response_insertion_total - gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ],
     484           0 :           pull_response_insertion_total,
     485           0 :           ((double)pull_response_insertion_total - (double)gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ] ) / (double)pull_response_insertion_total * 100.0,
     486           0 :           (double)gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_STALE ) ] / (double)pull_response_insertion_total * 100.0,
     487           0 :           (double)gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_DUPLICATE ) ] / (double)pull_response_insertion_total * 100.0 );
     488           0 :   printf( " Pull response CRDS insertion inc drops: (%lu/%lu) %.1f %% (%.1f %% no override, %.1f %% hash duplicate)\n\n",
     489           0 :           (pull_response_insertion_total - prev_pull_response_insertion_total) - (gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ]),
     490           0 :           pull_response_insertion_total - prev_pull_response_insertion_total,
     491           0 :           ((double)(pull_response_insertion_total - prev_pull_response_insertion_total) - (double)(gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PULL_RESPONSE ) ]) ) / (double)(pull_response_insertion_total - prev_pull_response_insertion_total) * 100.0,
     492           0 :           (double)(gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_STALE ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_STALE ) ]) / (double)(pull_response_insertion_total - prev_pull_response_insertion_total) * 100.0,
     493           0 :           (double)(gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_DUPLICATE ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PULL_RESPONSE_DUPLICATE ) ]) / (double)(pull_response_insertion_total - prev_pull_response_insertion_total) * 100.0 );
     494             : 
     495             :   /* Push message statistics */
     496           0 :   ulong push_drops   = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, MESSAGE_RX_DROPPED_PUSH_NO_VALID_CRDS ) );
     497           0 :   ulong push_success = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, MESSAGE_RX_SUCCESS_PUSH ) );
     498           0 :   printf( " Push drops: %lu/%lu\n", push_drops, push_drops + push_success );
     499             : 
     500           0 :   ulong push_crds_forwarded         = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PUSH ) )
     501           0 :                                     + aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PUSH_DUPLICATE ) );
     502           0 :   ulong push_crds_signature         = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_SIGNATURE ) );
     503           0 :   ulong push_crds_origin_no_contact = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_ORIGIN_NO_CONTACT_INFO ) );
     504           0 :   ulong push_crds_origin_shred      = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_ORIGIN_SHRED_VERSION ) );
     505           0 :   ulong push_crds_inactive          = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_INACTIVE ) );
     506           0 :   ulong push_crds_wallclock         = aggregate_gossvf_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_WALLCLOCK ) );
     507             : 
     508           0 :   ulong push_crds_total = push_crds_forwarded + push_crds_signature + push_crds_origin_no_contact + push_crds_origin_shred + push_crds_inactive + push_crds_wallclock;
     509             : 
     510           0 :   ulong prev_push_crds_forwarded         = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PUSH ) )
     511           0 :                                          + aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_SUCCESS_PUSH_DUPLICATE ) );
     512           0 :   ulong prev_push_crds_signature         = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_SIGNATURE ) );
     513           0 :   ulong prev_push_crds_origin_no_contact = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_ORIGIN_NO_CONTACT_INFO ) );
     514           0 :   ulong prev_push_crds_origin_shred      = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_ORIGIN_SHRED_VERSION ) );
     515           0 :   ulong prev_push_crds_inactive          = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_INACTIVE ) );
     516           0 :   ulong prev_push_crds_wallclock         = aggregate_gossvf_prev_counter( &ctx->gossvf, MIDX( COUNTER, GOSSVF, CRDS_RX_DROPPED_PUSH_WALLCLOCK ) );
     517             : 
     518           0 :   ulong prev_push_crds_total = prev_push_crds_forwarded + prev_push_crds_signature + prev_push_crds_origin_no_contact + prev_push_crds_origin_shred + prev_push_crds_inactive + prev_push_crds_wallclock;
     519             : 
     520           0 :   printf( " Push CRDS drops: (%lu/%lu) %.1f %% (%.1f %% signature, %.1f %% origin no contact info, %.1f %% origin shred version, %.1f %% inactive, %.1f %% wallclock)\n",
     521           0 :           push_crds_total - push_crds_forwarded,
     522           0 :           push_crds_total,
     523           0 :           ((double)push_crds_total - (double)push_crds_forwarded ) / (double)push_crds_total * 100.0,
     524           0 :           (double)push_crds_signature / (double)push_crds_total * 100.0,
     525           0 :           (double)push_crds_origin_no_contact / (double)push_crds_total * 100.0,
     526           0 :           (double)push_crds_origin_shred / (double)push_crds_total * 100.0,
     527           0 :           (double)push_crds_inactive / (double)push_crds_total * 100.0,
     528           0 :           (double)push_crds_wallclock / (double)push_crds_total * 100.0 );
     529             : 
     530           0 :   printf( " Push CRDS inc drops: (%lu/%lu) %.1f %% (%.1f %% signature, %.1f %% origin no contact info, %.1f %% origin shred version, %.1f %% inactive, %.1f %% wallclock)\n\n",
     531           0 :           (push_crds_total - prev_push_crds_total) - (push_crds_forwarded - prev_push_crds_forwarded),
     532           0 :           push_crds_total - prev_push_crds_total,
     533           0 :           ((double)(push_crds_total - prev_push_crds_total) - (double)(push_crds_forwarded - prev_push_crds_forwarded) ) / (double)(push_crds_total - prev_push_crds_total) * 100.0,
     534           0 :           (double)(push_crds_signature - prev_push_crds_signature) / (double)(push_crds_total - prev_push_crds_total) * 100.0,
     535           0 :           (double)(push_crds_origin_no_contact - prev_push_crds_origin_no_contact) / (double)(push_crds_total - prev_push_crds_total) * 100.0,
     536           0 :           (double)(push_crds_origin_shred - prev_push_crds_origin_shred) / (double)(push_crds_total - prev_push_crds_total) * 100.0,
     537           0 :           (double)(push_crds_inactive - prev_push_crds_inactive) / (double)(push_crds_total - prev_push_crds_total) * 100.0,
     538           0 :           (double)(push_crds_wallclock - prev_push_crds_wallclock) / (double)(push_crds_total - prev_push_crds_total) * 100.0 );
     539             : 
     540           0 :   ulong push_insertion_total = gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ] +
     541           0 :                                gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_STALE ) ] +
     542           0 :                                gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_DUPLICATE ) ];
     543           0 :   ulong prev_push_insertion_total = gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ] +
     544           0 :                                     gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_STALE ) ] +
     545           0 :                                     gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_DUPLICATE ) ];
     546             : 
     547           0 :   printf( " Push CRDS insertion drops: (%lu/%lu) %.1f %% (%.1f %% no override, %.1f %% hash duplicate)\n",
     548           0 :           push_insertion_total - gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ],
     549           0 :           push_insertion_total,
     550           0 :           ((double)push_insertion_total - (double)gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ] ) / (double)push_insertion_total * 100.0,
     551           0 :           (double)gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_STALE ) ] / (double)push_insertion_total * 100.0,
     552           0 :           (double)gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_DUPLICATE ) ] / (double)push_insertion_total * 100.0 );
     553           0 :   printf( " Push CRDS insertion inc drops: (%lu/%lu) %.1f %% (%.1f %% no override, %.1f %% hash duplicate)\n\n",
     554           0 :           (push_insertion_total - prev_push_insertion_total) - (gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ]),
     555           0 :           push_insertion_total - prev_push_insertion_total,
     556           0 :           ((double)(push_insertion_total - prev_push_insertion_total) - (double)(gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_UPSERTED_PUSH ) ]) ) / (double)(push_insertion_total - prev_push_insertion_total) * 100.0,
     557           0 :           (double)(gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_STALE ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_STALE ) ]) / (double)(push_insertion_total - prev_push_insertion_total) * 100.0,
     558           0 :           (double)(gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_DUPLICATE ) ] - gossip_prev[ MIDX( COUNTER, GOSSIP, CRDS_RX_DROPPED_PUSH_DUPLICATE ) ]) / (double)(push_insertion_total - prev_push_insertion_total) * 100.0 );
     559             : 
     560           0 :   printf( " +------------------------+--------------+  +------------+--------------+\n" );
     561           0 :   printf( " | CRDS Type              | Count        |  | Ping Type  | Count        |\n" );
     562           0 :   printf( " +------------------------+--------------+  +------------+--------------+\n" );
     563           0 :   printf( " | Contact Info V1        | %s |"        "  | Unpinged   | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_CONTACT_INFO_V1 ) ] ), fmt_count( buf2, gossip_metrics[ MIDX( GAUGE, GOSSIP, PING_TRACKED_UNPINGED ) ] ) );
     564           0 :   printf( " | Contact Info V2        | %s |"        "  | Invalid    | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_CONTACT_INFO_V2 ) ] ), fmt_count( buf2, gossip_metrics[ MIDX( GAUGE, GOSSIP, PING_TRACKED_INVALID ) ] ) );
     565           0 :   printf( " | Vote                   | %s |"        "  | Valid      | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_VOTE ) ] ),            fmt_count( buf2, gossip_metrics[ MIDX( GAUGE, GOSSIP, PING_TRACKED_VALID ) ] ) );
     566           0 :   printf( " | Lowest Slot            | %s |"        "  | Refreshing | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_LOWEST_SLOT ) ] ),     fmt_count( buf2, gossip_metrics[ MIDX( GAUGE, GOSSIP, PING_TRACKED_VALID_REFRESHING ) ] ) );
     567           0 :   printf( " | Snapshot Hashes        | %s |"        "  +------------+--------------+\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_SNAPSHOT_HASHES ) ] ) );
     568           0 :   printf( " | Accounts Hashes        | %s |"        "  +------------------------+--------------+\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_ACCOUNTS_HASHES ) ] ) );
     569           0 :   printf( " | Inc Snapshot Hashes    | %s |"        "  | Contact Info Events    | Count        |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_INCREMENTAL_SNAPSHOT_HASHES ) ] ) );
     570           0 :   printf( " | Epoch Slots            | %s |"        "  +------------------------+--------------+\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_EPOCH_SLOTS ) ] ) );
     571           0 :   printf( " | Version V1             | %s |"        "  | Unrecognized Socket    | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_VERSION_V1 ) ] ), fmt_count( buf2, 0UL ) );
     572           0 :   printf( " | Version V2             | %s |"        "  | IPv6 Address           | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_VERSION_V2 ) ] ), fmt_count( buf2, 0UL ) );
     573           0 :   printf( " | Node Instance          | %s |"        "  +------------------------+--------------+\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_NODE_INSTANCE ) ] ) );
     574           0 :   printf( " | Duplicate Shred        | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_DUPLICATE_SHRED ) ] ) );
     575           0 :   printf( " | Restart Last Voted     | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_RESTART_LAST_VOTED_FORK_SLOTS ) ] ) );
     576           0 :   printf( " | Restart Heaviest       | %s |\n", fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_RESTART_HEAVIEST_FORK ) ] ) );
     577           0 :   printf( " +------------------------+--------------+\n\n" );
     578             : 
     579           0 : #define DIFFX(METRIC) gossip_metrics[ MIDX( COUNTER, TILE, METRIC ) ] - gossip_prev[ MIDX( COUNTER, TILE, METRIC ) ]
     580           0 :   ulong hkeep_ticks = DIFFX(REGIME_DURATION_NANOS_CAUGHT_UP_HOUSEKEEPING) + DIFFX(REGIME_DURATION_NANOS_PROCESSING_HOUSEKEEPING) + DIFFX(REGIME_DURATION_NANOS_BACKPRESSURE_HOUSEKEEPING);
     581           0 :   ulong busy_ticks = DIFFX(REGIME_DURATION_NANOS_PROCESSING_PREFRAG) + DIFFX(REGIME_DURATION_NANOS_PROCESSING_POSTFRAG ) + DIFFX(REGIME_DURATION_NANOS_CAUGHT_UP_PREFRAG);
     582           0 :   ulong caught_up_ticks = DIFFX(REGIME_DURATION_NANOS_CAUGHT_UP_POSTFRAG);
     583           0 :   ulong backpressure_ticks = DIFFX(REGIME_DURATION_NANOS_BACKPRESSURE_PREFRAG);
     584           0 :   ulong total_ticks = hkeep_ticks + busy_ticks + caught_up_ticks + backpressure_ticks;
     585             : 
     586           0 :   printf( " Gossip Hkeep: %.1f %%  Busy: %.1f %%  Idle: %.1f %%  Backp: %0.1f %%\n",
     587           0 :           (double)hkeep_ticks/(double)total_ticks*100.0,
     588           0 :           (double)busy_ticks/(double)total_ticks*100.0,
     589           0 :           (double)caught_up_ticks/(double)total_ticks*100.0,
     590           0 :           (double)backpressure_ticks/(double)total_ticks*100.0 );
     591           0 : #undef DIFFX
     592             : 
     593             :   /* Aggregate gossvf performance metrics across all tiles */
     594           0 :   ulong gossvf_hkeep_ticks = 0UL, gossvf_busy_ticks = 0UL, gossvf_caught_up_ticks = 0UL, gossvf_backpressure_ticks = 0UL;
     595             : 
     596           0 :   for( ulong i = 0UL; i < ctx->gossvf.tile_count; i++ ) {
     597           0 :     volatile ulong * metrics  = ctx->gossvf.metrics[i];
     598           0 :     ulong * prev_metrics      = ctx->gossvf.prev_metrics[i];
     599             : 
     600           0 : #define DIFFX(METRIC) metrics[ MIDX( COUNTER, TILE, METRIC ) ] - prev_metrics[ MIDX( COUNTER, TILE, METRIC ) ]
     601           0 :     gossvf_hkeep_ticks        += DIFFX(REGIME_DURATION_NANOS_CAUGHT_UP_HOUSEKEEPING) + DIFFX(REGIME_DURATION_NANOS_PROCESSING_HOUSEKEEPING) + DIFFX(REGIME_DURATION_NANOS_BACKPRESSURE_HOUSEKEEPING);
     602           0 :     gossvf_busy_ticks         += DIFFX(REGIME_DURATION_NANOS_PROCESSING_PREFRAG) + DIFFX(REGIME_DURATION_NANOS_PROCESSING_POSTFRAG );
     603           0 :     gossvf_caught_up_ticks    += DIFFX(REGIME_DURATION_NANOS_CAUGHT_UP_PREFRAG) + DIFFX(REGIME_DURATION_NANOS_CAUGHT_UP_POSTFRAG);
     604           0 :     gossvf_backpressure_ticks += DIFFX(REGIME_DURATION_NANOS_BACKPRESSURE_PREFRAG);
     605           0 : #undef DIFFX
     606           0 :   }
     607             : 
     608           0 :   ulong gossvf_total_ticks = gossvf_hkeep_ticks + gossvf_busy_ticks + gossvf_caught_up_ticks + gossvf_backpressure_ticks;
     609             : 
     610           0 :   printf( " Gossvf Hkeep: %.1f %%  Busy: %.1f %%  Idle: %.1f %%  Backp: %0.1f %% (%lu tiles)\n\n",
     611           0 :           gossvf_total_ticks > 0UL ? (double)gossvf_hkeep_ticks/(double)gossvf_total_ticks*100.0 : 0.0,
     612           0 :           gossvf_total_ticks > 0UL ? (double)gossvf_busy_ticks/(double)gossvf_total_ticks*100.0 : 0.0,
     613           0 :           gossvf_total_ticks > 0UL ? (double)gossvf_caught_up_ticks/(double)gossvf_total_ticks*100.0 : 0.0,
     614           0 :           gossvf_total_ticks > 0UL ? (double)gossvf_backpressure_ticks/(double)gossvf_total_ticks*100.0 : 0.0,
     615           0 :           ctx->gossvf.tile_count );
     616             : 
     617           0 :   printf( " +--------------+--------------+--------------+--------------+--------------+--------------+\n" );
     618           0 :   printf( " |              | Entries      | Capacity     | Utilization  | Evicted      | Expired      |\n" );
     619           0 :   printf( " +--------------+--------------+--------------+--------------+--------------+--------------+\n" );
     620           0 :   printf( " | Table Size   | %s | %s | %s | %s | %s |\n",
     621           0 :     fmt_count( buf1, total_crds ),
     622           0 :     fmt_count( buf2, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_CAPACITY ) ] ),
     623           0 :     fmt_pct( buf3, (double)total_crds / (double)gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_CAPACITY ) ] ),
     624           0 :     fmt_count( buf4, gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_EVICTED ) ] ),
     625           0 :     fmt_count( buf5, gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_EXPIRED ) ] ) );
     626           0 :   printf( " | Contact Info | %s | %s | %s | %s |          n/a |\n",
     627           0 :     fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_CONTACT_INFO_V2 ) ] ),
     628           0 :     fmt_count( buf2, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_PEER_CAPACITY ) ] ),
     629           0 :     fmt_pct( buf3, (double)gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_OCCUPIED_CONTACT_INFO_V2 ) ] / (double)gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_PEER_CAPACITY ) ] ),
     630           0 :     fmt_count( buf4, gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_PEER_EVICTED ) ] ) );
     631           0 :   printf( " | Purged       | %s | %s | %s | %s | %s |\n",
     632           0 :     fmt_count( buf1, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_PURGED_OCCUPIED ) ] ),
     633           0 :     fmt_count( buf2, gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_PURGED_CAPACITY ) ] ),
     634           0 :     fmt_pct( buf3, (double)gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_PURGED_OCCUPIED ) ] / (double)gossip_metrics[ MIDX( GAUGE, GOSSIP, CRDS_PURGED_CAPACITY ) ] ),
     635           0 :     fmt_count( buf4, gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_PURGED_EVICTED ) ] ),
     636           0 :     fmt_count( buf5, gossip_metrics[ MIDX( COUNTER, GOSSIP, CRDS_PURGED_EXPIRED ) ] ) );
     637           0 :   printf( " +--------------+--------------+--------------+--------------+--------------+--------------+\n\n" );
     638             : 
     639           0 :   rx_deltas_t deltas = rx_deltas_aggregated( gossip_metrics, gossip_prev, &ctx->gossvf );
     640             : 
     641           0 :   printf( " +--------------------------------------------------------------------------+--------------+\n" );
     642           0 :   printf( " |              | RX count     | RX drops     | TX count     | RX bits      | TX bits      |\n" );
     643           0 :   printf( " +--------------+--------------+--------------+--------------+--------------+--------------+\n" );
     644           0 :   printf( " | Pull Request | %s | %s | %s | %s | %s |\n", fmt_count( buf1, deltas.pull_request_rx ), fmt_count( buf2, deltas.pull_request_rx_drop ),  fmt_count( buf3, deltas.pull_request_tx ),  fmt_bytes( buf4, deltas.pull_request_rx_bytes ),  fmt_bytes( buf5, deltas.pull_request_tx_bytes ) );
     645           0 :   printf( " | Pull Response| %s | %s | %s | %s | %s |\n", fmt_count( buf1, deltas.pull_response_rx), fmt_count( buf2, deltas.pull_response_rx_drop ), fmt_count( buf3, deltas.pull_response_tx ), fmt_bytes( buf4, deltas.pull_response_rx_bytes ), fmt_bytes( buf5, deltas.pull_response_tx_bytes ) );
     646           0 :   printf( " | Push         | %s | %s | %s | %s | %s |\n", fmt_count( buf1, deltas.push_rx ),         fmt_count( buf2, deltas.push_rx_drop ),          fmt_count( buf3, deltas.push_tx ),          fmt_bytes( buf4, deltas.push_rx_bytes ),          fmt_bytes( buf5, deltas.push_tx_bytes ) );
     647           0 :   printf( " | Prune        | %s | %s | %s | %s | %s |\n", fmt_count( buf1, deltas.prune_rx ),        fmt_count( buf2, deltas.prune_rx_drop ),         fmt_count( buf3, deltas.prune_tx ),         fmt_bytes( buf4, deltas.prune_rx_bytes ),         fmt_bytes( buf5, deltas.prune_tx_bytes ) );
     648           0 :   printf( " | Ping         | %s | %s | %s | %s | %s |\n", fmt_count( buf1, deltas.ping_rx ),         fmt_count( buf2, deltas.ping_rx_drop ),          fmt_count( buf3, deltas.ping_tx ),          fmt_bytes( buf4, deltas.ping_rx_bytes ),          fmt_bytes( buf5, deltas.ping_tx_bytes ) );
     649           0 :   printf( " | Pong         | %s | %s | %s | %s | %s |\n", fmt_count( buf1, deltas.pong_rx ),         fmt_count( buf2, deltas.pong_rx_drop ),          fmt_count( buf3, deltas.pong_tx ),          fmt_bytes( buf4, deltas.pong_rx_bytes ),          fmt_bytes( buf5, deltas.pong_tx_bytes ) );
     650           0 :   printf( " +--------------+--------------+--------------+--------------+--------------+--------------+\n\n" );
     651             : 
     652             :   /* Snapshot current metrics as previous for next render */
     653           0 :   for( ulong i=0UL; i<FD_METRICS_TOTAL_SZ/sizeof(ulong); i++ ) gossip_prev[ i ] = gossip_metrics[ i ];
     654             : 
     655           0 :   for( ulong tile_idx = 0UL; tile_idx < ctx->gossvf.tile_count; tile_idx++ ) {
     656           0 :     for( ulong i=0UL; i<FD_METRICS_TOTAL_SZ/sizeof(ulong); i++ ) {
     657           0 :       ctx->gossvf.prev_metrics[tile_idx][ i ] = ctx->gossvf.metrics[tile_idx][ i ];
     658           0 :     }
     659           0 :   }
     660           0 : }

Generated by: LCOV version 1.14