Skip to content

Commit 183cdbc

Browse files
alexandruaglauralt
authored andcommitted
bitmap: add AtomicBitmapArc
`AtomicBitmapArc` wraps an `AtomicBitmap` instance to provide a `Bitmap` implementation that uses slices which are based on `Arc` instead of references with their associated lifetimes. Signed-off-by: Alexandru Agache <[email protected]>
1 parent 1d15af0 commit 183cdbc

File tree

6 files changed

+98
-4
lines changed

6 files changed

+98
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
### Added
55

6+
- [[#160]](https://github.com/rust-vmm/vm-memory/pull/160): Add `ArcRef` and `AtomicBitmapArc` bitmap
7+
backend implementations.
68
- [[#149]](https://github.com/rust-vmm/vm-memory/issues/149): Implement builder for MmapRegion.
79
- [[#140]](https://github.com/rust-vmm/vm-memory/issues/140): Add dirty bitmap tracking abstractions.
810

coverage_config_x86_64.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"coverage_score": 88.5,
2+
"coverage_score": 87.6,
33
"exclude_path": "mmap_windows.rs",
44
"crate_features": "backend-mmap,backend-atomic,backend-bitmap"
55
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
3+
4+
use std::ops::Deref;
5+
use std::sync::Arc;
6+
7+
use crate::bitmap::{ArcSlice, AtomicBitmap, Bitmap, WithBitmapSlice};
8+
9+
#[cfg(feature = "backend-mmap")]
10+
use crate::mmap::NewBitmap;
11+
12+
/// A `Bitmap` implementation that's based on an atomically reference counted handle to an
13+
/// `AtomicBitmap` object.
14+
pub struct AtomicBitmapArc {
15+
inner: Arc<AtomicBitmap>,
16+
}
17+
18+
impl AtomicBitmapArc {
19+
pub fn new(inner: AtomicBitmap) -> Self {
20+
AtomicBitmapArc {
21+
inner: Arc::new(inner),
22+
}
23+
}
24+
}
25+
26+
// The current clone implementation creates a deep clone of the inner bitmap, as opposed to
27+
// simply cloning the `Arc`.
28+
impl Clone for AtomicBitmapArc {
29+
fn clone(&self) -> Self {
30+
Self::new(self.inner.deref().clone())
31+
}
32+
}
33+
34+
// Providing a `Deref` to `AtomicBitmap` implementation, so the methods of the inner object
35+
// can be called in a transparent manner.
36+
impl Deref for AtomicBitmapArc {
37+
type Target = AtomicBitmap;
38+
39+
fn deref(&self) -> &Self::Target {
40+
self.inner.deref()
41+
}
42+
}
43+
44+
impl WithBitmapSlice<'_> for AtomicBitmapArc {
45+
type S = ArcSlice<AtomicBitmap>;
46+
}
47+
48+
impl Bitmap for AtomicBitmapArc {
49+
fn mark_dirty(&self, offset: usize, len: usize) {
50+
self.inner.set_addr_range(offset, len)
51+
}
52+
53+
fn dirty_at(&self, offset: usize) -> bool {
54+
self.inner.is_addr_set(offset)
55+
}
56+
57+
fn slice_at(&self, offset: usize) -> <Self as WithBitmapSlice>::S {
58+
ArcSlice::new(self.inner.clone(), offset)
59+
}
60+
}
61+
62+
impl Default for AtomicBitmapArc {
63+
fn default() -> Self {
64+
Self::new(AtomicBitmap::default())
65+
}
66+
}
67+
68+
#[cfg(feature = "backend-mmap")]
69+
impl NewBitmap for AtomicBitmapArc {
70+
fn with_len(len: usize) -> Self {
71+
Self::new(AtomicBitmap::with_len(len))
72+
}
73+
}
74+
75+
#[cfg(test)]
76+
mod tests {
77+
use super::*;
78+
79+
use crate::bitmap::tests::test_bitmap;
80+
81+
#[test]
82+
fn test_bitmap_impl() {
83+
let b = AtomicBitmapArc::new(AtomicBitmap::new(0x2000, 128));
84+
test_bitmap(&b);
85+
}
86+
}

src/bitmap/backend/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
33

44
mod atomic_bitmap;
5+
mod atomic_bitmap_arc;
56
mod slice;
67

78
pub use atomic_bitmap::AtomicBitmap;
8-
pub use slice::RefSlice;
9+
pub use atomic_bitmap_arc::AtomicBitmapArc;
10+
pub use slice::{ArcSlice, RefSlice};

src/bitmap/backend/slice.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
use std::fmt::{self, Debug};
77
use std::ops::Deref;
8+
use std::sync::Arc;
89

910
use crate::bitmap::{Bitmap, BitmapSlice, WithBitmapSlice};
1011

@@ -89,6 +90,9 @@ impl<B: Default> Default for BaseSlice<B> {
8990
/// A `BitmapSlice` implementation that wraps a reference to a `Bitmap` object.
9091
pub type RefSlice<'a, B> = BaseSlice<&'a B>;
9192

93+
/// A `BitmapSlice` implementation that uses an `Arc` handle to a `Bitmap` object.
94+
pub type ArcSlice<B> = BaseSlice<Arc<B>>;
95+
9296
#[cfg(test)]
9397
mod tests {
9498
use super::*;
@@ -97,7 +101,7 @@ mod tests {
97101
use crate::bitmap::AtomicBitmap;
98102

99103
#[test]
100-
fn test_ref_slice() {
104+
fn test_slice() {
101105
let bitmap_size = 0x1_0000;
102106
let dirty_offset = 0x1000;
103107
let dirty_len = 0x100;

src/bitmap/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::fmt::Debug;
1414
use crate::{GuestMemory, GuestMemoryRegion};
1515

1616
#[cfg(any(test, feature = "backend-bitmap"))]
17-
pub use backend::{AtomicBitmap, RefSlice};
17+
pub use backend::{ArcSlice, AtomicBitmap, RefSlice};
1818

1919
/// Trait implemented by types that support creating `BitmapSlice` objects.
2020
pub trait WithBitmapSlice<'a> {

0 commit comments

Comments
 (0)