LCOV - code coverage report
Current view: top level - disco/events - fd_event_report.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 47 0.0 %
Date: 2026-11-11 12:40:43 Functions: 0 168 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_events_fd_event_report_h
       2             : #define HEADER_fd_src_disco_events_fd_event_report_h
       3             : 
       4             : /* fd_event_report.h provides a thread-local, fire-and-forget path for a
       5             :    tile to report a telemetry event to the event tile, mirroring how the
       6             :    metrics thread-local (fd_metrics_tl / FD_MCNT_*) works.
       7             : 
       8             :    A tile opts in by setting fd_topo_run_tile_t.max_event_sz; the topology
       9             :    then auto-wires a dedicated unreliable link from the tile to the event
      10             :    tile (see topology construction).  At tile boot, fd_event_register()
      11             :    sets up the thread-local reporter from that link.  Generated code emits
      12             :    one fd_event_report_<name>( msg ) macro per event schema (see
      13             :    generated/fd_event_gen.h) which forwards to fd_event_report_().
      14             : 
      15             :    The link is written directly via fd_mcache_publish (outside fd_stem); it
      16             :    is unreliable, so events are dropped if the event tile falls behind.
      17             :    When a tile has no event link (telemetry off / max_event_sz==0),
      18             :    fd_event_tl is NULL and reporting is a no-op. */
      19             : 
      20             : #include "../topo/fd_topo.h"
      21             : #include "../sleep/fd_sleep.h"
      22             : #include "../../tango/mcache/fd_mcache.h"
      23             : #include "../../tango/dcache/fd_dcache.h"
      24             : 
      25             : struct fd_event_reporter {
      26             :   fd_frag_meta_t * mcache;  /* mcache of the event link (joined) */
      27             :   ulong            depth;   /* mcache depth */
      28             :   ulong            seq;     /* next sequence number to publish */
      29             :   ulong *          seq_store; /* mcache header seq */
      30             : 
      31             :   fd_wksp_t *      mem;     /* workspace containing the dcache (chunk base) */
      32             :   ulong            chunk;   /* current write chunk */
      33             :   ulong            chunk0;  /* first chunk */
      34             :   ulong            wmark;   /* wrap watermark */
      35             :   ulong            mtu;     /* link mtu (== max_event_sz) */
      36             : 
      37             :   fd_sleep_t *     sleep;
      38             :   ulong            link_id;
      39             :   fd_sleep_wake_t  wake[ FD_SLEEP_BITS_CNT ];
      40             :   ulong            wake_cnt;
      41             : };
      42             : 
      43             : typedef struct fd_event_reporter fd_event_reporter_t;
      44             : 
      45             : /* The thread-local reporter for the currently running tile, or NULL if the
      46             :    tile has no event link. */
      47             : 
      48             : extern FD_TL fd_event_reporter_t * fd_event_tl;
      49             : 
      50             : FD_PROTOTYPES_BEGIN
      51             : 
      52             : /* fd_event_register sets up fd_event_tl for the calling tile.  If the tile
      53             :    has an event link (tile->event_link_id != ULONG_MAX) it joins the link's
      54             :    mcache/dcache; otherwise fd_event_tl is left NULL and reporting is a
      55             :    no-op.  Must be called once, after the tile's tango objects are joined
      56             :    (i.e. after fd_topo_fill_tile), before the run loop. */
      57             : 
      58             : void
      59             : fd_event_register( fd_topo_t const *      topo,
      60             :                    fd_topo_tile_t const * tile );
      61             : 
      62             : /* fd_event_reporter_join sets up r to publish on topo link link_id,
      63             :    whose mcache/dcache the calling tile has joined.  Returns r. */
      64             : 
      65             : fd_event_reporter_t *
      66             : fd_event_reporter_join( fd_event_reporter_t * r,
      67             :                         fd_topo_t const *     topo,
      68             :                         ulong                 link_id );
      69             : 
      70           0 : #define FD_EVENT_SIG( type, sz ) ( ((ulong)(sz)<<8) | ((ulong)(type)&0xFFUL) )
      71           0 : #define FD_EVENT_SIG_TYPE( sig ) ( (ulong)(sig)&0xFFUL )
      72           0 : #define FD_EVENT_SIG_SZ( sig )   ( (ulong)(sig)>>8 )
      73             : 
      74             : struct fd_event_report_iov {
      75             :   void const * base;
      76             :   ulong        sz;
      77             : };
      78             : 
      79             : typedef struct fd_event_report_iov fd_event_report_iov_t;
      80             : 
      81             : /* fd_event_report_ publishes a single event of sz bytes (the serialized
      82             :    fd_event_<name>_t struct) to the event link.  type is the event schema
      83             :    id, carried with the byte size in the frag sig (see FD_EVENT_SIG) so the
      84             :    event tile can dispatch and size-validate; the frag sz field is too
      85             :    narrow for large events and is published as 0.  No-op when
      86             :    fd_event_tl is NULL.  The generated fd_event_report_<name>() helpers call
      87             :    this with the right type and size. */
      88             : 
      89             : static inline void
      90           0 : fd_event_report_ring_( fd_event_reporter_t * r ) {
      91           0 :   if( FD_LIKELY( !r->sleep ) ) return;
      92           0 :   __atomic_store_n( &r->sleep->seq_mirror[ r->link_id ], r->seq, __ATOMIC_RELEASE );
      93           0 :   fd_sleep_wake_check( r->sleep, r->wake, r->wake_cnt );
      94           0 : }
      95             : 
      96             : static inline void
      97             : fd_event_report_( ulong        type,
      98             :                   void const * event,
      99           0 :                   ulong        sz ) {
     100           0 :   fd_event_reporter_t * r = fd_event_tl;
     101           0 :   if( FD_UNLIKELY( !r ) ) return; /* no event link / telemetry off */
     102             : 
     103           0 :   FD_TEST( type<=0xFFUL );
     104           0 :   FD_TEST( sz<=r->mtu );
     105             : 
     106           0 :   ulong tspub = fd_frag_meta_ts_comp( fd_tickcount() );
     107             : 
     108           0 :   fd_memcpy( fd_chunk_to_laddr( r->mem, r->chunk ), event, sz );
     109           0 :   fd_mcache_publish( r->mcache, r->depth, r->seq, FD_EVENT_SIG( type, sz ), r->chunk, 0UL, 0UL, 0UL, tspub );
     110           0 :   r->seq   = fd_seq_inc( r->seq, 1UL );
     111           0 :   r->chunk = fd_dcache_compact_next( r->chunk, sz, r->chunk0, r->wmark );
     112           0 :   fd_mcache_seq_update( r->seq_store, r->seq );
     113           0 :   fd_event_report_ring_( r );
     114           0 : }
     115             : 
     116             : static inline void
     117             : fd_event_report_gather_( ulong                         type,
     118             :                          fd_event_report_iov_t const * iov,
     119           0 :                          ulong                         iov_cnt ) {
     120           0 :   fd_event_reporter_t * r = fd_event_tl;
     121           0 :   if( FD_UNLIKELY( !r ) ) return; /* no event link / telemetry off */
     122             : 
     123           0 :   FD_TEST( type<=0xFFUL );
     124           0 :   ulong sz = 0UL;
     125           0 :   for( ulong i=0UL; i<iov_cnt; i++ ) {
     126           0 :     FD_TEST( iov[ i ].sz<=r->mtu-sz );
     127           0 :     sz += iov[ i ].sz;
     128           0 :   }
     129             : 
     130           0 :   ulong tspub = fd_frag_meta_ts_comp( fd_tickcount() );
     131             : 
     132           0 :   uchar * dst = fd_chunk_to_laddr( r->mem, r->chunk );
     133           0 :   for( ulong i=0UL; i<iov_cnt; i++ ) {
     134           0 :     fd_memcpy( dst, iov[ i ].base, iov[ i ].sz );
     135           0 :     dst += iov[ i ].sz;
     136           0 :   }
     137           0 :   fd_mcache_publish( r->mcache, r->depth, r->seq, FD_EVENT_SIG( type, sz ), r->chunk, 0UL, 0UL, 0UL, tspub );
     138           0 :   r->seq   = fd_seq_inc( r->seq, 1UL );
     139           0 :   r->chunk = fd_dcache_compact_next( r->chunk, sz, r->chunk0, r->wmark );
     140           0 :   fd_mcache_seq_update( r->seq_store, r->seq );
     141           0 :   fd_event_report_ring_( r );
     142           0 : }
     143             : 
     144           0 : #define FD_EVENT_TYPE_METRICS_TRIGGER (255UL)
     145             : 
     146             : struct fd_event_metrics_trigger {
     147             :   uint  reason;
     148             :   ulong slot;
     149             :   ulong snapct_state;
     150             : };
     151             : 
     152             : typedef struct fd_event_metrics_trigger fd_event_metrics_trigger_t;
     153             : 
     154             : static inline void
     155             : fd_event_metrics_trigger( uint  reason,
     156             :                           ulong slot,
     157           0 :                           ulong snapct_state ) {
     158           0 :   fd_event_metrics_trigger_t t = { .reason = reason, .slot = slot, .snapct_state = snapct_state };
     159           0 :   fd_event_report_( FD_EVENT_TYPE_METRICS_TRIGGER, &t, sizeof(t) );
     160           0 : }
     161             : 
     162             : FD_PROTOTYPES_END
     163             : 
     164             : #endif /* HEADER_fd_src_disco_events_fd_event_report_h */

Generated by: LCOV version 1.14