Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a ResourceLimiter for tracking allocations #300

Merged
merged 2 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions lib/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,16 +350,13 @@ impl ExecuteCtx {
// sent during execution.
store.data_mut().close_downstream_response_sender();

let heap_pages = instance
.get_memory(&mut store, "memory")
.expect("`memory` is exported")
.size(&store);
let heap_bytes = store.data().limiter().memory_allocated;

let request_duration = Instant::now().duration_since(start_timestamp);

info!(
"request completed using {} of WebAssembly heap",
bytesize::ByteSize::kib(heap_pages * 64)
bytesize::ByteSize::b(heap_bytes as u64)
);

info!("request completed in {:.0?}", request_duration);
Expand Down
37 changes: 37 additions & 0 deletions lib/src/linking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,42 @@ use {
wasmtime_wasi_nn::WasiNnCtx,
};

#[derive(Default)]
pub struct Limiter {
/// Total memory allocated so far.
pub memory_allocated: usize,
}

impl wasmtime::ResourceLimiter for Limiter {
fn memory_growing(
&mut self,
current: usize,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we confirm that this starts at zero? In other words, is memory_growing called when the initial heap for an instance is set up?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interface for allocating new Memory structures in wasmtime is Memory::new_dynamic and Memory::new_static. Both dispatch to Memory::limit_new, which will call memory_growing with a current value of 0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you for checking!

desired: usize,
_maximum: Option<usize>,
) -> anyhow::Result<bool> {
// Track the diff in memory allocated over time. As each instance will start with 0 and
// gradually resize, this will track the total allocations throughout the lifetime of the
// instance.
self.memory_allocated += desired - current;
Ok(true)
}

fn table_growing(
&mut self,
_current: u32,
_desired: u32,
_maximum: Option<u32>,
) -> anyhow::Result<bool> {
Ok(true)
}
}

pub struct WasmCtx {
wasi: WasiCtx,
wasi_nn: WasiNnCtx,
session: Session,
guest_profiler: Option<Box<GuestProfiler>>,
limiter: Limiter,
}

impl WasmCtx {
Expand All @@ -36,6 +67,10 @@ impl WasmCtx {
pub fn take_guest_profiler(&mut self) -> Option<Box<GuestProfiler>> {
self.guest_profiler.take()
}

pub fn limiter(&self) -> &Limiter {
&self.limiter
}
}

impl WasmCtx {
Expand All @@ -60,6 +95,7 @@ pub(crate) fn create_store(
wasi_nn,
session,
guest_profiler: guest_profiler.map(Box::new),
limiter: Limiter::default(),
};
let mut store = Store::new(ctx.engine(), wasm_ctx);
store.set_epoch_deadline(1);
Expand All @@ -70,6 +106,7 @@ pub(crate) fn create_store(
}
Ok(UpdateDeadline::Yield(1))
});
store.limiter(|ctx| &mut ctx.limiter);
Ok(store)
}

Expand Down