19#include "pw_allocator/allocator.h"
20#include "pw_metric/metric.h"
21#include "pw_status/status_with_size.h"
23namespace pw::allocator {
60#define PW_ALLOCATOR_METRICS_FOREACH(fn) \
61 fn(requested_bytes); \
62 fn(peak_requested_bytes); \
63 fn(cumulative_requested_bytes); \
64 fn(allocated_bytes); \
65 fn(peak_allocated_bytes); \
66 fn(cumulative_allocated_bytes); \
67 fn(num_allocations); \
68 fn(num_deallocations); \
70 fn(num_reallocations); \
71 fn(num_free_blocks); \
72 fn(smallest_free_block_size); \
73 fn(largest_free_block_size); \
77#define PW_ALLOCATOR_ABSORB_SEMICOLON() static_assert(true)
89#define PW_ALLOCATOR_METRICS_DECLARE(metric_name) \
90 static constexpr bool has_##metric_name() { return false; } \
91 ::pw::StatusWithSize get_##metric_name() const { \
92 return ::pw::StatusWithSize::NotFound(); \
94 static constexpr bool metric_name##_enabled() { return false; } \
95 PW_ALLOCATOR_ABSORB_SEMICOLON()
103 PW_ALLOCATOR_METRICS_FOREACH(PW_ALLOCATOR_METRICS_DECLARE);
117#undef PW_ALLOCATOR_METRICS_DECLARE
130#define PW_ALLOCATOR_METRICS_INCLUDE(metric_name) \
131 static_assert(!::pw::allocator::NoMetrics::has_##metric_name()); \
132 static constexpr bool has_##metric_name() { return true; } \
133 inline ::pw::StatusWithSize get_##metric_name() const { \
134 return ::pw::StatusWithSize(metric_name.value()); \
136 PW_METRIC(metric_name, #metric_name, 0U)
160#define PW_ALLOCATOR_METRICS_ENABLE(metric_name) \
161 static constexpr bool metric_name##_enabled() { return true; } \
162 PW_ALLOCATOR_METRICS_INCLUDE(metric_name)
172 PW_ALLOCATOR_METRICS_FOREACH(PW_ALLOCATOR_METRICS_ENABLE);
177template <
typename MetricsType>
178constexpr bool AnyEnabled();
181template <
typename MetricsType>
182void CopyMetrics(
const MetricsType& src, MetricsType& dst);
192template <
typename MetricsType>
198 const metric::Group& group()
const {
return group_; }
199 metric::Group& group() {
return group_; }
201 const MetricsType& metrics()
const {
return metrics_; }
253 metrics_.UpdateDeferred(allocator);
257 metric::Group group_;
258 MetricsType metrics_;
262inline uint32_t ClampU32(
size_t size) {
263 return static_cast<uint32_t
>(std::min(
264 size,
static_cast<size_t>(std::numeric_limits<uint32_t>::max())));
269template <
typename MetricsType>
270constexpr bool AnyEnabled() {
271#define PW_ALLOCATOR_RETURN_IF_ENABLED(metric_name) \
272 if (MetricsType::metric_name##_enabled()) { \
275 PW_ALLOCATOR_ABSORB_SEMICOLON()
277 PW_ALLOCATOR_METRICS_FOREACH(PW_ALLOCATOR_RETURN_IF_ENABLED);
280#undef PW_ALLOCATOR_RETURN_IF_ENABLED
283template <
typename MetricsType>
284void CopyMetrics(
const MetricsType& src, MetricsType& dst) {
285#define PW_ALLOCATOR_COPY_METRIC(metric_name) \
286 if constexpr (MetricsType::has_##metric_name()) { \
287 dst.metric_name.Set(src.metric_name.value()); \
289 PW_ALLOCATOR_ABSORB_SEMICOLON()
291 PW_ALLOCATOR_METRICS_FOREACH(PW_ALLOCATOR_COPY_METRIC);
293#undef PW_ALLOCATOR_COPY_METRIC
296template <
typename MetricsType>
297Metrics<MetricsType>::Metrics(metric::Token token) : group_(token) {
298#define PW_ALLOCATOR_ADD_TO_GROUP(metric_name) \
299 if constexpr (MetricsType::has_##metric_name()) { \
300 group_.Add(metrics_.metric_name); \
302 PW_ALLOCATOR_ABSORB_SEMICOLON()
304 PW_ALLOCATOR_METRICS_FOREACH(PW_ALLOCATOR_ADD_TO_GROUP);
306#undef PW_ALLOCATOR_ADD_TO_GROUP
309template <
typename MetricsType>
311 if constexpr (MetricsType::requested_bytes_enabled()) {
312 metrics_.requested_bytes.Increment(internal::ClampU32(increase));
313 metrics_.requested_bytes.Decrement(internal::ClampU32(decrease));
314 if constexpr (MetricsType::peak_requested_bytes_enabled()) {
315 uint32_t requested_bytes = metrics_.requested_bytes.value();
316 if (metrics_.peak_requested_bytes.value() < requested_bytes) {
317 metrics_.peak_requested_bytes.Set(requested_bytes);
320 if constexpr (MetricsType::cumulative_requested_bytes_enabled()) {
321 if (increase > decrease) {
322 metrics_.cumulative_requested_bytes.Increment(
323 internal::ClampU32(increase - decrease));
329template <
typename MetricsType>
331 if constexpr (MetricsType::allocated_bytes_enabled()) {
332 metrics_.allocated_bytes.Increment(internal::ClampU32(increase));
333 metrics_.allocated_bytes.Decrement(internal::ClampU32(decrease));
334 if constexpr (MetricsType::peak_allocated_bytes_enabled()) {
335 uint32_t allocated_bytes = metrics_.allocated_bytes.value();
336 if (metrics_.peak_allocated_bytes.value() < allocated_bytes) {
337 metrics_.peak_allocated_bytes.Set(allocated_bytes);
340 if constexpr (MetricsType::cumulative_allocated_bytes_enabled()) {
341 if (increase > decrease) {
342 metrics_.cumulative_allocated_bytes.Increment(
343 internal::ClampU32(increase - decrease));
349template <
typename MetricsType>
351 if constexpr (MetricsType::num_allocations_enabled()) {
352 metrics_.num_allocations.Increment();
356template <
typename MetricsType>
358 if constexpr (MetricsType::num_deallocations_enabled()) {
359 metrics_.num_deallocations.Increment();
363template <
typename MetricsType>
365 if constexpr (MetricsType::num_resizes_enabled()) {
366 metrics_.num_resizes.Increment();
370template <
typename MetricsType>
372 if constexpr (MetricsType::num_reallocations_enabled()) {
373 metrics_.num_reallocations.Increment();
377template <
typename MetricsType>
379 if constexpr (MetricsType::num_failures_enabled()) {
380 metrics_.num_failures.Increment();
382 if constexpr (MetricsType::unfulfilled_bytes_enabled()) {
383 metrics_.unfulfilled_bytes.Increment(internal::ClampU32(requested));
387#undef PW_ALLOCATOR_ABSORB_SEMICOLON
Definition: allocator.h:34
Definition: metrics.h:193
void IncrementDeallocations()
Records that a call to Deallocate was made.
Definition: metrics.h:357
void RecordFailure(size_t requested)
Definition: metrics.h:378
void ModifyRequested(size_t increase, size_t decrease)
Definition: metrics.h:310
void IncrementReallocations()
Records that a call to Reallocate was made.
Definition: metrics.h:371
void IncrementAllocations()
Records that a call to Allocate was made.
Definition: metrics.h:350
void UpdateDeferred(Allocator &allocator)
Definition: metrics.h:252
void IncrementResizes()
Records that a call to Resize was made.
Definition: metrics.h:364
void ModifyAllocated(size_t increase, size_t decrease)
Definition: metrics.h:330
Definition: metrics.h:102
void UpdateDeferred(Allocator &)
Definition: metrics.h:114
Definition: metrics.h:171