1 //===-- sanitizer_allocator_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 //===----------------------------------------------------------------------===//
9 // Part of the Sanitizer Allocator.
11 //===----------------------------------------------------------------------===//
12 #ifndef SANITIZER_ALLOCATOR_H
13 #error This file must be included inside sanitizer_allocator.h
16 // Memory allocator statistics
18 AllocatorStatAllocated
,
23 typedef uptr AllocatorStatCounters
[AllocatorStatCount
];
25 // Per-thread stats, live in per-thread cache.
26 class AllocatorStats
{
29 internal_memset(this, 0, sizeof(*this));
31 void InitLinkerInitialized() {}
33 void Add(AllocatorStat i
, uptr v
) {
34 v
+= atomic_load(&stats_
[i
], memory_order_relaxed
);
35 atomic_store(&stats_
[i
], v
, memory_order_relaxed
);
38 void Sub(AllocatorStat i
, uptr v
) {
39 v
= atomic_load(&stats_
[i
], memory_order_relaxed
) - v
;
40 atomic_store(&stats_
[i
], v
, memory_order_relaxed
);
43 void Set(AllocatorStat i
, uptr v
) {
44 atomic_store(&stats_
[i
], v
, memory_order_relaxed
);
47 uptr
Get(AllocatorStat i
) const {
48 return atomic_load(&stats_
[i
], memory_order_relaxed
);
52 friend class AllocatorGlobalStats
;
53 AllocatorStats
*next_
;
54 AllocatorStats
*prev_
;
55 atomic_uintptr_t stats_
[AllocatorStatCount
];
58 // Global stats, used for aggregation and querying.
59 class AllocatorGlobalStats
: public AllocatorStats
{
61 void InitLinkerInitialized() {
66 internal_memset(this, 0, sizeof(*this));
67 InitLinkerInitialized();
70 void Register(AllocatorStats
*s
) {
71 SpinMutexLock
l(&mu_
);
78 void Unregister(AllocatorStats
*s
) {
79 SpinMutexLock
l(&mu_
);
80 s
->prev_
->next_
= s
->next_
;
81 s
->next_
->prev_
= s
->prev_
;
82 for (int i
= 0; i
< AllocatorStatCount
; i
++)
83 Add(AllocatorStat(i
), s
->Get(AllocatorStat(i
)));
86 void Get(AllocatorStatCounters s
) const {
87 internal_memset(s
, 0, AllocatorStatCount
* sizeof(uptr
));
88 SpinMutexLock
l(&mu_
);
89 const AllocatorStats
*stats
= this;
91 for (int i
= 0; i
< AllocatorStatCount
; i
++)
92 s
[i
] += stats
->Get(AllocatorStat(i
));
97 // All stats must be non-negative.
98 for (int i
= 0; i
< AllocatorStatCount
; i
++)
99 s
[i
] = ((sptr
)s
[i
]) >= 0 ? s
[i
] : 0;
103 mutable StaticSpinMutex mu_
;