YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/memory/memory_usage_test_util.cc
Line
Count
Source (jump to first uncovered line)
1
//--------------------------------------------------------------------------------------------------
2
// Copyright (c) YugaByte, Inc.
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
// in compliance with the License.  You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software distributed under the License
10
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
// or implied.  See the License for the specific language governing permissions and limitations
12
// under the License.
13
//
14
//--------------------------------------------------------------------------------------------------
15
16
#include "yb/util/memory/memory_usage_test_util.h"
17
18
#include <map>
19
20
#include "yb/util/memory/arena.h"
21
#include "yb/util/size_literals.h"
22
23
#if defined(TCMALLOC_ENABLED)
24
#include <gperftools/malloc_hook.h>
25
#define MEMORY_USAGE_SUPPORTED
26
#endif // defined(TCMALLOC_ENABLED)
27
28
#if !defined(MEMORY_USAGE_SUPPORTED)
29
#include "yb/util/format.h"
30
#endif
31
32
namespace yb {
33
34
#if defined(MEMORY_USAGE_SUPPORTED)
35
36
size_t heap_requested_bytes = 0;
37
bool heap_allocation_tracking_enabled = false;
38
39
// We use preallocated arena for heap_allocations map to avoid this map memory allocations be
40
// counted by tcmalloc during memory usage tests.
41
ThreadSafeArena heap_allocations_map_arena(10_MB, 10_MB);
42
43
template<class Key, class Value, class Compare = std::less<Key>>
44
using MapOnArena =
45
    std::map<Key, Value, Compare, ThreadSafeArenaAllocator<std::pair<const Key, Value>>>;
46
MapOnArena<const void*, size_t> heap_allocations(&heap_allocations_map_arena);
47
48
void NewHook(const void* ptr, const std::size_t size) {
49
  if (heap_allocation_tracking_enabled) {
50
    heap_allocation_tracking_enabled = false;
51
    heap_requested_bytes += size;
52
    auto emplaced = heap_allocations.emplace(ptr, size);
53
    if (!emplaced.second) {
54
      LOG(FATAL) << "Double allocation at ptr: " << ptr << " size requested: " << size
55
                 << " previous size: " << emplaced.first->second;
56
    }
57
    heap_allocation_tracking_enabled = true;
58
  }
59
}
60
61
void DeleteHook(const void* ptr) {
62
  if (heap_allocation_tracking_enabled) {
63
    heap_allocation_tracking_enabled = false;
64
    auto it = heap_allocations.find(ptr);
65
    if (it != heap_allocations.end()) {
66
      heap_requested_bytes -= it->second;
67
      heap_allocations.erase(it);
68
    }
69
    heap_allocation_tracking_enabled = true;
70
  }
71
}
72
73
void StartAllocationsTracking() {
74
  heap_requested_bytes = 0;
75
  heap_allocations.clear();
76
  heap_allocation_tracking_enabled = true;
77
  MallocHook_AddNewHook(&NewHook);
78
  MallocHook_AddDeleteHook(&DeleteHook);
79
}
80
81
void StopAllocationsTracking() {
82
  heap_allocation_tracking_enabled = false;
83
  MallocHook_RemoveNewHook(&NewHook);
84
  MallocHook_RemoveDeleteHook(&DeleteHook);
85
}
86
87
size_t GetHeapRequestedBytes() {
88
  return heap_requested_bytes;
89
}
90
91
#else
92
93
std::string kNotSupported("$0 is not supported under ASAN/TSAN or without TCMalloc");
94
95
1
void StartAllocationsTracking() {
96
1
  LOG(FATAL) << Format(kNotSupported, __FUNCTION__);
97
1
}
98
99
0
void StopAllocationsTracking() {
100
0
  LOG(FATAL) << Format(kNotSupported, __FUNCTION__);
101
0
}
102
103
0
size_t GetHeapRequestedBytes() {
104
0
  LOG(FATAL) << Format(kNotSupported, __FUNCTION__);
105
0
  return 0;
106
0
}
107
108
#endif // defined(TCMALLOC_ENABLED) && !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
109
110
0
std::string DumpMemoryUsage(const MemoryUsage& memory_usage) {
111
0
  std::ostringstream ss;
112
0
  ss << "Entities: " << memory_usage.entities_count << std::endl;
113
0
  auto dump_memory = [&ss, &memory_usage](const char* label, const size_t bytes) {
114
0
    ss << "Memory " << label << ": " << bytes
115
0
       << ", per entity: " << bytes / memory_usage.entities_count << std::endl;
116
0
  };
117
0
  dump_memory("requested", memory_usage.heap_requested_bytes);
118
0
  dump_memory("allocated", memory_usage.heap_allocated_bytes);
119
0
  dump_memory("tracked", memory_usage.tracked_consumption);
120
0
  return ss.str();
121
0
}
122
123
}  // namespace yb