Files
ruin/lib/runtime/src/lib.rs
2026-05-16 16:38:10 -04:00

139 lines
5.0 KiB
Rust

//! Runtime, driver, async I/O, and channel primitives for RUIN.
//!
//! The crate is centered around a single-threaded event loop with explicit worker threads,
//! JavaScript-style microtask/macrotask scheduling and platform-specific async I/O backends.
//!
//! Most users will start with:
//!
//! - [`main`] or [`async_main`] for executable entry points
//! - [`run`], [`queue_task`], [`queue_microtask`], and [`queue_future`] for event-loop work
//! - [`fs`], [`net`], [`time`], and [`channel`] for async runtime services
//!
//! # Platform support
//!
//! `ruin-runtime` currently targets:
//! - Linux `x86_64`
//! - macOS `aarch64`
//!
//! RUIN runtime foundations.
//!
//! This crate provides a platform runtime substrate with a single-threaded runtime loop and
//! worker-thread task forwarding.
#![feature(thread_local)]
#[cfg(not(any(
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64")
)))]
compile_error!("ruin-runtime currently supports Linux x86_64 and macOS aarch64.");
extern crate alloc;
pub(crate) mod trace_targets {
pub const DRIVER: &str = "ruin_runtime::driver";
pub const RUNTIME: &str = "ruin_runtime::runtime";
pub const SCHEDULER: &str = "ruin_runtime::scheduler";
#[cfg(debug_assertions)]
pub const TIMER: &str = "ruin_runtime::timer";
#[cfg(debug_assertions)]
pub const ASYNC: &str = "ruin_runtime::async";
}
pub mod channel;
pub mod fd;
pub mod fs;
pub mod net;
#[doc(hidden)]
pub mod op;
#[doc(hidden)]
pub mod platform;
pub mod stdio;
#[doc(hidden)]
pub mod sys;
pub mod time;
/// Marks an `async fn main()` as the runtime entry point.
///
/// The macro generates a real Rust `main` that queues the returned future onto the main runtime
/// thread before calling [`run`].
pub use ruin_runtime_proc_macros::async_main;
/// Marks a synchronous `fn main()` as the runtime entry point.
///
/// The macro generates a real Rust `main` that queues the function body onto the main runtime
/// thread before calling [`run`].
pub use ruin_runtime_proc_macros::main;
/// Driver primitives re-exported from the active backend.
#[cfg(any(
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64")
))]
pub use platform::current::driver::{
Driver, ReadyEvents, ThreadNotifier, create, create_driver, monotonic_now,
};
/// Runtime/event-loop primitives re-exported from the active backend.
#[cfg(any(
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "macos", target_arch = "aarch64")
))]
pub use platform::current::runtime::{
IntervalHandle, JoinHandle, ThreadHandle, TimeoutHandle, WorkerHandle, clear_interval,
clear_timeout, current_thread_handle, queue_future, queue_microtask, queue_task, run,
run_ready_tasks, run_until_stalled, set_interval, set_timeout, spawn_worker, yield_now,
};
/// Public mesh-allocator surface re-exported from the Linux x86_64 backend.
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub use platform::linux_x86_64::mesh_alloc::{
ActiveMeshGuard, Arena, AtomicBitmap, BitIter, CLASS_TO_SIZE, CompactionAdvice,
CompactionEstimate, CompactionRecommendation, CompactionSkipReason,
DEFAULT_GLOBAL_MINIHEAP_CAPACITY, FutexMutex, GlobalMeshAllocator, MeshAllocator, MeshStats,
MiniHeap, MiniHeapFlags, MiniHeapId, Mwc, Mwc64, NUM_SIZE_CLASSES, PageConfig, PlatformHooks,
PlatformInstallError, RelaxedBitmap, RuntimeCompactionPolicy, RuntimeCompactionResult,
ShuffleEntry, ShuffleVector, Span, ThreadLocalHeap, byte_size_for_class,
ensure_fault_mediation_installed, install_platform_hooks, ok_to_proceed, page_count,
page_shift, page_size, retry_on_efault, retry_on_efault_ptrs, round_up_to_page,
runtime_slots_per_span, size_class_for,
};
/// Additional allocator helpers re-exported from the Linux x86_64 backend.
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub use platform::linux_x86_64::mesh_alloc::{FreelistId, bitmaps_meshable};
/// Returns the default global mesh allocator configuration for this crate.
///
/// This is useful when embedding the allocator in a `#[global_allocator]` static.
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
pub const fn default_global_allocator() -> GlobalMeshAllocator {
GlobalMeshAllocator::with_default_config()
}
#[cfg(test)]
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
mod tests {
use super::{MeshAllocator, page_size};
#[test]
fn mesh_allocator_smoke_test() {
let mut allocator =
MeshAllocator::new(page_size() * 1024, 256).expect("allocator should initialize");
let small = allocator
.allocate(64)
.expect("small allocation should succeed");
unsafe {
small.write_bytes(0xAB, 64);
}
allocator.deallocate(small);
let large_size = page_size() * 2;
let large = allocator
.allocate(large_size)
.expect("large allocation should succeed");
unsafe {
large.write_bytes(0xCD, large_size);
}
allocator.deallocate(large);
}
}