pub struct Workspace { /* private fields */ }Expand description
A caller-owned, bounded workspace: an ArenaProvider pre-sized to one
WorkspaceReq, so a steady-state execute whose requirement is within the
bound allocates nothing.
A plan computes a conservative requirement (Plan::workspace_req in the
owning crate) and execute_raw_in checks it component-wise against
Workspace::req before any write. The bound is grow-only and component-wise:
Workspace::reserve keeps the maximum of each field, so a large A block
does not stand in for a missing B panel. A parallel executor must call
Workspace::prepare_for so every worker slot is warmed before the execute.
§Examples
use tcontract_exec::{Workspace, WorkspaceReq};
let mut ws = Workspace::with_req(&WorkspaceReq { a_bytes: 64, ..Default::default() });
assert!(ws.req().a_bytes >= 64);
ws.reserve(&WorkspaceReq { b_bytes: 128, ..Default::default() });
// Component-wise: the A block is kept and the B panel is added.
assert!(ws.req().a_bytes >= 64 && ws.req().b_bytes >= 128);
let _provider = ws.as_provider();Implementations§
Source§impl Workspace
impl Workspace
Sourcepub fn with_req(req: &WorkspaceReq) -> Self
pub fn with_req(req: &WorkspaceReq) -> Self
A workspace sized and warmed for req: the worker slot of the calling
thread and one team set are grown to hold it, so a later execute within
the bound does not grow the arena.
Sourcepub fn reserve(&mut self, req: &WorkspaceReq)
pub fn reserve(&mut self, req: &WorkspaceReq)
Grow the bound to cover req as well, component-wise. The bound never
shrinks, and every field keeps its own maximum.
Sourcepub fn req(&self) -> &WorkspaceReq
pub fn req(&self) -> &WorkspaceReq
The per-component bound this workspace was sized to.
Sourcepub fn slots(&self) -> usize
pub fn slots(&self) -> usize
How many worker slots have been warmed. Workspace::prepare_for raises
it to the executor’s budget.
Sourcepub fn prepare_for(&mut self, exec: &Exec<'_>)
pub fn prepare_for(&mut self, exec: &Exec<'_>)
Warm one worker slot per worker the executor may run on, so a parallel
execute within the bound does not allocate a slot per lane. broadcast
runs the closure on budget distinct workers, one call to with_worker
each; a context that cannot co-schedule (a serial one or a same-pool
worker) keeps the calling thread’s slot only.
Sourcepub fn as_provider(&self) -> &dyn WorkspaceProvider
pub fn as_provider(&self) -> &dyn WorkspaceProvider
The provider a plan lends to the driver for one call.
Sourcepub fn retained_bytes(&self) -> usize
pub fn retained_bytes(&self) -> usize
Bytes the owner currently retains, idle or in use. A test observes it to prove an execute did not grow the arena.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Workspace
impl RefUnwindSafe for Workspace
impl Send for Workspace
impl Sync for Workspace
impl Unpin for Workspace
impl UnsafeUnpin for Workspace
impl UnwindSafe for Workspace
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more