LCOV - code coverage report
Current view: top level - app/shared/commands - mem.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 94 0.0 %
Date: 2026-03-19 18:19:27 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #include "../fd_config.h"
       2             : #include "../fd_action.h"
       3             : 
       4             : #include <unistd.h>
       5             : 
       6             : struct mem_obj_entry {
       7             :   ulong footprint;
       8             :   char  wksp[ 13 ];
       9             :   char  obj[ 13 ];
      10             : };
      11             : typedef struct mem_obj_entry mem_obj_entry_t;
      12             : 
      13             : #define SORT_NAME        sort_obj_by_footprint
      14           0 : #define SORT_KEY_T       mem_obj_entry_t
      15           0 : #define SORT_BEFORE(a,b) ((a).footprint>(b).footprint)
      16             : #include "../../../util/tmpl/fd_sort.c"
      17             : 
      18             : extern action_t * ACTIONS[];
      19             : 
      20             : static void
      21             : mem_cmd_args( int *    pargc,
      22             :               char *** pargv,
      23           0 :               args_t * args ) {
      24           0 :   char const * topo_name = fd_env_strip_cmdline_cstr( pargc, pargv, "--topo", NULL, "" );
      25           0 :   args->mem.sort = fd_env_strip_cmdline_contains( pargc, pargv, "--sort" );
      26             : 
      27           0 :   ulong topo_name_len = strlen( topo_name );
      28           0 :   if( FD_UNLIKELY( topo_name_len > sizeof(args->mem.topo)-1 ) ) FD_LOG_ERR(( "Unknown --topo %s", topo_name ));
      29           0 :   fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( args->mem.topo ), topo_name, topo_name_len ) );
      30           0 : }
      31             : 
      32             : static void
      33             : reconstruct_topo( config_t *   config,
      34           0 :                   char const * topo_name ) {
      35           0 :   if( !topo_name[0] ) return; /* keep default action topo */
      36             : 
      37           0 :   action_t const * selected = NULL;
      38           0 :   for( action_t ** a=ACTIONS; *a; a++ ) {
      39           0 :     action_t const * action = *a;
      40           0 :     if( 0==strcmp( action->name, topo_name ) ) {
      41           0 :       selected = action;
      42           0 :       break;
      43           0 :     }
      44           0 :   }
      45             : 
      46           0 :   if( !selected       ) FD_LOG_ERR(( "Unknown --topo %s", topo_name ));
      47           0 :   if( !selected->topo ) FD_LOG_ERR(( "Cannot recover topology for --topo %s", topo_name ));
      48             : 
      49           0 :   selected->topo( config );
      50           0 : }
      51             : 
      52             : void
      53             : mem_cmd_fn( args_t *   args,
      54           0 :             config_t * config ) {
      55           0 :   reconstruct_topo( config, args->mem.topo );
      56             : 
      57           0 :   if( FD_UNLIKELY( args->mem.sort ) ) {
      58           0 :     fd_topo_t * topo = &config->topo;
      59             : 
      60             :     /* Max entries: objects + per-wksp loose + per-wksp overhead + extra pages */
      61           0 :     mem_obj_entry_t entries[ FD_TOPO_MAX_OBJS + 2UL*FD_TOPO_MAX_WKSPS + 2UL ];
      62           0 :     ulong cnt = 0UL;
      63             : 
      64             :     /* Real topology objects */
      65           0 :     for( ulong i=0UL; i<topo->obj_cnt; i++ ) {
      66           0 :       fd_topo_obj_t * obj = &topo->objs[ i ];
      67           0 :       entries[ cnt ].footprint = obj->footprint;
      68           0 :       fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].wksp ), topo->workspaces[ obj->wksp_id ].name, sizeof(entries[ cnt ].wksp)-1 ) );
      69           0 :       fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].obj ), obj->name, sizeof(entries[ cnt ].obj)-1 ) );
      70           0 :       cnt++;
      71           0 :     }
      72             : 
      73             :     /* Per-workspace loose memory and page rounding overhead */
      74           0 :     for( ulong i=0UL; i<topo->wksp_cnt; i++ ) {
      75           0 :       fd_topo_wksp_t * wksp = &topo->workspaces[ i ];
      76           0 :       ulong loose = wksp->total_footprint - wksp->known_footprint;
      77           0 :       if( loose ) {
      78           0 :         entries[ cnt ].footprint = loose;
      79           0 :         fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].wksp ), wksp->name, sizeof(entries[ cnt ].wksp)-1 ) );
      80           0 :         fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].obj ), "loose", 5 ) );
      81           0 :         cnt++;
      82           0 :       }
      83           0 :       ulong pages_sz = wksp->page_cnt * wksp->page_sz;
      84           0 :       ulong overhead = pages_sz - wksp->total_footprint;
      85           0 :       if( overhead ) {
      86           0 :         entries[ cnt ].footprint = overhead;
      87           0 :         fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].wksp ), wksp->name, sizeof(entries[ cnt ].wksp)-1 ) );
      88           0 :         fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].obj ), "padding", 7 ) );
      89           0 :         cnt++;
      90           0 :       }
      91           0 :     }
      92             : 
      93             :     /* Tile stacks: each tile maps (FD_TILE_PRIVATE_STACK_SZ/FD_SHMEM_HUGE_PAGE_SZ)+2
      94             :        huge pages for its stack (see fd_topo_tile_extra_huge_pages). */
      95           0 :     ulong stack_huge_pages = topo->tile_cnt * ((FD_TILE_PRIVATE_STACK_SZ/FD_SHMEM_HUGE_PAGE_SZ)+2UL);
      96           0 :     if( stack_huge_pages ) {
      97           0 :       entries[ cnt ].footprint = stack_huge_pages * FD_SHMEM_HUGE_PAGE_SZ;
      98           0 :       fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].wksp ), "", 0 ) );
      99           0 :       fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].obj ), "tile_stacks", 11 ) );
     100           0 :       cnt++;
     101           0 :     }
     102             : 
     103             :     /* Extra normal pages (private keys, XSK rings, log locks, etc.) */
     104           0 :     ulong extra_normal = fd_topo_normal_page_cnt( topo );
     105           0 :     if( extra_normal ) {
     106           0 :       entries[ cnt ].footprint = extra_normal * FD_SHMEM_NORMAL_PAGE_SZ;
     107           0 :       fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].wksp ), "", 0 ) );
     108           0 :       fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( entries[ cnt ].obj ), "normal_pages", 12 ) );
     109           0 :       cnt++;
     110           0 :     }
     111             : 
     112           0 :     sort_obj_by_footprint_inplace( entries, cnt );
     113             : 
     114           0 :     ulong total = 0UL;
     115           0 :     for( ulong i=0UL; i<cnt; i++ ) total += entries[ i ].footprint;
     116             : 
     117           0 :     FD_LOG_STDOUT(( "%7s  %6s  %15s  %12s  %12s\n", "SIZE", "PCT", "BYTES", "WORKSPACE", "OBJECT" ));
     118           0 :     FD_LOG_STDOUT(( "-------  ------  ---------------  ------------  ------------\n" ));
     119           0 :     for( ulong i=0UL; i<cnt; i++ ) {
     120           0 :       ulong sz = entries[ i ].footprint;
     121           0 :       char sz_str[ 24 ];
     122           0 :       if( FD_LIKELY( sz >= (1UL<<30) ) )      FD_TEST( fd_cstr_printf_check( sz_str, 24, NULL, "%lu GiB", sz / (1UL<<30) ) );
     123           0 :       else if( FD_LIKELY( sz >= (1UL<<20) ) ) FD_TEST( fd_cstr_printf_check( sz_str, 24, NULL, "%lu MiB", sz / (1UL<<20) ) );
     124           0 :       else if( FD_LIKELY( sz >= (1UL<<10) ) ) FD_TEST( fd_cstr_printf_check( sz_str, 24, NULL, "%lu KiB", sz / (1UL<<10) ) );
     125           0 :       else                                    FD_TEST( fd_cstr_printf_check( sz_str, 24, NULL, "%lu B",   sz             ) );
     126           0 :       double pct = total ? 100.0 * (double)sz / (double)total : 0.0;
     127           0 :       FD_LOG_STDOUT(( "%7s  %5.1f%%  %15lu  %12s  %12s\n", sz_str, pct, sz, entries[ i ].wksp, entries[ i ].obj ));
     128           0 :     }
     129             : 
     130           0 :     char total_str[ 24 ];
     131           0 :     if( FD_LIKELY( total >= (1UL<<30) ) )      FD_TEST( fd_cstr_printf_check( total_str, 24, NULL, "%lu GiB", total / (1UL<<30) ) );
     132           0 :     else if( FD_LIKELY( total >= (1UL<<20) ) ) FD_TEST( fd_cstr_printf_check( total_str, 24, NULL, "%lu MiB", total / (1UL<<20) ) );
     133           0 :     else if( FD_LIKELY( total >= (1UL<<10) ) ) FD_TEST( fd_cstr_printf_check( total_str, 24, NULL, "%lu KiB", total / (1UL<<10) ) );
     134           0 :     else                                       FD_TEST( fd_cstr_printf_check( total_str, 24, NULL, "%lu B",   total             ) );
     135           0 :     FD_LOG_STDOUT(( "-------  ------  ---------------  ------------  ------------\n" ));
     136           0 :     FD_LOG_STDOUT(( "%7s  %5.1f%%  %15lu  %12s\n", total_str, 100.0, total, "TOTAL" ));
     137           0 :     return;
     138           0 :   }
     139             : 
     140           0 :   fd_topo_print_log( 1, &config->topo );
     141           0 : }
     142             : 
     143             : action_t fd_action_mem = {
     144             :   .name           = "mem",
     145             :   .args           = mem_cmd_args,
     146             :   .fn             = mem_cmd_fn,
     147             :   .require_config = 1,
     148             :   .perm           = NULL,
     149             :   .description    = "Print workspace memory and tile topology information",
     150             : };

Generated by: LCOV version 1.14