SpawnOpts { stack_reserve, guard_size } with Option<usize> fields, None
resolving to the Config defaults at spawn time — a deliberate deviation
from the RFC's plain-usize struct so struct-update syntax works without
a runtime handle in scope. Threaded across the five surfaces:
spawn_with, spawn_under_with, spawn_addr_with,
GenServerBuilder::stack_opts (mirrored on NamedGenServerBuilder), and
gen_statem::spawn_with (gen_statem has no builder, so the opts ride a
_with variant — Claude-solo surface call, flagged for review). Existing
spawns forward defaults; no call-site churn.
introspect::stack_shape(pid) pulled forward (agreed) as the first slice
of the RFC 019 introspection surface, giving tests an observable.
Tests (tests/spawn_opts.rs): override/partial-override/rounding on each
surface; obligation 4 from the outside — a dead custom stack is never
handed to the next default spawn (LIFO pool would expose it), and the
reverse (default stacks ARE recycled); 8 MiB reserve behaviorally
permits ~1 MiB recursion. Also: silence unused-Result in the c1
runtime test (join now unwrapped).
105 lines
3.7 KiB
Rust
105 lines
3.7 KiB
Rust
//! # smarm — Silly Marks Abstract Rust Machine
|
|
//!
|
|
//! Erlang-style green-thread actor concurrency for Rust.
|
|
//!
|
|
//! Multi-threaded: N scheduler OS threads (default: one per CPU) share a
|
|
//! single global run queue behind a `Mutex`. Actors communicate by sending
|
|
//! `Send` messages over channels; every actor has a supervisor. Synchronisation
|
|
//! primitives — `Mutex<T>` with mandatory lock timeouts, channel `recv`,
|
|
//! `sleep`, and epoll-backed `wait_readable`/`wait_writable` — all park the
|
|
//! green thread, never the OS thread.
|
|
//!
|
|
//! See `LOOM.md` for the design intent and the deferred-for-later list.
|
|
|
|
pub mod stack;
|
|
pub mod context;
|
|
pub mod preempt;
|
|
pub mod pid;
|
|
pub mod actor;
|
|
pub mod channel;
|
|
pub mod scheduler;
|
|
pub mod supervisor;
|
|
pub mod timer;
|
|
pub mod io;
|
|
pub mod mutex;
|
|
pub mod monitor;
|
|
pub mod registry;
|
|
pub mod pg;
|
|
pub mod link;
|
|
pub mod gen_server;
|
|
pub mod gen_statem;
|
|
pub mod introspect;
|
|
#[cfg(feature = "observer")]
|
|
pub mod observer;
|
|
pub mod runtime;
|
|
pub(crate) mod park;
|
|
pub(crate) mod raw_mutex;
|
|
pub(crate) mod slot_state;
|
|
pub(crate) mod sync_shim;
|
|
#[doc(hidden)] // pub only so benches/rq_micro.rs can drive the raw structures
|
|
pub mod run_queue;
|
|
pub mod trace;
|
|
pub mod causal;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Global allocator
|
|
// ---------------------------------------------------------------------------
|
|
|
|
#[global_allocator]
|
|
static ALLOCATOR: preempt::PreemptingAllocator = preempt::PreemptingAllocator;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Public API re-exports
|
|
// ---------------------------------------------------------------------------
|
|
|
|
pub use channel::{
|
|
channel, select, select_timeout, try_select, try_select_timeout, Receiver, RecvError,
|
|
RecvTimeoutError, Selectable, Sender,
|
|
};
|
|
pub use gen_server::{
|
|
call, cast, shutdown, whereis_server, CallError, CallTimeoutError, CastError, GenServer,
|
|
NamedGenServerBuilder, GenServerBuilder, GenServerCtx, GenServerName, GenServerRef, TimerHandle, Watcher,
|
|
};
|
|
pub use gen_statem::{
|
|
CallError as GenStatemCallError, Cx, Machine, Reply, Resolution, SendError as GenStatemSendError,
|
|
GenStatemRef,
|
|
};
|
|
pub use introspect::{
|
|
actor_info, snapshot, tree, tree_from, ActorInfo, ActorState, RuntimeSnapshot, RuntimeTree,
|
|
TreeNode, SNAPSHOT_FORMAT_VERSION,
|
|
};
|
|
#[cfg(feature = "observer")]
|
|
pub use observer::{ObserverReply, ObserverRequest};
|
|
pub use link::{link, trap_exit, unlink, ExitSignal};
|
|
pub use monitor::{demonitor, monitor, Down, DownReason, Monitor, MonitorId};
|
|
pub use mutex::{LockTimeout, Mutex, MutexGuard};
|
|
pub use pid::{Addressable, Erased, Name, Pid, RawPid};
|
|
pub use pg::{dispatch, join, leave, members, members_as, pick, pick_as, Incarnation, Member, NodeId};
|
|
pub use registry::{
|
|
install, lookup_as, register, send, send_dyn, send_to, unregister, whereis, RegisterError,
|
|
SendError,
|
|
};
|
|
pub use runtime::{init, Config, Runtime};
|
|
pub use scheduler::{
|
|
block_on_io, cancel_timer, request_stop, run, self_pid, send_after, send_after_named,
|
|
send_after_named_wall, send_after_wall, sleep, sleep_wall,
|
|
spawn, spawn_addr, spawn_addr_with, spawn_under, spawn_under_with, spawn_with,
|
|
wait_readable, wait_readable_timeout, wait_writable,
|
|
wait_writable_timeout, yield_now, FdArm, JoinError, JoinHandle, SpawnOpts,
|
|
};
|
|
pub use supervisor::{ChildSpec, OneForOne, Restart, Signal, Strategy};
|
|
pub use timer::TimerId;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// check!()
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/// Voluntarily check whether this actor's timeslice has expired, yielding
|
|
/// if so.
|
|
#[macro_export]
|
|
macro_rules! check {
|
|
() => {
|
|
$crate::preempt::maybe_preempt()
|
|
};
|
|
}
|