LCOV - code coverage report
Current view: top level - tango/fseq - fd_fseq.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 17 17 100.0 %
Date: 2024-11-13 11:58:15 Functions: 12 565 2.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_tango_fseq_fd_fseq_h
       2             : #define HEADER_fd_src_tango_fseq_fd_fseq_h
       3             : 
       4             : /* fseq provides APIs for wrapping up a sequence number as a persistent
       5             :    shared memory object (primarily for use in rx->tx flow control
       6             :    communications but potentially could be used for other cases of
       7             :    making sequence numbers visible to other processes at run-time). */
       8             : 
       9             : #include "../fd_tango_base.h"
      10             : 
      11             : /* FD_FSEQ_{ALIGN,FOOTPRINT} specify the alignment and footprint needed
      12             :    for a fseq.  ALIGN is a positive integer power of 2.  FOOTPRINT is a
      13             :    multiple of ALIGN.  ALIGN is recommended to be at least double cache
      14             :    line to mitigate various kinds of false sharing.  These are provided
      15             :    to facilitate compile time declarations. */
      16             : 
      17         156 : #define FD_FSEQ_ALIGN     (128UL)
      18         210 : #define FD_FSEQ_FOOTPRINT (128UL)
      19             : 
      20             : /* FD_FSEQ_APP_{ALIGN,FOOTPRINT} specify the alignment and footprint of
      21             :    a fseq's application region.  ALIGN is a positive integer power of 2.
      22             :    FOOTPRINT is a multiple of ALIGN. */
      23             : 
      24             : #define FD_FSEQ_APP_ALIGN     (32UL)
      25         297 : #define FD_FSEQ_APP_FOOTPRINT (96UL)
      26             : 
      27             : FD_PROTOTYPES_BEGIN
      28             : 
      29             : /* fd_fseq_{align,footprint} return the required alignment and footprint
      30             :    of a memory region suitable for use as a fseq.  fd_fseq_align returns
      31             :    FD_FSEQ_ALIGN.  fd_fseq_footprint returns FD_FSEQ_FOOTPRINT. */
      32             : 
      33             : FD_FN_CONST ulong
      34             : fd_fseq_align( void );
      35             : 
      36             : FD_FN_CONST ulong
      37             : fd_fseq_footprint( void );
      38             : 
      39             : /* fd_fseq_new formats an unused memory region for use as a fseq.  Assumes
      40             :    shmem is a non-NULL pointer to this region in the local address space
      41             :    with the required footprint and alignment.  The fseq will be
      42             :    initialized to seq0 and the application region will be cleared to 0.
      43             :    Returns shmem (and the memory region it points to will be formatted
      44             :    as a fseq, caller is not joined) and NULL on failure (logs details).
      45             :    Reasons for failure include an obviously bad memory region. */
      46             : 
      47             : void *
      48             : fd_fseq_new( void * shmem,
      49             :              ulong  seq0 );
      50             : 
      51             : /* fd_fseq_join joins the caller to the fseq.  shfseq points to the first
      52             :    byte of the memory region backing the fseq in the caller's address
      53             :    space.  Returns a pointer in the local address space to the fseq on
      54             :    success (IMPORTANT! THIS SHOULD NOT BE ASSUMED TO BE JUST A CAST OF
      55             :    SHFSEQ) or NULL on failure (logs details).  Reasons for failure
      56             :    include the shfseq is obviously not a local pointer to a memory
      57             :    region holding a fseq.  Every successful join should have a matching
      58             :    leave.  The lifetime of the join is until the matching leave or
      59             :    caller's thread group is terminated. */
      60             : 
      61             : ulong *
      62             : fd_fseq_join( void * shfseq );
      63             : 
      64             : /* fd_fseq_leave leaves a current local join.  Returns a pointer to the
      65             :    underlying shared memory region on success (IMPORTANT! THIS SHOULD
      66             :    NOT BE ASSUMED TO BE JUST A CAST OF FSEQ) and NULL on failure (logs
      67             :    details).  Reasons for failure include fseq is NULL. */
      68             : 
      69             : void *
      70             : fd_fseq_leave( ulong const * fseq );
      71             : 
      72             : /* fd_fseq_delete unformats a memory region used as a fseq.  Assumes
      73             :    nobody is joined to the region.  Returns a pointer to the underlying
      74             :    shared memory region or NULL if used obviously in error (e.g. shfseq
      75             :    obviously does not point to a fseq ... logs details).  The ownership
      76             :    of the memory region is transferred to the caller on success. */
      77             : 
      78             : void *
      79             : fd_fseq_delete( void * shfseq );
      80             : 
      81             : /* fd_fctl_app_laddr returns local address of the fctl's application
      82             :    region.  This will have FD_FCTL_APP_ALIGN alignment and room for at
      83             :    least FD_FCTL_APP_FOOTPRINT bytes.  Assumes fseq is a current local
      84             :    join.  fd_cnc_app_laddr_const is for const correctness.  The return
      85             :    values are valid for the lifetime of the local join. */
      86             : 
      87         195 : FD_FN_CONST static inline void *       fd_fseq_app_laddr      ( ulong *       fseq ) { return (void       *)&fseq[2]; }
      88           6 : FD_FN_CONST static inline void const * fd_fseq_app_laddr_const( ulong const * fseq ) { return (void const *)&fseq[2]; }
      89             : 
      90             : /* fd_fseq_seq0 returns the sequencer number used when the fseq was
      91             :    created.  Assumes fseq is a current local join. */
      92             : 
      93     3000006 : FD_FN_PURE static inline ulong fd_fseq_seq0( ulong const * fseq ) { return fseq[-1]; }
      94             : 
      95             : /* fd_fseq_query reads the current sequence number stored the fseq.  The
      96             :    value is observed at some point between when the call started and the
      97             :    call returned.  This acts as an implicit compiler fence.  Assumes
      98             :    fseq is a current local join. */
      99             : 
     100             : static inline ulong
     101     3000009 : fd_fseq_query( ulong const * fseq ) {
     102     3000009 :   FD_COMPILER_MFENCE();
     103     3000009 :   ulong seq = FD_VOLATILE_CONST( fseq[0] );
     104     3000009 :   FD_COMPILER_MFENCE();
     105     3000009 :   return seq;
     106     3000009 : }
     107             : 
     108             : /* fd_fseq_update updates the sequence number stored in the fseq to seq.
     109             :    The value is updated at some point between when the call started and
     110             :    the call returned.  This acts as an implicit compiler fence.  Assumes
     111             :    fseq is a current local join. */
     112             : 
     113             : static inline void
     114             : fd_fseq_update( ulong * fseq,
     115     3000000 :                 ulong   seq ) {
     116     3000000 :   FD_COMPILER_MFENCE();
     117     3000000 :   FD_VOLATILE( fseq[0] ) = seq;
     118     3000000 :   FD_COMPILER_MFENCE();
     119     3000000 : }
     120             : 
     121             : FD_PROTOTYPES_END
     122             : 
     123             : #endif /* HEADER_fd_src_tango_fseq_fd_fseq_h */

Generated by: LCOV version 1.14