LCOV - code coverage report
Current view: top level - disco - fd_clock_tile.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 15 39 38.5 %
Date: 2026-07-27 05:36:01 Functions: 4 175 2.3 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_fd_clock_tile_h
       2             : #define HEADER_fd_src_disco_fd_clock_tile_h
       3             : 
       4             : /* fd_clock_tile.h provides fd_clock convenience APIs for tiles */
       5             : 
       6             : #include "../tango/tempo/fd_tempo.h"
       7             : #include "../util/clock/fd_clock.h"
       8             : 
       9             : /* fd_clock_tile_t is a fast nanosecond clock source for Firedancer
      10             :    tiles (single-threaded usage). */
      11             : 
      12             : struct fd_clock_tile {
      13             :   fd_clock_shmem_t shmem[1];
      14             :   fd_clock_t       clock[1];
      15             :   fd_clock_epoch_t epoch[1];
      16             : };
      17             : 
      18             : typedef struct fd_clock_tile fd_clock_tile_t;
      19             : 
      20             : FD_PROTOTYPES_BEGIN
      21             : 
      22             : /* fd_clock_tile_init creates a new fd_clock_tile_t.  Assumes that the
      23             :    calling thread has pre-calibrated fd_tempo tick_per_ns value. */
      24             : 
      25             : static inline void
      26           6 : fd_clock_tile_init( fd_clock_tile_t * clock ) {
      27             :   /* fdctl calibrates tick_per_ns on startup, no need to calibrate here */
      28           6 :   double init_w = (double)fd_tempo_tick_per_ns( NULL );
      29             : 
      30           6 :   long init_x0, init_y0;
      31           6 :   int  clock_err = fd_clock_joint_read( _fd_tickcount, NULL, fd_log_wallclock_host, NULL, &init_x0, &init_y0, NULL );
      32           6 :   if( FD_UNLIKELY( clock_err ) ) FD_LOG_ERR(( "fd_clock_joint_read failed (%i-%s)", clock_err, fd_clock_strerror( clock_err ) ));
      33             : 
      34           6 :   long   recal_avg  = 10e6L; /* 10ms */
      35           6 :   void * shclock = fd_clock_new( clock->shmem, recal_avg, 0L, 0., 0., init_x0, init_y0, init_w );
      36           6 :   if( FD_UNLIKELY( !shclock ) ) FD_LOG_ERR(( "fd_clock_new failed" ));
      37             : 
      38           6 :   fd_clock_t * clock_ptr = fd_clock_join( clock->clock, shclock, _fd_tickcount, NULL );
      39           6 :   if( FD_UNLIKELY( !clock_ptr ) ) FD_LOG_ERR(( "fd_clock_join failed" ));
      40             : 
      41           6 :   fd_clock_epoch_init( clock->epoch, clock->shmem );
      42           6 : }
      43             : 
      44             : /* fd_clock_tile_recal_next returns the wallclock deadline after which
      45             :    the next recal should be done. */
      46             : 
      47             : static inline long
      48           0 : fd_clock_tile_recal_next( fd_clock_tile_t const * clock ) {
      49           0 :   return fd_clock_recal_next( clock->clock );
      50           0 : }
      51             : 
      52             : /* fd_clock_tile_recal is called periodically to synchronize tickcount
      53             :    to log_wallclock.  Returns the wallclock deadline after which the
      54             :    next recal should be done. */
      55             : 
      56             : static inline long
      57           0 : fd_clock_tile_recal( fd_clock_tile_t * clock ) {
      58           0 :   long x; long y;
      59           0 :   int err = fd_clock_joint_read( _fd_tickcount, NULL, fd_log_wallclock_host, NULL, &x, &y, NULL );
      60           0 :   if( FD_UNLIKELY( err ) ) {
      61             :     /* on recal fail, retry in 1ms */
      62           0 :     FD_LOG_WARNING(( "fd_clock_joint_read failed (%i-%s)", err, fd_clock_strerror( err ) ));
      63           0 :     return ( clock->shmem->recal_next = fd_clock_epoch_y( clock->epoch, fd_tickcount() ) + 1000000L );
      64           0 :   }
      65           0 :   long recal_next = fd_clock_recal( clock->clock, x, y );
      66           0 :   fd_clock_epoch_refresh( clock->epoch, clock->shmem );
      67           0 :   return recal_next;
      68           0 : }
      69             : 
      70             : /* fd_clock_tile_now returns an approximation of fd_log_wallclock. */
      71             : 
      72             : static inline long
      73   259810243 : fd_clock_tile_now( fd_clock_tile_t const * clock ) {
      74   259810243 :   return fd_clock_epoch_y( clock->epoch, fd_tickcount() );
      75   259810243 : }
      76             : 
      77             : /* fd_clock_tile_recal_due returns 1 if a recalibration is due, else 0. */
      78             : 
      79             : static inline int
      80           0 : fd_clock_tile_recal_due( fd_clock_tile_t * clock ) {
      81           0 :   return fd_clock_tile_now( clock ) >= fd_clock_tile_recal_next( clock );
      82           0 : }
      83             : 
      84             : /* fd_clock_tile_tickcount_to_wallclock converts an fd_tickcount()
      85             :    sample to a fd_log_wallclock() estimate. */
      86             : 
      87             : static inline long
      88             : fd_clock_tile_tickcount_to_wallclock( fd_clock_tile_t const * clock,
      89           0 :                                       long                    tickcount ) {
      90           0 :   return fd_clock_epoch_y( clock->epoch, tickcount );
      91           0 : }
      92             : 
      93             : /* fd_clock_tile_tickcount_decomp decompresses a frag_meta compressed
      94             :    tickcount sample. */
      95             : 
      96             : static inline long
      97             : fd_clock_tile_tickcount_decomp( fd_clock_tile_t const * clock,
      98           0 :                                 ulong                   ts_comp ) {
      99           0 :   long ref = clock->epoch->x0;
     100           0 :   return fd_frag_meta_ts_decomp( ts_comp, ref );
     101           0 : }
     102             : 
     103             : FD_PROTOTYPES_END
     104             : 
     105             : #endif /* HEADER_fd_src_disco_fd_clock_tile_h */

Generated by: LCOV version 1.14