Skip to content

File buffer.h

FileList > buffer > buffer.h

Go to the source code of this file

High-performance x86-64 Circular Buffer for RF Streaming. More...

  • #include <fcntl.h>
  • #include <stdio.h>
  • #include <sys/mman.h>
  • #include <unistd.h>
  • #include <stdbool.h>
  • #include <stddef.h>
  • #include <stdint.h>
  • #include <stdlib.h>
  • #include <string.h>

Public Static Functions

Type Name
void * dp__buf_alloc (size_t bytes, void ** handle_out)
Allocates a double-mapped ring-buffer region of bytes .
void dp__buf_free (void * addr, size_t bytes, void * handle)
Releases a double-mapped region created by dp__buf_alloc().
size_t dp__page_size (void)
Returns the granularity the double-mapped views must align to.

Macros

Type Name
define DECLARE_DP_BUFFER (name, type)
Generates a type-specific circular buffer implementation.
define DP_ALIGN (n) \_\_attribute\_\_ ((aligned (n)))
define DP_ASSERT_PWR2 (n) typedef char dp\_assert\_pwr2\_##n[((n) & ((n) - 1)) == 0 ? 1 : -1]
define DP_CACHELINE 64
Standard x86-64 cache-line size (64 bytes).
define DP_SPIN_HINT () ((void)0)

Detailed Description

Virtual Memory Buffers

doppler uses virtual memory mirroring to eliminate the "wrap-around" problem in circular buffers. This allows for zero-copy, branchless access to contiguous blocks of data across the buffer boundary.

Virtual Memory Mirroring

By mapping the same physical memory to two adjacent virtual addresses (A and A + N), we exploit the CPU's MMU to handle circular indexing at the hardware level.

of Two Masking

We use & mask instead of % capacity. On x86-64, bitwise AND is a single-cycle instruction, whereas integer modulo can take 20-80 cycles.

Sharing

The head and tail pointers are separated by 64 bytes to prevent the "Ping-Pong" effect where two CPU cores constantly invalidate each other's cache lines when updating indices.

Optimization

DP_SPIN_HINT() is used in the consumer loop to reduce power consumption and prevent the CPU from mispredicting the "loop end" during high-frequency polling.

Public Static Functions Documentation

function dp__buf_alloc

Allocates a double-mapped ring-buffer region of bytes .

static inline void * dp__buf_alloc (
    size_t bytes,
    void ** handle_out
) 

The returned address addr satisfies: * addr(0..bytes-1) ← first view (writable) * addr(bytes..2*bytes-1) ← second view (same physical pages)

On Windows, a HANDLE to the file-mapping object is written to handle_out and must be passed to dp__buf_free(). On POSIX, handle_out is set to NULL.

Returns:

Base address of the double-mapped region, or NULL on failure.


function dp__buf_free

Releases a double-mapped region created by dp__buf_alloc().

static inline void dp__buf_free (
    void * addr,
    size_t bytes,
    void * handle
) 

Parameters:

  • addr Base address returned by dp__buf_alloc().
  • bytes Size of ONE mapping (same value passed to dp__buf_alloc).
  • handle Platform handle returned via handle_out (Win32: HANDLE, else NULL).

function dp__page_size

Returns the granularity the double-mapped views must align to.

static inline size_t dp__page_size (
    void
) 

This is the unit the ring-buffer mirror is rounded up to. On POSIX that is the page size. On Windows it is the allocation granularity (64 KiB), which is ≥ dwPageSize: MapViewOfFileEx requires each view's base address to be a multiple of the allocation granularity, so the second (mirror) view at base + bytes is only placeable when bytes is a whole multiple of it. Using dwPageSize (4 KiB) here would let a sub-64-KiB buffer pass the size check and then fail to map.


Macro Definition Documentation

define DECLARE_DP_BUFFER

Generates a type-specific circular buffer implementation.

#define DECLARE_DP_BUFFER (
    name,
    type
) 

Parameters:

  • name Suffix for generated names (e.g., f32, i16).
  • type Underlying primitive type for complex I/Q samples.

define DP_ALIGN

#define DP_ALIGN (
    n
) `__attribute__ ((aligned (n)))`

define DP_ASSERT_PWR2

#define DP_ASSERT_PWR2 (
    n
) `typedef char dp_assert_pwr2_##n[((n) & ((n) - 1)) == 0 ? 1 : -1]`

define DP_CACHELINE

Standard x86-64 cache-line size (64 bytes).

#define DP_CACHELINE `64`


define DP_SPIN_HINT

#define DP_SPIN_HINT (

) `((void)0)`


The documentation for this class was generated from the following file native/inc/buffer/buffer.h