139 lines
5.0 KiB
Rust
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);
|
|
}
|
|
}
|