Merge pull request #5 from SKTT1Ryze/main

Add some scheduler
This commit is contained in:
hustccc 2021-03-06 15:31:21 +08:00 committed by GitHub
commit 57d3952e89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 113 additions and 10 deletions

View File

@ -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;
}
}

View File

@ -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> {
// 加入链表尾部

View File

@ -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> {
// 加入环形队列

View File

@ -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()
}
}

View File

@ -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);

View File

@ -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);