Pigweed
 
Loading...
Searching...
No Matches
pw::multibuf::Chunk Class Reference

#include <chunk.h>

Public Types

using element_type = std::byte
 
using value_type = std::byte
 
using size_type = size_t
 
using difference_type = ptrdiff_t
 
using pointer = std::byte *
 
using const_pointer = const std::byte *
 
using reference = std::byte &
 
using const_reference = const std::byte &
 
using iterator = std::byte *
 
using const_iterator = const std::byte *
 
using reverse_iterator = std::byte *
 
using const_reverse_iterator = const std::byte *
 

Public Member Functions

 Chunk (Chunk &)=delete
 
Chunkoperator= (Chunk &)=delete
 
 Chunk (Chunk &&)=delete
 
Chunkoperator= (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< OwnedChunkTakePrefix (size_t bytes_to_take)
 
std::optional< OwnedChunkTakeSuffix (size_t bytes_to_take)
 

Friends

class ChunkRegionTracker
 
class OwnedChunk
 
class MultiBuf
 
class MultiBufChunks
 

Detailed Description

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.

Member Function Documentation

◆ CanMerge()

bool pw::multibuf::Chunk::CanMerge ( const Chunk next_chunk) const

Returns if next_chunk is mergeable into the end of this Chunk.

This will only succeed when the two Chunk s are adjacent in memory and originated from the same region.

◆ ClaimPrefix()

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.

◆ ClaimSuffix()

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.

◆ DiscardPrefix()

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.

◆ Merge()

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.

◆ Slice()

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.

◆ TakePrefix()

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.

◆ TakeSuffix()

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.

◆ Truncate()

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.


The documentation for this class was generated from the following file: