Pigweed
Loading...
Searching...
No Matches
size_reporter.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 <cstddef>
18#include <cstdint>
19#include <cstring>
20#include <type_traits>
21
22#include "pw_assert/assert.h"
23#include "pw_bloat/bloat_this_binary.h"
24#include "pw_bytes/span.h"
25
26#ifndef PW_ALLOCATOR_SIZE_REPORTER_BASE
27#include "pw_allocator/allocator.h"
28#include "pw_allocator/null_allocator.h"
29#endif // PW_ALLOCATOR_SIZE_REPORTER_BASE
30
31namespace pw::allocator {
32
43class SizeReporter final {
44 public:
46 struct Foo final {
47 std::array<std::byte, 16> buffer;
48 };
49
51 struct Bar {
52 Foo foo;
53 size_t number;
54
55 Bar(size_t number_) : number(number_) {
56 std::memset(foo.buffer.data(), 0, foo.buffer.size());
57 }
58 };
59
61 struct Baz {
62 Foo foo;
63 uint16_t id;
64 };
65
66 void SetBaseline() {
67 pw::bloat::BloatThisBinary();
68 ByteSpan bytes = buffer();
69 Bar* bar = new (bytes.data()) Bar(0);
70 PW_ASSERT(bar != nullptr);
71 std::destroy_at(bar);
72#ifndef PW_ALLOCATOR_SIZE_REPORTER_BASE
73 // Include the NullAllocator to bake in the costs of the base `Allocator`.
74 Allocator& allocator = GetNullAllocator();
75 PW_ASSERT(allocator.Allocate(Layout::Of<Foo>()) == nullptr);
76#endif // PW_ALLOCATOR_SIZE_REPORTER_BASE
77 }
78
79 ByteSpan buffer() { return buffer_; }
80
81#ifndef PW_ALLOCATOR_SIZE_REPORTER_BASE
86 void Measure(Allocator& allocator) {
87 // Measure `Layout::Of`.
88 Layout layout = Layout::Of<Foo>();
89
90 // Measure `Allocate`.
91 void* ptr = allocator.Allocate(layout);
92
93 // Measure `Reallocate`.
94 allocator.Resize(ptr, sizeof(Bar));
95
96 // Measure `Reallocate`.
97 ptr = allocator.Reallocate(ptr, Layout::Of<Baz>());
98
99 // Measure `Deallocate`.
100 allocator.Deallocate(ptr);
101
102 // Measure `New`.
103 Foo* foo = allocator.template New<Foo>();
104
105 // Measure `Delete`.
106 allocator.Delete(foo);
107
108 // Measure `MakeUnique`.
109 UniquePtr<Foo> unique_foo = allocator.template MakeUnique<Foo>();
110 PW_ASSERT(ptr == nullptr || unique_foo != nullptr);
111 }
112#endif // PW_ALLOCATOR_SIZE_REPORTER_BASE
113
114 private:
115 std::array<std::byte, 0x400> buffer_;
116};
117
118} // namespace pw::allocator
Definition: allocator.h:32
bool Resize(void *ptr, size_t new_size)
Definition: allocator.h:81
void * Reallocate(void *ptr, Layout new_layout)
Definition: allocator.h:115
void * Allocate(Layout layout)
Definition: allocator.h:40
void Deallocate(void *ptr)
Definition: deallocator.h:47
void Delete(T *ptr)
Definition: deallocator.h:69
Definition: unique_ptr.h:47
Definition: layout.h:39
Definition: size_reporter.h:43
void Measure(Allocator &allocator)
Definition: size_reporter.h:86
Nested type used for exercising an allocator.
Definition: size_reporter.h:51
Nested type used for exercising an allocator.
Definition: size_reporter.h:61
Nested type used for exercising an allocator.
Definition: size_reporter.h:46