1 //===-- sanitizer_allocator_stats.h -----------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // Part of the Sanitizer Allocator.
10 //===----------------------------------------------------------------------===//
11 #ifndef SANITIZER_ALLOCATOR_H
12 #error This file must be included inside sanitizer_allocator.h
15 // Memory allocator statistics
17 AllocatorStatAllocated
,
22 typedef uptr AllocatorStatCounters
[AllocatorStatCount
];
24 // Per-thread stats, live in per-thread cache.
25 class AllocatorStats
{
28 internal_memset(this, 0, sizeof(*this));
30 void InitLinkerInitialized() {}
32 void Add(AllocatorStat i
, uptr v
) {
33 v
+= atomic_load(&stats_
[i
], memory_order_relaxed
);
34 atomic_store(&stats_
[i
], v
, memory_order_relaxed
);
37 void Sub(AllocatorStat i
, uptr v
) {
38 v
= atomic_load(&stats_
[i
], memory_order_relaxed
) - v
;
39 atomic_store(&stats_
[i
], v
, memory_order_relaxed
);
42 void Set(AllocatorStat i
, uptr v
) {
43 atomic_store(&stats_
[i
], v
, memory_order_relaxed
);
46 uptr
Get(AllocatorStat i
) const {
47 return atomic_load(&stats_
[i
], memory_order_relaxed
);
51 friend class AllocatorGlobalStats
;
52 AllocatorStats
*next_
;
53 AllocatorStats
*prev_
;
54 atomic_uintptr_t stats_
[AllocatorStatCount
];
57 // Global stats, used for aggregation and querying.
58 class AllocatorGlobalStats
: public AllocatorStats
{
60 void InitLinkerInitialized() {
65 internal_memset(this, 0, sizeof(*this));
66 InitLinkerInitialized();
69 void Register(AllocatorStats
*s
) {
70 SpinMutexLock
l(&mu_
);
77 void Unregister(AllocatorStats
*s
) {
78 SpinMutexLock
l(&mu_
);
79 s
->prev_
->next_
= s
->next_
;
80 s
->next_
->prev_
= s
->prev_
;
81 for (int i
= 0; i
< AllocatorStatCount
; i
++)
82 Add(AllocatorStat(i
), s
->Get(AllocatorStat(i
)));
85 void Get(AllocatorStatCounters s
) const {
86 internal_memset(s
, 0, AllocatorStatCount
* sizeof(uptr
));
87 SpinMutexLock
l(&mu_
);
88 const AllocatorStats
*stats
= this;
90 for (int i
= 0; i
< AllocatorStatCount
; i
++)
91 s
[i
] += stats
->Get(AllocatorStat(i
));
96 // All stats must be non-negative.
97 for (int i
= 0; i
< AllocatorStatCount
; i
++)
98 s
[i
] = ((sptr
)s
[i
]) >= 0 ? s
[i
] : 0;
102 mutable SpinMutex mu_
;