brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.6 KiB · ae4dac9 Raw
104 lines · c
1//===-- sanitizer_allocator_stats.h -----------------------------*- C++ -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8//9// Part of the Sanitizer Allocator.10//11//===----------------------------------------------------------------------===//12#ifndef SANITIZER_ALLOCATOR_H13#error This file must be included inside sanitizer_allocator.h14#endif15 16// Memory allocator statistics17enum AllocatorStat {18  AllocatorStatAllocated,19  AllocatorStatMapped,20  AllocatorStatCount21};22 23typedef uptr AllocatorStatCounters[AllocatorStatCount];24 25// Per-thread stats, live in per-thread cache.26class AllocatorStats {27 public:28  void Init() { internal_memset(this, 0, sizeof(*this)); }29  void Add(AllocatorStat i, uptr v) {30    atomic_fetch_add(&stats_[i], v, memory_order_relaxed);31  }32 33  void Sub(AllocatorStat i, uptr v) {34    atomic_fetch_sub(&stats_[i], v, memory_order_relaxed);35  }36 37  void Set(AllocatorStat i, uptr v) {38    atomic_store(&stats_[i], v, memory_order_relaxed);39  }40 41  uptr Get(AllocatorStat i) const {42    return atomic_load(&stats_[i], memory_order_relaxed);43  }44 45 private:46  friend class AllocatorGlobalStats;47  AllocatorStats *next_;48  AllocatorStats *prev_;49  atomic_uintptr_t stats_[AllocatorStatCount];50};51 52// Global stats, used for aggregation and querying.53class AllocatorGlobalStats : public AllocatorStats {54 public:55  void Init() {56    internal_memset(this, 0, sizeof(*this));57  }58 59  void Register(AllocatorStats *s) {60    SpinMutexLock l(&mu_);61    LazyInit();62    s->next_ = next_;63    s->prev_ = this;64    next_->prev_ = s;65    next_ = s;66  }67 68  void Unregister(AllocatorStats *s) {69    SpinMutexLock l(&mu_);70    s->prev_->next_ = s->next_;71    s->next_->prev_ = s->prev_;72    for (int i = 0; i < AllocatorStatCount; i++)73      Add(AllocatorStat(i), s->Get(AllocatorStat(i)));74  }75 76  void Get(AllocatorStatCounters s) const {77    internal_memset(s, 0, AllocatorStatCount * sizeof(uptr));78    SpinMutexLock l(&mu_);79    const AllocatorStats *stats = this;80    for (; stats;) {81      for (int i = 0; i < AllocatorStatCount; i++)82        s[i] += stats->Get(AllocatorStat(i));83      stats = stats->next_;84      if (stats == this)85        break;86    }87    // All stats must be non-negative.88    for (int i = 0; i < AllocatorStatCount; i++)89      s[i] = ((sptr)s[i]) >= 0 ? s[i] : 0;90  }91 92 private:93  void LazyInit() {94    if (!next_) {95      next_ = this;96      prev_ = this;97    }98  }99 100  mutable StaticSpinMutex mu_;101};102 103 104