Skip to content

Commit ed76271

Browse files
committed
feat: add multicore
1 parent 2267882 commit ed76271

File tree

10 files changed

+163
-164
lines changed

10 files changed

+163
-164
lines changed

Cargo.lock

+3-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kernel/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ serde_derive = "1.0.136"
1414

1515
[dependencies]
1616
allocator = { git = "https://github.com/Byte-OS/allocator.git", rev = "c6ce949146d5feab1d406502b19b035f5d392c35"}
17-
crate_interface = { git = "https://github.com/Byte-OS/crate_interface.git" }
1817
frame_allocator = { git = "https://github.com/Byte-OS/bit_frame_allocator.git" }
1918
logging = { git = "https://github.com/Byte-OS/logging.git", features = []}
2019
log = "0.4"

kernel/linker.lds.S

+8-8
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@ SECTIONS
4040

4141
_load_end = .;
4242

43-
.bss ALIGN(4K): {
44-
*(.bss.stack)
45-
_sbss = .;
46-
*(.bss .bss.*)
47-
*(.sbss .sbss.*)
48-
_ebss = .;
49-
}
50-
5143
. = ALIGN(4K);
5244
_percpu_start = .;
5345
.percpu 0x0 : AT(_percpu_start) {
@@ -62,6 +54,14 @@ SECTIONS
6254
. = _percpu_start + SIZEOF(.percpu);
6355
_percpu_end = .;
6456

57+
.bss ALIGN(4K): {
58+
*(.bss.stack)
59+
_sbss = .;
60+
*(.bss .bss.*)
61+
*(.sbss .sbss.*)
62+
_ebss = .;
63+
}
64+
6565
PROVIDE(end = .);
6666
/DISCARD/ : {
6767
*(.comment) *(.gnu*) *(.note*) *(.eh_frame*)

kernel/src/main.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,7 @@ fn main(hart_id: usize) {
214214

215215
// init kernel threads and async executor
216216
tasks::init();
217-
loop {
218-
arch::wfi()
219-
}
217+
// loop { arch::wfi() }
220218
tasks::run_tasks();
221219

222220
println!("Task All Finished!");

kernel/src/panic.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1-
use arch::shutdown;
1+
use arch::{hart_id, shutdown};
22
// use backtrace::backtrace;
33
use core::panic::PanicInfo;
44

55
// 程序遇到错误
66
#[panic_handler]
77
fn panic_handler(info: &PanicInfo) -> ! {
8-
println!("\x1b[1;31mpanic: '{}'\x1b[0m", info.message().unwrap());
8+
if let Some(location) = info.location() {
9+
println!(
10+
"\x1b[1;31m[Core {}][{}:{}]panic: '{}'\x1b[0m",
11+
hart_id(),
12+
location.file(),
13+
location.line(),
14+
info.message().unwrap()
15+
);
16+
} else {
17+
println!(
18+
"\x1b[1;31m[Core {}]panic: '{}'\x1b[0m",
19+
hart_id(),
20+
info.message().unwrap()
21+
);
22+
}
923
// backtrace();
1024
println!("!TEST FINISH!");
1125
// loop {}

kernel/src/syscall/task.rs

+17-21
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use arch::{
2424
};
2525
use async_recursion::async_recursion;
2626
use core::cmp;
27-
use executor::{select, yield_now, AsyncTask, TASK_QUEUE};
27+
use executor::{select, thread, tid2task, yield_now, AsyncTask};
2828
use frame_allocator::{ceil_div, frame_alloc_much, FrameTracker};
2929
use fs::dentry::{dentry_open, dentry_root};
3030
use fs::TimeSpec;
@@ -228,8 +228,10 @@ pub async fn exec_with_process(
228228
Ok(user_task)
229229
} else {
230230
drop(caches);
231-
let file = dentry_open(dentry_root(), &path, OpenFlags::O_RDONLY).map_err(from_vfs)?;
232-
let file = file.node.clone();
231+
let file = dentry_open(dentry_root(), &path, OpenFlags::O_RDONLY)
232+
.map_err(from_vfs)?
233+
.node
234+
.clone();
233235
debug!("file: {:#x?}", file.metadata().unwrap());
234236
let file_size = file.metadata().unwrap().size;
235237
let frame_ppn = frame_alloc_much(ceil_div(file_size, PAGE_SIZE));
@@ -454,10 +456,10 @@ impl UserTaskContainer {
454456
);
455457

456458
let new_task = match flags.contains(CloneFlags::CLONE_THREAD) {
457-
true => self.task.clone().thread_clone(user_entry()),
459+
true => self.task.clone().thread_clone(),
458460
// false => curr_task.clone().fork(user_entry()),
459461
// use cow(Copy On Write) to save memory.
460-
false => self.task.clone().cow_fork(user_entry()),
462+
false => self.task.clone().cow_fork(),
461463
};
462464

463465
let clear_child_tid = flags
@@ -484,6 +486,7 @@ impl UserTaskContainer {
484486
new_tcb.exit_signal = sig as u8;
485487
drop(new_tcb);
486488
yield_now().await;
489+
thread::spawn(new_task.clone(), user_entry());
487490
Ok(new_task.task_id)
488491
}
489492

@@ -531,11 +534,13 @@ impl UserTaskContainer {
531534
"wait ok: {} waiter: {}",
532535
child_task.task_id, self.task.task_id
533536
);
537+
// release the task resources
534538
self.task
535539
.pcb
536540
.lock()
537541
.children
538542
.retain(|x| x.task_id != child_task.task_id);
543+
child_task.release();
539544
debug!("wait pid: {}", child_task.exit_code().unwrap());
540545

541546
if status.is_valid() {
@@ -555,11 +560,13 @@ impl UserTaskContainer {
555560
match exit {
556561
Some(t1) => {
557562
let child_task = child_task.unwrap();
563+
// Release task.
558564
self.task
559565
.pcb
560566
.lock()
561567
.children
562568
.retain(|x| x.task_id != child_task.task_id);
569+
child_task.release();
563570
if status.is_valid() {
564571
*status.get_mut() = (t1 as i32) << 8;
565572
}
@@ -780,23 +787,12 @@ impl UserTaskContainer {
780787
self.tid, pid, signal
781788
);
782789

783-
let user_task = match pid == self.tid {
784-
true => Some(self.task.clone()),
785-
false => TASK_QUEUE
786-
.lock()
787-
.iter()
788-
.find(|x| x.task.get_task_id() == pid)
789-
.ok_or(LinuxError::ESRCH)?
790-
.task
791-
.clone()
790+
let user_task = match tid2task(pid) {
791+
Some(task) => task
792792
.downcast_arc::<UserTask>()
793-
.ok(),
794-
};
795-
796-
let user_task = match user_task {
797-
Some(t) => t,
798-
None => return Err(LinuxError::ESRCH),
799-
};
793+
.map_err(|_| LinuxError::ESRCH),
794+
None => Err(LinuxError::ESRCH),
795+
}?;
800796

801797
user_task.tcb.write().signal.add_signal(signal.clone());
802798

kernel/src/tasks/async_ops.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use core::{cmp, future::Future, pin::Pin, task::Poll};
22

33
use alloc::{sync::Arc, vec::Vec};
44
use arch::time::Time;
5+
use executor::AsyncTask;
56
use sync::Mutex;
67

78
use crate::syscall::consts::LinuxError;

kernel/src/tasks/initproc.rs

+29-15
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use alloc::{
44
string::{String, ToString},
55
vec::Vec,
66
};
7-
use arch::debug::DebugConsole;
8-
use executor::{current_task, task::TaskType, yield_now, TASK_QUEUE};
7+
use arch::{debug::DebugConsole, hart_id, shutdown};
8+
use executor::{current_task, release_task, task::TaskType, tid2task, yield_now, TASK_MAP};
99
use frame_allocator::get_free_pages;
1010
use fs::{
1111
dentry::{dentry_open, dentry_root, DentryNode},
@@ -56,9 +56,9 @@ fn clear() {
5656
}
5757

5858
async fn kill_all_tasks() {
59-
TASK_QUEUE
60-
.lock()
61-
.retain(|x| x.task_type != TaskType::MonolithicTask);
59+
TASK_MAP.lock().values().into_iter().for_each(|task| {
60+
task.upgrade().inspect(|x| x.exit(100));
61+
});
6262
}
6363

6464
async fn run_libc_test() -> bool {
@@ -129,13 +129,10 @@ async fn file_command(cmd: &str) {
129129
args_extend.extend(args.into_iter());
130130
// args.into_iter().for_each(|x| args_extend.push(x));
131131
let task_id = add_user_task(&filename, args_extend, Vec::new()).await;
132+
let task = tid2task(task_id).unwrap();
132133
loop {
133-
if TASK_QUEUE
134-
.lock()
135-
.iter()
136-
.find(|x| x.task.get_task_id() == task_id)
137-
.is_none()
138-
{
134+
if task.exit_code().is_some() {
135+
release_task(task_id);
139136
break;
140137
}
141138
yield_now().await;
@@ -225,6 +222,7 @@ pub async fn initproc() {
225222
// }
226223

227224
println!("start kernel tasks");
225+
228226
// command("ls").await;
229227
// command("entry-static.exe crypt").await;
230228
// command("./runtest.exe -w entry-dynamic.exe dlopen").await;
@@ -283,10 +281,12 @@ pub async fn initproc() {
283281
// command("busybox echo run libctest_testcode.sh").await;
284282
// command("busybox sh libctest_testcode.sh").await;
285283

284+
// command("busybox sh ./run-static.sh").await;
285+
// command("./runtest.exe -w entry-dynamic.exe pthread_robust_detach").await;
286286
// command("busybox echo 123").await;
287-
command("qjs.static test.js").await;
287+
// command("qjs.static test.js").await;
288288
// command("qjs.static").await;
289-
command("busybox sh").await;
289+
// command("busybox sh").await;
290290
// command("busybox echo run lua_testcode.sh").await;
291291
// command("busybox sh lua_testcode.sh").await;
292292

@@ -306,8 +306,8 @@ pub async fn initproc() {
306306
// command("busybox echo run lmbench_testcode.sh").await;
307307
// command("busybox sh lmbench_testcode.sh").await;
308308

309-
// command("busybox echo run unixbench_testcode.sh").await;
310-
// command("busybox sh unixbench_testcode.sh").await;
309+
command("busybox echo run unixbench_testcode.sh").await;
310+
command("busybox sh unixbench_testcode.sh").await;
311311

312312
// command("copy-file-range-test-1").await;
313313
// command("copy-file-range-test-2").await;
@@ -380,4 +380,18 @@ pub async fn initproc() {
380380

381381
// switch_to_kernel_page_table();
382382
println!("!TEST FINISH!");
383+
384+
// Shutdown if there just have blankkernel task.
385+
if TASK_MAP
386+
.lock()
387+
.values()
388+
.find(|x| {
389+
x.upgrade()
390+
.map(|x| x.get_task_type() != TaskType::BlankKernel)
391+
.unwrap_or(false)
392+
})
393+
.is_none()
394+
{
395+
shutdown();
396+
}
383397
}

kernel/src/tasks/mod.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use alloc::sync::Weak;
33
use alloc::{sync::Arc, vec::Vec};
44
use arch::get_cpu_num;
55
use devices::get_net_device;
6-
use executor::{current_task, thread, yield_now, AsyncTask, TaskId, DEFAULT_EXECUTOR, TASK_QUEUE};
6+
use executor::{current_task, thread, yield_now, AsyncTask, TaskId, DEFAULT_EXECUTOR};
77
use hal::{ITimerVal, TimeVal};
88

99
use crate::syscall::{exec_with_process, NET_SERVER};
@@ -74,9 +74,6 @@ pub async fn handle_net() {
7474
let mut buffer = vec![0u8; 2048];
7575
// #[cfg(feature = "net")]
7676
loop {
77-
if TASK_QUEUE.lock().len() == 0 {
78-
break;
79-
}
8077
let res = get_net_device(0).recv(&mut buffer);
8178
if let Ok(rlen) = res {
8279
NET_SERVER.analysis_net_data(&buffer[..rlen]);
@@ -86,11 +83,10 @@ pub async fn handle_net() {
8683
}
8784

8885
pub fn init() {
86+
DEFAULT_EXECUTOR.init(get_cpu_num());
8987
thread::spawn_blank(initproc());
9088
#[cfg(feature = "net")]
9189
thread::spawn_blank(KernelTask::new(handle_net()));
92-
93-
DEFAULT_EXECUTOR.init(get_cpu_num());
9490
}
9591

9692
pub fn run_tasks() {
@@ -99,8 +95,7 @@ pub fn run_tasks() {
9995

10096
pub async fn add_user_task(filename: &str, args: Vec<&str>, envp: Vec<&str>) -> TaskId {
10197
let curr_task = current_task();
102-
let task = UserTask::new(user_entry(), Weak::new(), initproc::USER_WORK_DIR);
103-
98+
let task = UserTask::new(Weak::new(), initproc::USER_WORK_DIR);
10499
task.before_run();
105100
exec_with_process(
106101
task.clone(),
@@ -111,6 +106,7 @@ pub async fn add_user_task(filename: &str, args: Vec<&str>, envp: Vec<&str>) ->
111106
.await
112107
.expect("can't add task to excutor");
113108
curr_task.before_run();
109+
thread::spawn(task.clone(), user_entry());
114110

115111
task.get_task_id()
116112
}

0 commit comments

Comments
 (0)