Pigweed
 
Loading...
Searching...
No Matches
header_chunk_region_tracker.h
1// Copyright 2023 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <cstddef>
17#include <memory>
18#include <optional>
19
20#include "pw_allocator/allocator.h"
21#include "pw_bytes/span.h"
22#include "pw_multibuf/chunk.h"
23
24namespace pw::multibuf {
25
32 public:
40 static std::optional<OwnedChunk> AllocateRegionAsChunk(
41 allocator::Allocator& alloc, size_t size) {
42 HeaderChunkRegionTracker* tracker = AllocateRegion(alloc, size);
43 if (tracker == nullptr) {
44 return std::nullopt;
45 }
46 std::optional<OwnedChunk> chunk = tracker->CreateFirstChunk();
47 if (!chunk.has_value()) {
48 tracker->Destroy();
49 return std::nullopt;
50 }
51 return chunk;
52 }
53
63 size_t size) {
64 auto layout =
65 allocator::Layout::Of<HeaderChunkRegionTracker>().Extend(size);
66 void* ptr = alloc.Allocate(layout);
67 if (ptr == nullptr) {
68 return nullptr;
69 }
70 std::byte* data =
71 reinterpret_cast<std::byte*>(ptr) + sizeof(HeaderChunkRegionTracker);
72 return new (ptr) HeaderChunkRegionTracker(ByteSpan(data, size), alloc);
73 }
74
75 ByteSpan Region() const final { return region_; }
77
78 protected:
79 void Destroy() final {
80 std::byte* ptr = reinterpret_cast<std::byte*>(this);
81 auto alloc = alloc_;
82 std::destroy_at(this);
83 alloc->Deallocate(ptr);
84 }
85
86 void* AllocateChunkClass() final {
87 return alloc_->Allocate(allocator::Layout::Of<Chunk>());
88 }
89
90 void DeallocateChunkClass(void* ptr) final { alloc_->Deallocate(ptr); }
91
92 private:
93 ByteSpan region_;
95
96 // NOTE: `region` must directly follow this `FakeChunkRegionTracker`
97 // in memory allocated by allocated by `alloc`.
98 HeaderChunkRegionTracker(ByteSpan region, allocator::Allocator& alloc)
99 : region_(region), alloc_(&alloc) {}
100};
101
102} // namespace pw::multibuf
Definition: allocator.h:34
void * Allocate(Layout layout)
Definition: allocator.h:45
void Deallocate(void *ptr)
Definition: deallocator.h:57
Definition: chunk.h:271
std::optional< OwnedChunk > CreateFirstChunk()
Definition: header_chunk_region_tracker.h:31
static std::optional< OwnedChunk > AllocateRegionAsChunk(allocator::Allocator &alloc, size_t size)
Definition: header_chunk_region_tracker.h:40
void * AllocateChunkClass() final
Definition: header_chunk_region_tracker.h:86
ByteSpan Region() const final
Definition: header_chunk_region_tracker.h:75
void DeallocateChunkClass(void *ptr) final
Deallocates a pointer returned by AllocateChunkClass.
Definition: header_chunk_region_tracker.h:90
void Destroy() final
Definition: header_chunk_region_tracker.h:79
static HeaderChunkRegionTracker * AllocateRegion(allocator::Allocator &alloc, size_t size)
Definition: header_chunk_region_tracker.h:62