Pigweed
 
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
29template <typename OffsetType = uintptr_t>
30using BucketBlock = DetailedBlock<OffsetType, UnorderedItem>;
31
55template <typename BlockType = BucketBlock<>,
56 size_t kMinInnerSize = 32,
57 size_t kNumBuckets = 5>
58class BucketAllocator : public BlockAllocator<BlockType> {
59 private:
61
62 public:
64 constexpr BucketAllocator() {
65 size_t max_inner_size = kMinInnerSize;
66 for (auto& bucket : span(buckets_.data(), kNumBuckets - 1)) {
67 bucket.set_max_inner_size(max_inner_size);
68 max_inner_size <<= 1;
69 }
70 }
71
78 explicit BucketAllocator(ByteSpan region) : BucketAllocator() {
79 Base::Init(region);
80 }
81
82 ~BucketAllocator() override {
83 for (auto& bucket : buckets_) {
84 bucket.Clear();
85 }
86 }
87
88 private:
91 for (auto& bucket : buckets_) {
92 if (layout.size() <= bucket.max_inner_size()) {
93 BlockType* block = bucket.RemoveCompatible(layout);
94 if (block != nullptr) {
95 return BlockType::AllocFirst(std::move(block), layout);
96 }
97 }
98 }
99 return BlockResult<BlockType>(nullptr, Status::NotFound());
100 }
101
103 void ReserveBlock(BlockType& block) override {
104 for (auto& bucket : buckets_) {
105 if (block.InnerSize() <= bucket.max_inner_size()) {
106 std::ignore = bucket.Remove(block);
107 break;
108 }
109 }
110 }
111
113 void RecycleBlock(BlockType& block) override {
114 for (auto& bucket : buckets_) {
115 if (block.InnerSize() <= bucket.max_inner_size()) {
116 std::ignore = bucket.Add(block);
117 break;
118 }
119 }
120 }
121
122 std::array<UnorderedBucket<BlockType>, kNumBuckets> buckets_;
123};
124
125} // namespace pw::allocator
Definition: block_allocator.h:104
void Init(ByteSpan region)
Definition: block_allocator.h:281
Definition: result.h:114
Definition: bucket_allocator.h:58
void RecycleBlock(BlockType &block) override
Definition: bucket_allocator.h:113
constexpr BucketAllocator()
Constexpr constructor. Callers must explicitly call Init.
Definition: bucket_allocator.h:64
BucketAllocator(ByteSpan region)
Definition: bucket_allocator.h:78
void ReserveBlock(BlockType &block) override
Definition: bucket_allocator.h:103
BlockResult< BlockType > ChooseBlock(Layout layout) override
Definition: bucket_allocator.h:90
Definition: layout.h:56