Skip to content

Commit

Permalink
feat: upgrade async kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
yfblock committed Apr 21, 2024
1 parent 797be47 commit 08b6246
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 99 deletions.
2 changes: 1 addition & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bit_field = "0.10.1"
lose-net-stack = { git = "https://github.com/byte-os/lose-net-stack", rev = "bb99460", features = ["log"]}
# lose-net-stack = { path = "../../lose-net-stack", features = ["log"]}
vfscore = { git = "https://github.com/Byte-OS/vfscore.git" }
async-recursion = "1.0.4"
async-recursion = "1.1.0"
futures-lite = { version = "1.13.0", default-features = false, features=["alloc"] }
# backtrace = { path = "../crates/backtrace" }
hashbrown = "0.14"
Expand Down
10 changes: 6 additions & 4 deletions kernel/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ macro_rules! display {

// write module config to file.
fn write_module_config(driver_list: Vec<String>) {
let manifest_path =
PathBuf::from(env::var("OUT_DIR").expect("can't find manifest dir"));
let manifest_path = PathBuf::from(env::var("OUT_DIR").expect("can't find manifest dir"));
let mut module_file_content = String::new();
driver_list.into_iter().for_each(|module| {
if module == "" { return };
if module == "" {
return;
};
module_file_content.push_str(&format!("extern crate {};\n", module.replace("-", "_")))
});
fs::write(manifest_path.join("drivers.rs"), module_file_content)
.expect("can't write file to manifest dir");
}

fn main() {
let drivers = std::env::var("CARGO_CFG_DRIVER").unwrap_or(String::from(""))
let drivers = std::env::var("CARGO_CFG_DRIVER")
.unwrap_or(String::from(""))
.split(",")
.map(|x| x.trim().to_owned())
.collect();
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ impl UserTaskContainer {
args[0] as _,
args[1] as _,
args[2] as _,
args[3] as _,
args[4] as _,
args[3].into(),
args[4].into(),
)
.await
}
Expand Down
34 changes: 16 additions & 18 deletions kernel/src/syscall/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,29 +375,27 @@ impl UserTaskContainer {
socket: usize,
level: usize,
optname: usize,
optval: *mut u32,
optlen: *mut u32,
optval: UserRef<u32>,
optlen: UserRef<u32>,
) -> SysResult {
debug!("[task {}] sys_getsockopt @ socket: {:#x}, level: {:#x}, optname: {:#x}, optval: {:#x?}, optlen: {:#x?}",
self.tid, socket, level, optname, optval, optlen);
unsafe {
let optval = optval.as_mut().unwrap();
let _optlen = optlen.as_mut().unwrap();

match optname {
// send buffer
0x7 => *optval = 32000,
// recv buffer
0x8 => *optval = 32000,
0x2 => *optval = 2000,
// getsockopt
0x4 => return Err(LinuxError::EPERM),
_ => {
// *optval = 2000;
}
let optval = optval.get_mut();
let _optlen = optlen.get_mut();

match optname {
// send buffer
0x7 => *optval = 32000,
// recv buffer
0x8 => *optval = 32000,
0x2 => *optval = 2000,
// getsockopt
0x4 => return Err(LinuxError::EPERM),
_ => {
// *optval = 2000;
}
// debug!("ptr value: {:?}", optval);
}
// debug!("ptr value: {:?}", optval);
Ok(0)
}

Expand Down
33 changes: 16 additions & 17 deletions kernel/src/syscall/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,14 @@ pub fn cache_task_template(path: &str) -> Result<(), LinuxError> {
Ok(())
}

#[async_recursion(?Send)]
pub async fn exec_with_process<'a>(
#[async_recursion(Sync)]
pub async fn exec_with_process(
task: Arc<UserTask>,
path: &'a str,
args: Vec<&'a str>,
envp: Vec<&'a str>,
path: String,
args: Vec<String>,
envp: Vec<String>,
) -> Result<Arc<UserTask>, LinuxError> {
// copy args, avoid free before pushing.
let args: Vec<String> = args.into_iter().map(|x| String::from(x)).collect();
let path = String::from(path);
let user_task = task.clone();
user_task.pcb.lock().memset.clear();
Expand Down Expand Up @@ -247,9 +246,9 @@ pub async fn exec_with_process<'a>(
let elf = if let Ok(elf) = xmas_elf::ElfFile::new(&buffer) {
elf
} else {
let mut new_args = vec!["busybox", "sh"];
args.iter().for_each(|x| new_args.push(x));
return exec_with_process(task, "busybox", new_args, envp).await;
let mut new_args = vec!["busybox".to_string(), "sh".to_string()];
args.iter().for_each(|x| new_args.push(x.clone()));
return exec_with_process(task, String::from("busybox"), new_args, envp).await;
};
let elf_header = elf.header;

Expand All @@ -270,10 +269,9 @@ pub async fn exec_with_process<'a>(
if let Some(header) = header {
if let Ok(SegmentData::Undefined(_data)) = header.get_data(&elf) {
drop(frame_ppn);
let lib_path = "libc.so";
let mut new_args = vec![lib_path, &path];
args[1..].iter().for_each(|x| new_args.push(x));
return exec_with_process(task, lib_path, new_args, envp).await;
let mut new_args = vec![String::from("libc.so")];
new_args.extend(args);
return exec_with_process(task, new_args[0].clone(), new_args, envp).await;
}
}

Expand Down Expand Up @@ -346,6 +344,7 @@ pub async fn exec_with_process<'a>(
assert_eq!(&buffer[offset..offset + file_size], page_space);
});

// relocate data
if base > 0 {
relocated_arr.into_iter().for_each(|(addr, value)| unsafe {
(addr as *mut usize).write_volatile(value);
Expand Down Expand Up @@ -407,13 +406,13 @@ impl UserTaskContainer {
let args = args
.slice_until_valid(|x| x.is_valid())
.into_iter()
.map(|x| x.get_cstr().unwrap())
.map(|x| x.get_cstr().unwrap().to_string())
.collect();
debug!("test1: envp: {:?}", envp);
let envp: Vec<&str> = envp
let envp: Vec<String> = envp
.slice_until_valid(|x| x.is_valid())
.into_iter()
.map(|x| x.get_cstr().unwrap())
.map(|x| x.get_cstr().unwrap().to_string())
.collect();
debug!(
"sys_execve @ filename: {} args: {:?}: envp: {:?}",
Expand All @@ -430,7 +429,7 @@ impl UserTaskContainer {
return Ok(0);
}
let _exec_file = FileItem::fs_open(filename, OpenFlags::O_RDONLY).map_err(from_vfs)?;
exec_with_process(self.task.clone(), filename, args, envp).await?;
exec_with_process(self.task.clone(), filename.to_string(), args, envp).await?;
self.task.before_run();
Ok(0)
}
Expand Down
12 changes: 9 additions & 3 deletions kernel/src/tasks/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use alloc::string::String;
use alloc::sync::Weak;
use alloc::{sync::Arc, vec::Vec};
use devices::get_net_device;
Expand Down Expand Up @@ -100,9 +101,14 @@ pub async fn add_user_task(filename: &str, args: Vec<&str>, envp: Vec<&str>) ->
let task = UserTask::new(user_entry(), Weak::new(), initproc::USER_WORK_DIR);

task.before_run();
exec_with_process(task.clone(), filename, args, envp)
.await
.expect("can't add task to excutor");
exec_with_process(
task.clone(),
String::from(filename),
args.into_iter().map(String::from).collect(),
envp.into_iter().map(String::from).collect(),
)
.await
.expect("can't add task to excutor");
thread::spawn(task.clone());
curr_task.before_run();

Expand Down
22 changes: 14 additions & 8 deletions kernel/src/tasks/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use arch::{
{TrapFrame, TrapFrameArgs, PAGE_SIZE},
};
use executor::{
task_id_alloc, thread, AsyncTask, DowncastTask, TaskFutureItem, TaskId, FUTURE_LIST,
task_id_alloc, thread, AsyncTask, DowncastTask, TaskId, FUTURE_LIST,
};
use frame_allocator::{ceil_div, frame_alloc_much, FrameTracker};
use fs::File;
Expand Down Expand Up @@ -49,13 +49,13 @@ impl Drop for KernelTask {
}

impl KernelTask {
pub fn new(future: impl Future<Output = ()> + 'static) -> Arc<Self> {
pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Arc<Self> {
let task_id = task_id_alloc();
let memset = vec![];

FUTURE_LIST
.lock()
.insert(task_id, TaskFutureItem(Box::pin(kernel_entry(future))));
.insert(task_id, Box::pin(kernel_entry(future)));

Arc::new(Self {
page_table: Arc::new(PageTableWrapper::alloc()),
Expand Down Expand Up @@ -126,7 +126,7 @@ impl Drop for UserTask {

impl UserTask {
pub fn new(
future: impl Future<Output = ()> + 'static,
future: impl Future<Output = ()> + Send + 'static,
parent: Weak<UserTask>,
work_dir: &str,
) -> Arc<Self> {
Expand All @@ -136,7 +136,7 @@ impl UserTask {

FUTURE_LIST
.lock()
.insert(task_id, TaskFutureItem(Box::pin(future)));
.insert(task_id, Box::pin(future));

let inner = ProcessControlBlock {
memset,
Expand Down Expand Up @@ -392,7 +392,10 @@ impl UserTask {
}

#[inline]
pub fn cow_fork(self: Arc<Self>, future: impl Future<Output = ()> + 'static) -> Arc<Self> {
pub fn cow_fork(
self: Arc<Self>,
future: impl Future<Output = ()> + Send + 'static,
) -> Arc<Self> {
// Give the frame_tracker in the memset a type.
// it will contains the frame used for page mapping、
// mmap or text section.
Expand Down Expand Up @@ -443,7 +446,10 @@ impl UserTask {
}

#[inline]
pub fn thread_clone(self: Arc<Self>, future: impl Future<Output = ()> + 'static) -> Arc<Self> {
pub fn thread_clone(
self: Arc<Self>,
future: impl Future<Output = ()> + Send + 'static,
) -> Arc<Self> {
// Give the frame_tracker in the memset a type.
// it will contains the frame used for page mapping、
// mmap or text section.
Expand Down Expand Up @@ -479,7 +485,7 @@ impl UserTask {

FUTURE_LIST
.lock()
.insert(task_id, TaskFutureItem(Box::pin(future)));
.insert(task_id, Box::pin(future));

thread::spawn(new_task.clone());
new_task
Expand Down
73 changes: 35 additions & 38 deletions kernel/src/user/entry.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use alloc::boxed::Box;
use arch::{kernel_page_table, TrapFrame, TrapFrameArgs};
use async_recursion::async_recursion;
use executor::{yield_now, AsyncTask};
use futures_lite::future;
use hal::TimeVal;
Expand Down Expand Up @@ -32,42 +34,42 @@ impl UserTaskContainer {
}
}

pub async fn entry_point(&mut self, cx_ref: &mut TrapFrame) {
let mut times = 0;

let check_signal = async || {
loop {
let sig_mask = self.task.tcb.read().sigmask;
let signal = self
.task
.tcb
.read()
.signal
.clone()
.mask(sig_mask)
.try_get_signal();
if let Some(signal) = signal {
debug!("mask: {:?}", sig_mask);
self.handle_signal(signal.clone()).await;
let mut tcb = self.task.tcb.write();
tcb.signal.remove_signal(signal.clone());
// check if it is a real time signal
if let Some(index) = signal.real_time_index()
&& tcb.signal_queue[index] > 0
{
tcb.signal.add_signal(signal.clone());
tcb.signal_queue[index] -= 1;
}
} else {
break;
pub async fn check_signal(&self) {
loop {
let sig_mask = self.task.tcb.read().sigmask;
let signal = self
.task
.tcb
.read()
.signal
.clone()
.mask(sig_mask)
.try_get_signal();
if let Some(signal) = signal {
debug!("mask: {:?}", sig_mask);
self.handle_signal(signal.clone()).await;
let mut tcb = self.task.tcb.write();
tcb.signal.remove_signal(signal.clone());
// check if it is a real time signal
if let Some(index) = signal.real_time_index()
&& tcb.signal_queue[index] > 0
{
tcb.signal.add_signal(signal.clone());
tcb.signal_queue[index] -= 1;
}
} else {
break;
}
};
}
}

pub async fn entry_point(&mut self, cx_ref: &mut TrapFrame) {
let mut times: i32 = 0;

loop {
self.check_timer();

check_signal().await;
self.check_signal().await;

// check for task exit status.
if let Some(exit_code) = self.check_thread_exit() {
Expand All @@ -87,7 +89,7 @@ impl UserTaskContainer {

let res = future::or(self.handle_syscall(cx_ref), async {
loop {
check_signal().await;
self.check_signal().await;

if let Some(_exit_code) = self.check_thread_exit() {
return UserTaskControlFlow::Break;
Expand Down Expand Up @@ -122,15 +124,10 @@ impl UserTaskContainer {
}
}

#[async_recursion(Sync)]
pub async fn user_entry() {
let task = current_user_task();
let cx_ref = task.force_cx_ref();
let tid = task.get_task_id();
UserTaskContainer {
task,
tid,
store_frames: vec![],
}
.entry_point(cx_ref)
.await;
UserTaskContainer { task, tid }.entry_point(cx_ref).await;
}
Loading

0 comments on commit 08b6246

Please sign in to comment.