Skip to content

Commit 60960df

Browse files
committed
fix(cardano-blockchain-types): use RwLock for mmap stat
Signed-off-by: bkioshn <[email protected]>
1 parent d156158 commit 60960df

File tree

2 files changed

+36
-95
lines changed

2 files changed

+36
-95
lines changed

rust/cardano-chain-follower/src/mithril_turbo_downloader.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ impl Inner {
146146
);
147147
}
148148
// Got the full file and its the expected size. Is it different?
149-
if memcmp(prev_mmap.file_as_slice(), buf.as_slice()) == cmp::Ordering::Equal {
149+
if memcmp(prev_mmap.as_slice(), buf.as_slice()) == cmp::Ordering::Equal {
150150
// Same so lets Hardlink it, and throw away the temp buffer.
151151

152152
// Make sure our big mmap get dropped.
Lines changed: 35 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
//! Memory-mapped file.
22
3-
use core::fmt;
43
use std::{
54
path::Path,
6-
sync::{
7-
atomic::{AtomicU64, Ordering},
8-
Arc,
9-
},
5+
sync::{Arc, RwLock},
106
};
117

128
use fmmap::{MmapFile, MmapFileExt};
139
use once_cell::sync::Lazy;
14-
use serde::{ser::SerializeStruct, Serialize, Serializer};
10+
use serde::Serialize;
1511

1612
/// Memory-mapped file.
1713
pub struct MemoryMapFile {
@@ -20,111 +16,94 @@ pub struct MemoryMapFile {
2016
/// The size of the memory-mapped file.
2117
size: u64,
2218
}
19+
2320
/// Global statistic for memory-mapped files.
24-
static MEMMAP_FILE_STATS: Lazy<MemMapFileStat> = Lazy::new(MemMapFileStat::default);
21+
static MEMMAP_FILE_STATS: Lazy<Arc<RwLock<MemMapFileStat>>> =
22+
Lazy::new(|| Arc::new(RwLock::new(MemMapFileStat::default())));
2523

2624
/// Memory-mapped file statistic.
2725
#[derive(Debug, Default, Clone, Serialize)]
28-
pub struct MemMapFileStat(Arc<MemMapFileStatInner>);
29-
30-
/// Internal structure to hold stats.
31-
struct MemMapFileStatInner {
26+
pub struct MemMapFileStat {
3227
/// A counter for the number of memory-mapped files.
33-
file_count: AtomicU64,
28+
file_count: u64,
3429
/// The total size of memory-mapped files.
35-
total_size: AtomicU64,
30+
total_size: u64,
3631
/// The amount of time that memory-mapped files have been dropped.
37-
drop_count: AtomicU64,
32+
drop_count: u64,
3833
/// The total size of memory-mapped files that have been dropped.
39-
drop_size: AtomicU64,
34+
drop_size: u64,
4035
/// A count of errors encountered.
41-
error_count: AtomicU64,
36+
error_count: u64,
4237
}
4338

4439
impl MemMapFileStat {
4540
/// Get the statistic file count.
4641
#[must_use]
4742
pub fn file_count(&self) -> u64 {
48-
self.0.file_count.load(Ordering::SeqCst)
43+
self.file_count
4944
}
5045

5146
/// Get the statistic total size.
5247
#[must_use]
5348
pub fn total_size(&self) -> u64 {
54-
self.0.total_size.load(Ordering::SeqCst)
49+
self.total_size
5550
}
5651

5752
/// Get the statistic drop count.
5853
#[must_use]
5954
pub fn drop_count(&self) -> u64 {
60-
self.0.drop_count.load(Ordering::SeqCst)
55+
self.drop_count
6156
}
6257

6358
/// Get the statistic drop size.
6459
#[must_use]
6560
pub fn drop_size(&self) -> u64 {
66-
self.0.drop_size.load(Ordering::SeqCst)
61+
self.drop_size
6762
}
6863

6964
/// Get the statistic error count.
7065
#[must_use]
7166
pub fn error_count(&self) -> u64 {
72-
self.0.error_count.load(Ordering::SeqCst)
67+
self.error_count
7368
}
7469
}
7570

7671
impl MemoryMapFile {
77-
/// Get the memory-mapped file.
78-
pub fn file(&self) -> &MmapFile {
79-
&self.file
80-
}
81-
8272
/// Get the memory-mapped file as a slice.
83-
pub fn file_as_slice(&self) -> &[u8] {
84-
self.file().as_slice()
85-
}
86-
87-
/// Get the size of the memory-mapped file.
88-
pub fn size(&self) -> u64 {
89-
self.size
73+
pub fn as_slice(&self) -> &[u8] {
74+
self.file.as_slice()
9075
}
9176

9277
/// Get the global memory-mapped file statistics.
93-
#[must_use]
94-
pub fn stat() -> &'static MemMapFileStat {
95-
&MEMMAP_FILE_STATS
78+
pub fn stat() -> Option<MemMapFileStat> {
79+
if let Ok(stat) = MEMMAP_FILE_STATS.read() {
80+
Some(stat.clone())
81+
} else {
82+
None
83+
}
9684
}
9785

9886
/// Update the global stats when a file is created.
9987
fn update_create_stat(&self) {
100-
MEMMAP_FILE_STATS
101-
.0
102-
.file_count
103-
.fetch_add(1, Ordering::SeqCst);
104-
MEMMAP_FILE_STATS
105-
.0
106-
.total_size
107-
.fetch_add(self.size, Ordering::SeqCst);
88+
if let Ok(mut stat) = MEMMAP_FILE_STATS.write() {
89+
stat.file_count += 1;
90+
stat.total_size += self.size;
91+
}
10892
}
10993

11094
/// Update the global stats when a file is dropped.
11195
fn update_drop_stat(&self) {
112-
MEMMAP_FILE_STATS
113-
.0
114-
.drop_count
115-
.fetch_add(1, Ordering::SeqCst);
116-
MEMMAP_FILE_STATS
117-
.0
118-
.drop_size
119-
.fetch_add(self.size, Ordering::SeqCst);
96+
if let Ok(mut stat) = MEMMAP_FILE_STATS.write() {
97+
stat.drop_count += 1;
98+
stat.drop_size += self.size;
99+
}
120100
}
121101

122102
/// Update the global error count when an error occurs.
123103
pub fn update_err_stat() {
124-
MEMMAP_FILE_STATS
125-
.0
126-
.error_count
127-
.fetch_add(1, Ordering::SeqCst);
104+
if let Ok(mut stat) = MEMMAP_FILE_STATS.write() {
105+
stat.error_count += 1;
106+
}
128107
}
129108
}
130109

@@ -153,41 +132,3 @@ impl TryFrom<&Path> for MemoryMapFile {
153132
}
154133
}
155134
}
156-
157-
impl Default for MemMapFileStatInner {
158-
fn default() -> Self {
159-
Self {
160-
file_count: AtomicU64::new(0),
161-
total_size: AtomicU64::new(0),
162-
drop_count: AtomicU64::new(0),
163-
drop_size: AtomicU64::new(0),
164-
error_count: AtomicU64::new(0),
165-
}
166-
}
167-
}
168-
169-
impl fmt::Debug for MemMapFileStatInner {
170-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171-
f.debug_struct("MemMapFileStat")
172-
.field("file_count", &self.file_count.load(Ordering::SeqCst))
173-
.field("total_size", &self.total_size.load(Ordering::SeqCst))
174-
.field("drop_count", &self.drop_count.load(Ordering::SeqCst))
175-
.field("drop_size", &self.drop_size.load(Ordering::SeqCst))
176-
.field("error_count", &self.error_count.load(Ordering::SeqCst))
177-
.finish()
178-
}
179-
}
180-
181-
impl Serialize for MemMapFileStatInner {
182-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
183-
where S: Serializer {
184-
let mut state = serializer.serialize_struct("MemMapFileStat", 5)?;
185-
186-
state.serialize_field("file_count", &self.file_count.load(Ordering::SeqCst))?;
187-
state.serialize_field("total_size", &self.total_size.load(Ordering::SeqCst))?;
188-
state.serialize_field("drop_count", &self.drop_count.load(Ordering::SeqCst))?;
189-
state.serialize_field("drop_size", &self.drop_size.load(Ordering::SeqCst))?;
190-
state.serialize_field("error_count", &self.error_count.load(Ordering::SeqCst))?;
191-
state.end()
192-
}
193-
}

0 commit comments

Comments
 (0)