1018981977
libsanitizer/ * All source files: Merge from upstream 285547. * configure.tgt (SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS): New variable. * configure.ac (SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS): Handle it. * asan/Makefile.am (asan_files): Add new files. * asan/Makefile.in: Regenerate. * ubsan/Makefile.in: Likewise. * lsan/Makefile.in: Likewise. * tsan/Makefile.am (tsan_files): Add new files. * tsan/Makefile.in: Regenerate. * sanitizer_common/Makefile.am (sanitizer_common_files): Add new files. (EXTRA_libsanitizer_common_la_SOURCES): Define. (libsanitizer_common_la_LIBADD): Likewise. (libsanitizer_common_la_DEPENDENCIES): Likewise. * sanitizer_common/Makefile.in: Regenerate. * interception/Makefile.in: Likewise. * libbacktace/Makefile.in: Likewise. * Makefile.in: Likewise. * configure: Likewise. * merge.sh: Handle builtins/assembly.h merging. * builtins/assembly.h: New file. * asan/libtool-version: Bump the libasan SONAME. From-SVN: r241977
104 lines
2.7 KiB
C++
104 lines
2.7 KiB
C++
//===-- sanitizer_allocator_stats.h -----------------------------*- C++ -*-===//
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the Sanitizer Allocator.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef SANITIZER_ALLOCATOR_H
|
|
#error This file must be included inside sanitizer_allocator.h
|
|
#endif
|
|
|
|
// Memory allocator statistics
|
|
enum AllocatorStat {
|
|
AllocatorStatAllocated,
|
|
AllocatorStatMapped,
|
|
AllocatorStatCount
|
|
};
|
|
|
|
typedef uptr AllocatorStatCounters[AllocatorStatCount];
|
|
|
|
// Per-thread stats, live in per-thread cache.
|
|
class AllocatorStats {
|
|
public:
|
|
void Init() {
|
|
internal_memset(this, 0, sizeof(*this));
|
|
}
|
|
void InitLinkerInitialized() {}
|
|
|
|
void Add(AllocatorStat i, uptr v) {
|
|
v += atomic_load(&stats_[i], memory_order_relaxed);
|
|
atomic_store(&stats_[i], v, memory_order_relaxed);
|
|
}
|
|
|
|
void Sub(AllocatorStat i, uptr v) {
|
|
v = atomic_load(&stats_[i], memory_order_relaxed) - v;
|
|
atomic_store(&stats_[i], v, memory_order_relaxed);
|
|
}
|
|
|
|
void Set(AllocatorStat i, uptr v) {
|
|
atomic_store(&stats_[i], v, memory_order_relaxed);
|
|
}
|
|
|
|
uptr Get(AllocatorStat i) const {
|
|
return atomic_load(&stats_[i], memory_order_relaxed);
|
|
}
|
|
|
|
private:
|
|
friend class AllocatorGlobalStats;
|
|
AllocatorStats *next_;
|
|
AllocatorStats *prev_;
|
|
atomic_uintptr_t stats_[AllocatorStatCount];
|
|
};
|
|
|
|
// Global stats, used for aggregation and querying.
|
|
class AllocatorGlobalStats : public AllocatorStats {
|
|
public:
|
|
void InitLinkerInitialized() {
|
|
next_ = this;
|
|
prev_ = this;
|
|
}
|
|
void Init() {
|
|
internal_memset(this, 0, sizeof(*this));
|
|
InitLinkerInitialized();
|
|
}
|
|
|
|
void Register(AllocatorStats *s) {
|
|
SpinMutexLock l(&mu_);
|
|
s->next_ = next_;
|
|
s->prev_ = this;
|
|
next_->prev_ = s;
|
|
next_ = s;
|
|
}
|
|
|
|
void Unregister(AllocatorStats *s) {
|
|
SpinMutexLock l(&mu_);
|
|
s->prev_->next_ = s->next_;
|
|
s->next_->prev_ = s->prev_;
|
|
for (int i = 0; i < AllocatorStatCount; i++)
|
|
Add(AllocatorStat(i), s->Get(AllocatorStat(i)));
|
|
}
|
|
|
|
void Get(AllocatorStatCounters s) const {
|
|
internal_memset(s, 0, AllocatorStatCount * sizeof(uptr));
|
|
SpinMutexLock l(&mu_);
|
|
const AllocatorStats *stats = this;
|
|
for (;;) {
|
|
for (int i = 0; i < AllocatorStatCount; i++)
|
|
s[i] += stats->Get(AllocatorStat(i));
|
|
stats = stats->next_;
|
|
if (stats == this)
|
|
break;
|
|
}
|
|
// All stats must be non-negative.
|
|
for (int i = 0; i < AllocatorStatCount; i++)
|
|
s[i] = ((sptr)s[i]) >= 0 ? s[i] : 0;
|
|
}
|
|
|
|
private:
|
|
mutable SpinMutex mu_;
|
|
};
|