Skip to content

Commit

Permalink
feat(kernel): add State::task_ready_queue
Browse files Browse the repository at this point in the history
The modification to `constance_port_std` in this commit is a work-around
for <rust-lang/rust#43475>.
  • Loading branch information
yvt committed Jun 9, 2020
1 parent a85847a commit 8f7b057
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 9 deletions.
28 changes: 22 additions & 6 deletions src/constance/src/kernel.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! The RTOS kernel
use atomic_ref::AtomicRef;
use core::{fmt, mem::forget, num::NonZeroUsize, sync::atomic::Ordering};
use core::{borrow::BorrowMut, fmt, mem::forget, num::NonZeroUsize, sync::atomic::Ordering};

use crate::utils::{BinUInteger, Init, PrioBitmap};
use crate::utils::{intrusive_list::StaticListHead, BinUInteger, Init, PrioBitmap};

#[macro_use]
mod cfg;
Expand Down Expand Up @@ -218,6 +218,8 @@ pub unsafe trait KernelCfg2: Port + Sized {

type TaskReadyBitmap: PrioBitmap;

type TaskReadyQueue: BorrowMut<[StaticListHead<TaskCb<Self>>]> + Init + 'static;

/// Access the kernel's global state.
fn state() -> &'static State<Self>;

Expand All @@ -239,6 +241,7 @@ pub struct State<
System: KernelCfg2,
PortTaskState: 'static = <System as Port>::PortTaskState,
TaskReadyBitmap: PrioBitmap = <System as KernelCfg2>::TaskReadyBitmap,
TaskReadyQueue: 'static = <System as KernelCfg2>::TaskReadyQueue,
TaskPriority: 'static = <System as KernelCfg1>::TaskPriority,
> {
// TODO: Make `running_task` non-null to simplify runtime code
Expand All @@ -248,38 +251,51 @@ pub struct State<
/// The task ready bitmap, in which each bit indicates whether the
/// task ready queue corresponding to that bit contains a task or not.
task_ready_bitmap: utils::CpuLockCell<System, TaskReadyBitmap>,

/// The task ready queues, in which each queue represents the list of
/// runnable task at the corresponding priority level.
task_ready_queue: utils::CpuLockCell<System, TaskReadyQueue>,
}

impl<
System: KernelCfg2,
PortTaskState: 'static,
TaskReadyBitmap: PrioBitmap,
TaskReadyQueue: 'static + Init,
TaskPriority: 'static,
> Init for State<System, PortTaskState, TaskReadyBitmap, TaskPriority>
> Init for State<System, PortTaskState, TaskReadyBitmap, TaskReadyQueue, TaskPriority>
{
const INIT: Self = Self {
running_task: AtomicRef::new(None),
task_ready_bitmap: Init::INIT,
task_ready_queue: Init::INIT,
};
}

impl<
System: Kernel,
PortTaskState: 'static + fmt::Debug,
TaskReadyBitmap: PrioBitmap,
TaskReadyQueue: 'static + fmt::Debug,
TaskPriority: 'static,
> fmt::Debug for State<System, PortTaskState, TaskReadyBitmap, TaskPriority>
> fmt::Debug for State<System, PortTaskState, TaskReadyBitmap, TaskReadyQueue, TaskPriority>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("State")
.field("running_task", &self.running_task)
.field("task_ready_bitmap", &self.task_ready_bitmap)
.field("task_ready_queue", &self.task_ready_queue)
.finish()
}
}

impl<System: KernelCfg2, PortTaskState: 'static, TaskReadyBitmap: PrioBitmap, TaskPriority>
State<System, PortTaskState, TaskReadyBitmap, TaskPriority>
impl<
System: KernelCfg2,
PortTaskState: 'static,
TaskReadyBitmap: PrioBitmap,
TaskReadyQueue: BorrowMut<[StaticListHead<TaskCb<System, PortTaskState, TaskPriority>>]> + Init + 'static,
TaskPriority,
> State<System, PortTaskState, TaskReadyBitmap, TaskReadyQueue, TaskPriority>
{
/// Get the currently running task.
pub fn running_task(&self) -> Option<&'static TaskCb<System, PortTaskState, TaskPriority>> {
Expand Down
6 changes: 5 additions & 1 deletion src/constance/src/kernel/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,10 @@ macro_rules! build {
CfgBuilder, HunkAttr, HunkInitAttr, KernelCfg1, KernelCfg2, Port, State, TaskAttr,
TaskCb,
},
utils::{AlignedStorage, FixedPrioBitmap, Init, RawCell, UIntegerWithBound},
utils::{
intrusive_list::StaticListHead, AlignedStorage, FixedPrioBitmap, Init, RawCell,
UIntegerWithBound,
},
};

// `$configure` produces two values: a `CfgBuilder` and an ID map
Expand Down Expand Up @@ -205,6 +208,7 @@ macro_rules! build {
// Safety: We are `build!`, so it's okay to `impl` this
unsafe impl KernelCfg2 for $sys {
type TaskReadyBitmap = TaskReadyBitmap;
type TaskReadyQueue = [StaticListHead<TaskCb<Self>>; CFG.num_task_priority_levels];

fn state() -> &'static KernelState {
&KERNEL_STATE
Expand Down
2 changes: 1 addition & 1 deletion src/constance/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ macro_rules! If {
mod aligned_storage;
mod init;
mod int;
pub(crate) mod intrusive_list;
pub mod intrusive_list;
mod prio_bitmap;
mod rawcell;
mod zeroinit;
Expand Down
8 changes: 7 additions & 1 deletion src/constance_port_std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(unsafe_block_in_unsafe_fn)] // `unsafe fn` doesn't imply `unsafe {}`
#![deny(unsafe_op_in_unsafe_fn)]
use atomic_ref::AtomicRef;
use constance::prelude::*;
use constance::{prelude::*, utils::intrusive_list::StaticListHead};
use parking_lot::{lock_api::RawMutex, Mutex};
use std::{
mem::ManuallyDrop,
Expand Down Expand Up @@ -121,6 +121,8 @@ impl State {
pub unsafe fn dispatch_first_task<System: Kernel>(&'static self) -> !
where
System: Port<PortTaskState = TaskState>,
// FIXME: Work-around for <https://github.com/rust-lang/rust/issues/43475>
System::TaskReadyQueue: std::borrow::BorrowMut<[StaticListHead<TaskCb<System>>]>,
{
log::trace!("dispatch_first_task");
assert!(self.is_cpu_lock_active());
Expand Down Expand Up @@ -197,6 +199,8 @@ impl State {
pub unsafe fn yield_cpu<System: Kernel>(&self)
where
System: Port<PortTaskState = TaskState>,
// FIXME: Work-around for <https://github.com/rust-lang/rust/issues/43475>
System::TaskReadyQueue: std::borrow::BorrowMut<[StaticListHead<TaskCb<System>>]>,
{
log::trace!("yield_cpu");
assert!(!self.is_cpu_lock_active());
Expand All @@ -208,6 +212,8 @@ impl State {
pub unsafe fn exit_and_dispatch<System: Kernel>(&self) -> !
where
System: Port<PortTaskState = TaskState>,
// Work-around <https://github.com/rust-lang/rust/issues/43475>
System::TaskReadyQueue: std::borrow::BorrowMut<[StaticListHead<TaskCb<System>>]>,
{
log::trace!("exit_and_dispatch");
assert!(self.is_cpu_lock_active());
Expand Down

0 comments on commit 8f7b057

Please sign in to comment.