/// Returns a new builder with the multi thread scheduler selected. /// /// Configuration methods can be chained on the return value. #[cfg(feature = "rt-multi-thread")] #[cfg_attr(docsrs, doc(cfg(feature = "rt-multi-thread")))] pubfnnew_multi_thread() -> Builder { // The number `61` is fairly arbitrary. I believe this value was copied from golang. Builder::new(Kind::MultiThread, 61) }
/// Enables both I/O and time drivers. /// /// Doing this is a shorthand for calling `enable_io` and `enable_time` /// individually. If additional components are added to Tokio in the future, /// `enable_all` will include these future components. pubfnenable_all(&mutself) -> &mutSelf { #[cfg(any( feature = "net", all(unix, feature = "process"), all(unix, feature = "signal") ))] self.enable_io(); #[cfg(feature = "time")] self.enable_time();
self }
操作成员变量,使能运行时I/O和定时器
build
1 2 3 4 5 6 7 8 9 10 11 12
/// Creates the configured `Runtime`. /// /// The returned `Runtime` instance is ready to spawn tasks. pubfnbuild(&mutself) -> io::Result<Runtime> { match &self.kind { Kind::CurrentThread => self.build_current_thread_runtime(), #[cfg(feature = "rt-multi-thread")] Kind::MultiThread => self.build_threaded_runtime(), #[cfg(all(tokio_unstable, feature = "rt-multi-thread"))] Kind::MultiThreadAlt => self.build_alt_threaded_runtime(), } }
fnbuild_threaded_runtime(&mutself) -> io::Result<Runtime> { use crate::loom::sys::num_cpus; use crate::runtime::{Config, runtime::Scheduler}; use crate::runtime::scheduler::{self, MultiThread};
let core_threads = self.worker_threads.unwrap_or_else(num_cpus);
let (driver, driver_handle) = driver::Driver::new(self.get_cfg(core_threads))?;
// Create the blocking pool let blocking_pool = blocking::create_blocking_pool(self, self.max_blocking_threads + core_threads); let blocking_spawner = blocking_pool.spawner().clone();
// Generate a rng seed for this runtime. let seed_generator_1 = self.seed_generator.next_generator(); let seed_generator_2 = self.seed_generator.next_generator();
(1) POST( Power On Self Test):上电自检,BIOS 对计算机硬件(CPU、主板、内存等)的检测。 (2) POST 之后的初始化与启动相关硬件(磁盘、键盘控制器等)。 (3) 为 OS 创建一些参数,如 ACPI、E820 表等。 (4) 选择引导设备,从设备中加载 BootLoader,进而启动操作系统。
VmcsGuestNW::RIP.write(entry.as_usize() & 0xffff)?; VmcsGuest16::CS_SELECTOR.write(((entry.as_usize() >> 4) & 0xf000) asu16)?; // On Intel requires 'base' to be 'selector * 16' in real mode. VmcsGuestNW::CS_BASE.write(entry.as_usize() & 0xf0000)?;
实现了clone,但是具体的flags没有处理,只按照fork的语义+返回并且用给定的栈。这个位置应该加上Copy on Write的支持,在MemorySet的Backend里加上这个,给每个页一个标记,然后在处理Page Fault的时候如果这个标记有了,就把这个页给复制一份,然后取消共享(虽然因为时间的关系没有实现)。我觉得Backend这个设计很好,在一些库里可以看到。这个设计让我们可以很方便地扩展三方库给的一些功能,同时不破坏这个库本身的代码和结构。
/// Prints to the standard output, with a newline. #[macro_export] macro_rules! println { () => { $crate::print!("\n") }; ($($arg:tt)*) => { $crate::io::__print_impl(format_args!("\x1b[31m{}\n\x1b[0m", format_args!($($arg)*))); } }
/// Write a slice of bytes to the console. pubfnwrite_bytes(bytes: &[u8]) { let color_begin = "\x1b[31m"; let color_end = "\x1b[0m"; for c in color_begin.bytes() { putchar(c); } for c in bytes { putchar(*c); } for c in color_end.bytes() { putchar(c); } } } ... ...