Files
hakorune/src/runtime/ring0/mod.rs

148 lines
3.7 KiB
Rust
Raw Normal View History

//! Phase 88: Ring0Context - OS API 抽象化レイヤー
//!
//! Ring0 は Box を知らない、Nyash を知らない純粋な OS API 層。
mod errors;
mod std_impls;
mod traits;
pub use errors::{IoError, TimeError};
pub use std_impls::{NoopMem, StdFs, StdIo, StdLog, StdMem, StdThread, StdTime};
pub use traits::{
FsApi, FsMetadata, IoApi, LogApi, LogLevel, MemApi, MemStats, ThreadApi, TimeApi,
};
use std::sync::{Arc, OnceLock};
/// Phase 88: Ring0 コンテキスト
///
/// OS API レイヤーを trait で抽象化し、1つの構造体に束ねる。
pub struct Ring0Context {
pub mem: Arc<dyn MemApi>,
pub io: Arc<dyn IoApi>,
pub time: Arc<dyn TimeApi>,
pub log: Arc<dyn LogApi>,
pub fs: Arc<dyn FsApi>, // Phase 90-A
pub thread: Arc<dyn ThreadApi>, // Phase 90-D
}
impl Ring0Context {
/// 新規 Ring0Context を作成
pub fn new(
mem: Arc<dyn MemApi>,
io: Arc<dyn IoApi>,
time: Arc<dyn TimeApi>,
log: Arc<dyn LogApi>,
fs: Arc<dyn FsApi>,
thread: Arc<dyn ThreadApi>,
) -> Self {
Self {
mem,
io,
time,
log,
fs,
thread,
}
}
}
impl std::fmt::Debug for Ring0Context {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Ring0Context")
.field("mem", &"<dyn MemApi>")
.field("io", &"<dyn IoApi>")
.field("time", &"<dyn TimeApi>")
.field("log", &"<dyn LogApi>")
.field("fs", &"<dyn FsApi>")
.field("thread", &"<dyn ThreadApi>")
.finish()
}
}
/// デフォルト Ring0Context を作成std ベース)
pub fn default_ring0() -> Ring0Context {
Ring0Context {
mem: Arc::new(StdMem::new()),
io: Arc::new(StdIo),
time: Arc::new(StdTime),
log: Arc::new(StdLog),
fs: Arc::new(StdFs),
thread: Arc::new(StdThread),
}
}
// ===== グローバル Ring0Context =====
pub static GLOBAL_RING0: OnceLock<Arc<Ring0Context>> = OnceLock::new();
/// グローバル Ring0Context を初期化
pub fn init_global_ring0(ctx: Ring0Context) {
GLOBAL_RING0
.set(Arc::new(ctx))
.expect("[Phase 88] Ring0Context already initialized");
}
/// グローバル Ring0Context を取得
pub fn get_global_ring0() -> Arc<Ring0Context> {
GLOBAL_RING0
.get()
.expect("[Phase 88] Ring0Context not initialized")
.clone()
}
// ===== テスト =====
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_ring0_context_creation() {
let ring0 = default_ring0();
ring0.log.info("test message");
}
#[test]
fn test_io_api() {
let ring0 = default_ring0();
let result = ring0.io.stdout_write(b"test\n");
assert!(result.is_ok());
}
#[test]
fn test_time_api() {
let ring0 = default_ring0();
let now = ring0.time.now();
assert!(now.is_ok());
let instant = ring0.time.monotonic_now();
assert!(instant.is_ok());
}
#[test]
fn test_log_levels() {
let ring0 = default_ring0();
ring0.log.debug("debug message");
ring0.log.info("info message");
ring0.log.warn("warn message");
ring0.log.error("error message");
}
#[test]
fn test_default_ring0_uses_stdmem() {
let ring0 = default_ring0();
let ptr = ring0.mem.alloc(512);
assert!(!ptr.is_null(), "default_ring0 should use StdMem");
ring0.mem.free(ptr);
// Clean up
unsafe {
std::alloc::dealloc(
ptr,
std::alloc::Layout::from_size_align_unchecked(512, 1),
)
};
}
}