1 //===-- stats.h -------------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #define SCUDO_STATS_H_
12 #include "atomic_helpers.h"
19 // Memory allocator statistics
20 enum StatType { StatAllocated, StatMapped, StatCount };
22 typedef uptr StatCounters[StatCount];
24 // Per-thread stats, live in per-thread cache. We use atomics so that the
25 // numbers themselves are consistent. But we don't use atomic_{add|sub} or a
26 // lock, because those are expensive operations , and we only care for the stats
27 // to be "somewhat" correct: eg. if we call GlobalStats::get while a thread is
28 // LocalStats::add'ing, this is OK, we will still get a meaningful number.
31 void initLinkerInitialized() {}
32 void init() { memset(this, 0, sizeof(*this)); }
34 void add(StatType I, uptr V) {
35 V += atomic_load_relaxed(&StatsArray[I]);
36 atomic_store_relaxed(&StatsArray[I], V);
39 void sub(StatType I, uptr V) {
40 V = atomic_load_relaxed(&StatsArray[I]) - V;
41 atomic_store_relaxed(&StatsArray[I], V);
44 void set(StatType I, uptr V) { atomic_store_relaxed(&StatsArray[I], V); }
46 uptr get(StatType I) const { return atomic_load_relaxed(&StatsArray[I]); }
49 friend class GlobalStats;
50 atomic_uptr StatsArray[StatCount];
55 // Global stats, used for aggregation and querying.
56 class GlobalStats : public LocalStats {
58 void initLinkerInitialized() {
63 memset(this, 0, sizeof(*this));
64 initLinkerInitialized();
67 void link(LocalStats *S) {
75 void unlink(LocalStats *S) {
77 S->Prev->Next = S->Next;
78 S->Next->Prev = S->Prev;
79 for (uptr I = 0; I < StatCount; I++)
80 add(static_cast<StatType>(I), S->get(static_cast<StatType>(I)));
83 void get(uptr *S) const {
84 memset(S, 0, StatCount * sizeof(uptr));
86 const LocalStats *Stats = this;
88 for (uptr I = 0; I < StatCount; I++)
89 S[I] += Stats->get(static_cast<StatType>(I));
94 // All stats must be non-negative.
95 for (uptr I = 0; I < StatCount; I++)
96 S[I] = static_cast<sptr>(S[I]) >= 0 ? S[I] : 0;
100 mutable HybridMutex Mutex;
105 #endif // SCUDO_STATS_H_