pub struct Runtime { /* private fields */ }Expand description
Global state manager for the Zombie runtime.
Implementations§
Source§impl Runtime
impl Runtime
Sourcepub fn with_config(config: ZombieConfig) -> Self
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.
Sourcepub fn init()
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).
Sourcepub fn init_with_config(config: ZombieConfig)
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).
Sourcepub fn is_initialized() -> bool
pub fn is_initialized() -> bool
Check if Runtime is initialized on the current thread.
Sourcepub fn with<R, F: FnOnce(&Runtime) -> R>(f: F) -> R
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.
Sourcepub fn with_mut<R, F: FnOnce(&mut Runtime) -> R>(f: F) -> R
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.
Sourcepub fn try_with<R, F: FnOnce(&Runtime) -> R>(f: F) -> Option<R>
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.
Sourcepub fn try_with_mut<R, F: FnOnce(&mut Runtime) -> R>(f: F) -> Option<R>
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.
Sourcepub fn has_memory_limit(&self) -> bool
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.
Sourcepub fn current_tock(&self) -> Tock
pub fn current_tock(&self) -> Tock
Get current tock without advancing.
Sourcepub fn find_context_with_key(
&mut self,
tock: Tock,
) -> Option<(Tock, &Rc<dyn ContextNode>)>
pub fn find_context_with_key( &mut self, tock: Tock, ) -> Option<(Tock, &Rc<dyn ContextNode>)>
Find context containing a tock (with its start key).
Sourcepub fn find_context_and_value<T: 'static + Clone + ZombieOps>(
&mut self,
tock: Tock,
) -> Option<ContextLookupResult<'_, T>>
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.
Sourcepub fn find_replay_context(
&mut self,
target_tock: Tock,
) -> Option<(Tock, &Rc<dyn ContextNode>)>
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:
- Target is in a context that still exists: use that context’s start_tock
- Target was in a context that was deleted (evicted): use predecessor’s end_tock
Returns (replay_from_tock, context) for replay initialization.
Sourcepub fn insert_context(&mut self, start: Tock, ctx: Rc<dyn ContextNode>)
pub fn insert_context(&mut self, start: Tock, ctx: Rc<dyn ContextNode>)
Insert a context.
Sourcepub fn remove_context(&mut self, start: Tock)
pub fn remove_context(&mut self, start: Tock)
Remove a context.
Sourcepub fn current_record(&self) -> &Record
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.
Sourcepub fn current_record_mut(&mut self) -> &mut Record
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.
Sourcepub fn push_head_record(&mut self, replayer: Rc<Replayer>, start_tock: Tock)
pub fn push_head_record(&mut self, replayer: Rc<Replayer>, start_tock: Tock)
Push a HeadRecord for a new computation.
Sourcepub fn is_current_record_tailcall(&self) -> bool
pub fn is_current_record_tailcall(&self) -> bool
Check if current record is a HeadRecord (tailcall context)
Sourcepub fn suspend_record(&mut self, replayer: Rc<Replayer>) -> bool
pub fn suspend_record(&mut self, replayer: Rc<Replayer>) -> bool
Suspend current record (creates context). Returns true if this was a tailcall (HeadRecord suspend).
Sourcepub fn replace_head_record(&mut self, replayer: Rc<Replayer>, start_tock: Tock)
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.
Sourcepub fn finish_record(&mut self, result_tock: Tock) -> bool
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.
Sourcepub fn get_weak(&mut self, tock: Tock) -> Option<Weak<dyn EZombieNode>>
pub fn get_weak(&mut self, tock: Tock) -> Option<Weak<dyn EZombieNode>>
Get a weak reference to a zombie node by its tock.
Sourcepub fn pop_value_record(&mut self) -> Tock
pub fn pop_value_record(&mut self) -> Tock
Pop value record and resume parent, return result tock.
Sourcepub fn prepare_replay_current_record(&mut self) -> (Rc<Replayer>, ReplayInputs)
pub fn prepare_replay_current_record(&mut self) -> (Rc<Replayer>, ReplayInputs)
Prepare replay for current record.
Sourcepub fn get_replay_inputs_for_replayer(
&mut self,
replayer: &Rc<Replayer>,
) -> ReplayInputs
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).
Sourcepub fn pop_record_after_replay(&mut self)
pub fn pop_record_after_replay(&mut self)
Pop record after replay completes (should be empty HeadRecord).
Sourcepub fn register_dependency(&mut self, tock: Tock)
pub fn register_dependency(&mut self, tock: Tock)
Register a dependency on the current record.
Sourcepub fn push_replay(
&mut self,
target: Tock,
result: Rc<RefCell<Option<Rc<dyn EZombieNode>>>>,
)
pub fn push_replay( &mut self, target: Tock, result: Rc<RefCell<Option<Rc<dyn EZombieNode>>>>, )
Push replay state.
Sourcepub fn pop_replay(&mut self) -> Option<Rc<dyn EZombieNode>>
pub fn pop_replay(&mut self) -> Option<Rc<dyn EZombieNode>>
Pop replay state and return result.
Sourcepub fn at_replay_target(&self, tock: Tock) -> bool
pub fn at_replay_target(&self, tock: Tock) -> bool
Check if we’ve reached current replay target.
Sourcepub fn set_replay_result(&self, node: Rc<dyn EZombieNode>)
pub fn set_replay_result(&self, node: Rc<dyn EZombieNode>)
Set replay result.
Sourcepub fn replay_has_result(&self) -> bool
pub fn replay_has_result(&self) -> bool
Check if current replay has result.
Sourcepub fn current_replay_target(&self) -> Tock
pub fn current_replay_target(&self) -> Tock
Get current replay target.
Sourcepub fn replay_depth(&self) -> usize
pub fn replay_depth(&self) -> usize
Replay depth (1 = not replaying).
Sourcepub fn should_unroll(&self) -> bool
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:
- Current record is a tailcall (HeadRecord)
- The tock delta is within unroll_factor
Sourcepub fn unroll_factor(&self) -> usize
pub fn unroll_factor(&self) -> usize
Get unroll factor from config.
Sourcepub fn touch_context(&mut self, pool_index: usize)
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_limitis set (eviction enabled) - Only called from slow path (cache miss)
Sourcepub fn evict_one_with_protection(
&mut self,
protected_tock: Option<Tock>,
) -> bool
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.
Sourcepub fn total_space(&self) -> usize
pub fn total_space(&self) -> usize
Get total space used by all contexts in the heap (O(1)).
Sourcepub fn maybe_evict(&mut self)
pub fn maybe_evict(&mut self)
Check memory limit and evict if necessary. This is called after creating new zombie values.
Sourcepub fn maybe_evict_with_protection(&mut self, protected_tock: Option<Tock>)
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.
Sourcepub fn meter(&self) -> &ZombieMeter
pub fn meter(&self) -> &ZombieMeter
Get meter reference.
Sourcepub fn meter_mut(&mut self) -> &mut ZombieMeter
pub fn meter_mut(&mut self) -> &mut ZombieMeter
Get meter mutable reference.
Sourcepub fn context_count(&self) -> usize
pub fn context_count(&self) -> usize
Number of contexts in tock tree.
Sourcepub fn metadata_bytes(&self) -> usize
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).