From ef0482ccacacb879d2982643a27ccc984ce8fb16 Mon Sep 17 00:00:00 2001 From: Yuekai Jia Date: Mon, 22 Jul 2024 21:11:26 +0800 Subject: [PATCH] Import app docs from the arceos main repo --- README.md | 6 +- c/httpserver/httpserver.c | 2 +- c/iperf/README.md | 2 +- c/redis/README.md | 6 +- docs/apps_display.md | 106 +++++++++++ docs/apps_echoserver.md | 106 +++++++++++ docs/apps_exception.md | 66 +++++++ docs/apps_fs_shell.md | 310 ++++++++++++++++++++++++++++++++ docs/apps_helloworld.md | 59 ++++++ docs/apps_httpclient.md | 88 +++++++++ docs/apps_httpserver.md | 177 ++++++++++++++++++ docs/apps_memtest.md | 54 ++++++ docs/apps_parallel.md | 184 +++++++++++++++++++ docs/apps_priority.md | 42 +++++ docs/apps_sleep.md | 122 +++++++++++++ docs/apps_yield.md | 91 ++++++++++ docs/figures/display.png | Bin 0 -> 124401 bytes docs/init.md | 44 +++++ rust/net/httpserver/src/main.rs | 2 +- 19 files changed, 1458 insertions(+), 9 deletions(-) create mode 100644 docs/apps_display.md create mode 100644 docs/apps_echoserver.md create mode 100644 docs/apps_exception.md create mode 100644 docs/apps_fs_shell.md create mode 100644 docs/apps_helloworld.md create mode 100644 docs/apps_httpclient.md create mode 100644 docs/apps_httpserver.md create mode 100644 docs/apps_memtest.md create mode 100644 docs/apps_parallel.md create mode 100644 docs/apps_priority.md create mode 100644 docs/apps_sleep.md create mode 100644 docs/apps_yield.md create mode 100644 docs/figures/display.png create mode 100644 docs/init.md diff --git a/README.md b/README.md index d4ec105..02af090 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Other arguments are the same as ArceOS's [Makefile](https://github.com/arceos-or For example, to run the [httpserver](rust/net/httpserver/) on `qemu-system-aarch64` with 4 cores and log level `info`: ```bash -make A=apps/net/httpserver ARCH=aarch64 LOG=info SMP=4 run NET=y +make A=rust/net/httpserver ARCH=aarch64 LOG=info SMP=4 run NET=y ``` Note that the `NET=y` argument is required to enable the network device in QEMU. These arguments (`BLK`, `GRAPHIC`, etc.) only take effect at runtime not build time. @@ -76,7 +76,7 @@ Note that the `NET=y` argument is required to enable the network device in QEMU. | [helloworld](rust/helloworld/) | | | A minimal app that just prints a string | | [exception](rust/exception/) | | | Exception handling test | | [memtest](rust/memtest/) | alloc | axalloc | Dynamic memory allocation test | -| [display](rust/display/) | display | axdisplay | Graphic/GUI test | +| [display](rust/display/) | display | axdriver, axdisplay | Graphic/GUI test | | [yield](rust/task/yield/) | multitask | axalloc, axtask | Multi-threaded yielding test | | [sleep](rust/task/sleep/) | multitask, irq | axalloc, axtask | Thread sleeping test | | [parallel](rust/task/parallel/) | alloc, multitask | axalloc, axtask | Parallel computing test (to test synchronization & mutex) | @@ -85,7 +85,7 @@ Note that the `NET=y` argument is required to enable the network device in QEMU. | [shell](rust/fs/shell/) | alloc, fs | axalloc, axdriver, axfs | A simple shell that responds to filesystem operations | | [httpclient](rust/net/httpclient/) | net | axalloc, axdriver, axnet | A simple client that sends an HTTP request and then prints the response | | [udpserver](rust/net/udpserver/) | net | axalloc, axdriver, axnet | A single-threaded echo server using UDP protocol | -| [echoserver](rust/net/echoserver/) | alloc, multitask, net | axalloc, axdriver, axnet, axtask | A multi-threaded TCP server that reverses messages sent by the client | +| [echoserver](rust/net/echoserver/) | alloc, multitask, net | axalloc, axdriver, axnet, axtask | A multi-threaded TCP server that reverses messages sent by the client | | [httpserver](rust/net/httpserver/) | alloc, multitask, net | axalloc, axdriver, axnet, axtask | A multi-threaded HTTP server that serves a static web page | | [bwbench](rust/net/bwbench/) | net | axalloc, axdriver, axnet | Network bandwidth benchmark | diff --git a/c/httpserver/httpserver.c b/c/httpserver/httpserver.c index b6f7ac5..5ea7a79 100644 --- a/c/httpserver/httpserver.c +++ b/c/httpserver/httpserver.c @@ -24,7 +24,7 @@ const char content[] = "\n\ \n\
\n\
\n\ - Powered by ArceOS example HTTP server v0.1.0\n\ + Powered by ArceOS example HTTP server v0.1.0\n\
\n\ \n\ \n\ diff --git a/c/iperf/README.md b/c/iperf/README.md index ca6f146..8a0d5a2 100644 --- a/c/iperf/README.md +++ b/c/iperf/README.md @@ -6,7 +6,7 @@ Build and start the [`iperf3`](https://github.com/esnet/iperf) server on ArceOS: ```bash # in arceos root directory -make A=apps/c/iperf BLK=y NET=y ARCH= run +make A=c/iperf BLK=y NET=y ARCH= run ``` ## Benchmark diff --git a/c/redis/README.md b/c/redis/README.md index f5c2441..da18a45 100644 --- a/c/redis/README.md +++ b/c/redis/README.md @@ -1,8 +1,8 @@ # How to run? - Run: - - `make A=apps/c/redis/ LOG=error NET=y BLK=y ARCH=aarch64 SMP=4 run`(for aarch64) - - `make A=apps/c/redis/ LOG=error NET=y BLK=y ARCH=x86_64 SMP=4 run`(for x86_64) + - `make A=c/redis/ LOG=error NET=y BLK=y ARCH=aarch64 SMP=4 run`(for aarch64) + - `make A=c/redis/ LOG=error NET=y BLK=y ARCH=x86_64 SMP=4 run`(for x86_64) # How to test? - Use `redis-cli -p 5555` to connect to redis-server, and enjoy ArceOS-Redis world! @@ -269,7 +269,7 @@ MSET (10 keys): 183150.19 requests per second ## Compile and Run -- `make A=apps/c/redis LOG=error PLATFORM=x86_64-pc-oslab SMP=4 FEATURES=driver-ixgbe,driver-ramdisk IP=10.2.2.2 GW=10.2.2.1` +- `make A=c/redis LOG=error PLATFORM=x86_64-pc-oslab SMP=4 FEATURES=driver-ixgbe,driver-ramdisk IP=10.2.2.2 GW=10.2.2.1` - Copy `redis_x86_64-pc-oslab.elf` to `/boot`, then reboot. - Enter `grub` then boot the PC by ArceOS Redis. - Connect to ArceOS-Redis server by: diff --git a/docs/apps_display.md b/docs/apps_display.md new file mode 100644 index 0000000..bf16634 --- /dev/null +++ b/docs/apps_display.md @@ -0,0 +1,106 @@ +# INTRODUCTION +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [display](../rust/display/) | display | axdriver, axdisplay | Graphic/GUI test | + +# RUN + +```bash +make A=rust/display GRAPHIC=y LOG=debug run +``` + +# RESULT + +```text +... +[ 0.408067 axdriver:59] Initialize device drivers... +[ 0.410941 driver_virtio:50] Detected virtio MMIO device with vendor id: 0x554D4551, device type: GPU, version: Legacy +[ 0.414473 virtio_drivers::device::gpu:47] Device features EDID | NOTIFY_ON_EMPTY | ANY_LAYOUT | RING_INDIRECT_DESC | RING_EVENT_IDX +[ 0.418886 virtio_drivers::device::gpu:57] events_read: 0x0, num_scanouts: 0x1 +[ 0.423408 virtio_drivers::device::gpu:102] => RespDisplayInfo { header: CtrlHeader { hdr_type: Command(4353), flags: 0, fence_id: 0, ctx_id: 0, _padding: 0 }, rect: Rect { x: 0, y: 0, width: 1280, height: 800 }, enabled: 1, flags: 0 } +[ 0.452037 axdriver::virtio:88] created a new Display device: "virtio-gpu" +[ 0.455473 axdisplay:17] Initialize Display subsystem... +[ 0.458124 axdisplay:19] number of Displays: 1 +... +... +... +(never end) +``` +![display](figures/display.png) + +# STEPS + +## step1 + +``` rust +let mut board = DrawingBoard::new(); +board.disp.clear(Rgb888::BLACK).unwrap(); +``` + +**flow chart** +```mermaid +graph TD; + A["DrawingBoard::new()"] --> B["display::Display::new()"]; + A --> C["embedded_graphics::prelude::Point::new(INIT_X, INIT_Y)"]; + B --> D["libax::display::framebuffer_info"] + B --> E["core::slice::from_raw_parts_mut"] + B --> F["embedded_graphics::prelude::Size::new"] + D --> G["axsync::Mutex(axdriver::DisplayDevices)::lock"] + D --> H["axdriver::DisplayDevices::info"] +``` + +## step2 +``` rust +for _ in 0..5 { + board.latest_pos.x += RECT_SIZE as i32 + 20; + board.paint(); + framebuffer_flush(); + } +... +impl DrawingBoard { + ... + fn paint(&mut self) { + Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE)) + .into_styled(PrimitiveStyle::with_stroke(Rgb888::RED, 10)) + .draw(&mut self.disp) + .ok(); + Circle::new(self.latest_pos + Point::new(-70, -300), 150) + .into_styled(PrimitiveStyle::with_fill(Rgb888::BLUE)) + .draw(&mut self.disp) + .ok(); + Triangle::new( + self.latest_pos + Point::new(0, 150), + self.latest_pos + Point::new(80, 200), + self.latest_pos + Point::new(-120, 300), + ) + .into_styled(PrimitiveStyle::with_stroke(Rgb888::GREEN, 10)) + .draw(&mut self.disp) + .ok(); + let text = "ArceOS"; + Text::with_alignment( + text, + self.latest_pos + Point::new(0, 300), + MonoTextStyle::new(&FONT_10X20, Rgb888::YELLOW), + Alignment::Center, + ) + .draw(&mut self.disp) + .ok(); + } +} +``` + +**flow chart** +```mermaid +graph TD; + A["DrawingBoard::paint"] --> B["embedded_graphics::primitives::{Circle, PrimitiveStyle, Rectangle, Triangle}"]; + A --> C["embedded_graphics::text::{Alignment, Text}"] + B --> D["impl embedded_graphics::draw_target::DrawTarget, embedded_graphics::prelude::OriginDimensions for Display"] + C --> D +``` + +## step3 +``` rust +loop { + core::hint::spin_loop(); +} +``` diff --git a/docs/apps_echoserver.md b/docs/apps_echoserver.md new file mode 100644 index 0000000..1c62cdf --- /dev/null +++ b/docs/apps_echoserver.md @@ -0,0 +1,106 @@ +# INTRODUCTION + +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [echoserver](../rust/net/echoserver/) | alloc, multitask, net | axalloc, axdriver, axnet, axtask | A multi-threaded TCP server that reverses messages sent by the client | + +# RUN + +```console +$ make A=rust/net/echoserver NET=y run +... +Hello, echo server! +listen on: 10.0.2.15:5555 +``` + +In another shell, use `telnet` (or `nc`) to connect to localhost (`127.0.0.1`) to view the reversed echo message: + +```console +$ telnet localhost 5555 +Trying 127.0.0.1... +Connected to localhost. +Escape character is '^]'. +hello +olleh +12345 +54321 +``` + +```console +$ nc 127.0.0.1 5555 +hello +olleh +12345 +54321 +``` + +# STEPS + +## step1 + +[init](./init.md) + +After executed all initial actions, then arceos calls `main` function in `echoserver` app. + +## step2 + +`main` calls `accept_loop()`, which will keep processing incoming tcp connection. + +```rust +let (addr, port) = (IpAddr::from_str(LOCAL_IP).unwrap(), LOCAL_PORT); +let mut listener = TcpListener::bind((addr, port).into())?; +println!("listen on: {}", listener.local_addr().unwrap()); + +let mut i = 0; +loop { + match listener.accept() { + ... + } + Err(e) => return Err(e), + } + i += 1; +} +``` + +## step3 + +Once it receives a tcp connection. It will get a `(stream, addr)` pair from `libax::net`. +`main` task will spawn a task to reverse every package it receives. + +```rust +Ok((stream, addr)) => { + info!("new client {}: {}", i, addr); + task::spawn(move || match echo_server(stream) { + Err(e) => error!("client connection error: {:?}", e), + Ok(()) => info!("client {} closed successfully", i), + }); +} +``` + +## step4 + +Reverse bytes in package it receives. + +```rust +fn reverse(buf: &[u8]) -> Vec { + let mut lines = buf + .split(|&b| b == b'\n') + .map(Vec::from) + .collect::>(); + for line in lines.iter_mut() { + line.reverse(); + } + lines.join(&b'\n') +} + +fn echo_server(mut stream: TcpStream) -> io::Result { + let mut buf = [0u8; 1024]; + loop { + let n = stream.read(&mut buf)?; + if n == 0 { + return Ok(()); + } + stream.write_all(reverse(&buf[..n]).as_slice())?; + } +} +``` diff --git a/docs/apps_exception.md b/docs/apps_exception.md new file mode 100644 index 0000000..9a49542 --- /dev/null +++ b/docs/apps_exception.md @@ -0,0 +1,66 @@ +# INTRODUCTION + +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [exception](../rust/exception/) | | | Exception handling test | + +# RUN + +```console +$ make A=rust/exception LOG=debug run +... +Running exception tests... +[ 0.249873 0 axhal::arch::riscv::trap:13] Exception(Breakpoint) @ 0xffffffc0802001e8 +Exception tests run OK! +[ 0.068358 0 axtask::api:6] main task exited: exit_code=0 +[ 0.069128 0 axhal::platform::qemu_virt_riscv::misc:2] Shutting down... +``` + +# STEPS + +## step1 + +[init](./init.md) + +After executed all initial actions, then arceos calls `main` function in `exception` app. + +## step2 + +``` Rust +fn raise_break_exception() { + unsafe { + #[cfg(target_arch = "x86_64")] + asm!("int3"); + #[cfg(target_arch = "aarch64")] + asm!("brk #0"); + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + asm!("ebreak"); + } +} + +#[no_mangle] +fn main() { + println!("Running exception tests..."); + raise_break_exception(); + println!("Exception tests run OK!"); +} +``` + +**flow chart** + +```mermaid +graph TD; + A[" asm!(ebreak)"] --> B["raise exception"]; + B --> C["axhal::arch::riscv::trap.S::trap_vector_base"]; + C --> D["switch sscratch and sp"]; + C -- "from U mode" --> E["Ltrap_entry_u: SAVE_REGS 1; a1 <-- 1"]; + C -- "from S mode" --> F["Ltrap_entry_s: SAVE_REGS 0; a1 <-- 0"]; + E --> G[axhal::arch::riscv::trap::riscv_trap_handler]; + F --> G; + G -- "Trap::Exception(E::Breakpoint)" --> H["handle_breakpoint(&mut tf.sepc)"]; + H --> I["debug!(Exception(Breakpoint) @ {:#x} , sepc);*sepc += 2;"]; + I -- "from U mode" --> J["Ltrap_entry_u: RESTORE_REGS 1"]; + I -- "from S mode" --> K["Ltrap_entry_s: RESTORE_REGS 0"]; + J --> L[sret]; + K --> L; +``` diff --git a/docs/apps_fs_shell.md b/docs/apps_fs_shell.md new file mode 100644 index 0000000..3d8c3ca --- /dev/null +++ b/docs/apps_fs_shell.md @@ -0,0 +1,310 @@ +# INTRODUCTION + +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [shell](../rust/fs/shell/) | alloc, fs | axalloc, axdriver, axfs | A simple shell that responds to filesystem operations | + +# RUN + +Before running the app, make an image of FAT32: + +```shell +make disk_img +``` + +Run the app: + +```shell +make A=rust/fs/shell ARCH=aarch64 LOG=debug BLK=y run +``` + +# RESULT + +``` +... +[ 0.006204 0 axdriver:64] Initialize device drivers... +[ 0.006396 0 driver_virtio:50] Detected virtio MMIO device with vendor id: 0x554D4551, device type: Block, version: Legacy +[ 0.006614 0 virtio_drivers::device::blk:55] device features: SEG_MAX | GEOMETRY | BLK_SIZE | SCSI | FLUSH | TOPOLOGY | CONFIG_WCE | DISCARD | WRITE_ZEROES | NOTIFY_ON_EMPTY | RING_INDIRECT_DESC | RING_EVENT_IDX +[ 0.007094 0 virtio_drivers::device::blk:64] config: 0xffff00000a003f00 +[ 0.007270 0 virtio_drivers::device::blk:69] found a block device of size 34000KB +[ 0.007956 0 axdriver::virtio:88] created a new Block device: "virtio-blk" +[ 0.008488 0 axfs:25] Initialize filesystems... +[ 0.008584 0 axfs:26] use block device: "virtio-blk" +[ 0.025432 0 axalloc:57] expand heap memory: [0xffff00004012f000, 0xffff00004013f000) +[ 0.025680 0 axalloc:57] expand heap memory: [0xffff00004013f000, 0xffff00004015f000) +[ 0.026510 0 axfs::fs::fatfs:122] create Dir at fatfs: /dev +[ 0.043112 0 axfs::fs::fatfs:102] lookup at fatfs: /dev +[ 0.049562 0 fatfs::dir:140] Is a directory +[ 0.057550 0 axruntime:137] Initialize interrupt handlers... +[ 0.057870 0 axruntime:143] Primary CPU 0 init OK. +Available commands: + cat + cd + echo + exit + help + ls + mkdir + pwd + rm + uname +arceos:/$ +``` + +# STEPS + +## Step1 + +[init](./init.md) + +After executed all initial actions, then arceos calls `main` function in `shell` app. + +## Step2 + +The program reads one command from `stdin` each time and pass it to `cmd::run_cmd`. + +```rust +fn main() { + let mut stdin = libax::io::stdin(); + let mut stdout = libax::io::stdout(); + + let mut buf = [0; MAX_CMD_LEN]; + let mut cursor = 0; + cmd::run_cmd("help".as_bytes()); + print_prompt(); + + loop { + if stdin.read(&mut buf[cursor..cursor + 1]).ok() != Some(1) { + continue; + } + if buf[cursor] == b'\x1b' { + buf[cursor] = b'^'; + } + match buf[cursor] { + CR | LF => { + println!(); + if cursor > 0 { + cmd::run_cmd(&buf[..cursor]); + cursor = 0; + } + print_prompt(); + } + BS | DL => { + if cursor > 0 { + stdout.write(&[BS, SPACE, BS]).unwrap(); + cursor -= 1; + } + } + 0..=31 => {} + c => { + if cursor < MAX_CMD_LEN - 1 { + stdout.write(&[c]).unwrap(); + cursor += 1; + } + } + } + } +} +``` + +## Step3 + +The commands are parsed and executed in `cmd::run_cmd`. + +```rust +pub fn run_cmd(line: &[u8]) { + let line_str = unsafe { core::str::from_utf8_unchecked(line) }; + let (cmd, args) = split_whitespace(line_str); + if !cmd.is_empty() { + for (name, func) in CMD_TABLE { + if cmd == *name { + func(args); + return; + } + } + println!("{}: command not found", cmd); + } +} +``` + +**flowchart** + +```mermaid +graph TD + run_cmd["cmd::run_cmd"] + + cat["cmd::do_cat"] + cd["cmd:do_cd"] + echo["cmd::do_echo"] + exit["cmd::do_exit"] + help["cmd::do_help"] + ls["cmd::do_ls"] + mkdir["cmd::do_mkdir"] + pwd["cmd::do_pwd"] + rm["cmd::do_rm"] + uname["cmd::do_uname"] + + run_cmd --> cat + run_cmd --> cd + run_cmd --> echo + run_cmd --> exit + run_cmd --> help + run_cmd --> ls + run_cmd --> mkdir + run_cmd --> pwd + run_cmd --> rm + run_cmd --> uname + + stdout_w["libax::io::stdout().write()"] + fopen["libax::fs::File::open"] + fread["libax::fs::file::File::read"] + fcreate["libax::fs::File::create"] + fwrite["libax::fs::file::File::write"] + fs_meta[libax::fs::metadata] + fs_readdir[libax::fs::read_dir] + fs_createdir[libax::fs::create_dir] + fs_rmdir[libax::fs::remove_dir] + fs_rmfile[libax::fs::remove_file] + + cat --> fopen + cat --> fread + cat --> stdout_w + cd --> set_dir["libax::env::set_current_dir"] + echo --> fcreate + echo --> fwrite + exit --> lib_exit["libax::task::exit"] + ls --> get_dir["libax::env::current_dir"] + ls --> fs_meta + ls --> fs_readdir + mkdir --> fs_createdir + pwd --> get_dir + rm --> fs_meta + rm --> fs_rmdir + rm --> fs_rmfile +``` + +For the details of the file system APIs included in the chart, see the section below. + +# File system APIs + +> **Notes for the flow charts below**: normal lines denote the calling stack, while dashed lines denote the returning of results. + +### Create files, open files, and get metadata + +```mermaid +graph TD + lib_create[libax::fs::File::create] --> |WRITE/CREATE/TRUNCATE| open_opt + lib_open[libax::fs::File::open] --> |READ ONLY| open_opt + lib_meta[libax::fs::metadata] --> lib_open1[libax::fs::File::open] --> |READ ONLY| open_opt + lib_meta --> f_meta[axfs::fops::File::get_attr] --> vfs_getattr + lib_meta -..-> |not found/permission denied| err(Return error) + open_opt["axfs::api::file::OpenOptions::open"] --> fops_open + + fops_open["axfs::fops::File::open"] --> fops_openat + fops_openat["axfs::fops::File::_open_at"] + fops_openat --> lookup + fops_openat --> |w/ CREATE flag| create_file + fops_openat --> vfs_getattr + + lookup["axfs::root::lookup"] --> vfs_lookup + create_file["axfs::root::create_file"] + create_file --> vfs_lookup + create_file --> vfs_create + create_file --> vfs_truncate + create_file --> vfs_open + + vfs_lookup["axfs_vfs::VfsNodeOps::lookup"] --> fs_impl + vfs_create["axfs_vfs::VfsNodeOps::create"] --> fs_impl + vfs_getattr["axfs_vfs::VfsNodeOps::get_attr"] --> fs_impl + vfs_truncate[axfs_vfs::VfsNodeOps::truncate] --> fs_impl + vfs_open[axfs_vfs::VfsNodeOps::open] --> fs_impl + fs_impl[[FS implementation]] +``` + + + +### Create directories + +```mermaid +graph TD + lib_mkdir[libax::fs::create_dir] --> builder_create["axfs::api::DirBuilder::create"] + builder_create --> root_create[axfs::root::create_dir] --> lookup[axfs::root::lookup] + lookup -..-> |exists/other error| err(Return error) + root_create -->|type=VfsNodeType::Dir| node_create[axfs_vfs::VfsNodeOps::create] --> fs_impl[[FS implementation]] + + lookup --> vfs_lookup["axfs_vfs::VfsNodeOps::lookup"] --> fs_impl[[FS implementation]] +``` + + + +### Read and write files + +```mermaid +graph LR + lib_read[libax::fs::File::read] --> fops_read + fops_read[axfs::fops::File::read] ---> |w/ read permission| vfs_read_at + vfs_read_at[axfs_vfs::VfsNodeOps::read] --> fs_impl[[FS implementation]] + + lib_write[libax::fs::File::write] --> fops_write + fops_write[axfs::fops::File::write] ---> |w/ write permission| vfs_write_at + vfs_write_at[axfs_vfs::VfsNodeOps::write] --> fs_impl[[FS implementation]] + + fops_read -.-> |else| err1(Return error) + fops_write -.-> |else| err(Return error) +``` + +### Get current directory + +```mermaid +graph LR + lib_gwd[libax::fs::current_dir] --> root_gwd[axfs::root::current_dir] + lib_gwd -.-> return("Return path") +``` + +### Set current directory + +```mermaid +graph TD + lib_cd[libax::fs::set_current_dir] --> root_cd[axfs::root::set_current_dir] + + root_cd -..-> |is root| change[Set CURRENT_DIR and CURRENT_DIR_PATH] + root_cd --> |else| lookup["axfs::root::lookup"] + + vfs_lookup["axfs_vfs::VfsNodeOps::lookup"] + lookup --> vfs_lookup --> fs_impl[[FS implementation]] + lookup -..-> |found & is directory & has permission| change + +``` + +### Remove directory + +```mermaid +graph TD + lib_rmdir[libax::fs::remove_dir] --> root_rmdir[axfs::root::remove_dir] + + root_rmdir -.-> |empty/is root/invalid/permission denied| ret_err(Return error) + + root_rmdir --> lookup[axfs::root::lookup] --> vfs_lookup["axfs_vfs::VfsNodeOps::lookup"] ---> fs_impl[[FS implementation]] + lookup -...-> |not found| ret_err + + root_rmdir --> meta[axfs_vfs::VfsNodeOps::get_attr] --> fs_impl + meta -..-> |not a dir/permission denied| ret_err + + root_rmdir --> remove_[axfs_vfs::VfsNodeOps::remove] ---> fs_impl + +``` + +### Remove file + +```mermaid +graph TD + lib_rm[libax::fs::remove_file] --> root_rm[axfs::root::remove_file] + + root_rm --> lookup[axfs::root::lookup] --> vfs_lookup["axfs_vfs::VfsNodeOps::lookup"] + ---> fs_impl[[FS implementation]] + lookup -.-> |not found| ret_err + root_rm ---> meta[axfs_vfs::VfsNodeOps::get_attr] ---> fs_impl + meta -..-> |not a file/permission denied| ret_err(Return error) + root_rm --> remove_[axfs_vfs::VfsNodeOps::remove] ---> fs_impl + +``` diff --git a/docs/apps_helloworld.md b/docs/apps_helloworld.md new file mode 100644 index 0000000..a98d5f0 --- /dev/null +++ b/docs/apps_helloworld.md @@ -0,0 +1,59 @@ +# INTRODUCTION +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [helloworld](../rust/helloworld/) | | | A minimal app that just prints a string | + +# RUN + +```shell +make A=rust/helloworld SMP=4 LOG=debug run +``` + +# STEPS + +## step1 +[init](./init.md) + +After executed all initial actions, then arceos calls `main` function in `helloworld` app. + +## step2 + +```Rust +fn main() { + libax::println!("Hello, world!"); +} +``` + +**flow chart** + +```mermaid +graph TD; + A[main] --> B["libax::println!(Hello, world!)"]; + B --> C[libax:io::__print_impl]; + C --> D[INLINE_LOCK=Mutex::new]; + C --> _guard=INLINE_LOCK.lock; + C --> E["stdout().write_fmt(args)"]; +``` + +### step2.1 + +```mermaid +graph TD; + T["stdout()"] --> A["libax::io::stdio.rs::stdout()"]; + A --> B["INSTANCE: Mutex = Mutex::new(StdoutRaw)"]; + A --> C["return Stdout { inner: &INSTANCE }"]; +``` + +### step2.2 + +```mermaid +graph TD; + T["stdout().write_fmt(args)"] --> A["Stdout::write"]; + A --> B["self.inner.lock().write(buf)"]; + B --> C["StdoutRaw::write"]; + C --> D["axhal::console::write_bytes(buf);"]; + C --> E["Ok(buf.len())"]; + D --> F["putchar"]; + F --> G["axhal::platform::qemu_virt_riscv::console::putchar"]; + G --> H["sbi_rt::legacy::console_putchar"]; +``` diff --git a/docs/apps_httpclient.md b/docs/apps_httpclient.md new file mode 100644 index 0000000..67bba80 --- /dev/null +++ b/docs/apps_httpclient.md @@ -0,0 +1,88 @@ +# INTRODUCTION +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [httpclient](../rust/net/httpclient/) | net | axalloc, axdriver, axnet | A simple client that sends an HTTP request and then prints the response | + +# RUN +```bash +make A=rust/net/httpclient SMP=1 NET=y LOG=debug run +``` + +# RESULT +```text +... +[ 0.065494 0 axalloc:128] initialize global allocator at: [0xffffffc080286000, 0xffffffc088000000) +[ 0.068109 0 axruntime:115] Initialize kernel page table... +[ 0.070549 0 axdriver:59] Initialize device drivers... +[ 0.072131 0 driver_virtio:50] Detected virtio MMIO device with vendor id: 0x554D4551, device type: Network, version: Legacy +[ 0.074003 0 virtio_drivers::device::net:117] Device features CTRL_GUEST_OFFLOADS | MAC | GSO | MRG_RXBUF | STATUS | CTRL_VQ | CTRL_RX | CTRL_VLAN | CTRL_RX_EXTRA | GUEST_ANNOUNCE | CTL_MAC_ADDR | RING_INDIRECT_DESC | RING_EVENT_IDX +[ 0.077999 0 virtio_drivers::device::net:127] Got MAC=[52, 54, 00, 12, 34, 56], status=LINK_UP +[ 0.080748 0 axalloc:57] expand heap memory: [0xffffffc080298000, 0xffffffc0802a8000) +[ 0.082357 0 axalloc:57] expand heap memory: [0xffffffc0802a8000, 0xffffffc0802c8000) +[ 0.083769 0 axalloc:57] expand heap memory: [0xffffffc0802c8000, 0xffffffc080308000) +[ 0.085864 0 axdriver::virtio:88] created a new Net device: "virtio-net" +[ 0.087057 0 axnet:22] Initialize network subsystem... +[ 0.087859 0 axnet:24] number of NICs: 1 +[ 0.088517 0 axnet:27] NIC 0: "virtio-net" +[ 0.089360 0 axalloc:57] expand heap memory: [0xffffffc080308000, 0xffffffc080408000) +[ 0.092033 0 axnet::smoltcp_impl:273] created net interface "eth0": +[ 0.093315 0 axnet::smoltcp_impl:275] ether: 52-54-00-12-34-56 +[ 0.094667 0 axnet::smoltcp_impl:277] ip: 10.0.2.15/24 +[ 0.095947 0 axnet::smoltcp_impl:278] gateway: 10.0.2.2 +[ 0.097154 0 axruntime:134] Initialize interrupt handlers... +[ 0.098892 0 axruntime:140] Primary CPU 0 init OK. +Hello, simple http client! +[ 0.100960 0 axnet::smoltcp_impl:67] socket #0: created +[ 0.103106 0 smoltcp::iface::interface:1599] address 10.0.2.2 not in neighbor cache, sending ARP request +HTTP/1.1 200 OK +Server: nginx +Date: Sat, 08 Apr 2023 18:58:27 GMT +Content-Type: text/plain +Content-Length: 13 +Connection: keep-alive +Access-Control-Allow-Origin: * +Cache-Control: no-cache, no-store, must-revalidate + +183.172.74.58 +[ 0.585681 0 axnet::smoltcp_impl::tcp:148] socket #0: shutting down +[ 0.587517 0 axnet::smoltcp_impl:95] socket #0: destroyed +... +``` + +# STEPS + +## step1 +``` rust +let (addr, port) = (IpAddr::from_str(DEST_IP).unwrap(), 80); +let mut stream = TcpStream::connect((addr, port).into())?; +``` + +**flow chart** +```mermaid +graph TD; + A["libax::tcp::TcpStream::connect"] --> B["smoltcp::wire::IpEndpoint::From(addr, port)"] + A --> C["axnet::smoltcp_impl::TcpSocket::new"] + A --> D["axnet::smoltcp_impl::TcpSocket::connect(addr)"] + C --> E["axsync::Mutex(smoltcp::iface::SocketSet)::new"] +``` + +## step2 +``` rust +stream.write(REQUEST.as_bytes())?; + +let mut buf = [0; 1024]; +let n = stream.read(&mut buf)?; +let response = core::str::from_utf8(&buf[..n]).unwrap(); +println!("{}", response); +``` + +**flow chart** +```mermaid +graph TD; + A["impl Read, Write for libax::TcpStream"] --> B["libax::TcpStream::read"] + A["impl Read, Write for libax::TcpStream"] --> C["libax::TcpStream::write"] + B --> D["smoltcp_impl::TcpSocket::recv(buf)"] + C --> E["smoltcp_impl::TcpSocket::send(buf)"] + D --> F["libax::println"] + E --> F +``` diff --git a/docs/apps_httpserver.md b/docs/apps_httpserver.md new file mode 100644 index 0000000..76a92b4 --- /dev/null +++ b/docs/apps_httpserver.md @@ -0,0 +1,177 @@ +# INTRODUCTION +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [httpserver](../rust/net/httpserver) | alloc, multitask, net | axalloc, axdriver, axnet, axtask | A multi-threaded HTTP server that serves a static web page | + +# RUN + +```shell +make A=rust/net/httpserver SMP=4 NET=y LOG=info run +``` + +# RESULT + +``` +... +[ 0.101078 axtask:75] use FIFO scheduler. +[ 0.102733 axdriver:59] Initialize device drivers... +[ 0.104475 driver_virtio:50] Detected virtio MMIO device with vendor id: 0x554D4551, device type: Network, version: Legacy +[ 0.107095 virtio_drivers::device::net:117] Device features CTRL_GUEST_OFFLOADS | MAC | GSO | MRG_RXBUF | STATUS | CTRL_VQ | CTRL_RX | CTRL_VLAN | CTRL_RX_EXTRA | GUEST_ANNOUNCE | CTL_MAC_ADDR | RING_INDIRECT_DESC | RING_EVENT_IDX +[ 0.113234 virtio_drivers::device::net:127] Got MAC=[52, 54, 00, 12, 34, 56], status=LINK_UP +[ 0.116326 axdriver::virtio:88] created a new Net device: "virtio-net" +[ 0.118063 axnet:22] Initialize network subsystem... +[ 0.119247 axnet:24] number of NICs: 1 +[ 0.120442 axnet:27] NIC 0: "virtio-net" +[ 0.121819 axalloc:57] expand heap memory: [0xffffffc080654000, 0xffffffc080a54000) +[ 0.124142 axalloc:57] expand heap memory: [0xffffffc080a54000, 0xffffffc081254000) +[ 0.127314 axnet::smoltcp_impl:273] created net interface "eth0": +[ 0.128951 axnet::smoltcp_impl:275] ether: 52-54-00-12-34-56 +[ 0.130706 axnet::smoltcp_impl:277] ip: 10.0.2.15/24 +[ 0.132189 axnet::smoltcp_impl:278] gateway: 10.0.2.2 +[ 0.133746 axruntime:134] Initialize interrupt handlers... +... +Hello, ArceOS HTTP server! +... +[ 0.148419 0:2 axnet::smoltcp_impl:67] socket #0: created +[ 0.148850 0:2 axnet::smoltcp_impl::tcp:111] socket listening on 10.0.2.15:5555 +[ 0.149305 0:2 axnet::smoltcp_impl:95] socket #0: destroyed +listen on: http://10.0.2.15:5555/ +``` + +Open http://127.0.0.1:5555/ in your browser, or use command lines in another shell to view the web page: + +```console +$ curl http://127.0.0.1:5555/ + + + Hello, ArceOS + + +
+

Hello, ArceOS

+
+
+
+ Powered by ArceOS example HTTP server v0.1.0 +
+ + +``` + +# STEPS + +## step 1 +[init](./init.md) + +After executed all initial actions, then arceos calls `main` function in `memtest` app. + +## step 2 +```Rust +fn http_server(mut stream: TcpStream) -> io::Result { + ... + stream.read(&mut buf)?; + ... + stream.write_all(reponse.as_bytes())?; + ... +} + +fn accept_loop() -> io::Result { + let (addr, port) = (IpAddr::from_str(LOCAL_IP).unwrap(), LOCAL_PORT); + let mut listener = TcpListener::bind((addr, port).into())?; + ... + loop { + match listener.accept() { + Ok((stream, addr)) => { + task::spawn(move || match http_server(stream) { + Err(e) => error!("client connection error: {:?}", e), + Ok(()) => info!("client {} closed successfully", i), + }); + } + Err(e) => return Err(e), + } + i += 1; + } +} + +#[no_mangle] +fn main() { + println!("Hello, ArceOS HTTP server!"); + accept_loop().expect("test HTTP server failed"); +} +``` + +### step 2.1 + +```Rust +let (addr, port) = (IpAddr::from_str(LOCAL_IP).unwrap(), LOCAL_PORT); +let mut listener = TcpListener::bind((addr, port).into())?; +``` + +**flow chart** + +```mermaid +graph TD; +T["libax::net::tcp::TcpStream::bind()"] +T-->A["smoltcp::wire::ip::IpAddr::from_str()"] +T-->B["axnet::smoltcp_impl::tcp::TcpSocket::new()"] +T-->C["axnet::smoltcp_impl::tcp::TcpSocket::bind()"] +T-->D["axnet::smoltcp_impl::tcp::TcpSocket::listen()"] +B-->E["axnet::smoltcp_impl::SocketSetWrapper::new_tcp_socket()"] +E-->F["axsync::mutex< smoltcp::iface::socket_set::SocketSet >"] +F-->G["managed::slice::ManagedSlice< smoltcp::iface::socket_set::SocketStorage >"] +G-->H["smoltcp::iface::socket_meta::Meta + smoltcp::socket::Socket"] +H-->I["SocketHandle + NeighborState"] +H-->J["Raw + Icmp + udp + tcp"] + +D-->K["ListenTable: Box< [Mutex< Option< Box< ListenTableEntry > > >] >(tcp)"] +K-->L["ListenTableEntry: VecDeque< SocketHandle >(syn_queue)"] +L-->M["Tcp is a multi-wrapped sync queue of SocketHandle"] +``` + +### step 2.2 + +```Rust +match listener.accept() { + Ok((stream, addr)) => { + ... + } + Err(e) => return Err(e), +} +``` + +**flow chart** + +```mermaid +graph TD; +T["libax::net::tcp::TcpListener::accept()"] +T-->A["axnet::smoltcp_impl::tcp::TcpSocket::accept()"] +A-->B["Mutex< SocketSet >.poll_interfaces()"] +B-->C["axnet::smoltcp_impl::InterfaceWrapper< axdriver::VirtIoNetDev >.poll"] +C-->Z["many things"] +A-->D["axnet::smoltcp_impl::listen_table::ListenTable::accept()"] +D-->E["check the sync queue"] + +``` + + + + + +### step 2.3 + +```Rust +stream.read(&mut buf)?; +stream.write_all(reponse.as_bytes())?; +``` + +**flow chart** + +```mermaid +graph TD; + A["impl Read, Write for libax::TcpStream"] --> B["libax::TcpStream::read"] + A["impl Read, Write for libax::TcpStream"] --> C["libax::TcpStream::write"] + B --> D["smoltcp_impl::TcpSocket::recv(buf)"] + C --> E["smoltcp_impl::TcpSocket::send(buf)"] + +``` + diff --git a/docs/apps_memtest.md b/docs/apps_memtest.md new file mode 100644 index 0000000..9340861 --- /dev/null +++ b/docs/apps_memtest.md @@ -0,0 +1,54 @@ +# INTRODUCTION +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [memtest](../rust/memtest/) | alloc | axalloc | Dynamic memory allocation test | +# RUN + +```console +$ make A=rust/memtest SMP=4 LOG=info run +... +Running memory tests... +test_vec() OK! +test_btree_map() OK! +Memory tests run OK! +[ 0.523323 3 axhal::platform::qemu_virt_riscv::misc:2] Shutting down... +... +``` + +# STEPS + +## step1 + +[init](./init.md) + +After executed all initial actions, then arceos calls `main` function in `memtest` app. + +## step2 +```Rust +fn test_vec() { +... + let mut v = Vec::with_capacity(N); +... +} +fn test_btree_map() { +... + let mut m = BTreeMap::new(); +... +} +fn main() { + println!("Running memory tests..."); + test_vec(); + test_btree_map(); + println!("Memory tests run OK!"); +} +``` + +**flow chart** + +```mermaid +graph TD; +A["rust.alloc runtime"] --> B["impl GlobalAlloc for axalloc::GlobalAllocator alloc()"]; +B --> C["axalloc::GlobalAllocator::alloc()"]; +C --> D["simple two-level allocator: if no heap memory, allocate from the page allocator"]; + +``` diff --git a/docs/apps_parallel.md b/docs/apps_parallel.md new file mode 100644 index 0000000..699acfe --- /dev/null +++ b/docs/apps_parallel.md @@ -0,0 +1,184 @@ +# INTRODUCTION + +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [parallel](../rust/task/parallel/) | alloc, multitask | axalloc, axtask | Parallel computing test (to test synchronization & mutex) | + +# RUN + +## Without preemption (FIFO scheduler) + +```shell +make A=rust/task/parallel LOG=info run +``` + +## With preemption (RR scheduler) + +```shell +make A=rust/task/parallel LOG=info APP_FEATURES=preempt run +``` + +## Using multicore + +```shell +make A=rust/task/parallel LOG=info SMP=4 run +``` + +# RESULT + +```console +$ make A=rust/task/parallel APP_FEATURES=preempt SMP=4 run +... +part 0: TaskId(7) [0, 125000) +part 3: TaskId(10) [375000, 500000) +part 1: TaskId(8) [125000, 250000) +part 2: TaskId(9) [250000, 375000) +part 4: TaskId(11) [500000, 625000) +part 5: TaskId(12) [625000, 750000) +part 6: TaskId(13) [750000, 875000) +part 7: TaskId(14) [875000, 1000000) +part 8: TaskId(15) [1000000, 1125000) +part 9: TaskId(16) [1125000, 1250000) +part 10: TaskId(17) [1250000, 1375000) +part 11: TaskId(18) [1375000, 1500000) +part 12: TaskId(19) [1500000, 1625000) +part 13: TaskId(20) [1625000, 1750000) +part 14: TaskId(21) [1750000, 1875000) +part 15: TaskId(22) [1875000, 2000000) +part 15: TaskId(22) finished +part 3: TaskId(10) finished +part 2: TaskId(9) finished +part 1: TaskId(8) finished +part 0: TaskId(7) finished +part 7: TaskId(14) finished +part 4: TaskId(11) finished +part 6: TaskId(13) finished +part 5: TaskId(12) finished +part 8: TaskId(15) finished +part 10: TaskId(17) finished +part 9: TaskId(16) finished +part 11: TaskId(18) finished +part 13: TaskId(20) finished +part 14: TaskId(21) finished +part 12: TaskId(19) finished +main task woken up! timeout=false +sum = 61783189038 +Parallel summation tests run OK! +[ 1.219708 3:2 axhal::platform::qemu_virt_aarch64::psci:25] Shutting down... +``` + +# PROCESS + +`main`使用`MAIN_WQ`睡眠 500ms,并检查`main`的唤醒是因为时间到(而非其他`task`的`notify()`)。 + +`main`调用`task::spawn`产生`NUM_TASKS`个`task`,分别进行计算。计算完毕后,使用一个`WaitQueue`(`static BARRIER_WQ`)以等待其他`task`的完成。 +在全部`task`完成后,执行`BARRIER_WQ.notify_all(true)`,继续各`task`的执行。 + +`main`在生成`task`后,调用`MAIN_WQ.wait_timeout()`等待 600ms,随后检查`task`的计算结果。 + +# FUNCTIONS + +## barrier + +`BARRIER_COUNT += 1`,记录已经完成计算的`task`数量。 + +`BARRIER_WQ.wait_until()`,block 至所有`task`均完成计算。 + +`BARRIER_WQ.notify_all()`,唤醒`BARRIER_WQ`内的所有 task 继续执行。 + +# STEPS + +## step1 + +[init](./init.md) + +After executed all initial actions, then arceos calls `main` function in `parallel` app. + +## step2 + +Calculate expected value from tasks. + +```rust +let vec = Arc::new( + (0..NUM_DATA) + .map(|_| rand::rand_u32() as u64) + .collect::>(), +); +let expect: u64 = vec.iter().map(sqrt).sum(); +``` + +## step3 + +Sleep `main` task in `MAIN_WQ` for 500ms. `main` **must** be timed out to wake up since there's no other task to `notify()` it. + +```rust +let timeout = MAIN_WQ.wait_timeout(Duration::from_millis(500)); +assert!(timeout); +``` + +## step4 + +`main` task spawn all `NUM_TASKS` tasks. + +```rust +for i in 0..NUM_TASKS { + let vec = vec.clone(); + task::spawn(move || { + ... + }); +} +``` + +Each task will do the calculation, then call `barrier()`. + +```rust +// task: +let left = i * (NUM_DATA / NUM_TASKS); +let right = (left + (NUM_DATA / NUM_TASKS)).min(NUM_DATA); +println!( + "part {}: {:?} [{}, {})", + i, + task::current().id(), + left, + right +); + +RESULTS.lock()[i] = vec[left..right].iter().map(sqrt).sum(); + +barrier(); + +println!("part {}: {:?} finished", i, task::current().id()); +let n = FINISHED_TASKS.fetch_add(1, Ordering::Relaxed); +if n == NUM_TASKS - 1 { + MAIN_WQ.notify_one(true); +} + +fn barrier() { + static BARRIER_WQ: WaitQueue = WaitQueue::new(); + static BARRIER_COUNT: AtomicUsize = AtomicUsize::new(0); + BARRIER_COUNT.fetch_add(1, Ordering::Relaxed); + BARRIER_WQ.wait_until(|| BARRIER_COUNT.load(Ordering::Relaxed) == NUM_TASKS); + BARRIER_WQ.notify_all(true); +} +``` + +`barrier()` will keep track of how many tasks have finished calculation in `BARRIER_COUNT`. + +Task will sleep in `BARRIER_WQ` until all tasks have finished. Then, the first awake task will `notify_all()` tasks to wake up. + +Task will print some info, add 1 to `FINISHED_TASKS`. The last task (`n == NUM_TASKS - 1`) will notify the `main` task to wake up. + +## step5 + +`main` will sleep 600ms in `MAIN_WQ` after spawning all the tasks. Once awake, `main` will check the actual calculation results. + +```rust +let timeout = MAIN_WQ.wait_timeout(Duration::from_millis(600)); +println!("main task woken up! timeout={}", timeout); + +let actual = RESULTS.lock().iter().sum(); +println!("sum = {}", actual); +assert_eq!(expect, actual); + +println!("Parallel summation tests run OK!"); +``` diff --git a/docs/apps_priority.md b/docs/apps_priority.md new file mode 100644 index 0000000..9fc2bc9 --- /dev/null +++ b/docs/apps_priority.md @@ -0,0 +1,42 @@ +# INTRODUCTION + +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [priority](../rust/task/priority/) | alloc, multitask, sched_fifo, sched_rr, sched_cfs | axalloc, axtask | Task priority test | + +# RUN +```shell +make A=rust/task/priority ARCH=riscv64 SMP=1 APP_FEATURES=sched_cfs run LOG=info +``` +Other choises of APP_FEATURES: sched_fifo, sched_rr + +## Using multicore +```shell +make A=rust/task/sched-realtime ARCH=riscv64 SMP=4 APP_FEATURES=sched_cfs run LOG=info +``` +Other choises of APP_FEATURES: sched_fifo, sched_rr + +# RESULT +```console +$ make A=rust/task/priority ARCH=riscv64 SMP=1 APP_FEATURES=sched_cfs run LOG=info +... +part 0: TaskId(4) [0, 40) +part 1: TaskId(5) [0, 40) +part 2: TaskId(6) [0, 40) +part 3: TaskId(7) [0, 40) +part 4: TaskId(8) [0, 4) +part 3: TaskId(7) finished +part 4: TaskId(8) finished +part 2: TaskId(6) finished +part 1: TaskId(5) finished +part 0: TaskId(4) finished +sum = 3318102132 +leave time: +task 0 = 614ms +task 1 = 479ms +task 2 = 374ms +task 3 = 166ms +task 4 = 371ms +Priority tests run OK! +[ 1.274073 0:2 axhal::platform::qemu_virt_riscv::misc:3] Shutting down... +``` diff --git a/docs/apps_sleep.md b/docs/apps_sleep.md new file mode 100644 index 0000000..7e442d2 --- /dev/null +++ b/docs/apps_sleep.md @@ -0,0 +1,122 @@ +# INTRODUCTION +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [sleep](../rust/task/sleep) | multitask, irq | axalloc, axtask | Thread sleeping test | + +# RUN + +``` +make A=rust/task/sleep SMP=4 LOG=debug run +``` + +# RESULT +``` +... + +[ 0.077898 axruntime:109] Initialize global memory allocator... +[ 0.080584 axalloc:128] initialize global allocator at: [0xffffffc08033c000, 0xffffffc088000000) +[ 0.084562 axruntime:115] Initialize kernel page table... +[ 0.088103 axtask:69] Initialize scheduling... +[ 0.090130 axtask::task:113] new task: Task(1, "idle") +[ 0.091833 axalloc:57] expand heap memory: [0xffffffc08034a000, 0xffffffc08035a000) + +... + +[ 9.205714 1:2 axtask::run_queue:127] task sleep: Task(2, "main"), deadline=9.2151238s +[ 9.207086 1:6 axtask:144] idle task: waiting for IRQs... +[ 9.207282 2:1 axtask::run_queue:49] task yield: Task(1, "idle") +[ 9.208362 2:1 axtask:144] idle task: waiting for IRQs... +[ 9.209530 0:4 axtask::run_queue:114] task unblock: Task(11, "") +[ 9.210129 0:4 axtask::run_queue:49] task yield: Task(4, "idle") +[ 9.210775 0:11 arceos_sleep:40] task 3 actual sleep 4.0016563s seconds (1). +task 3 sleep 4 seconds (2) ... + +... + +Sleep tests run OK! +[ 16.228092 2:2 axtask::run_queue:80] task exit: Task(2, "main"), exit_code=0 +[ 16.228823 2:2 axhal::platform::qemu_virt_riscv::misc:2] Shutting down... +``` + +# STEPS + +## step1 +[init](./init.md) +After executed all initial actions, then arceos calls `main` function in `helloworld` app. + +## step2 +```Rust +fn main(){ +... +} +``` + +### step2.1 +```Rust + println!("Hello, main task!"); + let now = Instant::now(); + task::sleep(Duration::from_secs(1)); + let elapsed = now.elapsed(); + println!("main task sleep for {:?}", elapsed); +``` + +**flow chart** + +```mermaid +graph TD; + S["libax::task::sleep()"] + + S-->arg["libax::time::Duration::from_secs()"] + arg-->argA["libax::time::Duration::new(secs)"] + + S-->A["axhal::time::wall_time()"] + A-->AA["axhal::time::TimeValue::from_nanos()"] + + S-->B["axtask::run_queue::AxRunQueue::sleep_until()"] + B-->B.lock["SpinNoIrq< axtask::run_queue::AxRunQueue >"] + B-->BA["axtask::timers::set_alarm_wakeup()"] + BA-->BAA["SpinNoIrq < timer_list::TimeList< axtask::timers::TaskWakeupEvent>>"] + BAA-->BAAA["BinaryHeap < timer_list::TimerEventWrapper >"] + BAA-->BAAB["AxTaskRef = Arc< AxTask >"] + BAAB-->BAABA["scheduler::FifoTask< axtask::task::TaskInner >"] + B-->BB["axtask::run_queue::resched_inner()"] + BB-->BBA["axtask::task::set_state()"] +``` + +### step2.2 + +```Rust + task::spawn(|| { + for i in 0..30 { + info!(" tick {}", i); + task::sleep(Duration::from_millis(500)); + } + }); +``` + +**flow chart** + +```mermaid +graph TD; + T["axtask::task::spawn(closure fn)"] + T-->A["axtask::task::TaskInner::new(entry, name, axconfig::TASK_STACK_SIZE)"] + A-->B["axtask::task::TaskInner::new_common(axtask::task::TaskId, name)"] + A-->C["axtask::task::TaskStack::alloc(size)"] +``` + +### step2.3 + +```Rust + while FINISHED_TASKS.load(Ordering::Relaxed) < NUM_TASKS { + task::sleep(Duration::from_millis(10)); + } +``` + +**flow chart** + +```mermaid +graph TD; + T["FINISHED_TASKS.load(Ordering::Relaxed)"] + T --> A["core::sync::atomic::AtomicUsize::new(num)"] + T --> B["core::sync::atomic::Ordering::Relaxed"] +``` diff --git a/docs/apps_yield.md b/docs/apps_yield.md new file mode 100644 index 0000000..0e86efb --- /dev/null +++ b/docs/apps_yield.md @@ -0,0 +1,91 @@ +# INTRODUCTION +| App | Enabled features | Extra modules | Description | +|-|-|-|-| +| [yield](../rust/task/yield/) | multitask | axalloc, axtask | Multi-threaded yielding test | + +# RUN + +## Without preemption (FIFO scheduler) + +```shell +make A=rust/task/yield ARCH=riscv64 LOG=info NET=y SMP=1 run +``` + +## With preemption (RR scheduler) + +```shell +make A=rust/task/yield ARCH=riscv64 LOG=info NET=y SMP=1 APP_FEATURES=preempt run +``` + +## RESULT + +``` +Hello, main task! +Hello, task 0! id = TaskId(4) +Hello, task 1! id = TaskId(5) +Hello, task 2! id = TaskId(6) +Hello, task 3! id = TaskId(7) +Hello, task 4! id = TaskId(8) +Hello, task 5! id = TaskId(9) +Hello, task 6! id = TaskId(10) +Hello, task 7! id = TaskId(11) +Hello, task 8! id = TaskId(12) +Hello, task 9! id = TaskId(13) +Task yielding tests run OK! +``` + +# STEPS + +## step1 + +* OS init +* After executed all initial actions, then arceos call main function in `yield` app. + +## step2 + +* Use the `task::spawn` cycle to generate `NUM_TASKS` tasks (similar to threads). +* Each task executes a function, just print its ID. +* If preemption is disabled, the task voluntarily executes `yield` to give up the CPU. +* If SMP is not enabled, the execution order of tasks must be FIFO. +* `main task` will wait for all other tasks to complete. If not, continue to execute `yield` and wait. + +```rust +fn main() { + for i in 0..NUM_TASKS { + task::spawn(move || { + println!("Hello, task {}! id = {:?}", i, task::current().id()); + // 此时已经启动了yield + // 因为preempt所需要的依赖libax/sched_rr并没有被包含进去 + #[cfg(not(feature = "preempt"))] + task::yield_now(); + + let order = FINISHED_TASKS.fetch_add(1, Ordering::Relaxed); + if option_env!("SMP") == Some("1") { + assert!(order == i); // FIFO scheduler + } + }); + } + println!("Hello, main task{}!"); + while FINISHED_TASKS.load(Ordering::Relaxed) < NUM_TASKS { + #[cfg(not(feature = "preempt"))] + task::yield_now(); + } + println!("Task yielding tests run OK!"); +} +``` + +**flow chart** + +```mermaid +graph TD; + T["main task"] --> A["axtask::lib::spawn"]; + A -- "task_i" --> B["axtask::run_queue::AxRunqQueue.scheduler.push_back(tasak_i)"]; + A --> C["RUN_QUEUE.lock()"]; + B -- "repeat n times" --> A; + B -- "main task" --> D["axtask::lib::yield_now"]; + D --> E["axtask::run_queue::AxRunqQueue::resched_inner"]; + E -- "prev" --> F["axtask::run_queue::AxRunqQueue.scheduler.push_back(prev)"]; + E -- "next=axtask::run_queue::AxRunqQueue.scheduler.pop_front()" --> G["axtask::run_queue::AxRunqQueue:: switch_to(prev,next)"]; + G -- "repeat n times" --> D; + G -- "all n subtask finished" --> H["finished"] +``` diff --git a/docs/figures/display.png b/docs/figures/display.png new file mode 100644 index 0000000000000000000000000000000000000000..3bfab41f0921a8e672550868009426b01b2d781d GIT binary patch literal 124401 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 z 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%0DR~c}%KotL`1}Q1+(Wd@YN639v)}oL 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 z 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 HF6@5*p5e_) literal 0 HcmV?d00001 diff --git a/docs/init.md b/docs/init.md new file mode 100644 index 0000000..3218fe7 --- /dev/null +++ b/docs/init.md @@ -0,0 +1,44 @@ +```mermaid +graph TD; + A[axhal::platform::qemu_virt_riscv::boot.rs::_boot] --> init_boot_page_table; + A --> init_mmu; + A --> P[platform_init]; + A --> B[axruntime::rust_main]; + P --> P1["axhal::mem::clear_bss()"]; + P --> P2["axhal::arch::riscv::set_trap_vector_base()"]; + P --> P3["axhal::cpu::init_percpu()"]; + P --> P4["axhal::platform::qemu_virt_riscv::irq.rs::init()"]; + P --> P5["axhal::platform::qemu_virt_riscv::time.rs::init()"]; + B --> axlog::init; + B --> D[init_allocator]; + B --> remap_kernel_memory; + B --> axtask::init_scheduler; + B --> axdriver::init_drivers; + B --> Q[axfs::init_filesystems]; + B --> axnet::init_network; + B --> axdisplay::init_display; + B --> init_interrupt; + B --> mp::start_secondary_cpus; + B --> C[main]; + Q --> Q1["disk=axfs::dev::Disk::new()"]; + Q --> Q2["axfs::root::init_rootfs(disk)"]; + Q2 --fatfs--> Q21["main_fs=axfs::fs::fatfs::FatFileSystem::new()"]; + Q2 --> Q22["MAIN_FS.init_by(main_fs); MAIN_FS.init()"]; + Q2 --> Q23["root_dir = RootDirectory::new(MAIN_FS)"]; + Q2 --devfs--> Q24["axfs_devfs::DeviceFileSystem::new()"]; + Q2 --devfs--> Q25["devfs.add(null, zero, bar)"]; + Q2 -->Q26["root_dir.mount(devfs)"]; + Q2 -->Q27["init ROOT_DIR, CURRENT_DIR"]; + D --> E["In free memory_regions: axalloc::global_init"]; + D --> F["In free memory_regions: axalloc::global_add_memory"]; + E --> G[axalloc::GLOBAL_ALLOCATOR.init]; + F --> H[axalloc::GLOBAL_ALLOCATOR.add_memory]; + G --> I["PAGE: self.palloc.lock().init"]; + G --> J["BYTE: self.balloc.lock().init"]; + H --> K["BYTE: self.balloc.lock().add_memory"]; + I --> M["allocator::bitmap::BitmapPageAllocator::init()"]; + J -->L["allocator::slab::SlabByteAllocator::init() self.inner = unsafe { Some(Heap::new(start, size))"]; + K --> N["allocator::slab::SlabByteAllocator::add_memory: self.inner_mut().add_memory(start, size);"]; + +``` + diff --git a/rust/net/httpserver/src/main.rs b/rust/net/httpserver/src/main.rs index 6b18d12..dd06e38 100644 --- a/rust/net/httpserver/src/main.rs +++ b/rust/net/httpserver/src/main.rs @@ -42,7 +42,7 @@ const CONTENT: &str = r#"
- Powered by ArceOS example HTTP server v0.1.0 + Powered by ArceOS example HTTP server v0.1.0