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/allocator.h"
19#include "pw_multibuf/config.h"
20#include "pw_multibuf/multibuf_v1.h"
21
22namespace pw::multibuf {
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::SimpleAllocator;
55};
56
57} // namespace internal
58
60
62class PW_MULTIBUF_DEPRECATED SimpleAllocator : public MultiBufAllocator {
63 public:
79 pw::allocator::Allocator& metadata_alloc,
80 size_t alignment = 1);
81
82 private:
84 size_t min_size,
85 size_t desired_size,
86 ContiguityRequirement contiguity_requirement) final;
87
88 std::optional<size_t> DoGetBackingCapacity() final {
89 return data_area_.size();
90 }
91
93 pw::Result<MultiBuf> InternalAllocateContiguous(size_t size)
95
101 struct FreeBlock final {
105 IntrusiveList<internal::LinkedRegionTracker>::iterator iter;
106
109 };
110
111 pw::Result<OwnedChunk> InsertRegion(const FreeBlock&)
113
115 struct AvailableMemorySize final {
117 size_t total;
119 size_t contiguous;
120 };
121
124 AvailableMemorySize GetAvailableMemorySize()
126
128 enum class ControlFlow {
129 Continue,
130 Break,
131 };
132
138 template <typename Fn>
139 void ForEachFreeBlock(Fn function) PW_EXCLUSIVE_LOCKS_REQUIRED(lock_) {
140 std::byte* last_used_end = data_area_.data();
141 // We need to track only the `prev_iter` in order to ensure that we don't
142 // miss any blocks that ``function`` inserts.
143 auto prev_iter = regions_.before_begin();
144 while (true) {
145 // Compute ``cur_iter`` by incrementing ``prev_iter``.
146 auto cur_iter = prev_iter;
147 cur_iter++;
148 if (cur_iter == regions_.end()) {
149 break;
150 }
151 size_t unused =
152 static_cast<size_t>(cur_iter->region_.data() - last_used_end);
153 if (unused != 0) {
154 ControlFlow cf = function({prev_iter, ByteSpan(last_used_end, unused)});
155 if (cf == ControlFlow::Break) {
156 return;
157 }
158 }
159 last_used_end = cur_iter->region_.data() + cur_iter->region_.size();
160 prev_iter = cur_iter;
161 }
162 size_t unused = static_cast<size_t>(
163 (data_area_.data() + data_area_.size()) - last_used_end);
164 if (unused != 0) {
165 function({prev_iter, ByteSpan(last_used_end, unused)});
166 }
167 }
168
169 pw::sync::Mutex lock_;
170 IntrusiveList<internal::LinkedRegionTracker> regions_ PW_GUARDED_BY(lock_);
171 pw::allocator::Allocator& metadata_alloc_;
172 const ByteSpan data_area_;
173 const size_t alignment_;
174
175 friend class internal::LinkedRegionTracker;
176};
177
179
180} // namespace pw::multibuf
Definition: allocator.h:36
Definition: poll.h:25
Definition: intrusive_list.h:88
Definition: chunk.h:274
Definition: allocator.h:57
A simple first-fit MultiBufAllocator.
Definition: simple_allocator.h:62
SimpleAllocator(ByteSpan data_area, pw::allocator::Allocator &metadata_alloc, size_t alignment=1)
pw::Result< MultiBuf > DoAllocate(size_t min_size, size_t desired_size, ContiguityRequirement contiguity_requirement) final
std::optional< size_t > DoGetBackingCapacity() final
Definition: simple_allocator.h:88
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