5
5
#include " core/page_usage_stats.h"
6
6
7
7
#include < absl/container/flat_hash_set.h>
8
+ #include < absl/strings/ascii.h>
8
9
#include < absl/strings/str_join.h>
9
10
#include < glog/logging.h>
10
11
#include < hdr/hdr_histogram.h>
@@ -23,28 +24,31 @@ mi_page_usage_stats_t mi_heap_page_is_underutilized(mi_heap_t* heap, void* p, fl
23
24
24
25
namespace dfly {
25
26
27
+ using absl::StrAppend;
28
+ using absl::StrFormat;
29
+ using absl::StripTrailingAsciiWhitespace;
30
+
26
31
namespace {
27
32
constexpr auto kUsageHistPoints = std::array{50 , 90 , 99 };
28
33
constexpr auto kInitialSBFCap = 1000 ;
29
34
constexpr auto kFProb = 0.001 ;
30
35
constexpr auto kGrowthFactor = 2 ;
31
36
constexpr auto kHistSignificantFigures = 3 ;
32
37
33
- FilterWithSize MakeSBF () {
34
- return {.sbf = SBF{kInitialSBFCap , kFProb , kGrowthFactor , PMR_NS::get_default_resource ()},
35
- .size = 0 };
36
- }
37
-
38
38
} // namespace
39
39
40
+ FilterWithSize::FilterWithSize ()
41
+ : sbf{SBF{kInitialSBFCap , kFProb , kGrowthFactor , PMR_NS::get_default_resource ()}}, size{0 } {
42
+ }
43
+
40
44
void FilterWithSize::Add (uintptr_t address) {
41
45
const auto s = std::to_string (address);
42
46
if (sbf.Add (s)) {
43
47
size += 1 ;
44
48
}
45
49
}
46
50
47
- void CollectedPageStats::Merge (CollectedPageStats&& other, ShardId shard_id) {
51
+ void CollectedPageStats::Merge (CollectedPageStats&& other, uint16_t shard_id) {
48
52
this ->pages_scanned += other.pages_scanned ;
49
53
this ->pages_marked_for_realloc += other.pages_marked_for_realloc ;
50
54
this ->pages_full += other.pages_full ;
@@ -54,54 +58,50 @@ void CollectedPageStats::Merge(CollectedPageStats&& other, ShardId shard_id) {
54
58
shard_wide_summary.emplace (std::make_pair (shard_id, std::move (other.page_usage_hist )));
55
59
}
56
60
57
- CollectedPageStats CollectedPageStats::Merge (CollectedPageStats* stats, const size_t size ,
61
+ CollectedPageStats CollectedPageStats::Merge (absl::Span< CollectedPageStats> stats,
58
62
const float threshold) {
59
63
CollectedPageStats result;
60
64
result.threshold = threshold;
61
- for (size_t i = 0 ; i < size; ++i) {
62
- result.Merge (std::move (*stats), i);
63
- stats++;
65
+
66
+ size_t shard_index = 0 ;
67
+ for (CollectedPageStats& stat : stats) {
68
+ result.Merge (std::move (stat), shard_index++);
64
69
}
65
70
return result;
66
71
}
67
72
68
73
std::string CollectedPageStats::ToString () const {
69
- std::vector<std::string> rows;
70
- rows.push_back (absl::StrFormat (" Page usage threshold: %f" , threshold * 100 ));
71
- rows.push_back (absl::StrFormat (" Pages scanned: %d" , pages_scanned));
72
- rows.push_back (absl::StrFormat (" Pages marked for reallocation: %d" , pages_marked_for_realloc));
73
- rows.push_back (absl::StrFormat (" Pages full: %d" , pages_full));
74
- rows.push_back (absl::StrFormat (" Pages reserved for malloc: %d" , pages_reserved_for_malloc));
75
- rows.push_back (
76
- absl::StrFormat (" Pages skipped due to heap mismatch: %d" , pages_with_heap_mismatch));
77
- rows.push_back (absl::StrFormat (" Pages with usage above threshold: %d" , pages_above_threshold));
74
+ std::string response;
75
+ StrAppend (&response, " Page usage threshold: " , threshold * 100 , " \n " );
76
+ StrAppend (&response, " Pages scanned: " , pages_scanned, " \n " );
77
+ StrAppend (&response, " Pages marked for reallocation: " , pages_marked_for_realloc, " \n " );
78
+ StrAppend (&response, " Pages full: " , pages_full, " \n " );
79
+ StrAppend (&response, " Pages reserved for malloc: " , pages_reserved_for_malloc, " \n " );
80
+ StrAppend (&response, " Pages skipped due to heap mismatch: " , pages_with_heap_mismatch, " \n " );
81
+ StrAppend (&response, " Pages with usage above threshold: " , pages_above_threshold, " \n " );
78
82
for (const auto & [shard_id, usage] : shard_wide_summary) {
79
- rows. push_back ( absl::StrFormat ( " [Shard %d] " , shard_id) );
83
+ StrAppend (&response, " [Shard " , shard_id, " ] \n " );
80
84
for (const auto & [percentage, count] : usage) {
81
- rows.push_back (absl::StrFormat (" %d%% pages are below %d%% block usage" , percentage, count));
85
+ StrAppend (&response,
86
+ StrFormat (" %d%% pages are below %d%% block usage\n " , percentage, count));
82
87
}
83
88
}
84
- return absl::StrJoin (rows, " \n " );
89
+ StripTrailingAsciiWhitespace (&response);
90
+ return response;
85
91
}
86
92
87
- UniquePages::UniquePages ()
88
- : pages_scanned{MakeSBF ()},
89
- pages_marked_for_realloc{MakeSBF ()},
90
- pages_full{MakeSBF ()},
91
- pages_reserved_for_malloc{MakeSBF ()},
92
- pages_with_heap_mismatch{MakeSBF ()},
93
- pages_above_threshold{MakeSBF ()} {
93
+ PageUsage::UniquePages::UniquePages () {
94
94
hdr_histogram* h = nullptr ;
95
95
const auto init_result = hdr_init (1 , 100 , kHistSignificantFigures , &h);
96
96
CHECK_EQ (0 , init_result) << " failed to initialize histogram" ;
97
97
page_usage_hist = h;
98
98
}
99
99
100
- UniquePages::~UniquePages () {
100
+ PageUsage:: UniquePages::~UniquePages () {
101
101
hdr_close (page_usage_hist);
102
102
}
103
103
104
- void UniquePages::AddStat (mi_page_usage_stats_t stat) {
104
+ void PageUsage:: UniquePages::AddStat (mi_page_usage_stats_t stat) {
105
105
const auto address = stat.page_address ;
106
106
pages_scanned.Add (address);
107
107
if (stat.flags == MI_DFLY_PAGE_BELOW_THRESHOLD) {
@@ -124,7 +124,7 @@ void UniquePages::AddStat(mi_page_usage_stats_t stat) {
124
124
}
125
125
}
126
126
127
- CollectedPageStats UniquePages::CollectedStats () const {
127
+ CollectedPageStats PageUsage:: UniquePages::CollectedStats () const {
128
128
CollectedPageStats::ShardUsageSummary usage;
129
129
for (const auto p : kUsageHistPoints ) {
130
130
usage[p] = hdr_value_at_percentile (page_usage_hist, p);
0 commit comments