#include <chunk.h>
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 |
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.
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 Chunk
s 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 Release
d.
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 Chunk
s 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 Chunk
s exist within it. This allows the memory to be later reclaimed using ClaimSuffix
.
This method will acquire a mutex and is not IRQ safe.