1515#include "../../flamenco/runtime/fd_bank.h"
1616#include "../../flamenco/runtime/fd_exec_stack.h"
1717
18+ struct fd_bank_out {
19+ ulong idx ;
20+ fd_wksp_t * mem ;
21+ ulong chunk0 ;
22+ ulong wmark ;
23+ ulong chunk ;
24+ };
25+
26+ typedef struct fd_bank_out fd_bank_out_t ;
27+
1828typedef struct {
1929 ulong kind_id ;
2030
@@ -32,16 +42,10 @@ typedef struct {
3242 ulong pack_in_chunk0 ;
3343 ulong pack_in_wmark ;
3444
35- fd_wksp_t * out_mem ;
36- ulong out_chunk0 ;
37- ulong out_wmark ;
38- ulong out_chunk ;
45+ fd_bank_out_t out_poh [1 ];
46+ fd_bank_out_t out_pack [1 ];
3947
40- fd_wksp_t * rebate_mem ;
41- ulong rebate_chunk0 ;
42- ulong rebate_wmark ;
43- ulong rebate_chunk ;
44- ulong rebates_for_slot ;
48+ ulong rebates_for_slot ;
4549 fd_pack_rebate_sum_t rebater [ 1 ];
4650
4751 fd_banks_t * banks ;
@@ -112,9 +116,8 @@ during_frag( fd_bank_ctx_t * ctx,
112116 ulong chunk ,
113117 ulong sz ,
114118 ulong ctl FD_PARAM_UNUSED ) {
115-
116119 uchar * src = (uchar * )fd_chunk_to_laddr ( ctx -> pack_in_mem , chunk );
117- uchar * dst = (uchar * )fd_chunk_to_laddr ( ctx -> out_mem , ctx -> out_chunk );
120+ uchar * dst = (uchar * )fd_chunk_to_laddr ( ctx -> out_poh -> mem , ctx -> out_poh -> chunk );
118121
119122 if ( FD_UNLIKELY ( chunk < ctx -> pack_in_chunk0 || chunk > ctx -> pack_in_wmark || sz > USHORT_MAX ) )
120123 FD_LOG_ERR (( "chunk %lu %lu corrupt, not in range [%lu,%lu]" , chunk , sz , ctx -> pack_in_chunk0 , ctx -> pack_in_wmark ));
@@ -155,7 +158,7 @@ handle_microblock( fd_bank_ctx_t * ctx,
155158 ulong sz ,
156159 ulong begin_tspub ,
157160 fd_stem_context_t * stem ) {
158- uchar * dst = (uchar * )fd_chunk_to_laddr ( ctx -> out_mem , ctx -> out_chunk );
161+ uchar * dst = (uchar * )fd_chunk_to_laddr ( ctx -> out_poh -> mem , ctx -> out_poh -> chunk );
159162
160163 ulong slot = fd_disco_poh_sig_slot ( sig );
161164 ulong txn_cnt = (sz - sizeof (fd_microblock_bank_trailer_t ))/sizeof (fd_txn_p_t );
@@ -329,8 +332,8 @@ handle_microblock( fd_bank_ctx_t * ctx,
329332 transactions so the PoH tile can keep an accurate count of microblocks
330333 it has seen. */
331334 ulong new_sz = txn_cnt * sizeof (fd_txn_p_t ) + sizeof (fd_microblock_trailer_t );
332- fd_stem_publish ( stem , 0UL , bank_sig , ctx -> out_chunk , new_sz , 0UL , (ulong )fd_frag_meta_ts_comp ( microblock_start_ticks ), (ulong )fd_frag_meta_ts_comp ( tickcount ) );
333- ctx -> out_chunk = fd_dcache_compact_next ( ctx -> out_chunk , new_sz , ctx -> out_chunk0 , ctx -> out_wmark );
335+ fd_stem_publish ( stem , ctx -> out_poh -> idx , bank_sig , ctx -> out_poh -> chunk , new_sz , 0UL , (ulong )fd_frag_meta_ts_comp ( microblock_start_ticks ), (ulong )fd_frag_meta_ts_comp ( tickcount ) );
336+ ctx -> out_poh -> chunk = fd_dcache_compact_next ( ctx -> out_poh -> chunk , new_sz , ctx -> out_poh -> chunk0 , ctx -> out_poh -> wmark );
334337}
335338
336339static inline void
@@ -341,7 +344,7 @@ handle_bundle( fd_bank_ctx_t * ctx,
341344 ulong begin_tspub ,
342345 fd_stem_context_t * stem ) {
343346
344- fd_txn_p_t * txns = (fd_txn_p_t * )fd_chunk_to_laddr ( ctx -> out_mem , ctx -> out_chunk );
347+ fd_txn_p_t * txns = (fd_txn_p_t * )fd_chunk_to_laddr ( ctx -> out_poh -> mem , ctx -> out_poh -> chunk );
345348
346349 ulong slot = fd_disco_poh_sig_slot ( sig );
347350 ulong txn_cnt = (sz - sizeof (fd_microblock_bank_trailer_t ))/sizeof (fd_txn_p_t );
@@ -447,7 +450,7 @@ handle_bundle( fd_bank_ctx_t * ctx,
447450 }
448451
449452 for ( ulong i = 0UL ; i < txn_cnt ; i ++ ) {
450- uchar * dst = (uchar * )fd_chunk_to_laddr ( ctx -> out_mem , ctx -> out_chunk );
453+ uchar * dst = (uchar * )fd_chunk_to_laddr ( ctx -> out_poh -> mem , ctx -> out_poh -> chunk );
451454 fd_memcpy ( dst , bundle_txn_temp + i , sizeof (fd_txn_p_t ) );
452455
453456 fd_microblock_trailer_t * trailer = (fd_microblock_trailer_t * )( dst + sizeof (fd_txn_p_t ) );
@@ -472,8 +475,8 @@ handle_bundle( fd_bank_ctx_t * ctx,
472475 trailer -> txn_preload_end_pct = (uchar )(((double )(tx_preload_end_ticks - microblock_start_ticks ) * (double )UCHAR_MAX ) / (double )microblock_duration_ticks );
473476
474477 ulong new_sz = sizeof (fd_txn_p_t ) + sizeof (fd_microblock_trailer_t );
475- fd_stem_publish ( stem , 0UL , bank_sig , ctx -> out_chunk , new_sz , 0UL , (ulong )fd_frag_meta_ts_comp ( microblock_start_ticks ), (ulong )fd_frag_meta_ts_comp ( tickcount ) );
476- ctx -> out_chunk = fd_dcache_compact_next ( ctx -> out_chunk , new_sz , ctx -> out_chunk0 , ctx -> out_wmark );
478+ fd_stem_publish ( stem , ctx -> out_poh -> idx , bank_sig , ctx -> out_poh -> chunk , new_sz , 0UL , (ulong )fd_frag_meta_ts_comp ( microblock_start_ticks ), (ulong )fd_frag_meta_ts_comp ( tickcount ) );
479+ ctx -> out_poh -> chunk = fd_dcache_compact_next ( ctx -> out_poh -> chunk , new_sz , ctx -> out_poh -> chunk0 , ctx -> out_poh -> wmark );
477480 }
478481
479482 metrics_write ( ctx );
@@ -503,12 +506,43 @@ after_frag( fd_bank_ctx_t * ctx,
503506
504507 /* TODO: Use fancier logic to coalesce rebates e.g. and move this to
505508 after_credit */
506- ulong written_sz = 0UL ;
507- while ( 0UL != (written_sz = fd_pack_rebate_sum_report ( ctx -> rebater , fd_chunk_to_laddr ( ctx -> rebate_mem , ctx -> rebate_chunk ) )) ) {
508- ulong tspub = (ulong )fd_frag_meta_ts_comp ( fd_tickcount () );
509- fd_stem_publish ( stem , 1UL , slot , ctx -> rebate_chunk , written_sz , 0UL , tsorig , tspub );
510- ctx -> rebate_chunk = fd_dcache_compact_next ( ctx -> rebate_chunk , written_sz , ctx -> rebate_chunk0 , ctx -> rebate_wmark );
509+ if ( FD_LIKELY ( ctx -> out_pack -> idx != ULONG_MAX ) ) {
510+ ulong written_sz = 0UL ;
511+ while ( 0UL != (written_sz = fd_pack_rebate_sum_report ( ctx -> rebater , fd_chunk_to_laddr ( ctx -> out_pack -> mem , ctx -> out_pack -> chunk ) )) ) {
512+ ulong tspub = (ulong )fd_frag_meta_ts_comp ( fd_tickcount () );
513+ fd_stem_publish ( stem , ctx -> out_pack -> idx , slot , ctx -> out_pack -> chunk , written_sz , 0UL , tsorig , tspub );
514+ ctx -> out_pack -> chunk = fd_dcache_compact_next ( ctx -> out_pack -> chunk , written_sz , ctx -> out_pack -> chunk0 , ctx -> out_pack -> wmark );
515+ }
516+ } else {
517+ uchar _temp [ USHORT_MAX ] __attribute__((aligned (alignof(fd_pack_rebate_t ))));
518+ ulong written_sz = 0UL ;
519+ while ( 0UL != (written_sz = fd_pack_rebate_sum_report ( ctx -> rebater , fd_type_pun ( _temp ) ) ) ) {
520+ /* Discard rebates if no output */
521+ }
522+ }
523+ }
524+
525+ static inline fd_bank_out_t
526+ out1 ( fd_topo_t const * topo ,
527+ fd_topo_tile_t const * tile ,
528+ char const * name ) {
529+ ulong idx = ULONG_MAX ;
530+
531+ for ( ulong i = 0UL ; i < tile -> out_cnt ; i ++ ) {
532+ fd_topo_link_t const * link = & topo -> links [ tile -> out_link_id [ i ] ];
533+ if ( !strcmp ( link -> name , name ) ) {
534+ if ( FD_UNLIKELY ( idx != ULONG_MAX ) ) FD_LOG_ERR (( "tile %s:%lu had multiple output links named %s but expected one" , tile -> name , tile -> kind_id , name ));
535+ idx = i ;
536+ }
511537 }
538+
539+ if ( FD_UNLIKELY ( idx == ULONG_MAX ) ) return (fd_bank_out_t ){ .idx = ULONG_MAX , .mem = NULL , .chunk0 = 0 , .wmark = 0 , .chunk = 0 };
540+
541+ void * mem = topo -> workspaces [ topo -> objs [ topo -> links [ tile -> out_link_id [ idx ] ].dcache_obj_id ].wksp_id ].wksp ;
542+ ulong chunk0 = fd_dcache_compact_chunk0 ( mem , topo -> links [ tile -> out_link_id [ idx ] ].dcache );
543+ ulong wmark = fd_dcache_compact_wmark ( mem , topo -> links [ tile -> out_link_id [ idx ] ].dcache , topo -> links [ tile -> out_link_id [ idx ] ].mtu );
544+
545+ return (fd_bank_out_t ){ .idx = idx , .mem = mem , .chunk0 = chunk0 , .wmark = wmark , .chunk = chunk0 };
512546}
513547
514548static void
@@ -580,16 +614,8 @@ unprivileged_init( fd_topo_t * topo,
580614 ctx -> pack_in_chunk0 = fd_dcache_compact_chunk0 ( ctx -> pack_in_mem , topo -> links [ tile -> in_link_id [ 0UL ] ].dcache );
581615 ctx -> pack_in_wmark = fd_dcache_compact_wmark ( ctx -> pack_in_mem , topo -> links [ tile -> in_link_id [ 0UL ] ].dcache , topo -> links [ tile -> in_link_id [ 0UL ] ].mtu );
582616
583- ctx -> out_mem = topo -> workspaces [ topo -> objs [ topo -> links [ tile -> out_link_id [ 0 ] ].dcache_obj_id ].wksp_id ].wksp ;
584- ctx -> out_chunk0 = fd_dcache_compact_chunk0 ( ctx -> out_mem , topo -> links [ tile -> out_link_id [ 0 ] ].dcache );
585- ctx -> out_wmark = fd_dcache_compact_wmark ( ctx -> out_mem , topo -> links [ tile -> out_link_id [ 0 ] ].dcache , topo -> links [ tile -> out_link_id [ 0 ] ].mtu );
586- ctx -> out_chunk = ctx -> out_chunk0 ;
587-
588-
589- ctx -> rebate_mem = topo -> workspaces [ topo -> objs [ topo -> links [ tile -> out_link_id [ 1 ] ].dcache_obj_id ].wksp_id ].wksp ;
590- ctx -> rebate_chunk0 = fd_dcache_compact_chunk0 ( ctx -> rebate_mem , topo -> links [ tile -> out_link_id [ 1 ] ].dcache );
591- ctx -> rebate_wmark = fd_dcache_compact_wmark ( ctx -> rebate_mem , topo -> links [ tile -> out_link_id [ 1 ] ].dcache , topo -> links [ tile -> out_link_id [ 1 ] ].mtu );
592- ctx -> rebate_chunk = ctx -> rebate_chunk0 ;
617+ * ctx -> out_poh = out1 ( topo , tile , "bank_poh" ); FD_TEST ( ctx -> out_poh -> idx != ULONG_MAX );
618+ * ctx -> out_pack = out1 ( topo , tile , "bank_pack" );
593619}
594620
595621static ulong
0 commit comments