rust-based-os-comp2022
rust-based-os-comp2022 copied to clipboard
[Question] 标题示例: 为什么这里需要添加&
fn run_first_task(&self){
let mut inner = self.inner.exclusive_access();
let task0 = &mut inner.tasks[0];
task0.task_status = TaskStatus::Ready;
// ??? 改为不可变状态有什么作用么
let next_task_cx_ptr = &task0.task_cx as *const TaskContext;
drop(inner);
let mut _unused = TaskContext::zero_init();
unsafe {
// 切换上下文
__switch(&mut _unused as *mut TaskContext, next_task_cx_ptr);
}
panic!("unreachable in run_first_task")
}
let next_task_cx_ptr = &task0.task_cx as *const TaskContext;
这句代码有什么说法么 ?当前上下文修改为 const
但是好像并没有什么作用吧?
转成指针,这个是根据__switch要求转的
// /task/switch.rs
/// Switch to the context of `next_task_cx_ptr`, saving the current context in `current_task_cx_ptr`.
pub fn __switch(current_task_cx_ptr: *mut TaskContext, next_task_cx_ptr: *const TaskContext);
# /task/switch.S
__switch:
# __switch(
# current_task_cx_ptr: *mut TaskContext,
# next_task_cx_ptr: *const TaskContext
# )
# save kernel stack of current task
sd sp, 8(a0)
# save ra & s0~s11 of current execution
sd ra, 0(a0)
.set n, 0
.rept 12
SAVE_SN %n
.set n, n + 1
.endr
# restore ra & s0~s11 of next execution
ld ra, 0(a1)
.set n, 0
.rept 12
LOAD_SN %n
.set n, n + 1
.endr
# restore kernel stack of next task
ld sp, 8(a1)
ret
__switch 的功能是将当前上下文保存到current_task_cx_ptr, 并换上 next_task_cx_ptr指向的上下文。 所以在接口上要求 current_task_cx_ptr 是可变指针,next_task_cx_ptr 是不可变指针。
我看了一下特性好像大部分指针都是 Rust 管理的指针,但是 *const
可以转换为裸指针也就是原始指针,是不是代表 rust 管理的指针到汇编代码里面会报错
准确术语来说,Rust 一般管理的是借用 (borrow),或者说引用,也就是 &
和 &mut
。
至于 *const
和 *mut
,它们就是所谓裸指针 (raw pointer)。
借用论本质而言到底还是一个指针,但是 Rust 对它有严格的约束。而对裸指针的约束就十分宽松了。
这里 __switch
要求的是接收指针。也许接收借用也是可以的,但既然这里都切换控制流,转换到汇编这种层次去了,Rust 编译器显然已经难以约束,所以还是用裸指针最好。