Runtime

Struct Runtime 

Source
pub struct Runtime { /* private fields */ }
Expand description

Global state manager for the Zombie runtime.

Implementations§

Source§

impl Runtime

Source

pub fn new() -> Self

Create a new Runtime with default config.

Source

pub fn with_config(config: ZombieConfig) -> Self

Create with custom config.

Note: This also initializes UFArena if not already done. This ensures Runtime::new() can be used directly in tests.

Source

pub fn init()

Initialize thread-local Runtime.

§Panics

This function does not panic. If already initialized, the old state is replaced (useful for test isolation).

Source

pub fn init_with_config(config: ZombieConfig)

Initialize with custom config.

§Panics

This function does not panic. If already initialized, the old state is replaced (useful for test isolation).

Source

pub fn is_initialized() -> bool

Check if Runtime is initialized on the current thread.

Source

pub fn with<R, F: FnOnce(&Runtime) -> R>(f: F) -> R

Access thread-local Runtime (immutable).

§Panics

Panics if Runtime::init() has not been called on this thread.

Source

pub fn with_mut<R, F: FnOnce(&mut Runtime) -> R>(f: F) -> R

Access thread-local Runtime (mutable).

§Panics

Panics if Runtime::init() has not been called on this thread.

Source

pub fn try_with<R, F: FnOnce(&Runtime) -> R>(f: F) -> Option<R>

Try to access thread-local Runtime without panicking.

Returns None if not initialized.

Source

pub fn try_with_mut<R, F: FnOnce(&mut Runtime) -> R>(f: F) -> Option<R>

Try to access thread-local Runtime mutably without panicking.

Returns None if not initialized.

Source

pub fn has_memory_limit(&self) -> bool

Check if memory_limit is set (eviction enabled).

This is a simple field access, used to skip expensive operations when eviction is disabled.

Source

pub fn tick(&mut self) -> Tock

Allocate a tock and return the old value (post-increment).

Source

pub fn current_tock(&self) -> Tock

Get current tock without advancing.

Source

pub fn set_tock(&mut self, tock: Tock)

Set current tock (for replay).

Source

pub fn find_context_with_key( &mut self, tock: Tock, ) -> Option<(Tock, &Rc<dyn ContextNode>)>

Find context containing a tock (with its start key).

Source

pub fn find_context_and_value<T: 'static + Clone + ZombieOps>( &mut self, tock: Tock, ) -> Option<ContextLookupResult<'_, T>>

Find context and typed value for a given tock. Returns (context_start_tock, context_ref, typed_node) if found. This is an optimized version that returns the context for caching during bind setup.

Source

pub fn find_replay_context( &mut self, target_tock: Tock, ) -> Option<(Tock, &Rc<dyn ContextNode>)>

Finds the context to replay from for a given target tock.

Returns the context that can replay to recreate the target value. There are two cases:

  1. Target is in a context that still exists: use that context’s start_tock
  2. Target was in a context that was deleted (evicted): use predecessor’s end_tock

Returns (replay_from_tock, context) for replay initialization.

Source

pub fn insert_context(&mut self, start: Tock, ctx: Rc<dyn ContextNode>)

Insert a context.

Source

pub fn remove_context(&mut self, start: Tock)

Remove a context.

Source

pub fn current_record(&self) -> &Record

Get current record (top of record stack).

§Safety Invariant

Uses unwrap() because the record stack is guaranteed non-empty after initialization. See the documentation on the records field.

Source

pub fn current_record_mut(&mut self) -> &mut Record

Get current record mutably.

§Safety Invariant

Uses unwrap() because the record stack is guaranteed non-empty after initialization. See the documentation on the records field.

Source

pub fn push_head_record(&mut self, replayer: Rc<Replayer>, start_tock: Tock)

Push a HeadRecord for a new computation.

Source

pub fn is_current_record_tailcall(&self) -> bool

Check if current record is a HeadRecord (tailcall context)

Source

pub fn suspend_record(&mut self, replayer: Rc<Replayer>) -> bool

Suspend current record (creates context). Returns true if this was a tailcall (HeadRecord suspend).

Source

pub fn replace_head_record(&mut self, replayer: Rc<Replayer>, start_tock: Tock)

Replace current record with a new HeadRecord (for tailcall semantics). This is used when an inner bind happens inside a HeadRecord.

Source

pub fn finish_record(&mut self, result_tock: Tock) -> bool

Finish record with result (creates ValueRecord). Returns true if actually finished, false if record was already replaced by tailcall.

Source

pub fn get_weak(&mut self, tock: Tock) -> Option<Weak<dyn EZombieNode>>

Get a weak reference to a zombie node by its tock.

Source

pub fn pop_value_record(&mut self) -> Tock

Pop value record and resume parent, return result tock.

Source

pub fn prepare_replay_current_record(&mut self) -> (Rc<Replayer>, ReplayInputs)

Prepare replay for current record.

Source

pub fn get_replay_inputs_for_replayer( &mut self, replayer: &Rc<Replayer>, ) -> ReplayInputs

Get replay inputs for a replayer without marking as played. Used when resuming from a nested replay (WaitingForInput state).

Source

pub fn pop_record_after_replay(&mut self)

Pop record after replay completes (should be empty HeadRecord).

Source

pub fn register_dependency(&mut self, tock: Tock)

Register a dependency on the current record.

Source

pub fn push_replay( &mut self, target: Tock, result: Rc<RefCell<Option<Rc<dyn EZombieNode>>>>, )

Push replay state.

Source

pub fn pop_replay(&mut self) -> Option<Rc<dyn EZombieNode>>

Pop replay state and return result.

Source

pub fn at_replay_target(&self, tock: Tock) -> bool

Check if we’ve reached current replay target.

Source

pub fn set_replay_result(&self, node: Rc<dyn EZombieNode>)

Set replay result.

Source

pub fn replay_has_result(&self) -> bool

Check if current replay has result.

Source

pub fn current_replay_target(&self) -> Tock

Get current replay target.

Source

pub fn replay_depth(&self) -> usize

Replay depth (1 = not replaying).

Source

pub fn should_unroll(&self) -> bool

Check if we should unroll (skip creating context).

C++ implementation:

if (t.records.back()->is_tailcall() && t.current_tock - t.records.back()->t < unroll_factor) {
    // unroll
}

We only unroll when:

  1. Current record is a tailcall (HeadRecord)
  2. The tock delta is within unroll_factor
Source

pub fn unroll_factor(&self) -> usize

Get unroll factor from config.

Source

pub fn touch_context(&mut self, pool_index: usize)

Touch a context in the GD heap to update its priority - O(log n).

This implements the “access recency” part of the Greedy-Dual algorithm. When a context is accessed (its values read), we touch it to delay eviction.

Uses pool_index stored in FullContext for O(1) lookup + O(log n) rebalance, matching the C++ implementation’s performance characteristics.

§Performance
  • O(log n) using pool_index (like C++ implementation)
  • Only called when memory_limit is set (eviction enabled)
  • Only called from slow path (cache miss)
Source

pub fn evict_one_with_protection( &mut self, protected_tock: Option<Tock>, ) -> bool

Evict one context from the heap. protected_tock specifies a context start_tock that should be skipped.

Source

pub fn total_space(&self) -> usize

Get total space used by all contexts in the heap (O(1)).

Source

pub fn maybe_evict(&mut self)

Check memory limit and evict if necessary. This is called after creating new zombie values.

Source

pub fn maybe_evict_with_protection(&mut self, protected_tock: Option<Tock>)

Check memory limit and evict if necessary, with a protected context. The context with start_tock = protected_tock will not be evicted.

Source

pub fn evict_one(&mut self) -> bool

Evict one context (convenience wrapper).

Source

pub fn meter(&self) -> &ZombieMeter

Get meter reference.

Source

pub fn meter_mut(&mut self) -> &mut ZombieMeter

Get meter mutable reference.

Source

pub fn context_count(&self) -> usize

Number of contexts in tock tree.

Source

pub fn metadata_bytes(&self) -> usize

Estimated metadata memory usage in bytes.

This includes:

  • Contexts (FullContext, RootContext) with their SmallVecs
  • GD heap entries
  • Tock tree (SplayList) nodes

Does NOT include user data (the actual Zombie values).

Source

pub fn heap_len(&self) -> usize

Number of entries in the GD heap.

Trait Implementations§

Source§

impl Default for Runtime

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Runtime

§

impl !RefUnwindSafe for Runtime

§

impl !Send for Runtime

§

impl !Sync for Runtime

§

impl Unpin for Runtime

§

impl !UnwindSafe for Runtime

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.