C/C++ API Reference
Loading...
Searching...
No Matches
simple_allocator.h
1// Copyright 2024 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 "pw_allocator/allocator.h"
17#include "pw_containers/intrusive_list.h"
18#include "pw_multibuf/config.h"
19#include "pw_multibuf/v1/allocator.h"
20#include "pw_multibuf/v1/multibuf.h"
21
22namespace pw::multibuf::v1 {
23
24class SimpleAllocator;
25
26namespace internal {
27
30class PW_MULTIBUF_DEPRECATED LinkedRegionTracker final
31 : public ChunkRegionTracker,
32 public IntrusiveList<LinkedRegionTracker>::Item {
33 public:
35 : parent_(parent), region_(region) {}
37
38 // LinkedRegionTracker is not copyable nor movable.
40 LinkedRegionTracker& operator=(const LinkedRegionTracker&) = delete;
42 LinkedRegionTracker& operator=(LinkedRegionTracker&&) = delete;
43
44 protected:
45 void Destroy() final;
46 ByteSpan Region() const final { return region_; }
47 void* AllocateChunkClass() final;
48 void DeallocateChunkClass(void*) final;
49
50 private:
51 SimpleAllocator& parent_;
52 const ByteSpan region_;
53
54 friend class ::pw::multibuf::v1::SimpleAllocator;
55};
56
57} // namespace internal
58
60
62class PW_MULTIBUF_DEPRECATED SimpleAllocator : public MultiBufAllocator {
63 public:
67 static constexpr size_t kAllocationOverhead = 0;
68
84 pw::allocator::Allocator& metadata_alloc,
85 size_t alignment = 1);
86
91 constexpr size_t alignment() const { return alignment_; }
92
93 private:
95 size_t min_size,
96 size_t desired_size,
97 ContiguityRequirement contiguity_requirement) final;
98
99 std::optional<size_t> DoGetBackingCapacity() final {
100 return data_area_.size();
101 }
102
104 pw::Result<MultiBuf> InternalAllocateContiguous(size_t size)
106
112 struct FreeBlock final {
116 IntrusiveList<internal::LinkedRegionTracker>::iterator iter;
117
120 };
121
122 pw::Result<OwnedChunk> InsertRegion(const FreeBlock&)
124
126 struct AvailableMemorySize final {
128 size_t total;
130 size_t contiguous;
131 };
132
135 AvailableMemorySize GetAvailableMemorySize()
137
139 enum class ControlFlow {
140 Continue,
141 Break,
142 };
143
149 template <typename Fn>
150 void ForEachFreeBlock(Fn function) PW_EXCLUSIVE_LOCKS_REQUIRED(lock_) {
151 std::byte* last_used_end = data_area_.data();
152 // We need to track only the `prev_iter` in order to ensure that we don't
153 // miss any blocks that ``function`` inserts.
154 auto prev_iter = regions_.before_begin();
155 while (true) {
156 // Compute ``cur_iter`` by incrementing ``prev_iter``.
157 auto cur_iter = prev_iter;
158 cur_iter++;
159 if (cur_iter == regions_.end()) {
160 break;
161 }
162 size_t unused =
163 static_cast<size_t>(cur_iter->region_.data() - last_used_end);
164 if (unused != 0) {
165 ControlFlow cf = function({prev_iter, ByteSpan(last_used_end, unused)});
166 if (cf == ControlFlow::Break) {
167 return;
168 }
169 }
170 last_used_end = cur_iter->region_.data() + cur_iter->region_.size();
171 prev_iter = cur_iter;
172 }
173 size_t unused = static_cast<size_t>(
174 (data_area_.data() + data_area_.size()) - last_used_end);
175 if (unused != 0) {
176 function({prev_iter, ByteSpan(last_used_end, unused)});
177 }
178 }
179
180 pw::sync::Mutex lock_;
181 IntrusiveList<internal::LinkedRegionTracker> regions_ PW_GUARDED_BY(lock_);
182 pw::allocator::Allocator& metadata_alloc_;
183 const ByteSpan data_area_;
184 const size_t alignment_;
185
186 friend class internal::LinkedRegionTracker;
187};
188
190
191} // namespace pw::multibuf::v1
Definition: allocator.h:45
Definition: result.h:145
Definition: intrusive_list.h:88
Definition: allocator.h:57
A simple first-fit MultiBufAllocator.
Definition: simple_allocator.h:62
pw::Result< MultiBuf > DoAllocate(size_t min_size, size_t desired_size, ContiguityRequirement contiguity_requirement) final
constexpr size_t alignment() const
Definition: simple_allocator.h:91
std::optional< size_t > DoGetBackingCapacity() final
Definition: simple_allocator.h:99
SimpleAllocator(ByteSpan data_area, pw::allocator::Allocator &metadata_alloc, size_t alignment=1)
Definition: simple_allocator.h:32
Definition: mutex.h:40
#define PW_GUARDED_BY(x)
Definition: lock_annotations.h:60
#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: lock_annotations.h:146
The Pigweed namespace.
Definition: alignment.h:27