A handle to a contiguous slice of data.
A Chunk is similar to a ByteSpan, but is aware of its underlying memory region, and is able to split, shrink, and grow into neighboring empty space within its region.
This class is optimized to allow multiple owners to write into neighboring regions of the same allocation. In order to support zero-copy DMA of communications buffers, allocators can create properly-aligned Chunk regions inside an allocation.
One example usecase for this is communication drivers that want to reserve space at the front or rear of a buffer for headers or footers. A driver can DiscardPrefix in order to reserve bytes for headers, Truncate in order to reserve bytes for footers, and then pass the Chunk to the user to fill in. These discarded bytes are still held by the underlying region, so the header and footer space can later be reclaimed using the ClaimPrefix and ClaimSuffix methods. The region itself is only released once there are no remaining Chunks within it.
Public Member Functions | |
| Chunk (Chunk &)=delete | |
| Chunk & | operator= (Chunk &)=delete |
| Chunk (Chunk &&)=delete | |
| Chunk & | operator= (Chunk &&)=delete |
| std::byte * | data () |
| const std::byte * | data () const |
| size_t | size () const |
| bool | empty () const |
| std::byte & | operator[] (size_t index) |
| const std::byte & | operator[] (size_t index) const |
| std::byte * | begin () |
| const std::byte * | begin () const |
| const std::byte * | cbegin () const |
| std::byte * | end () |
| const std::byte * | end () const |
| const std::byte * | cend () const |
| bool | CanMerge (const Chunk &next_chunk) const |
| bool | Merge (OwnedChunk &next_chunk) |
| bool | ClaimPrefix (size_t bytes_to_claim) |
| bool | ClaimSuffix (size_t bytes_to_claim) |
| void | DiscardPrefix (size_t bytes_to_discard) |
| void | Slice (size_t begin, size_t end) |
| void | Truncate (size_t len) |
| std::optional< OwnedChunk > | TakePrefix (size_t bytes_to_take) |
| std::optional< OwnedChunk > | TakeSuffix (size_t bytes_to_take) |
Friends | |
| class | ChunkRegionTracker |
| class | OwnedChunk |
| class | MultiBuf |
| class | MultiBufChunks |
| bool pw::multibuf::Chunk::CanMerge | ( | const Chunk & | next_chunk | ) | const |
| bool pw::multibuf::Chunk::ClaimPrefix | ( | size_t | bytes_to_claim | ) |
Attempts to add bytes_to_claim to the front of this buffer by advancing its range backwards in memory. Returns true if the operation succeeded.
This will only succeed if this Chunk points to a section of a region that has unreferenced bytes preceding it. For example, a Chunk which has been shrunk using DiscardPrefix can be re-expanded using ClaimPrefix.
This method will acquire a mutex and is not IRQ safe.
| bool pw::multibuf::Chunk::ClaimSuffix | ( | size_t | bytes_to_claim | ) |
Attempts to add bytes_to_claim to the front of this buffer by advancing its range forwards in memory. Returns true if the operation succeeded.
This will only succeed if this Chunk points to a section of a region that has unreferenced bytes following it. For example, a Chunk which has been shrunk using Truncate can be re-expanded using
This method will acquire a mutex and is not IRQ safe.
| void pw::multibuf::Chunk::DiscardPrefix | ( | size_t | bytes_to_discard | ) |
Shrinks this handle to refer to the data beginning at offset bytes_to_discard.
Does not modify the underlying data. The discarded memory continues to be held by the underlying region as long as any Chunks exist within it. This allows the memory to be later reclaimed using ClaimPrefix.
This method will acquire a mutex and is not IRQ safe.
| bool pw::multibuf::Chunk::Merge | ( | OwnedChunk & | next_chunk | ) |
Attempts to merge next_chunk into the end of this Chunk.
If the chunks are successfully merged, this Chunk will be extended forwards to encompass the space of next_chunk, and next_chunk will be emptied and Released.
This will only succeed when the two Chunk s are adjacent in memory and originated from the same region.
If the chunks are not mergeable, neither Chunk will be modified.
| void pw::multibuf::Chunk::Slice | ( | size_t | begin, |
| size_t | end | ||
| ) |
Shrinks this handle to refer to data in the range begin..<end.
Does not modify the underlying data. The discarded memory continues to be held by the underlying region as long as any Chunks exist within it. This allows the memory to be later reclaimed using ClaimPrefix or ClaimSuffix.
This method will acquire a mutex and is not IRQ safe.
| std::optional< OwnedChunk > pw::multibuf::Chunk::TakePrefix | ( | size_t | bytes_to_take | ) |
Attempts to shrink this handle to refer to the data beginning at offset bytes_to_take, returning the first bytes_to_take bytes as a new OwnedChunk.
If the inner call to AllocateChunkClass fails, this function will return std::nullopt and this handle's span will not change.
This method will acquire a mutex and is not IRQ safe.
| std::optional< OwnedChunk > pw::multibuf::Chunk::TakeSuffix | ( | size_t | bytes_to_take | ) |
Attempts to shrink this handle to refer only the first len - bytes_to_take bytes, returning the last bytes_to_take bytes as a new OwnedChunk.
If the inner call to AllocateChunkClass fails, this function will return std::nullopt and this handle's span will not change.
This method will acquire a mutex and is not IRQ safe.
| void pw::multibuf::Chunk::Truncate | ( | size_t | len | ) |
Shrinks this handle to refer to only the first len bytes.
Does not modify the underlying data. The discarded memory continues to be held by the underlying region as long as any Chunks exist within it. This allows the memory to be later reclaimed using ClaimSuffix.
This method will acquire a mutex and is not IRQ safe.
|
friend |
MultiBuf interface with mutable data and the option of adding layered data views.