LCOV - code coverage report
Current view: top level - util/tmpl - fd_voff.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 6 10 60.0 %
Date: 2024-11-13 11:58:15 Functions: 9 21 42.9 %

          Line data    Source code
       1             : /* Declare a header-only API for fast manipulation of versioned offsets.
       2             :    These are useful building blocks of interprocess lockfree algorithms.
       3             :    The (ver,off) pair itself is represented in an atomic operation
       4             :    friendly primitive unsigned integer type.  Example:
       5             : 
       6             :      #define VOFF_NAME my_voff
       7             :      #include "util/tmpl/fd_voff.c"
       8             : 
       9             :    will declare the following in the compile unit:
      10             : 
      11             :      typedef ulong my_voff_t;
      12             : 
      13             :      enum {
      14             :        my_voff_VER_WIDTH = 20,
      15             :        my_voff_OFF_WIDTH = 44
      16             :      };
      17             : 
      18             :      int       my_voff_ver_width( void );                 // return the version bit width (20)
      19             :      int       my_voff_off_width( void );                 // return the offset bit width (44)
      20             :      ulong     my_voff_ver_max  ( void );                 // return the maximum version number (2^20-1)
      21             :      ulong     my_voff_off_max  ( void );                 // return the maximum offset (2^44-1)
      22             :      my_voff_t my_voff          ( ulong ver, ulong off ); // pack the least significant bits of ver and off into a my_voff_t.
      23             :      ulong     my_voff_ver      ( my_voff_t voff );       // unpack the version from a my_voff_t, will be in [0,my_voff_ver_max()]
      24             :      ulong     my_voff_off      ( my_voff_t voff );       // unpack the version from a my_voff_t, will be in [0,my_voff_off_max()]
      25             : 
      26             :    This is safe for multiple inclusion and other options exist for fine
      27             :    tuning described below. */
      28             : 
      29             : #ifndef VOFF_NAME
      30             : #error "Define VOFF_NAME"
      31             : #endif
      32             : 
      33             : /* VOFF_TYPE is a type that behaves like a primitive integral type, is
      34             :    efficient to pass around by value and is ideally atomic operation
      35             :    friendly.  Defaults to ulong. */
      36             : 
      37             : #ifndef VOFF_TYPE
      38             : #define VOFF_TYPE ulong
      39             : #endif
      40             : 
      41             : /* VOFF_VER_WIDTH is the bit width to use for versions.  All other
      42             :    bytes in the VOFF_TYPE will be used for offsets.  As such, this
      43             :    should be in [1,width_type) */
      44             : 
      45             : #ifndef VOFF_VER_WIDTH
      46   180000000 : #define VOFF_VER_WIDTH (20)
      47             : #endif
      48             : 
      49             : #define VOFF_(x)FD_EXPAND_THEN_CONCAT3(VOFF_NAME,_,x)
      50             : 
      51             : typedef VOFF_TYPE VOFF_(t);
      52             : 
      53             : enum {
      54             :   VOFF_(VER_WIDTH) = VOFF_VER_WIDTH,
      55             :   VOFF_(OFF_WIDTH) = 8*(int)sizeof(VOFF_TYPE) - VOFF_VER_WIDTH
      56             : };
      57             : 
      58             : FD_PROTOTYPES_BEGIN
      59             : 
      60           0 : FD_FN_CONST static inline int       VOFF_(ver_width)( void ) { return VOFF_VER_WIDTH;                                    }
      61           0 : FD_FN_CONST static inline int       VOFF_(off_width)( void ) { return 8*(int)sizeof(VOFF_TYPE) - VOFF_VER_WIDTH;         }
      62           0 : FD_FN_CONST static inline VOFF_TYPE VOFF_(ver_max)  ( void ) { return (((VOFF_TYPE)1) << VOFF_VER_WIDTH) - (VOFF_TYPE)1; }
      63           0 : FD_FN_CONST static inline VOFF_TYPE VOFF_(off_max)  ( void ) { return (~(VOFF_TYPE)0) >> VOFF_VER_WIDTH;                 }
      64             : 
      65             : FD_FN_CONST static inline VOFF_(t)
      66             : VOFF_NAME( VOFF_TYPE ver,
      67   122782647 :            VOFF_TYPE off) {
      68   122782647 :   return (ver & ((((VOFF_TYPE)1)<<VOFF_VER_WIDTH) - (VOFF_TYPE)1)) | (off << VOFF_VER_WIDTH);
      69   122782647 : }
      70             : 
      71    62733885 : FD_FN_CONST static inline VOFF_TYPE VOFF_(ver)( VOFF_(t) voff ) { return voff & ((((VOFF_TYPE)1)<<VOFF_VER_WIDTH) - (VOFF_TYPE)1); }
      72   201543807 : FD_FN_CONST static inline VOFF_TYPE VOFF_(off)( VOFF_(t) voff ) { return voff >> VOFF_VER_WIDTH;                                   }
      73             : 
      74             : FD_PROTOTYPES_END
      75             : 
      76             : #undef VOFF_
      77             : 
      78             : #undef VOFF_VER_WIDTH
      79             : #undef VOFF_TYPE
      80             : #undef VOFF_NAME
      81             : 

Generated by: LCOV version 1.14