Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
rcore-os
RCore Tutorial V3
提交
1bc53c0b
R
RCore Tutorial V3
项目概览
rcore-os
/
RCore Tutorial V3
上一次同步 1 年多
通知
15
Star
793
Fork
260
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
4
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
RCore Tutorial V3
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
4
Issue
4
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
1bc53c0b
编写于
12月 08, 2020
作者:
Y
Yifan Wu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Split TaskManager and Processor.
上级
0c12d43b
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
175 addition
and
132 deletion
+175
-132
os/src/main.rs
os/src/main.rs
+10
-2
os/src/task/manager.rs
os/src/task/manager.rs
+34
-0
os/src/task/mod.rs
os/src/task/mod.rs
+27
-128
os/src/task/processor.rs
os/src/task/processor.rs
+96
-0
os/src/task/task.rs
os/src/task/task.rs
+6
-2
os/src/trap/mod.rs
os/src/trap/mod.rs
+2
-0
未找到文件。
os/src/main.rs
浏览文件 @
1bc53c0b
...
...
@@ -43,10 +43,18 @@ pub fn rust_main() -> ! {
mm
::
init
();
println!
(
"[kernel] back to world!"
);
mm
::
remap_test
();
// add apps
let
num_app
=
loader
::
get_num_app
();
println!
(
"num_app={}"
,
num_app
);
for
i
in
0
..
num_app
{
println!
(
"i={}"
,
i
);
task
::
add_application
(
loader
::
get_app_data
(
i
),
i
);
}
trap
::
init
();
//trap::enable_interrupt();
trap
::
enable_timer_interrupt
();
timer
::
set_next_trigger
();
task
::
run_first_task
();
println!
(
"before task::run_tasks!"
);
task
::
run_tasks
();
panic!
(
"Unreachable in rust_main!"
);
}
\ No newline at end of file
os/src/task/manager.rs
0 → 100644
浏览文件 @
1bc53c0b
use
super
::
TaskControlBlock
;
use
alloc
::
collections
::
VecDeque
;
use
alloc
::
sync
::
Arc
;
use
spin
::
Mutex
;
use
lazy_static
::
*
;
pub
struct
TaskManager
{
ready_queue
:
VecDeque
<
Arc
<
Mutex
<
TaskControlBlock
>>>
,
}
/// A simple FIFO scheduler.
impl
TaskManager
{
pub
fn
new
()
->
Self
{
Self
{
ready_queue
:
VecDeque
::
new
(),
}
}
pub
fn
add
(
&
mut
self
,
task
:
Arc
<
Mutex
<
TaskControlBlock
>>
)
{
self
.ready_queue
.push_back
(
task
);
}
pub
fn
fetch
(
&
mut
self
)
->
Option
<
Arc
<
Mutex
<
TaskControlBlock
>>>
{
self
.ready_queue
.pop_front
()
}
}
lazy_static!
{
pub
static
ref
TASK_MANAGER
:
Mutex
<
TaskManager
>
=
Mutex
::
new
(
TaskManager
::
new
());
}
pub
fn
add_task
(
task
:
Arc
<
Mutex
<
TaskControlBlock
>>
)
{
TASK_MANAGER
.lock
()
.add
(
task
);
}
pub
fn
fetch_task
()
->
Option
<
Arc
<
Mutex
<
TaskControlBlock
>>>
{
TASK_MANAGER
.lock
()
.fetch
()
}
\ No newline at end of file
os/src/task/mod.rs
浏览文件 @
1bc53c0b
mod
context
;
mod
switch
;
mod
task
;
mod
manager
;
mod
processor
;
use
crate
::
loader
::{
get_num_app
,
get_app_data
};
use
crate
::
trap
::
TrapContext
;
...
...
@@ -9,141 +11,38 @@ use lazy_static::*;
use
switch
::
__
switch
;
use
task
::{
TaskControlBlock
,
TaskStatus
};
use
alloc
::
vec
::
Vec
;
use
alloc
::
sync
::
Arc
;
use
spin
::
Mutex
;
use
manager
::
fetch_task
;
pub
use
context
::
TaskContext
;
pub
struct
TaskManager
{
num_app
:
usize
,
inner
:
RefCell
<
TaskManagerInner
>
,
}
struct
TaskManagerInner
{
tasks
:
Vec
<
TaskControlBlock
>
,
current_task
:
usize
,
}
unsafe
impl
Sync
for
TaskManager
{}
lazy_static!
{
pub
static
ref
TASK_MANAGER
:
TaskManager
=
{
println!
(
"init TASK_MANAGER"
);
let
num_app
=
get_num_app
();
println!
(
"num_app = {}"
,
num_app
);
let
mut
tasks
:
Vec
<
TaskControlBlock
>
=
Vec
::
new
();
for
i
in
0
..
num_app
{
tasks
.push
(
TaskControlBlock
::
new
(
get_app_data
(
i
),
i
,
));
}
TaskManager
{
num_app
,
inner
:
RefCell
::
new
(
TaskManagerInner
{
tasks
,
current_task
:
0
,
}),
}
};
}
impl
TaskManager
{
fn
run_first_task
(
&
self
)
{
self
.inner
.borrow_mut
()
.tasks
[
0
]
.task_status
=
TaskStatus
::
Running
;
let
next_task_cx
=
self
.inner
.borrow
()
.tasks
[
0
]
.get_task_cx_ptr2
();
let
_u
nused
:
usize
=
0
;
unsafe
{
__
switch
(
&
_u
nused
as
*
const
_
,
next_task_cx
,
);
}
}
fn
mark_current_suspended
(
&
self
)
{
let
mut
inner
=
self
.inner
.borrow_mut
();
let
current
=
inner
.current_task
;
inner
.tasks
[
current
]
.task_status
=
TaskStatus
::
Ready
;
}
fn
mark_current_exited
(
&
self
)
{
let
mut
inner
=
self
.inner
.borrow_mut
();
let
current
=
inner
.current_task
;
inner
.tasks
[
current
]
.task_status
=
TaskStatus
::
Exited
;
}
fn
find_next_task
(
&
self
)
->
Option
<
usize
>
{
let
inner
=
self
.inner
.borrow
();
let
current
=
inner
.current_task
;
(
current
+
1
..
current
+
self
.num_app
+
1
)
.map
(|
id
|
id
%
self
.num_app
)
.find
(|
id
|
{
inner
.tasks
[
*
id
]
.task_status
==
TaskStatus
::
Ready
})
}
fn
get_current_token
(
&
self
)
->
usize
{
let
inner
=
self
.inner
.borrow
();
let
current
=
inner
.current_task
;
inner
.tasks
[
current
]
.get_user_token
()
}
fn
get_current_trap_cx
(
&
self
)
->
&
mut
TrapContext
{
let
inner
=
self
.inner
.borrow
();
let
current
=
inner
.current_task
;
inner
.tasks
[
current
]
.get_trap_cx
()
}
fn
run_next_task
(
&
self
)
{
if
let
Some
(
next
)
=
self
.find_next_task
()
{
let
mut
inner
=
self
.inner
.borrow_mut
();
let
current
=
inner
.current_task
;
inner
.tasks
[
next
]
.task_status
=
TaskStatus
::
Running
;
inner
.current_task
=
next
;
let
current_task_cx
=
inner
.tasks
[
current
]
.get_task_cx_ptr2
();
let
next_task_cx
=
inner
.tasks
[
next
]
.get_task_cx_ptr2
();
core
::
mem
::
drop
(
inner
);
unsafe
{
__
switch
(
current_task_cx
,
next_task_cx
,
);
}
}
else
{
panic!
(
"All applications completed!"
);
}
}
}
pub
fn
run_first_task
()
{
TASK_MANAGER
.run_first_task
();
}
fn
run_next_task
()
{
TASK_MANAGER
.run_next_task
();
}
fn
mark_current_suspended
()
{
TASK_MANAGER
.mark_current_suspended
();
}
fn
mark_current_exited
()
{
TASK_MANAGER
.mark_current_exited
();
}
pub
use
processor
::{
run_tasks
,
current_task
,
current_user_token
,
current_trap_cx
,
take_current_task
,
schedule
,
};
pub
use
manager
::
add_task
;
pub
fn
suspend_current_and_run_next
()
{
mark_current_suspended
();
run_next_task
();
// There must be an application running.
let
task
=
current_task
()
.unwrap
();
let
task_cx_ptr
=
task
.lock
()
.get_task_cx_ptr2
();
// Change status to Ready.
task
.lock
()
.task_status
=
TaskStatus
::
Ready
;
// push back to ready queue.
add_task
(
task
);
// jump to scheduling cycle
schedule
(
task_cx_ptr
);
}
pub
fn
exit_current_and_run_next
()
{
mark_current_exited
();
run_next_task
(
);
// The resource recycle mechanism needs child processes. Now we just panic!
panic!
(
"An application exited!"
);
}
pub
fn
current_user_token
()
->
usize
{
TASK_MANAGER
.get_current_token
()
pub
fn
add_application
(
elf_data
:
&
[
u8
],
app_id
:
usize
)
{
add_task
(
Arc
::
new
(
Mutex
::
new
(
TaskControlBlock
::
new
(
elf_data
,
app_id
))));
}
pub
fn
current_trap_cx
()
->
&
'static
mut
TrapContext
{
TASK_MANAGER
.get_current_trap_cx
()
}
\ No newline at end of file
os/src/task/processor.rs
0 → 100644
浏览文件 @
1bc53c0b
use
super
::
TaskControlBlock
;
use
alloc
::
sync
::
Arc
;
use
spin
::
Mutex
;
use
lazy_static
::
*
;
use
super
::{
add_task
,
fetch_task
};
use
super
::
__
switch
;
use
crate
::
trap
::
TrapContext
;
pub
struct
Processor
{
inner
:
Mutex
<
ProcessorInner
>
,
}
unsafe
impl
Sync
for
Processor
{}
struct
ProcessorInner
{
current
:
Option
<
Arc
<
Mutex
<
TaskControlBlock
>>>
,
idle_task_cx_ptr
:
usize
,
}
impl
Processor
{
pub
fn
new
()
->
Self
{
Self
{
inner
:
Mutex
::
new
(
ProcessorInner
{
current
:
None
,
idle_task_cx_ptr
:
0
,
}),
}
}
fn
get_idle_task_cx_ptr2
(
&
self
)
->
*
const
usize
{
let
inner
=
self
.inner
.lock
();
&
inner
.idle_task_cx_ptr
as
*
const
usize
}
pub
fn
run
(
&
self
)
{
//println!("into Processor::run");
loop
{
if
let
Some
(
task
)
=
fetch_task
()
{
//println!("found task!");
let
idle_task_cx_ptr
=
self
.get_idle_task_cx_ptr2
();
let
next_task_cx_ptr
=
task
.lock
()
.get_task_cx_ptr2
();
//println!("next_task_cx_ptr={:p}", next_task_cx_ptr);
self
.inner
.lock
()
.current
=
Some
(
task
);
unsafe
{
__
switch
(
idle_task_cx_ptr
,
next_task_cx_ptr
,
);
}
}
}
}
pub
fn
take_current
(
&
self
)
->
Option
<
Arc
<
Mutex
<
TaskControlBlock
>>>
{
self
.inner
.lock
()
.current
.take
()
}
pub
fn
current
(
&
self
)
->
Option
<
Arc
<
Mutex
<
TaskControlBlock
>>>
{
self
.inner
.lock
()
.current
.as_ref
()
.map
(|
task
|
task
.clone
())
}
}
lazy_static!
{
pub
static
ref
PROCESSOR
:
Processor
=
Processor
::
new
();
}
pub
fn
run_tasks
()
{
PROCESSOR
.run
();
}
pub
fn
take_current_task
()
->
Option
<
Arc
<
Mutex
<
TaskControlBlock
>>>
{
PROCESSOR
.take_current
()
}
pub
fn
current_task
()
->
Option
<
Arc
<
Mutex
<
TaskControlBlock
>>>
{
//println!("into current_task!");
PROCESSOR
.current
()
}
pub
fn
current_user_token
()
->
usize
{
//println!("into current_user_token!");
let
task
=
current_task
()
.unwrap
();
//println!("Got task in current_user_token!");
let
token
=
task
.lock
()
.get_user_token
();
token
}
pub
fn
current_trap_cx
()
->
&
'static
mut
TrapContext
{
current_task
()
.unwrap
()
.as_ref
()
.lock
()
.get_trap_cx
()
}
pub
fn
schedule
(
switched_task_cx_ptr2
:
*
const
usize
)
{
let
idle_task_cx_ptr2
=
PROCESSOR
.get_idle_task_cx_ptr2
();
unsafe
{
__
switch
(
switched_task_cx_ptr2
,
idle_task_cx_ptr2
,
);
}
}
os/src/task/task.rs
浏览文件 @
1bc53c0b
...
...
@@ -4,11 +4,14 @@ use crate::config::{TRAP_CONTEXT, kernel_stack_position};
use
super
::
TaskContext
;
pub
struct
TaskControlBlock
{
// immutable
pub
trap_cx_ppn
:
PhysPageNum
,
pub
base_size
:
usize
,
//pub pid: usize,
// mutable
pub
task_cx_ptr
:
usize
,
pub
task_status
:
TaskStatus
,
pub
memory_set
:
MemorySet
,
pub
trap_cx_ppn
:
PhysPageNum
,
pub
base_size
:
usize
,
}
impl
TaskControlBlock
{
...
...
@@ -65,4 +68,5 @@ pub enum TaskStatus {
Ready
,
Running
,
Exited
,
Zombie
,
}
\ No newline at end of file
os/src/trap/mod.rs
浏览文件 @
1bc53c0b
...
...
@@ -83,6 +83,7 @@ pub fn trap_handler() -> ! {
#[no_mangle]
pub
fn
trap_return
()
->
!
{
//println!("into trap_return!");
set_user_trap_entry
();
let
trap_cx_ptr
=
TRAP_CONTEXT
;
let
user_satp
=
current_user_token
();
...
...
@@ -91,6 +92,7 @@ pub fn trap_return() -> ! {
fn
__
restore
();
}
let
restore_va
=
__
restore
as
usize
-
__
alltraps
as
usize
+
TRAMPOLINE
;
//println!("before jr!");
unsafe
{
llvm_asm!
(
"jr $0"
::
"r"
(
restore_va
),
"{a0}"
(
trap_cx_ptr
),
"{a1}"
(
user_satp
)
::
"volatile"
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录