Skip to content

Commit

Permalink
bitmap: add AtomicBitmapArc
Browse files Browse the repository at this point in the history
`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 <aagch@amazon.com>
  • Loading branch information
alexandruag authored and lauralt committed Jul 30, 2021
1 parent 1d15af0 commit 183cdbc
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

### Added

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

Expand Down
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"coverage_score": 88.5,
"coverage_score": 87.6,
"exclude_path": "mmap_windows.rs",
"crate_features": "backend-mmap,backend-atomic,backend-bitmap"
}
86 changes: 86 additions & 0 deletions src/bitmap/backend/atomic_bitmap_arc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause

use std::ops::Deref;
use std::sync::Arc;

use crate::bitmap::{ArcSlice, AtomicBitmap, Bitmap, WithBitmapSlice};

#[cfg(feature = "backend-mmap")]
use crate::mmap::NewBitmap;

/// A `Bitmap` implementation that's based on an atomically reference counted handle to an
/// `AtomicBitmap` object.
pub struct AtomicBitmapArc {
inner: Arc<AtomicBitmap>,
}

impl AtomicBitmapArc {
pub fn new(inner: AtomicBitmap) -> Self {
AtomicBitmapArc {
inner: Arc::new(inner),
}
}
}

// The current clone implementation creates a deep clone of the inner bitmap, as opposed to
// simply cloning the `Arc`.
impl Clone for AtomicBitmapArc {
fn clone(&self) -> Self {
Self::new(self.inner.deref().clone())
}
}

// Providing a `Deref` to `AtomicBitmap` implementation, so the methods of the inner object
// can be called in a transparent manner.
impl Deref for AtomicBitmapArc {
type Target = AtomicBitmap;

fn deref(&self) -> &Self::Target {
self.inner.deref()
}
}

impl WithBitmapSlice<'_> for AtomicBitmapArc {
type S = ArcSlice<AtomicBitmap>;
}

impl Bitmap for AtomicBitmapArc {
fn mark_dirty(&self, offset: usize, len: usize) {
self.inner.set_addr_range(offset, len)
}

fn dirty_at(&self, offset: usize) -> bool {
self.inner.is_addr_set(offset)
}

fn slice_at(&self, offset: usize) -> <Self as WithBitmapSlice>::S {
ArcSlice::new(self.inner.clone(), offset)
}
}

impl Default for AtomicBitmapArc {
fn default() -> Self {
Self::new(AtomicBitmap::default())
}
}

#[cfg(feature = "backend-mmap")]
impl NewBitmap for AtomicBitmapArc {
fn with_len(len: usize) -> Self {
Self::new(AtomicBitmap::with_len(len))
}
}

#[cfg(test)]
mod tests {
use super::*;

use crate::bitmap::tests::test_bitmap;

#[test]
fn test_bitmap_impl() {
let b = AtomicBitmapArc::new(AtomicBitmap::new(0x2000, 128));
test_bitmap(&b);
}
}
4 changes: 3 additions & 1 deletion src/bitmap/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause

mod atomic_bitmap;
mod atomic_bitmap_arc;
mod slice;

pub use atomic_bitmap::AtomicBitmap;
pub use slice::RefSlice;
pub use atomic_bitmap_arc::AtomicBitmapArc;
pub use slice::{ArcSlice, RefSlice};
6 changes: 5 additions & 1 deletion src/bitmap/backend/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use std::fmt::{self, Debug};
use std::ops::Deref;
use std::sync::Arc;

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

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

/// A `BitmapSlice` implementation that uses an `Arc` handle to a `Bitmap` object.
pub type ArcSlice<B> = BaseSlice<Arc<B>>;

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -97,7 +101,7 @@ mod tests {
use crate::bitmap::AtomicBitmap;

#[test]
fn test_ref_slice() {
fn test_slice() {
let bitmap_size = 0x1_0000;
let dirty_offset = 0x1000;
let dirty_len = 0x100;
Expand Down
2 changes: 1 addition & 1 deletion src/bitmap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::fmt::Debug;
use crate::{GuestMemory, GuestMemoryRegion};

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

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

0 comments on commit 183cdbc

Please sign in to comment.