commit
57d3952e89
|
@ -1,5 +1,5 @@
|
|||
pub use allocator::{Allocator, StackedAllocator};
|
||||
pub use scheduler::{Scheduler, FifoScheduler, RingFifoScheduler};
|
||||
pub use scheduler::{Scheduler, ScheduledItem, FifoScheduler, RingFifoScheduler, SameAddrSpaceScheduler};
|
||||
|
||||
mod allocator {
|
||||
mod stacked_allocator;
|
||||
|
@ -18,11 +18,12 @@ mod allocator {
|
|||
mod scheduler {
|
||||
mod fifo_scheduler;
|
||||
mod ring_fifo_scheduler;
|
||||
|
||||
mod same_addr_scheduler;
|
||||
pub use fifo_scheduler::FifoScheduler;
|
||||
pub use ring_fifo_scheduler::RingFifoScheduler;
|
||||
pub use same_addr_scheduler::SameAddrSpaceScheduler;
|
||||
|
||||
pub trait Scheduler<T: Clone + PartialEq> {
|
||||
pub trait Scheduler<T: ScheduledItem + Clone + PartialEq> {
|
||||
/// 优先级的类型
|
||||
type Priority;
|
||||
/// 向调度器中添加一个任务;成功返回None,如果不成功,返回T
|
||||
|
@ -36,4 +37,9 @@ mod scheduler {
|
|||
/// 设置任务的优先级
|
||||
fn set_priority(&mut self, task: T, prio: Self::Priority);
|
||||
}
|
||||
|
||||
/// 被调度者需要实现的 `Trait`
|
||||
pub trait ScheduledItem {
|
||||
fn need_switch(&self) -> bool;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::Scheduler;
|
||||
use super::{Scheduler, ScheduledItem};
|
||||
use alloc::collections::LinkedList;
|
||||
|
||||
/// 先进先出任务调度器
|
||||
|
@ -16,7 +16,7 @@ impl<T> FifoScheduler<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + PartialEq> Scheduler<T> for FifoScheduler<T> {
|
||||
impl<T: ScheduledItem + Clone + PartialEq> Scheduler<T> for FifoScheduler<T> {
|
||||
type Priority = ();
|
||||
fn add_task(&mut self, task: T) -> Option<T> {
|
||||
// 加入链表尾部
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::Scheduler;
|
||||
use super::{Scheduler, ScheduledItem};
|
||||
use core::mem::MaybeUninit;
|
||||
use core::ptr;
|
||||
|
||||
|
@ -16,7 +16,7 @@ impl<T, const N: usize> RingFifoScheduler<T, N> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + PartialEq, const N: usize> Scheduler<T> for RingFifoScheduler<T, N> {
|
||||
impl<T: ScheduledItem + Clone + PartialEq, const N: usize> Scheduler<T> for RingFifoScheduler<T, N> {
|
||||
type Priority = ();
|
||||
fn add_task(&mut self, task: T) -> Option<T> {
|
||||
// 加入环形队列
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
use super::{Scheduler, ScheduledItem};
|
||||
use alloc::collections::LinkedList;
|
||||
|
||||
/// 尽量调度相同地址空间的调度器
|
||||
pub struct SameAddrSpaceScheduler<T, const N: usize> {
|
||||
tasks: LinkedList<T>,
|
||||
max_len: usize
|
||||
}
|
||||
|
||||
impl<T, const N: usize> SameAddrSpaceScheduler<T, N> {
|
||||
#[allow(unused)]
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
tasks: LinkedList::new(),
|
||||
max_len: N
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const N: usize> Scheduler<T> for SameAddrSpaceScheduler<T, N>
|
||||
where T: ScheduledItem + Clone + PartialEq
|
||||
|
||||
{
|
||||
type Priority = ();
|
||||
/// 添加任务到调度队列
|
||||
/// 如果队列已满,返回 Some(task)
|
||||
fn add_task(&mut self, task: T) -> Option<T> {
|
||||
if self.tasks.len() < self.max_len {
|
||||
// 加入链表尾部
|
||||
self.tasks.push_back(task);
|
||||
None
|
||||
} else {
|
||||
Some(task)
|
||||
}
|
||||
}
|
||||
/// 取出下一个当前地址空间的任务
|
||||
/// 如果当前地址空间的任务或者所有任务已经完成,返回 None
|
||||
fn next_task(&mut self) -> Option<T> {
|
||||
|
||||
let mut count = 0;
|
||||
let len = self.tasks.len();
|
||||
while self.tasks.front().is_some() && count < len {
|
||||
// note(unwrap): 前面 self.tasks.front().is_some() 返回 Some
|
||||
let task = self.tasks.pop_front().unwrap();
|
||||
if task.need_switch() {
|
||||
self.tasks.push_back(task);
|
||||
count += 1;
|
||||
} else {
|
||||
return Some(task);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
/// 尝试获取下一个当前地址空间的任务的引用
|
||||
/// 如果不存在,则返回链表头部的任务的引用
|
||||
/// 如果所有任务已经完成,返回 None
|
||||
fn peek_next_task(&self) -> Option<&T> {
|
||||
let mut iter = self.tasks.iter();
|
||||
loop {
|
||||
let task = iter.next();
|
||||
if task.is_some() {
|
||||
if !task.as_ref().unwrap().need_switch() {
|
||||
return task;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.tasks.front()
|
||||
}
|
||||
fn remove_task(&mut self, task: &T) {
|
||||
// 移除相应的线程并且确认恰移除一个线程
|
||||
let mut removed = self.tasks.drain_filter(|t| t == task);
|
||||
assert!(removed.next().is_some() && removed.next().is_none());
|
||||
}
|
||||
fn set_priority(&mut self, _task: T, _prio: Self::Priority) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const N: usize> IntoIterator for SameAddrSpaceScheduler<T, N> {
|
||||
type Item = T;
|
||||
type IntoIter = alloc::collections::linked_list::IntoIter<Self::Item>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.tasks.into_iter()
|
||||
}
|
||||
|
||||
}
|
|
@ -85,6 +85,7 @@ pub extern "C" fn rust_main() -> ! {
|
|||
|
||||
println!("task_1: {:?}", task_1);
|
||||
println!("task_2: {:?}", task_2);
|
||||
println!("task_3: {:?}", task_3);
|
||||
|
||||
let shared_scheduler = process::shared_scheduler();
|
||||
println!("Shared scheduler: {:?}", shared_scheduler);
|
||||
|
|
|
@ -8,17 +8,19 @@ pub use task::{Task, TaskId};
|
|||
pub use process::{Process, ProcessId};
|
||||
pub use executor::Executor;
|
||||
|
||||
use crate::{algorithm::{Scheduler, RingFifoScheduler}, memory::AddressSpaceId};
|
||||
#[allow(unused_imports)]
|
||||
use crate::{algorithm::{Scheduler, ScheduledItem, RingFifoScheduler, SameAddrSpaceScheduler}, memory::AddressSpaceId};
|
||||
use core::ptr::NonNull;
|
||||
|
||||
/// 共享调度器的类型
|
||||
type SharedScheduler = spin::Mutex<RingFifoScheduler<SharedTaskHandle, 500>>;
|
||||
// type SharedScheduler = spin::Mutex<RingFifoScheduler<SharedTaskHandle, 500>>;
|
||||
type SharedScheduler = spin::Mutex<SameAddrSpaceScheduler<SharedTaskHandle, 500>>;
|
||||
|
||||
/// 所有任务的调度器
|
||||
///
|
||||
/// 注意:所有.shared_data段内的数据不应该分配堆空间
|
||||
#[link_section = ".shared_data"]
|
||||
pub static SHARED_SCHEDULER: SharedScheduler = spin::Mutex::new(RingFifoScheduler::new());
|
||||
pub static SHARED_SCHEDULER: SharedScheduler = spin::Mutex::new(SameAddrSpaceScheduler::new());
|
||||
|
||||
pub fn shared_scheduler() -> NonNull<()> {
|
||||
NonNull::new(&SHARED_SCHEDULER as *const _ as *mut ()).expect("create non null pointer")
|
||||
|
@ -41,6 +43,12 @@ impl SharedTaskHandle {
|
|||
}
|
||||
}
|
||||
|
||||
impl ScheduledItem for SharedTaskHandle {
|
||||
fn need_switch(&self) -> bool {
|
||||
self.should_switch()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)] // todo: 用上 -- luojia65
|
||||
pub static SHARED_RAW_TABLE: (unsafe fn(NonNull<()>, SharedTaskHandle) -> Option<SharedTaskHandle>, unsafe fn(NonNull<()>) -> TaskResult)
|
||||
= (shared_add_task, shared_pop_task);
|
||||
|
|
Loading…
Reference in New Issue