C/C++ API Reference
Loading...
Searching...
No Matches
bucket_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 <array>
17#include <cstdint>
18#include <utility>
19
20#include "pw_allocator/block/detailed_block.h"
21#include "pw_allocator/block_allocator.h"
22#include "pw_allocator/bucket/unordered.h"
23#include "pw_status/try.h"
24
25namespace pw::allocator {
26
28
31template <typename OffsetType = uintptr_t>
33
57template <typename BlockType = BucketBlock<>,
58 size_t kMinInnerSize = 32,
59 size_t kNumBuckets = 5>
60class BucketAllocator : public BlockAllocator<BlockType> {
61 private:
63
64 public:
66 constexpr BucketAllocator() {
67 size_t max_inner_size = kMinInnerSize;
68 for (auto& bucket : span(buckets_.data(), kNumBuckets - 1)) {
69 bucket.set_max_inner_size(max_inner_size);
70 max_inner_size <<= 1;
71 }
72 }
73
81 Base::Init(region);
82 }
83
84 ~BucketAllocator() override {
85 for (auto& bucket : buckets_) {
86 bucket.Clear();
87 }
88 }
89
90 private:
92 size_t DoGetMaxAllocatable() override {
93 for (auto b = buckets_.rbegin(); b != buckets_.rend(); ++b) {
94 const BlockType* largest = b->FindLargest();
95 if (largest != nullptr) {
96 return largest->InnerSize();
97 }
98 }
99 return 0;
100 }
101
104 for (auto& bucket : buckets_) {
105 if (bucket.max_inner_size() < layout.size()) {
106 continue;
107 }
108 BlockType* block = bucket.RemoveCompatible(layout);
109 if (block != nullptr) {
110 return BlockType::AllocFirst(std::move(block), layout);
111 }
112 }
113 return BlockResult<BlockType>(nullptr, Status::NotFound());
114 }
115
117 void ReserveBlock(BlockType& block) override {
118 for (auto& bucket : buckets_) {
119 if (block.InnerSize() <= bucket.max_inner_size()) {
120 std::ignore = bucket.Remove(block);
121 break;
122 }
123 }
124 }
125
127 void RecycleBlock(BlockType& block) override {
128 for (auto& bucket : buckets_) {
129 if (block.InnerSize() <= bucket.max_inner_size()) {
130 std::ignore = bucket.Add(block);
131 break;
132 }
133 }
134 }
135
136 std::array<UnorderedBucket<BlockType>, kNumBuckets> buckets_;
137};
138
140
141} // namespace pw::allocator
Definition: block_allocator.h:106
void Init(ByteSpan region)
Definition: block_allocator.h:310
Definition: result.h:116
Definition: bucket_allocator.h:60
void RecycleBlock(BlockType &block) override
Definition: bucket_allocator.h:127
constexpr BucketAllocator()
Constexpr constructor. Callers must explicitly call Init.
Definition: bucket_allocator.h:66
BucketAllocator(ByteSpan region)
Definition: bucket_allocator.h:80
size_t DoGetMaxAllocatable() override
Definition: bucket_allocator.h:92
void ReserveBlock(BlockType &block) override
Definition: bucket_allocator.h:117
BlockResult< BlockType > ChooseBlock(Layout layout) override
Definition: bucket_allocator.h:103
Definition: detailed_block.h:88
Definition: layout.h:58
Definition: span_impl.h:235