FFI-safe shared function table

This commit is contained in:
luojia65 2021-04-21 11:07:44 +08:00
parent 327a1bde1f
commit 774fabf237
4 changed files with 63 additions and 30 deletions

24
Cargo.lock generated
View File

@ -95,6 +95,16 @@ version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]]
name = "riscv"
version = "0.6.0"
source = "git+https://github.com.cnpmjs.org/rust-embedded/riscv.git?rev=7e9d2e5b#7e9d2e5bb05ccabf5539fcea36877748d7236c6e"
dependencies = [
"bare-metal",
"bit_field",
"riscv-target",
]
[[package]]
name = "riscv"
version = "0.6.0"
@ -139,6 +149,17 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "shared-scheduler"
version = "0.1.0"
dependencies = [
"buddy_system_allocator",
"lazy_static",
"r0",
"riscv 0.6.0 (git+https://github.com.cnpmjs.org/rust-embedded/riscv.git?rev=7e9d2e5b)",
"spin 0.7.1",
]
[[package]]
name = "spin"
version = "0.5.2"
@ -170,7 +191,7 @@ dependencies = [
"hashbrown",
"lazy_static",
"r0",
"riscv",
"riscv 0.6.0 (git+https://github.com.cnpmjs.org/HUST-OS/riscv.git)",
"spin 0.7.1",
"woke",
]
@ -181,6 +202,7 @@ version = "0.1.0"
dependencies = [
"buddy_system_allocator",
"lazy_static",
"r0",
"spin 0.5.2",
"woke",
]

View File

@ -1,5 +1,6 @@
//! 为协程内核设计的共享调度器运行时
//!
//! 为协程内核设计的共享调度器载荷
//! 以二进制包的形式编译
#![no_std]
#![no_main]
#![feature(panic_info_message)]
@ -25,12 +26,12 @@ static HEAP: LockedHeap = LockedHeap::empty();
#[cfg_attr(not(test), panic_handler)]
pub fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
println!("[shared-rt] panic: {:?}", panic_info);
println!("[shared scheduler] panic: {:?}", panic_info);
sbi::shutdown()
}
#[cfg_attr(not(test), alloc_error_handler)]
pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
println!("[shared-rt] alloc panic: {:?}", layout);
println!("[shared scheduler] alloc panic: {:?}", layout);
sbi::shutdown()
}

View File

@ -10,17 +10,15 @@ use spin::Mutex;
#[no_mangle]
#[link_section = ".data"]
#[export_name = "_raw_table"]
pub static __shared_raw_table: [unsafe extern "C" fn(); 3] = [
_shared_scheduler,
_shared_add_task,
_shared_pop_task
];
extern "C" {
fn _shared_scheduler();
fn _shared_add_task();
fn _shared_pop_task();
}
pub static __shared_raw_table: (
extern "C" fn() -> NonNull<()>,
unsafe extern "C" fn(NonNull<()>, SharedTaskHandle) -> FfiOption<SharedTaskHandle>,
unsafe extern "C" fn(NonNull<()>, extern "C" fn(&SharedTaskHandle) -> bool) -> TaskResult,
) = (
shared_scheduler,
shared_add_task,
shared_pop_task,
);
/// 共享调度器的类型
type SharedScheduler = Mutex<RingFifoScheduler<SharedTaskHandle, 100>>;
@ -39,9 +37,8 @@ pub fn current_task() -> Option<SharedTaskHandle> {
/// 得到共享的调度器指针
///
/// 可以在共享的添加任务,弹出下一个任务中使用
#[no_mangle]
#[export_name = "_shared_scheduler"]
pub fn shared_scheduler() -> NonNull<()> {
// todo不要导出这个函数
pub extern "C" fn shared_scheduler() -> NonNull<()> {
NonNull::new(&SHARED_SCHEDULER as *const _ as *mut ())
.expect("create non null pointer")
}
@ -59,28 +56,41 @@ pub struct SharedTaskHandle {
pub(crate) task_ptr: usize,
}
// 跨FFI边界安全的Option枚举结构
#[repr(C)]
pub enum FfiOption<T> {
None,
Some(T),
}
impl<T> From<Option<T>> for FfiOption<T> {
fn from(src: Option<T>) -> FfiOption<T> {
if let Some(t) = src {
FfiOption::Some(t)
} else {
FfiOption::None
}
}
}
/// 给共享调度器添加任务
///
/// 在内核态和用户态都可以调用
#[no_mangle]
#[export_name = "_shared_add_task"]
pub unsafe fn shared_add_task(
pub unsafe extern "C" fn shared_add_task(
shared_scheduler: NonNull<()>,
handle: SharedTaskHandle
) -> Option<SharedTaskHandle> {
) -> FfiOption<SharedTaskHandle> { // 如果未来有FFI-safe core::option::Option换掉这个返回值
let s: NonNull<SharedScheduler> = shared_scheduler.cast();
let mut scheduler = s.as_ref().lock();
scheduler.add_task(handle)
scheduler.add_task(handle).into()
}
/// 从共享调度器中弹出一个任务
///
/// 在内核态和用户态都可以调用
#[no_mangle]
#[export_name = "_shared_pop_task"]
pub unsafe fn shared_pop_task(
pub unsafe extern "C" fn shared_pop_task(
shared_scheduler: NonNull<()>,
should_switch: fn(&SharedTaskHandle) -> bool
should_switch: extern "C" fn(&SharedTaskHandle) -> bool
) -> TaskResult {
// 得到共享调度器的引用
let mut s: NonNull<SharedScheduler> = shared_scheduler.cast();
@ -98,4 +108,4 @@ pub unsafe fn shared_pop_task(
// 没有任务了,返回已完成
return TaskResult::Finished;
}
}
}

View File

@ -119,7 +119,7 @@ impl MemorySet {
mapping.map_segment(segment, None)?;
}
// 映射共享荷,目前地址是写死的
// 映射共享荷,目前地址是写死的
let va_range = VirtualAddress(0x8600_0000)..VirtualAddress(0x8640_0000);
let pa_range = PhysicalAddress(0x8600_0000)..PhysicalAddress(0x8640_0000);
mapping.map_defined(&va_range, &pa_range, Flags::WRITABLE | Flags::READABLE | Flags::EXECUTABLE );