Expand description
§Triple Buffering Crate
This crate provides utilities for implementing triple buffering and generalized
multi-buffering patterns. It includes the TripleBuffer
type alias, built on top of
the generic MultiBuffer
struct, enabling developers to create and manage buffers
designed for high-performance, concurrent, or time-sensitive workloads.
The primary purpose of this crate is to facilitate safe, lock-free access to the latest
data in one buffer while enabling concurrent modifications in other buffers. Each buffer
is associated with a version tag (BufferTag
), which helps track updates and ensures
consumers can identify the most recent data or detect stale reads.
§Main Features
TripleBuffer<T>
: A convenient alias for three buffers (standard triple buffering).- Generic Multi-buffering:
MultiBuffer<T, SIZE>
supports any number of buffers through constant generics. - Buffer tags for tracking updates: Each buffer has a version tag to help identify the latest state.
- Lock-free concurrency: Allows safe access without blocking threads.
- Convenience methods: Intuitive API for buffer access, mutation, and publishing updated buffers.
§Examples
§TripleBuffer Example
The following example demonstrates how to use a TripleBuffer
in typical scenarios:
use multibuffer::TripleBuffer;
fn main() {
// Create a TripleBuffer with an initial value of 0.
let buffer = TripleBuffer::new(|| 0);
// Modify a specific buffer (index 1).
*buffer.get_mut(1) = 42;
// Publish the updated buffer (index 1) with a version tag of 1.
buffer.publish(1, 1);
// Access the latest published buffer and its tag.
let (latest, tag) = buffer.get_latest();
assert_eq!(*latest, 42);
assert_eq!(tag, 1);
// Perform further modifications and publishing.
*buffer.get_mut(2) = 100;
buffer.publish(2, 2);
let (latest, tag) = buffer.get_latest();
assert_eq!(*latest, 100);
assert_eq!(tag, 2);
}
§Implementation Details
- The
MultiBuffer
struct maintains an internal array of buffers, version tags, and a fence pointer to track the latest published buffer. - Buffers are allocated using
UnsafeCell
to allow efficient mutable access without requiring synchronization primitives. - The version tags (
BufferTag
) are updated on publishing and help consumers confirm they are reading the most up-to-date data. - The
Sync
implementation is designed with precautions to ensure safe multi-threaded usage, as long as the user adheres to the safety rules outlined in the API documentation.
§Notes
- Correctness of the implementation depends on the user following the API’s safety guidelines.
Specifically, concurrent misuse of the
get_latest
andget_mut
methods may result in undefined behavior. - The crate relies on Rust’s constant generics (
const SIZE: usize
) to specify the number of buffers, which needs to be determined at compile-time.
Structs§
- Multi
Buffer - A generic multi-buffering structure designed for lock-free concurrency, supporting a configurable number of buffers, each tagged with a version number for tracking updates.
Type Aliases§
- Buffer
Index - A type alias representing the index of a buffer.
- Buffer
Tag - A type alias for the version tag of a buffer.
- Triple
Buffer - A type alias for a triple buffer, which is a specialized form of the
MultiBuffer
struct with a fixed size of three buffers. This is commonly used for triple buffering scenarios.