20#include "pw_allocator/allocator.h"
21#include "pw_allocator/capability.h"
22#include "pw_allocator/metrics.h"
23#include "pw_assert/assert.h"
24#include "pw_metric/metric.h"
25#include "pw_preprocessor/compiler.h"
26#include "pw_result/result.h"
27#include "pw_status/status.h"
28#include "pw_status/status_with_size.h"
30namespace pw::allocator {
36} kAddTrackingAllocatorAsChild = {};
46template <
typename MetricsType>
50 :
Allocator(allocator.capabilities() | kImplementsGetRequestedLayout),
51 allocator_(allocator),
54 template <
typename OtherMetrics>
59 parent.metric_group().Add(metric_group());
62 const metric::Group& metric_group()
const {
return metrics_.group(); }
63 metric::Group& metric_group() {
return metrics_.group(); }
65 const MetricsType& metrics()
const {
return metrics_.metrics(); }
69 void* DoAllocate(
Layout layout)
override;
72 void DoDeallocate(
void* ptr)
override;
75 void DoDeallocate(
void* ptr,
Layout)
override { DoDeallocate(ptr); }
78 bool DoResize(
void* ptr,
size_t new_size)
override;
81 void* DoReallocate(
void* ptr,
Layout new_layout)
override;
84 Result<Layout> DoGetInfo(InfoType info_type,
const void* ptr)
const override {
85 return GetInfo(allocator_, info_type, ptr);
94template <
typename MetricsType>
97 void* new_ptr = allocator_.Allocate(requested);
98 if (new_ptr ==
nullptr) {
99 metrics_.RecordFailure(requested.size());
102 Layout allocated = Layout::Unwrap(GetAllocatedLayout(new_ptr));
103 metrics_.IncrementAllocations();
104 metrics_.ModifyRequested(requested.size(), 0);
105 metrics_.ModifyAllocated(allocated.size(), 0);
109template <
typename MetricsType>
110void TrackingAllocator<MetricsType>::DoDeallocate(
void* ptr) {
111 Layout requested = Layout::Unwrap(GetRequestedLayout(ptr));
112 Layout allocated = Layout::Unwrap(GetAllocatedLayout(ptr));
113 allocator_.Deallocate(ptr);
114 metrics_.IncrementDeallocations();
115 metrics_.ModifyRequested(0, requested.size());
116 metrics_.ModifyAllocated(0, allocated.size());
119template <
typename MetricsType>
120bool TrackingAllocator<MetricsType>::DoResize(
void* ptr,
size_t new_size) {
121 Layout requested = Layout::Unwrap(GetRequestedLayout(ptr));
122 Layout allocated = Layout::Unwrap(GetAllocatedLayout(ptr));
123 Layout new_requested(new_size, requested.alignment());
124 if (!allocator_.Resize(ptr, new_requested.size())) {
125 metrics_.RecordFailure(new_size);
128 Layout new_allocated = Layout::Unwrap(GetAllocatedLayout(ptr));
129 metrics_.IncrementResizes();
130 metrics_.ModifyRequested(new_requested.size(), requested.size());
131 metrics_.ModifyAllocated(new_allocated.size(), allocated.size());
135template <
typename MetricsType>
136void* TrackingAllocator<MetricsType>::DoReallocate(
void* ptr,
138 Layout requested = Layout::Unwrap(GetRequestedLayout(ptr));
139 Layout allocated = Layout::Unwrap(GetAllocatedLayout(ptr));
140 Layout new_requested(new_layout.size(), requested.alignment());
141 void* new_ptr = allocator_.Reallocate(ptr, new_requested);
142 if (new_ptr ==
nullptr) {
143 metrics_.RecordFailure(new_requested.size());
146 metrics_.IncrementReallocations();
147 metrics_.ModifyRequested(new_requested.size(), requested.size());
148 Layout new_allocated = Layout::Unwrap(GetAllocatedLayout(new_ptr));
149 if (ptr != new_ptr) {
152 metrics_.ModifyAllocated(new_allocated.size(), 0);
153 metrics_.ModifyAllocated(0, allocated.size());
156 metrics_.ModifyAllocated(new_allocated.size(), allocated.size());
173template <
typename MetricsType>
174using TrackingAllocatorImpl = TrackingAllocator<MetricsType>;
Definition: allocator.h:32
constexpr Allocator()=default
TODO(b/326509341): Remove when downstream consumers migrate.
Definition: tracking_allocator.h:47
Definition: metrics.h:124
Definition: tracking_allocator.h:35