19#include "pw_allocator/allocator.h"
20#include "pw_metric/metric.h"
21#include "pw_status/status_with_size.h"
23namespace pw::allocator {
62#define PW_ALLOCATOR_METRICS_FOREACH(fn) \
63 fn(requested_bytes); \
64 fn(peak_requested_bytes); \
65 fn(cumulative_requested_bytes); \
66 fn(allocated_bytes); \
67 fn(peak_allocated_bytes); \
68 fn(cumulative_allocated_bytes); \
69 fn(num_allocations); \
70 fn(num_deallocations); \
72 fn(num_reallocations); \
73 fn(num_free_blocks); \
74 fn(smallest_free_block_size); \
75 fn(largest_free_block_size); \
79#define PW_ALLOCATOR_ABSORB_SEMICOLON() static_assert(true)
91#define PW_ALLOCATOR_METRICS_DECLARE(metric_name) \
92 static constexpr bool has_##metric_name() { return false; } \
93 ::pw::StatusWithSize get_##metric_name() const { \
94 return ::pw::StatusWithSize::NotFound(); \
96 static constexpr bool metric_name##_enabled() { return false; } \
97 PW_ALLOCATOR_ABSORB_SEMICOLON()
119#undef PW_ALLOCATOR_METRICS_DECLARE
132#define PW_ALLOCATOR_METRICS_INCLUDE(metric_name) \
133 static_assert(!::pw::allocator::NoMetrics::has_##metric_name()); \
134 static constexpr bool has_##metric_name() { return true; } \
135 inline ::pw::StatusWithSize get_##metric_name() const { \
136 return ::pw::StatusWithSize(metric_name.value()); \
138 PW_METRIC(metric_name, #metric_name, 0U)
162#define PW_ALLOCATOR_METRICS_ENABLE(metric_name) \
163 static constexpr bool metric_name##_enabled() { return true; } \
164 PW_ALLOCATOR_METRICS_INCLUDE(metric_name)
179template <
typename MetricsType>
183template <
typename MetricsType>
184void CopyMetrics(
const MetricsType& src, MetricsType& dst);
194template <
typename MetricsType>
200 const metric::Group& group()
const {
return group_; }
201 metric::Group& group() {
return group_; }
203 const MetricsType& metrics()
const {
return metrics_; }
255 metrics_.UpdateDeferred(allocator);
259 metric::Group group_;
260 MetricsType metrics_;
265 return static_cast<uint32_t
>(std::min(
266 size,
static_cast<size_t>(std::numeric_limits<uint32_t>::max())));
273template <
typename MetricsType>
275#define PW_ALLOCATOR_RETURN_IF_ENABLED(metric_name) \
276 if (MetricsType::metric_name##_enabled()) { \
279 PW_ALLOCATOR_ABSORB_SEMICOLON()
284#undef PW_ALLOCATOR_RETURN_IF_ENABLED
287template <
typename MetricsType>
289#define PW_ALLOCATOR_COPY_METRIC(metric_name) \
290 if constexpr (MetricsType::has_##metric_name()) { \
291 dst.metric_name.Set(src.metric_name.value()); \
293 PW_ALLOCATOR_ABSORB_SEMICOLON()
297#undef PW_ALLOCATOR_COPY_METRIC
300template <
typename MetricsType>
301Metrics<MetricsType>::Metrics(metric::Token token) : group_(token) {
302#define PW_ALLOCATOR_ADD_TO_GROUP(metric_name) \
303 if constexpr (MetricsType::has_##metric_name()) { \
304 group_.Add(metrics_.metric_name); \
306 PW_ALLOCATOR_ABSORB_SEMICOLON()
310#undef PW_ALLOCATOR_ADD_TO_GROUP
313template <
typename MetricsType>
315 if constexpr (MetricsType::requested_bytes_enabled()) {
318 if constexpr (MetricsType::peak_requested_bytes_enabled()) {
319 uint32_t requested_bytes = metrics_.requested_bytes.value();
320 if (metrics_.peak_requested_bytes.value() < requested_bytes) {
321 metrics_.peak_requested_bytes.Set(requested_bytes);
324 if constexpr (MetricsType::cumulative_requested_bytes_enabled()) {
325 if (increase > decrease) {
326 metrics_.cumulative_requested_bytes.Increment(
333template <
typename MetricsType>
335 if constexpr (MetricsType::allocated_bytes_enabled()) {
338 if constexpr (MetricsType::peak_allocated_bytes_enabled()) {
339 uint32_t allocated_bytes = metrics_.allocated_bytes.value();
340 if (metrics_.peak_allocated_bytes.value() < allocated_bytes) {
341 metrics_.peak_allocated_bytes.Set(allocated_bytes);
344 if constexpr (MetricsType::cumulative_allocated_bytes_enabled()) {
345 if (increase > decrease) {
346 metrics_.cumulative_allocated_bytes.Increment(
353template <
typename MetricsType>
355 if constexpr (MetricsType::num_allocations_enabled()) {
356 metrics_.num_allocations.Increment();
360template <
typename MetricsType>
362 if constexpr (MetricsType::num_deallocations_enabled()) {
363 metrics_.num_deallocations.Increment();
367template <
typename MetricsType>
369 if constexpr (MetricsType::num_resizes_enabled()) {
370 metrics_.num_resizes.Increment();
374template <
typename MetricsType>
376 if constexpr (MetricsType::num_reallocations_enabled()) {
377 metrics_.num_reallocations.Increment();
381template <
typename MetricsType>
383 if constexpr (MetricsType::num_failures_enabled()) {
384 metrics_.num_failures.Increment();
386 if constexpr (MetricsType::unfulfilled_bytes_enabled()) {
391#undef PW_ALLOCATOR_ABSORB_SEMICOLON
Definition: allocator.h:36
Definition: metrics.h:195
void IncrementDeallocations()
Records that a call to Deallocate was made.
Definition: metrics.h:361
void RecordFailure(size_t requested)
Definition: metrics.h:382
void ModifyRequested(size_t increase, size_t decrease)
Definition: metrics.h:314
void IncrementReallocations()
Records that a call to Reallocate was made.
Definition: metrics.h:375
void IncrementAllocations()
Records that a call to Allocate was made.
Definition: metrics.h:354
void UpdateDeferred(Allocator &allocator)
Definition: metrics.h:254
void IncrementResizes()
Records that a call to Resize was made.
Definition: metrics.h:368
void ModifyAllocated(size_t increase, size_t decrease)
Definition: metrics.h:334
constexpr bool AnyEnabled()
Definition: metrics.h:274
uint32_t ClampU32(size_t size)
Helper method for converting size_ts to uint32_ts.
Definition: metrics.h:264
#define PW_ALLOCATOR_METRICS_ENABLE(metric_name)
Definition: metrics.h:162
#define PW_ALLOCATOR_METRICS_DECLARE(metric_name)
Definition: metrics.h:91
void UpdateDeferred(Allocator &)
Definition: metrics.h:116
#define PW_ALLOCATOR_METRICS_FOREACH(fn)
Definition: metrics.h:62
void CopyMetrics(const MetricsType &src, MetricsType &dst)
Copies the values enabled for a given MetricsType from src to dst.
Definition: metrics.h:288
Definition: metrics.h:104
Definition: metrics.h:173