Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
Stone749990226 committed Jul 27, 2024
2 parents 97219f4 + 460a3f6 commit ae9bdc4
Show file tree
Hide file tree
Showing 31 changed files with 239 additions and 546 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ TEST_DIR := ./testcase/$(TEST)
export STRACE :=
export SMP :=
export PREEMPT :=
export DEBUG :=

# Args
DISASM_ARGS = -d
Expand Down
4 changes: 4 additions & 0 deletions arch/src/riscv64/sstatus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ impl Sstatus {
}
}

pub fn sie(&mut self) -> bool {
self.bits.get_bit(1)
}

pub fn set_spie(&mut self, val: bool) {
self.bits.set_bit(5, val);
}
Expand Down
4 changes: 4 additions & 0 deletions crates/recycle-allocator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@ impl RecycleAllocator {
);
self.recycled.push(Reverse(id));
}

pub fn recycled_len(&self) -> usize {
self.recycled.len()
}
}
36 changes: 20 additions & 16 deletions crates/ring-buffer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ enum RingBufferState {
Normal,
}

pub struct RingBuffer<const N: usize> {
pub struct RingBuffer {
arr: Vec<u8>,
// NOTE: When and only when `head` equals `tail`, `state` can only be `Full` or `Empty`.
head: usize,
tail: usize,
state: RingBufferState,
}

impl<const N: usize> RingBuffer<N> {
pub fn new() -> Self {
impl RingBuffer {
pub fn new(len: usize) -> Self {
Self {
arr: vec![0; N],
arr: vec![0; len],
head: 0,
tail: 0,
state: RingBufferState::Empty,
Expand All @@ -47,21 +47,22 @@ impl<const N: usize> RingBuffer<N> {
}

let ret_len;
let n = self.arr.len();
if self.head < self.tail {
ret_len = cmp::min(self.tail - self.head, buf.len());
buf[..ret_len].copy_from_slice(&self.arr[self.head..self.head + ret_len]);
} else {
// also handles full
ret_len = cmp::min(N - self.head + self.tail, buf.len());
if ret_len <= (N - self.head) {
ret_len = cmp::min(n - self.head + self.tail, buf.len());
if ret_len <= (n - self.head) {
buf[..ret_len].copy_from_slice(&self.arr[self.head..self.head + ret_len]);
} else {
let right_len = N - self.head;
let right_len = n - self.head;
buf[..right_len].copy_from_slice(&self.arr[self.head..]);
buf[right_len..ret_len].copy_from_slice(&self.arr[..(ret_len - right_len)]);
}
}
self.head = (self.head + ret_len) % N;
self.head = (self.head + ret_len) % n;

if self.head == self.tail {
self.state = RingBufferState::Empty;
Expand All @@ -79,21 +80,22 @@ impl<const N: usize> RingBuffer<N> {
}

let ret_len;
let n = self.arr.len();
if self.head <= self.tail {
// also handles empty
ret_len = cmp::min(N - (self.tail - self.head), buf.len());
if ret_len <= (N - self.tail) {
ret_len = cmp::min(n - (self.tail - self.head), buf.len());
if ret_len <= (n - self.tail) {
self.arr[self.tail..self.tail + ret_len].copy_from_slice(&buf[..ret_len]);
} else {
self.arr[self.tail..].copy_from_slice(&buf[..N - self.tail]);
self.arr[..(ret_len - (N - self.tail))]
.copy_from_slice(&buf[N - self.tail..ret_len]);
self.arr[self.tail..].copy_from_slice(&buf[..n - self.tail]);
self.arr[..(ret_len - (n - self.tail))]
.copy_from_slice(&buf[n - self.tail..ret_len]);
}
} else {
ret_len = cmp::min(self.head - self.tail, buf.len());
self.arr[self.tail..self.tail + ret_len].copy_from_slice(&buf[..ret_len]);
}
self.tail = (self.tail + ret_len) % N;
self.tail = (self.tail + ret_len) % n;

if self.head == self.tail {
self.state = RingBufferState::Full;
Expand All @@ -109,8 +111,9 @@ impl<const N: usize> RingBuffer<N> {
return None;
}

let n = self.arr.len();
let c = self.arr[self.head];
self.head = (self.head + 1) % N;
self.head = (self.head + 1) % n;
if self.head == self.tail {
self.state = RingBufferState::Empty;
} else {
Expand All @@ -124,8 +127,9 @@ impl<const N: usize> RingBuffer<N> {
return None;
}

let n = self.arr.len();
self.arr[self.tail] = byte;
self.tail = (self.tail + 1) % N;
self.tail = (self.tail + 1) % n;
if self.head == self.tail {
self.state = RingBufferState::Full;
} else {
Expand Down
4 changes: 2 additions & 2 deletions driver/src/serial/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub struct Serial {
}

pub struct SerialInner {
read_buf: RingBuffer<UART_BUF_LEN>, // Hard-coded buffer size
read_buf: RingBuffer, // Hard-coded buffer size
/// Hold waker of pollin tasks.
pollin_queue: VecDeque<Waker>,
}
Expand All @@ -64,7 +64,7 @@ impl Serial {
meta,
uart: UnsafeCell::new(driver),
inner: SpinNoIrqLock::new(SerialInner {
read_buf: RingBuffer::new(),
read_buf: RingBuffer::new(UART_BUF_LEN),
pollin_queue: VecDeque::new(),
}),
}
Expand Down
1 change: 1 addition & 0 deletions kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@ config = { path = "../config" }
strace = []
smp = []
preempt = []
debug = []
3 changes: 3 additions & 0 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ endif
ifneq ($(PREEMPT), )
FEATURES += preempt
endif
ifneq ($(DEBUG), )
FEATURES += debug
endif

CARGO_BUILD_ARGS :=
ifeq ($(MODE), release)
Expand Down
27 changes: 10 additions & 17 deletions kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,16 @@ use core::{
sync::atomic::{AtomicBool, Ordering},
};

use arch::time::get_time_duration;
use driver::BLOCK_DEVICE;
use executor::task_len;
use timer::timelimited_task::ksleep_s;

use crate::{processor::hart, task::TASK_MANAGER};
use crate::{
processor::hart,
task::{TASK_MANAGER, TID_ALLOCATOR},
utils::{print_proc_tree, spawn_debug_tasks},
};

extern crate alloc;

Expand Down Expand Up @@ -71,26 +76,14 @@ fn rust_main(hart_id: usize, dtb_addr: usize) {
trap::init();
driver::init();
vfs::init();

#[cfg(feature = "debug")]
utils::spawn_debug_tasks(print_proc_tree, 5);

task::spawn_kernel_task(async move {
task::spawn_init_proc();
});

// task::spawn_kernel_task(async move {
// loop {
// log::error!(
// "buffer head cnts {}",
// BLOCK_DEVICE.get().unwrap().buffer_head_cnts()
// );
// ksleep_s(3).await;
// }
// });
// task::spawn_kernel_task(async move {
// loop {
// log::error!("task counts {}", task_len());
// ksleep_s(3).await;
// }
// });

#[cfg(feature = "smp")]
boot::start_harts(hart_id);
} else {
Expand Down
5 changes: 3 additions & 2 deletions kernel/src/mm/memory_space/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,9 @@ impl MemorySpace {
(entry, auxv)
}

/// Check whether the elf file is dynamic linked and
/// if so, load the dl interpreter.
/// Check whether the elf file is dynamic linked and if so, load the dl
/// interpreter.
///
/// Return the interpreter's entry point(at the base of DL_INTERP_OFFSET) if
/// so.
pub fn load_dl_interp_if_needed(&mut self, elf: &ElfFile) -> Option<usize> {
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/syscall/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use core::{

use arch::time::get_time_duration;
use async_utils::{dyn_future, Async, Select2Futures, SelectOutput};
use config::board::BLOCK_SIZE;
use config::{board::BLOCK_SIZE, fs::PIPE_BUF_LEN};
use driver::BLOCK_DEVICE;
use memory::VirtAddr;
use strum::FromRepr;
Expand Down Expand Up @@ -524,7 +524,7 @@ impl Syscall<'_> {
let task = self.task;
let flags = OpenFlags::from_bits(flags)
.unwrap_or_else(|| unimplemented!("unknown flags, should add them"));
let (pipe_read, pipe_write) = new_pipe();
let (pipe_read, pipe_write) = new_pipe(PIPE_BUF_LEN);
let pipe = task.with_mut_fd_table(|table| {
let fd_read = table.alloc(pipe_read, flags)?;
let fd_write = table.alloc(pipe_write, flags)?;
Expand Down
3 changes: 2 additions & 1 deletion kernel/src/syscall/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use socket::*;
use systype::{SysError, SysResult, SyscallResult};
use vfs::pipefs::new_pipe;
use vfs_core::OpenFlags;
use virtio_drivers::PAGE_SIZE;

use super::Syscall;
use crate::{
Expand Down Expand Up @@ -329,7 +330,7 @@ impl Syscall<'_> {
sv: UserWritePtr<[u32; 2]>,
) -> SyscallResult {
let task = self.task;
let (pipe_read, pipe_write) = new_pipe();
let (pipe_read, pipe_write) = new_pipe(PAGE_SIZE);
let pipe = task.with_mut_fd_table(|table| {
let fd_read = table.alloc(pipe_read, OpenFlags::empty())?;
let fd_write = table.alloc(pipe_write, OpenFlags::empty())?;
Expand Down
36 changes: 21 additions & 15 deletions kernel/src/syscall/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,23 +217,29 @@ impl Syscall<'_> {
task.set_running();
let si = task.with_mut_sig_pending(|pending| pending.get_expect(SigSet::SIGCHLD));
if let Some(info) = si {
if let SigDetails::CHLD {
pid,
status,
utime,
stime,
} = info.details
{
match target {
WaitFor::AnyChild => break (pid, status, utime, stime),
WaitFor::Pid(target_pid) => {
if target_pid == pid {
break (pid, status, utime, stime);
}
let children = task.children();
let child = match target {
WaitFor::AnyChild => children
.values()
.find(|c| c.is_zombie() && c.with_thread_group(|tg| tg.len() == 1)),
WaitFor::Pid(pid) => {
let child = children.get(&pid).unwrap();
if child.is_zombie() && child.with_thread_group(|tg| tg.len() == 1) {
Some(child)
} else {
None
}
WaitFor::PGid(_) => unimplemented!(),
WaitFor::AnyChildInGroup => unimplemented!(),
}
WaitFor::PGid(_) => unimplemented!(),
WaitFor::AnyChildInGroup => unimplemented!(),
};
if let Some(child) = child {
break (
child.pid(),
child.exit_code(),
child.time_stat_ref().user_time(),
child.time_stat_ref().sys_time(),
);
}
} else {
return Err(SysError::EINTR);
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/syscall/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ impl Syscall<'_> {
return Ok(0);
}
let sleep = req - current;
task.suspend_timeout(req).await
task.suspend_timeout(sleep).await
} else {
task.suspend_timeout(req).await
};
Expand Down
4 changes: 4 additions & 0 deletions kernel/src/task/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ impl TaskManager {
}
}

pub fn tasks(&self) -> Vec<Arc<Task>> {
self.0.lock().values().map(|t| t.upgrade().unwrap()).collect()
}

pub fn for_each(&self, f: impl Fn(&Arc<Task>) -> SysResult<()>) -> SysResult<()> {
for task in self.0.lock().values() {
f(&task.upgrade().unwrap())?
Expand Down
12 changes: 6 additions & 6 deletions kernel/src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ pub mod signal;
pub mod task;
mod tid;

use alloc::{sync::Arc, vec::Vec};
use alloc::{string::ToString, sync::Arc, vec, vec::Vec};

use async_utils::block_on;
use config::process::USER_STACK_SIZE;
pub use manager::{PROCESS_GROUP_MANAGER, TASK_MANAGER};
pub use schedule::{spawn_kernel_task, spawn_user_task};
pub use task::Task;
pub use tid::{PGid, Pid, Tid};
pub use tid::{PGid, Pid, Tid, TID_ALLOCATOR};
use vfs::sys_root_dentry;
use vfs_core::Path;

Expand All @@ -25,7 +25,7 @@ use crate::{

pub fn spawn_init_proc() {
let init_proc_path = "/init_proc";
let argv = Vec::new();
let args = vec![init_proc_path.to_string()];
let envp = Vec::new();

let file = Path::new(sys_root_dentry(), sys_root_dentry(), init_proc_path)
Expand All @@ -37,14 +37,14 @@ pub fn spawn_init_proc() {

let mut memory_space = MemorySpace::new_user();
unsafe { memory_space.switch_page_table() };
let (entry, auxv) = memory_space.parse_and_map_elf(file, &elf_data);
let (entry, auxv) = memory_space.parse_and_map_elf(file.clone(), &elf_data);
let sp_init = memory_space.alloc_stack_lazily(USER_STACK_SIZE);
let (sp, argc, argv, envp) = within_sum(|| init_stack(sp_init, argv, envp, auxv));
let (sp, argc, argv, envp) = within_sum(|| init_stack(sp_init, args.clone(), envp, auxv));
memory_space.alloc_heap_lazily();

let trap_context = TrapContext::new(entry, sp);

let task = Task::new_init(memory_space, trap_context);
let task = Task::new_init(memory_space, trap_context, file, args);
schedule::spawn_user_task(task);
}

Expand Down
6 changes: 6 additions & 0 deletions kernel/src/task/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ impl<F: Future<Output = ()> + Send + 'static> Future for KernelTaskFuture<F> {
pub async fn task_loop(task: Arc<Task>) {
*task.waker() = Some(get_waker().await);
loop {
match task.state() {
Zombie => break,
Stopped => suspend_now().await,
_ => {}
}

trap::user_trap::trap_return(&task);

// task may be set to zombie by other task, e.g. execve will kill other tasks in
Expand Down
7 changes: 1 addition & 6 deletions kernel/src/task/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,7 @@ impl Task {
SigInfo {
sig: Sig::SIGCHLD,
code,
details: SigDetails::CHLD {
pid: self.pid(),
status: signum.raw() as i32 & 0x7F,
utime: self.time_stat().user_time(),
stime: self.time_stat().sys_time(),
},
details: SigDetails::None,
},
false,
);
Expand Down
Loading

0 comments on commit ae9bdc4

Please sign in to comment.