File 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 64Standard 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 .
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().
Parameters:
addrBase address returned by dp__buf_alloc().bytesSize of ONE mapping (same value passed to dp__buf_alloc).handlePlatform handle returned via handle_out (Win32: HANDLE, else NULL).
function dp__page_size¶
Returns the granularity the double-mapped views must align to.
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.
Parameters:
nameSuffix for generated names (e.g., f32, i16).typeUnderlying primitive type for complex I/Q samples.
define DP_ALIGN¶
define DP_ASSERT_PWR2¶
define DP_CACHELINE¶
Standard x86-64 cache-line size (64 bytes).
define DP_SPIN_HINT¶
The documentation for this class was generated from the following file native/inc/buffer/buffer.h