Skip to content

Commit 3030a6d

Browse files
authored
Move memory stats gathering from polkadot to parity-util-mem (#588)
* Move memory stats gathering from `polkadot` to `parity-util-mem` * Bump version to 0.10.1 * Update the CHANGELOG
1 parent c031b09 commit 3030a6d

File tree

5 files changed

+129
-3
lines changed

5 files changed

+129
-3
lines changed

parity-util-mem/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ The format is based on [Keep a Changelog].
44

55
[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
66

7-
## [Unreleased]
7+
## [0.10.1] - 2021-09-15
8+
- Added support for memory stats gathering, ported over from `polkadot`. [#588](https://github.com/paritytech/parity-common/pull/588)
9+
10+
## [0.10.0] - 2021-07-02
811
- Fixed `malloc_usable_size` for FreeBSD. [#553](https://github.com/paritytech/parity-common/pull/553)
912

1013
### Breaking

parity-util-mem/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "parity-util-mem"
3-
version = "0.10.0"
3+
version = "0.10.1"
44
authors = ["Parity Technologies <admin@parity.io>"]
55
repository = "https://github.com/paritytech/parity-common"
66
description = "Collection of memory related utilities"
@@ -37,6 +37,10 @@ winapi = { version = "0.3.8", features = ["heapapi"] }
3737
version = "0.3.2"
3838
optional = true
3939

40+
[target.'cfg(not(target_os = "windows"))'.dependencies.jemalloc-ctl]
41+
version = "0.3.3"
42+
optional = true
43+
4044
[features]
4145
default = ["std", "ethereum-impls", "lru", "hashbrown", "smallvec", "primitive-types"]
4246
std = ["parking_lot"]
@@ -45,7 +49,7 @@ dlmalloc-global = ["dlmalloc", "estimate-heapsize"]
4549
# use wee_alloc as global allocator
4650
weealloc-global = ["wee_alloc", "estimate-heapsize"]
4751
# use jemalloc as global allocator
48-
jemalloc-global = ["jemallocator"]
52+
jemalloc-global = ["jemallocator", "jemalloc-ctl"]
4953
# use mimalloc as global allocator
5054
mimalloc-global = ["mimalloc", "libmimalloc-sys"]
5155
# implement additional types

parity-util-mem/src/lib.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,37 @@ cfg_if::cfg_if! {
2424
/// Global allocator
2525
#[global_allocator]
2626
pub static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
27+
28+
mod memory_stats_jemalloc;
29+
use memory_stats_jemalloc as memory_stats;
2730
} else if #[cfg(feature = "dlmalloc-global")] {
2831
/// Global allocator
2932
#[global_allocator]
3033
pub static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc;
34+
35+
mod memory_stats_noop;
36+
use memory_stats_noop as memory_stats;
3137
} else if #[cfg(feature = "weealloc-global")] {
3238
/// Global allocator
3339
#[global_allocator]
3440
pub static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
41+
42+
mod memory_stats_noop;
43+
use memory_stats_noop as memory_stats;
3544
} else if #[cfg(all(
3645
feature = "mimalloc-global",
3746
not(target_arch = "wasm32")
3847
))] {
3948
/// Global allocator
4049
#[global_allocator]
4150
pub static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
51+
52+
mod memory_stats_noop;
53+
use memory_stats_noop as memory_stats;
4254
} else {
4355
// default allocator used
56+
mod memory_stats_noop;
57+
use memory_stats_noop as memory_stats;
4458
}
4559
}
4660

@@ -78,6 +92,48 @@ pub fn malloc_size<T: MallocSizeOf + ?Sized>(t: &T) -> usize {
7892
MallocSizeOf::size_of(t, &mut allocators::new_malloc_size_ops())
7993
}
8094

95+
/// An error related to the memory stats gathering.
96+
#[derive(Clone, Debug)]
97+
pub struct MemoryStatsError(memory_stats::Error);
98+
99+
#[cfg(feature = "std")]
100+
impl std::fmt::Display for MemoryStatsError {
101+
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
102+
self.0.fmt(fmt)
103+
}
104+
}
105+
106+
#[cfg(feature = "std")]
107+
impl std::error::Error for MemoryStatsError {}
108+
109+
/// Snapshot of collected memory metrics.
110+
#[non_exhaustive]
111+
#[derive(Debug, Clone)]
112+
pub struct MemoryAllocationSnapshot {
113+
/// Total resident memory, in bytes.
114+
pub resident: u64,
115+
/// Total allocated memory, in bytes.
116+
pub allocated: u64,
117+
}
118+
119+
/// Accessor to the allocator internals.
120+
#[derive(Clone)]
121+
pub struct MemoryAllocationTracker(self::memory_stats::MemoryAllocationTracker);
122+
123+
impl MemoryAllocationTracker {
124+
/// Create an instance of an allocation tracker.
125+
pub fn new() -> Result<Self, MemoryStatsError> {
126+
self::memory_stats::MemoryAllocationTracker::new()
127+
.map(MemoryAllocationTracker)
128+
.map_err(MemoryStatsError)
129+
}
130+
131+
/// Create an allocation snapshot.
132+
pub fn snapshot(&self) -> Result<MemoryAllocationSnapshot, MemoryStatsError> {
133+
self.0.snapshot().map_err(MemoryStatsError)
134+
}
135+
}
136+
81137
#[cfg(feature = "std")]
82138
#[cfg(test)]
83139
mod test {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2021 Parity Technologies
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
pub use jemalloc_ctl::Error;
10+
use jemalloc_ctl::{epoch, stats};
11+
12+
#[derive(Clone)]
13+
pub struct MemoryAllocationTracker {
14+
epoch: jemalloc_ctl::epoch_mib,
15+
allocated: stats::allocated_mib,
16+
resident: stats::resident_mib,
17+
}
18+
19+
impl MemoryAllocationTracker {
20+
pub fn new() -> Result<Self, Error> {
21+
Ok(Self { epoch: epoch::mib()?, allocated: stats::allocated::mib()?, resident: stats::resident::mib()? })
22+
}
23+
24+
pub fn snapshot(&self) -> Result<crate::MemoryAllocationSnapshot, Error> {
25+
// update stats by advancing the allocation epoch
26+
self.epoch.advance()?;
27+
28+
let allocated: u64 = self.allocated.read()? as _;
29+
let resident: u64 = self.resident.read()? as _;
30+
Ok(crate::MemoryAllocationSnapshot { allocated, resident })
31+
}
32+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2021 Parity Technologies
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
#[derive(Clone, Debug)]
10+
pub struct Unimplemented;
11+
pub use Unimplemented as Error;
12+
13+
#[cfg(feature = "std")]
14+
impl std::fmt::Display for Unimplemented {
15+
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
16+
fmt.write_str("unimplemented")
17+
}
18+
}
19+
20+
#[derive(Clone)]
21+
pub struct MemoryAllocationTracker {}
22+
23+
impl MemoryAllocationTracker {
24+
pub fn new() -> Result<Self, Error> {
25+
Err(Error)
26+
}
27+
28+
pub fn snapshot(&self) -> Result<crate::MemoryAllocationSnapshot, Error> {
29+
unimplemented!();
30+
}
31+
}

0 commit comments

Comments
 (0)