Merge pull request #29 from HUST-OS/main
merge main to clean_up_the_code
This commit is contained in:
commit
114857add4
|
@ -6,19 +6,7 @@ mod user_syscall;
|
|||
pub use user_syscall::user_trap_handler;
|
||||
|
||||
use config::*;
|
||||
|
||||
use crate::{
|
||||
hart::KernelHartInfo,
|
||||
memory::{
|
||||
AddressSpaceId,
|
||||
Satp,
|
||||
VirtualPageNumber,
|
||||
VirtualAddress,
|
||||
PhysicalPageNumber,
|
||||
KERNEL_MAP_OFFSET
|
||||
}
|
||||
};
|
||||
|
||||
use crate::memory::{AddressSpaceId, Satp, VirtualPageNumber, VirtualAddress,};
|
||||
use bit_field::BitField;
|
||||
|
||||
pub enum SyscallResult {
|
||||
|
@ -34,10 +22,10 @@ impl SyscallResult {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn syscall(param: [usize; 6], func: usize, module: usize) -> SyscallResult {
|
||||
pub fn syscall(param: [usize; 6], user_satp: usize, func: usize, module: usize) -> SyscallResult {
|
||||
match module {
|
||||
MODULE_PROCESS => do_process(param, func),
|
||||
MODULE_TEST_INTERFACE => do_test_interfase(param, func),
|
||||
MODULE_PROCESS => do_process(param, user_satp, func),
|
||||
MODULE_TEST_INTERFACE => do_test_interface(param, user_satp, func),
|
||||
MODULE_TASK => do_task(param, func),
|
||||
_ => panic!("Unknown module {:x}", module),
|
||||
}
|
||||
|
@ -51,41 +39,44 @@ fn switch_next_task(param: [usize; 6], func: usize) -> SyscallResult {
|
|||
todo!()
|
||||
}
|
||||
|
||||
fn do_process(param: [usize; 6], func: usize) -> SyscallResult {
|
||||
fn do_process(param: [usize; 6], user_satp: usize, func: usize) -> SyscallResult {
|
||||
match func {
|
||||
FUNC_PROCESS_EXIT => SyscallResult::Terminate(param[0] as i32),
|
||||
FUNC_PROCESS_PANIC => panic!("User panic!"),
|
||||
FUNC_PROCESS_PANIC => { //[line as usize, col as usize, f_buf, f_len, m_buf, m_len]
|
||||
let [line, col, f_buf, f_len, m_buf, m_len] = param;
|
||||
let user_satp = crate::memory::Satp::new(user_satp);
|
||||
let file_name = if f_buf == 0 {
|
||||
None
|
||||
} else {
|
||||
let slice = unsafe { get_user_buf(user_satp, f_buf, f_len) };
|
||||
Some(core::str::from_utf8(slice).unwrap())
|
||||
};
|
||||
let msg = if m_buf == 0 {
|
||||
None
|
||||
} else {
|
||||
let slice = unsafe { get_user_buf(user_satp, m_buf, m_len) };
|
||||
Some(core::str::from_utf8(slice).unwrap())
|
||||
};
|
||||
let file_name = file_name.unwrap_or("<no file>");
|
||||
let msg = msg.unwrap_or("<no message>");
|
||||
println!("[Kernel] User process panicked at '{}', {}:{}:{}", msg, file_name, line, col);
|
||||
SyscallResult::Terminate(-1)
|
||||
},
|
||||
_ => panic!("Unknown syscall process, func: {}, param: {:?}", func, param)
|
||||
}
|
||||
}
|
||||
|
||||
fn do_test_interfase(param: [usize; 6], func: usize) -> SyscallResult {
|
||||
fn do_test_interface(param: [usize; 6], user_satp: usize, func: usize) -> SyscallResult {
|
||||
match func {
|
||||
FUNC_TEST_WRITE => {
|
||||
let (asid, _fd, buf_ptr, buf_len) =
|
||||
(param[0], param[1], param[2], param[3]); // 地址空间参数,文件描述符,缓冲区指针,缓冲区长度
|
||||
// println!("[kernel] enter do_test_write with asid: {}, buf_ptr: {:#x}, buf_len: {}", asid, buf_ptr, buf_len);
|
||||
let user_asid = unsafe { AddressSpaceId::from_raw(asid) };
|
||||
if let Some(user_satp) = KernelHartInfo::get_satp(user_asid) {
|
||||
let offset = buf_ptr.get_bits(0..12); // Sv39 里面虚拟地址偏移量为低 12 位
|
||||
let vpn = VirtualPageNumber::floor(VirtualAddress(buf_ptr));
|
||||
let ppn = user_satp.translate(vpn).unwrap();
|
||||
unsafe {
|
||||
let ptr = (ppn
|
||||
.start_address()
|
||||
.0
|
||||
.wrapping_add(KERNEL_MAP_OFFSET)
|
||||
.wrapping_add(offset) as *const u8)
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let slice = core::slice::from_raw_parts(ptr, buf_len);
|
||||
let str = core::str::from_utf8(slice).unwrap();
|
||||
print!("{}", str);
|
||||
let (_iface, buf_ptr, buf_len) =
|
||||
(param[0], param[1], param[2]); // 调试接口编号,缓冲区指针,缓冲区长度
|
||||
let user_satp = crate::memory::Satp::new(user_satp);
|
||||
let slice = unsafe { get_user_buf(user_satp, buf_ptr, buf_len) };
|
||||
for &byte in slice {
|
||||
crate::sbi::console_putchar(byte as usize);
|
||||
}
|
||||
SyscallResult::Procceed { code: 0, extra: buf_len }
|
||||
}
|
||||
} else {
|
||||
panic!("User asid not found!")
|
||||
}
|
||||
},
|
||||
_ => panic!("Unknown syscall test, func: {}, param: {:?}", func, param)
|
||||
}
|
||||
|
@ -94,3 +85,13 @@ fn do_test_interfase(param: [usize; 6], func: usize) -> SyscallResult {
|
|||
fn do_task(param: [usize; 6], func: usize) -> SyscallResult {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn get_user_buf<'a>(user_satp: Satp, buf_ptr: usize, buf_len: usize) -> &'a [u8] {
|
||||
let offset = buf_ptr.get_bits(0..12); // Sv39 里面虚拟地址偏移量为低 12 位
|
||||
let vpn = VirtualPageNumber::floor(VirtualAddress(buf_ptr));
|
||||
let ppn = user_satp.translate(vpn).expect("no page fault");
|
||||
let va = ppn.start_address().virtual_address_linear()
|
||||
.0.wrapping_add(offset);
|
||||
let ptr = (va as *const u8).as_ref().expect("non-null pointer");
|
||||
core::slice::from_raw_parts(ptr, buf_len)
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ pub extern "C" fn user_trap_handler() {
|
|||
unsafe {
|
||||
asm!("mv {}, t2", out(reg) user_satp, options(nomem, nostack));
|
||||
}
|
||||
let user_satp = Satp::new(user_satp);
|
||||
let swap_cx = unsafe { get_swap_cx(&user_satp) };
|
||||
let user_satp_2 = Satp::new(user_satp);
|
||||
let swap_cx = unsafe { get_swap_cx(&user_satp_2) };
|
||||
// 从 SwapContext 中读东西
|
||||
let a0 = swap_cx.x[9];
|
||||
let a1 = swap_cx.x[10];
|
||||
|
@ -34,18 +34,17 @@ pub extern "C" fn user_trap_handler() {
|
|||
crate::sbi::shutdown();
|
||||
},
|
||||
Trap::Exception(scause::Exception::UserEnvCall) => {
|
||||
let func = a6;
|
||||
let param = [a0, a1, a2, a3, a4, a5];
|
||||
match syscall(param, func, a7) {
|
||||
match syscall(param, user_satp, a6, a7) {
|
||||
SyscallResult::Procceed { code, extra} => {
|
||||
swap_cx.x[9] = code;
|
||||
swap_cx.x[10] = extra;
|
||||
swap_cx.epc = swap_cx.epc.wrapping_add(4);
|
||||
trap::switch_to_user(swap_cx, user_satp.inner())
|
||||
trap::switch_to_user(swap_cx, user_satp)
|
||||
},
|
||||
SyscallResult::Retry => {
|
||||
// 不跳过指令,继续运行
|
||||
trap::switch_to_user(swap_cx, user_satp.inner())
|
||||
trap::switch_to_user(swap_cx, user_satp)
|
||||
},
|
||||
SyscallResult::NextASID{ satp } => {
|
||||
// 需要转到目标地址空间去运行
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::task::{TaskResult, SharedTaskHandle, KernelTask};
|
||||
use crate::task::{TaskResult, KernelTask};
|
||||
use woke::waker_ref;
|
||||
use alloc::sync::Arc;
|
||||
use core::{mem, task::{Poll, Context}};
|
||||
|
|
|
@ -265,9 +265,9 @@ fn breakpoint(trap_frame: &mut TrapFrame) -> *mut TrapFrame {
|
|||
}
|
||||
|
||||
fn syscall(trap_frame: &mut TrapFrame) -> *mut TrapFrame {
|
||||
println!("Syscall at {:#08x}", trap_frame.sepc);
|
||||
println!("Syscall at {:#08x}; note that user_satp /*todo*/", trap_frame.sepc);
|
||||
let param = [trap_frame.x[10], trap_frame.x[11], 0, 0, 0, 0]; // a0, a1
|
||||
match do_syscall(param, trap_frame.x[16], trap_frame.x[17]) { // a6, a7
|
||||
match do_syscall(param, 0/* todo */, trap_frame.x[16], trap_frame.x[17]) { // a6, a7
|
||||
SyscallResult::Procceed { code, extra } => {
|
||||
trap_frame.x[10] = code; // a0
|
||||
trap_frame.x[11] = extra; // a1
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(asm)]
|
||||
#![feature(llvm_asm)]
|
||||
|
||||
extern crate alloc;
|
||||
#[macro_use]
|
||||
extern crate tornado_user;
|
||||
use alloc::vec;
|
||||
|
||||
// 同步函数的例子,没有调用execute_async_main
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
println!("[user] enter main!");
|
||||
let mut test_v = vec![1, 2, 3, 4, 5];
|
||||
test_v.iter_mut().for_each(|x| *x += 1);
|
||||
assert_eq!(test_v, vec![2, 3, 4, 5, 6]);
|
||||
println!("[User] alloc-test: success!");
|
||||
0
|
||||
}
|
|
@ -6,37 +6,27 @@
|
|||
extern crate alloc;
|
||||
#[macro_use]
|
||||
extern crate tornado_user;
|
||||
use alloc::vec;
|
||||
use core::future::Future;
|
||||
use core::task::{Context, Poll};
|
||||
use core::pin::Pin;
|
||||
use tornado_user::{
|
||||
SHARED_PAYLOAD_BASE,
|
||||
shared,
|
||||
task,
|
||||
exit,
|
||||
};
|
||||
|
||||
async fn async_main() -> i32 {
|
||||
// todo: 唤醒逻辑
|
||||
tornado_user::spawn(async {
|
||||
let ans = FibonacciFuture::new(5).await;
|
||||
println!("[User] Fibonacci[5] = {}", ans);
|
||||
});
|
||||
let ans = FibonacciFuture::new(6).await;
|
||||
println!("[User] Fibonacci[6] = {}", ans);
|
||||
0
|
||||
}
|
||||
|
||||
// 异步main函数,由entry调用execute_async_main
|
||||
#[no_mangle]
|
||||
fn main() -> ! {
|
||||
let mut test_v = vec![1, 2, 3, 4, 5];
|
||||
test_v.iter_mut().for_each(|x| *x += 1);
|
||||
assert_eq!(test_v, vec![2, 3, 4, 5, 6]);
|
||||
let shared_payload = unsafe { shared::SharedPayload::new(SHARED_PAYLOAD_BASE) };
|
||||
let task = task::UserTask::new(FibonacciFuture::new(6));
|
||||
unsafe {
|
||||
/* todo: hart_id, asid */
|
||||
shared_payload.add_task(0, tornado_user::shared::AddressSpaceId::from_raw(tornado_user::ADDRESS_SPACE_ID), task.task_repr());
|
||||
fn main() -> i32 {
|
||||
tornado_user::execute_async_main(async_main())
|
||||
}
|
||||
|
||||
shared::run_until_idle(
|
||||
|| unsafe { shared_payload.peek_task(shared::user_should_switch) },
|
||||
|task_repr| unsafe { shared_payload.delete_task(task_repr) }
|
||||
);
|
||||
// 用户态退出的系统调用
|
||||
exit(0);
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
struct FibonacciFuture {
|
||||
a: usize,
|
||||
|
@ -57,17 +47,17 @@ impl FibonacciFuture {
|
|||
}
|
||||
|
||||
impl Future for FibonacciFuture {
|
||||
type Output = ();
|
||||
type Output = usize;
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
if self.i == self.cnt {
|
||||
println!("Fibonacci result: {}", self.a);
|
||||
Poll::Ready(())
|
||||
println!("Fibonacci {} result: {}", self.cnt, self.a);
|
||||
Poll::Ready(self.a)
|
||||
} else {
|
||||
let t = self.a;
|
||||
self.a += self.b;
|
||||
self.b = t;
|
||||
self.i += 1;
|
||||
println!("Fibonacci: i = {}, a = {}, b = {}", self.i, self.a, self.b);
|
||||
println!("Fibonacci {}: i = {}, a = {}, b = {}", self.cnt, self.i, self.a, self.b);
|
||||
cx.waker().wake_by_ref();
|
||||
Poll::Pending
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
use core::fmt::{self, Write};
|
||||
use super::test_write;
|
||||
|
||||
struct Stdout;
|
||||
|
||||
impl Write for Stdout {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
test_write(s.as_bytes());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub fn print(args: fmt::Arguments) {
|
||||
Stdout.write_fmt(args).unwrap();
|
||||
}
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($fmt: literal $(, $($arg: tt)+)?) => {
|
||||
$crate::console::print(format_args!($fmt $(, $($arg)+)?));
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
($fmt: literal $(, $($arg: tt)+)?) => {
|
||||
$crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
|
||||
}
|
||||
}
|
|
@ -7,65 +7,108 @@
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
#[macro_use]
|
||||
pub mod console;
|
||||
pub mod shared;
|
||||
pub mod task;
|
||||
|
||||
use buddy_system_allocator::LockedHeap;
|
||||
use core::future::Future;
|
||||
|
||||
|
||||
const USER_HEAP_SIZE: usize = 32768;
|
||||
|
||||
pub static mut ADDRESS_SPACE_ID: usize = 0;
|
||||
pub static mut SHARED_PAYLOAD_BASE: usize = 0;
|
||||
const USER_HEAP_SIZE: usize = 64 * 1024;
|
||||
|
||||
static mut HEAP_SPACE: [u8; USER_HEAP_SIZE] = [0; USER_HEAP_SIZE];
|
||||
|
||||
static mut SHARED_PAYLOAD_BASE: usize = 0;
|
||||
static mut ADDRESS_SPACE_ID: usize = 0;
|
||||
|
||||
#[global_allocator]
|
||||
static HEAP: LockedHeap = LockedHeap::empty();
|
||||
|
||||
#[cfg_attr(not(test), panic_handler)]
|
||||
pub fn panic_handler(_panic_info: &core::panic::PanicInfo) -> ! {
|
||||
sys_panic();
|
||||
pub fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
|
||||
let err = panic_info.message().unwrap().as_str();
|
||||
if let Some(location) = panic_info.location() {
|
||||
syscall::sys_panic(Some(location.file()), location.line(), location.column(), err);
|
||||
} else {
|
||||
syscall::sys_panic(None, 0, 0, err);
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[cfg_attr(not(test), alloc_error_handler)]
|
||||
pub fn handle_alloc_error(_layout: core::alloc::Layout) -> ! {
|
||||
sys_panic();
|
||||
unreachable!()
|
||||
pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
|
||||
println!("[User] user alloc error, layout = {:?}", layout);
|
||||
panic!("user alloc error: {:?}", layout)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[link_section = ".text.entry"]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
let mut ret: usize;
|
||||
let mut address_space_id: usize;
|
||||
let mut shared_payload_base: usize;
|
||||
unsafe {
|
||||
// 从 gp 寄存器里面取出 shared_raw_table 的地址
|
||||
asm!("mv {}, gp", out(reg) ret, options(nomem, nostack));
|
||||
SHARED_PAYLOAD_BASE = ret;
|
||||
asm!("mv {}, gp", out(reg) shared_payload_base, options(nomem, nostack));
|
||||
SHARED_PAYLOAD_BASE = shared_payload_base;
|
||||
// 从 tp 寄存器里面取出该用户态的地址空间编号
|
||||
asm!("mv {}, tp", out(reg) ret, options(nomem, nostack));
|
||||
ADDRESS_SPACE_ID = ret;
|
||||
asm!("mv {}, tp", out(reg) address_space_id, options(nomem, nostack));
|
||||
ADDRESS_SPACE_ID = address_space_id;
|
||||
}
|
||||
extern "C" {
|
||||
fn sbss(); fn ebss();
|
||||
}
|
||||
unsafe {
|
||||
r0::zero_bss(&mut sbss as *mut _ as *mut u32, &mut ebss as *mut _ as *mut u32);
|
||||
HEAP.lock().init(HEAP_SPACE.as_ptr() as usize, USER_HEAP_SIZE);
|
||||
}
|
||||
main()
|
||||
let exit_code = main();
|
||||
exit(exit_code);
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
#[linkage = "weak"]
|
||||
#[link_section = ".text"] // 必须指定,否则llvm好像会把名字为“entry”的函数链接到最开始……
|
||||
#[no_mangle]
|
||||
fn main() -> ! {
|
||||
fn main() -> i32 {
|
||||
println!("[User] No main function found; user exit");
|
||||
panic!("Can not find main!");
|
||||
}
|
||||
|
||||
/// 运行一个异步的main函数,在用户的entry函数里调用
|
||||
/// 应该作为标准库的一部分,这里使用一个库函数来模拟有标准库的情况
|
||||
pub fn execute_async_main(main: impl Future<Output = i32> + Send + Sync + 'static) -> i32 {
|
||||
let shared_payload = unsafe { shared::SharedPayload::new(SHARED_PAYLOAD_BASE) };
|
||||
let asid = unsafe { shared::AddressSpaceId::from_raw(ADDRESS_SPACE_ID) };
|
||||
static mut EXIT_CODE: i32 = 0;
|
||||
let main_task = task::UserTask::new(async move {
|
||||
unsafe { EXIT_CODE = main.await };
|
||||
});
|
||||
unsafe {
|
||||
shared_payload.add_task(0/* todo */, asid, main_task.task_repr());
|
||||
}
|
||||
shared::run_until_ready(
|
||||
|| unsafe { shared_payload.peek_task(shared::user_should_switch) },
|
||||
|task_repr| unsafe { shared_payload.delete_task(task_repr) }
|
||||
);
|
||||
unsafe { EXIT_CODE }
|
||||
}
|
||||
|
||||
/// 生成一个新的任务
|
||||
pub fn spawn(future: impl Future<Output = ()> + Send + Sync + 'static) {
|
||||
let shared_payload = unsafe { shared::SharedPayload::new(SHARED_PAYLOAD_BASE) };
|
||||
let asid = unsafe { shared::AddressSpaceId::from_raw(ADDRESS_SPACE_ID) };
|
||||
let task = task::UserTask::new(future);
|
||||
unsafe {
|
||||
shared_payload.add_task(0/* todo */, asid, task.task_repr());
|
||||
}
|
||||
}
|
||||
|
||||
use syscall::*;
|
||||
|
||||
pub fn exit(exit_code: i32) -> SyscallResult { sys_exit(exit_code) }
|
||||
pub fn do_yield(next_asid: usize) -> SyscallResult { sys_yield(next_asid) }
|
||||
pub fn test_write(buf: &[u8]) -> SyscallResult { unsafe { sys_test_write(ADDRESS_SPACE_ID, buf) }}
|
||||
pub fn test_write(buf: &[u8]) -> SyscallResult { sys_test_write(buf) }
|
||||
mod syscall {
|
||||
const MODULE_PROCESS: usize = 0x114514;
|
||||
const MODULE_TEST_INTERFACE: usize = 0x233666;
|
||||
|
@ -186,51 +229,23 @@ mod syscall {
|
|||
}
|
||||
|
||||
pub fn sys_exit(exit_code: i32) -> SyscallResult {
|
||||
syscall_1(MODULE_PROCESS, FUNC_PROCESS_EXIT, exit_code as usize) // 暂时放着,写法不规范
|
||||
syscall_1(MODULE_PROCESS, FUNC_PROCESS_EXIT, exit_code as usize)
|
||||
}
|
||||
|
||||
pub fn sys_panic() -> SyscallResult {
|
||||
syscall_0(MODULE_PROCESS, FUNC_PROCESS_PANIC)
|
||||
pub fn sys_panic(file_name: Option<&str>, line: u32, col: u32, msg: Option<&str>) -> SyscallResult {
|
||||
let (f_buf, f_len) = file_name.map(|s| (s.as_ptr() as usize, s.len())).unwrap_or((0, 0));
|
||||
let (m_buf, m_len) = msg.map(|s| (s.as_ptr() as usize, s.len())).unwrap_or((0, 0));
|
||||
syscall_6(
|
||||
MODULE_PROCESS, FUNC_PROCESS_PANIC,
|
||||
[line as usize, col as usize, f_buf, f_len, m_buf, m_len]
|
||||
)
|
||||
}
|
||||
|
||||
pub fn sys_yield(next_asid: usize) -> SyscallResult {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn sys_test_write(asid: usize, buf: &[u8]) -> SyscallResult {
|
||||
syscall_4(MODULE_TEST_INTERFACE, FUNC_TEST_WRITE, [asid, 0, buf.as_ptr() as usize, buf.len()])
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
pub mod console {
|
||||
use core::fmt::{self, Write};
|
||||
use super::test_write;
|
||||
|
||||
struct Stdout;
|
||||
|
||||
impl Write for Stdout {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
test_write(s.as_bytes());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print(args: fmt::Arguments) {
|
||||
Stdout.write_fmt(args).unwrap();
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($fmt: literal $(, $($arg: tt)+)?) => {
|
||||
$crate::console::print(format_args!($fmt $(, $($arg)+)?));
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
($fmt: literal $(, $($arg: tt)+)?) => {
|
||||
$crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
|
||||
}
|
||||
pub fn sys_test_write(buf: &[u8]) -> SyscallResult {
|
||||
syscall_3(MODULE_TEST_INTERFACE, FUNC_TEST_WRITE, [0, buf.as_ptr() as usize, buf.len()])
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ pub extern "C" fn user_should_switch(_handle: &SharedTaskHandle) -> bool {
|
|||
}
|
||||
|
||||
// 该执行器目前是测试使用,当轮询到一个完成的任务就退出了
|
||||
pub fn run_until_idle(
|
||||
pub fn run_until_ready(
|
||||
peek_task: impl Fn() -> TaskResult,
|
||||
delete_task: impl Fn(usize) -> bool,
|
||||
) {
|
||||
|
@ -43,15 +43,11 @@ pub fn run_until_idle(
|
|||
let task = peek_task();
|
||||
println!(">>> user executor: next task = {:x?}", task);
|
||||
match task {
|
||||
TaskResult::Task(task_repr) => {
|
||||
// 在相同的(内核)地址空间里面
|
||||
TaskResult::Task(task_repr) => { // 在相同的地址空间里面
|
||||
let task: Arc<UserTask> = unsafe { Arc::from_raw(task_repr as *mut _) };
|
||||
task.mark_sleep();
|
||||
// make a waker for our task
|
||||
let waker = waker_ref(&task);
|
||||
// poll our future and give it a waker
|
||||
let mut context = Context::from_waker(&*waker);
|
||||
|
||||
println!(">>> User executor: task = {:p}", task);
|
||||
let ret = task.future.lock().as_mut().poll(&mut context);
|
||||
if let Poll::Pending = ret {
|
||||
mem::forget(task); // 不要释放task的内存,它将继续保存在内存中被使用
|
||||
|
@ -63,7 +59,9 @@ pub fn run_until_idle(
|
|||
// 让出操作
|
||||
do_yield(next_asid);
|
||||
},
|
||||
TaskResult::Finished => break
|
||||
TaskResult::Finished => {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,15 +13,12 @@ use core::pin::Pin;
|
|||
use alloc::boxed::Box;
|
||||
use core::future::Future;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use super::shared::{AddressSpaceId};
|
||||
|
||||
/// 临时的用户态任务实现
|
||||
|
||||
pub struct UserTask {
|
||||
/// 任务的编号
|
||||
pub id: UserTaskId,
|
||||
/// 任务所属的地址空间
|
||||
pub asid: AddressSpaceId,
|
||||
/// 任务信息的可变部分
|
||||
pub inner: Mutex<UserTaskInner>,
|
||||
/// 任务的 future
|
||||
|
@ -64,7 +61,6 @@ impl UserTask {
|
|||
Arc::new(
|
||||
UserTask {
|
||||
id,
|
||||
asid: unsafe { AddressSpaceId::from_raw(crate::ADDRESS_SPACE_ID) },
|
||||
inner: Mutex::new(UserTaskInner {
|
||||
sleeping: false,
|
||||
finished: false,
|
||||
|
|
Loading…
Reference in New Issue