LCOV - code coverage report
Current view: top level - disco/events - fd_circq.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 1 0.0 %
Date: 2025-01-08 12:08:44 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_events_fd_circq_h
       2             : #define HEADER_fd_src_disco_events_fd_circq_h
       3             : 
       4             : /* The circular buffer is a structure, which stores a queue of messages,
       5             :    supporting two operations: push_back and pop_front.  Unlike a regular
       6             :    queue, the circular buffer is fixed size and push_back must always
       7             :    succeed.
       8             : 
       9             :    To ensure push_back always succeeds, the circular buffer will evict
      10             :    old messages if necessary to make room for the new one.
      11             : 
      12             :    One more complication is that the circular buffer must store
      13             :    metadata about the messages in the data buffer itself, as it does not
      14             :    have a separate metadata region.  The structure of the buffer then
      15             :    looks as follows:
      16             : 
      17             :     +-------+-----+------+-----+-------+-----+------+-----+-------+-----+------+
      18             :     + meta0 | pad | msg0 | pad | meta1 | pad | msg1 | pad | meta2 | pad | msg2 |
      19             :     +-------+-----+------+-----+-------+-----+------+-----+-------+-----+------+
      20             :      ^  |                        ^  |                        ^  |
      21             :      |  +-----next---------next--+  +------------------------+  |
      22             :      |                                                          |
      23             :    head                                                        tail
      24             : 
      25             :    Here, the meta elements are fd_circq_message_t, which each point to
      26             :    the next message in the queue, and head, tail are the head and tail
      27             :    of the queue respectively. */
      28             : 
      29             : #include "../fd_disco_base.h"
      30             : 
      31           0 : #define FD_CIRCQ_ALIGN (4096UL)
      32             : 
      33             : struct __attribute__((aligned(FD_CIRCQ_ALIGN))) fd_circq_private {
      34             :   /* Current count of elements in the queue. */
      35             :   ulong cnt;
      36             : 
      37             :   /* These are offsets relative to the end of this struct of the
      38             :      metadata for the first, and last message in the queue,
      39             :      respectively. */
      40             :   ulong head;
      41             :   ulong tail;
      42             : 
      43             :   ulong size;
      44             : 
      45             :   struct {
      46             :     ulong drop_cnt;
      47             :   } metrics;
      48             : 
      49             :   /* padding out to 4k here ... */
      50             : };
      51             : 
      52             : typedef struct fd_circq_private fd_circq_t;
      53             : 
      54             : FD_PROTOTYPES_BEGIN
      55             : 
      56             : FD_FN_CONST ulong
      57             : fd_circq_align( void );
      58             : 
      59             : FD_FN_CONST ulong
      60             : fd_circq_footprint( ulong sz );
      61             : 
      62             : void *
      63             : fd_circq_new( void * shmem,
      64             :                 ulong  sz );
      65             : 
      66             : fd_circq_t *
      67             : fd_circq_join( void * shbuf );
      68             : 
      69             : void *
      70             : fd_circq_leave( fd_circq_t * buf );
      71             : 
      72             : void *
      73             : fd_circq_delete( void * shbuf );
      74             : 
      75             : /* fd_circq_push_back appends a message of size sz into the circular
      76             :    buffer, evicting any old messages if they would be overwritten when
      77             :    the buffer wraps around.  Returns the address of the memory contents
      78             :    in the buffer on success, or NULL on failure.  The only two reasons
      79             :    for failure are if the requested sz (along with the message metadata)
      80             :    exceeds the size of the entire buffer and can't fit, or if the
      81             :    requested alignment is not a power of 2, or is larger than 4096. */
      82             : 
      83             : uchar *
      84             : fd_circq_push_back( fd_circq_t * circq,
      85             :                     ulong        align,
      86             :                     ulong        footprint );
      87             : 
      88             : /* fd_circq_pop_front pops the oldest message from the circular buffer
      89             :    and returns the address of the memory contents in the buffer.  The
      90             :    memory contents are guaranteed to be valid until the next call to
      91             :    fd_circq_push_back.  Returns NULL if there are no messages in the
      92             :    circular buffer. */
      93             : 
      94             : uchar const *
      95             : fd_circq_pop_front( fd_circq_t * circq );
      96             : 
      97             : FD_PROTOTYPES_END
      98             : 
      99             : #endif /* HEADER_fd_src_disco_events_fd_circq_h */

Generated by: LCOV version 1.14