Skip to content

Commit

Permalink
改了一点细节 chyyuu#17
Browse files Browse the repository at this point in the history
  • Loading branch information
Tuyixiang committed May 4, 2020
1 parent d949e3d commit 7e655e4
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 20 deletions.
2 changes: 2 additions & 0 deletions os/src/data_structure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
mod segment_tree_allocator;
mod stacked_allocator;
mod unsafe_wrapper;

pub use segment_tree_allocator::SegmentTreeAllocator;
pub use stacked_allocator::StackedAllocator;
pub use unsafe_wrapper::{UnsafeWrapper, StaticUnsafeWrapper};

/// 分配器:固定容量,每次分配 / 回收一个元素
pub trait Allocator {
Expand Down
70 changes: 70 additions & 0 deletions os/src/data_structure/unsafe_wrapper.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//! 允许像 C 指针一样随意使用的 [`UnsafeWrapper`]
use alloc::boxed::Box;
use core::cell::UnsafeCell;

/// 允许从 &self 获取 &mut 内部变量
pub struct UnsafeWrapper<T> {
object: UnsafeCell<T>,
}

impl<T> UnsafeWrapper<T> {
pub fn new(object: T) -> Self {
Self {
object: UnsafeCell::new(object),
}
}

pub fn get(&self) -> &mut T {
unsafe { &mut *self.object.get() }
}
}

impl<T: Default> Default for UnsafeWrapper<T> {
fn default() -> Self {
Self {
object: UnsafeCell::new(T::default()),
}
}
}

unsafe impl<T> Sync for UnsafeWrapper<T> {}

pub trait StaticUnsafeInit {
fn static_unsafe_init() -> Self;
}

pub struct StaticUnsafeWrapper<T> {
pointer: UnsafeCell<*const UnsafeCell<T>>,
_phantom: core::marker::PhantomData<T>,
}

impl<T> StaticUnsafeWrapper<T> {
pub const fn new() -> Self {
Self {
pointer: UnsafeCell::new(0 as *const _),
_phantom: core::marker::PhantomData,
}
}
}

impl<T: Default> StaticUnsafeWrapper<T> {
pub fn get(&self) -> &mut T {
unsafe {
if *self.pointer.get() as usize == 0 {
let boxed = Box::new(UnsafeCell::new(T::default()));
*self.pointer.get() = Box::into_raw(boxed);
}
&mut *(**self.pointer.get()).get()
}
}
}

impl<T: Default> core::ops::Deref for StaticUnsafeWrapper<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.get()
}
}

unsafe impl<T> Sync for StaticUnsafeWrapper<T> {}
2 changes: 1 addition & 1 deletion os/src/interrupt/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ fn breakpoint(trap_frame: &mut TrapFrame) -> *mut TrapFrame {
/// 处理时钟中断
fn supervisor_timer(trap_frame: &mut TrapFrame) -> *mut TrapFrame {
timer::tick();
PROCESSOR.tick(trap_frame)
PROCESSOR.get().tick(trap_frame)
}
8 changes: 4 additions & 4 deletions os/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ pub extern "C" fn rust_main() -> ! {
memory::init();

let process = Process::new_kernel().unwrap();

let thread = Thread::new(process.clone(), sample_process as usize, Some(&[12345usize])).unwrap();
PROCESSOR.schedule_thread(thread);
PROCESSOR.get().schedule_thread(thread);
let thread = Thread::new(process, sample_process as usize, Some(&[12345usize])).unwrap();
PROCESSOR.schedule_thread(thread);
PROCESSOR.get().schedule_thread(thread);

PROCESSOR.run();
PROCESSOR.get().run();
}

fn sample_process(arg: usize) {
Expand Down
35 changes: 20 additions & 15 deletions os/src/process/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
use super::*;
use lazy_static::*;
use crate::data_structure::UnsafeWrapper;

lazy_static! {
pub static ref PROCESSOR: Processor = Processor::default();
/// 全局的 [`Processor`]
pub static ref PROCESSOR: UnsafeWrapper<Processor> = Default::default();
}

/// 线程调度和管理
#[derive(Default)]
pub struct Processor {
current_thread: RwLock<Option<Arc<Thread>>>,
scheduler: RwLock<Scheduler>,
/// 当前正在执行的线程
current_thread: Option<Arc<Thread>>,
/// 线程调度器,其中不包括正在执行的线程
scheduler: Scheduler,
}

impl Processor {
Expand All @@ -20,13 +25,13 @@ impl Processor {
/// 来从 `TrapFrame` 中继续执行该线程。
///
/// 注意调用 `run()` 的线程会就此步入虚无,不再被使用
pub fn run(&self) -> ! {
pub fn run(&mut self) -> ! {
// interrupt.asm 中的标签
extern "C" {
fn __restore(trap_frame: *mut TrapFrame);
}
// 从 current_thread 中取出 TrapFrame
let thread = self.current_thread.write().as_ref().unwrap().clone();
let thread = self.current_thread.as_ref().unwrap().clone();
let trap_frame = thread.run();
// 因为这个线程不会回来回收,所以手动 drop 掉线程的一个 Arc
drop(thread);
Expand All @@ -38,28 +43,28 @@ impl Processor {
}

/// 在一个时钟中断时,替换掉 trap_frame
pub fn tick(&self, trap_frame: &mut TrapFrame) -> *mut TrapFrame {
pub fn tick(&mut self, trap_frame: &mut TrapFrame) -> *mut TrapFrame {
// 暂停当前线程
let current_thread = self.current_thread.write().take().unwrap();
let current_thread = self.current_thread.take().unwrap();
current_thread.park(*trap_frame);
// 将其放回调度器
self.scheduler.write().store(current_thread);
self.scheduler.store(current_thread);

// 取出一个线程
let next_thread = self.scheduler.write().get();
// 取出其 TrapFrame
let next_thread = self.scheduler.get();
let trap_frame = next_thread.run();
// 作为当前线程
self.current_thread.write().replace(next_thread);
self.current_thread.replace(next_thread);
trap_frame
}

/// 添加一个待执行的线程
pub fn schedule_thread(&self, thread: Arc<Thread>) {
if self.current_thread.read().is_none() {
self.current_thread.write().replace(thread);
pub fn schedule_thread(&mut self, thread: Arc<Thread>) {
// 如果 current_thread 为空就添加为 current_thread,否则丢给 scheduler
if self.current_thread.is_none() {
self.current_thread.replace(thread);
} else {
self.scheduler.write().store(thread);
self.scheduler.store(thread);
}
}
}

0 comments on commit 7e655e4

Please sign in to comment.