Skip to content

Commit

Permalink
reduce gap to stage1
Browse files Browse the repository at this point in the history
  • Loading branch information
stlankes committed Nov 10, 2024
1 parent 71521e3 commit b4bf6d9
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/arch/x86/kernel/entry32.s
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

.code32

.set BOOT_STACK_SIZE, 4096
.set BOOT_STACK_SIZE, 0x3000

# We use a special name to map this section at the begin of our kernel
# => Multiboot expects its magic number at the beginning of the kernel.
Expand Down
10 changes: 4 additions & 6 deletions src/arch/x86/kernel/switch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::arch::asm;
use core::arch::naked_asm;

#[cfg(target_arch = "x86_64")]
macro_rules! save_context {
Expand Down Expand Up @@ -42,8 +42,8 @@ macro_rules! restore_context {
pop r8
pop rdi
pop rsi
add rsp, 8
pop rbp
add rsp, 8
pop rbx
pop rdx
pop rcx
Expand All @@ -67,14 +67,13 @@ pub(crate) unsafe extern "C" fn switch(_old_stack: *mut usize, _new_stack: usize
// rdi = old_stack => the address to store the old rsp
// rsi = new_stack => stack pointer of the new task

asm!(
naked_asm!(
save_context!(),
// Store the old `rsp` behind `old_stack`
"mov [rdi], rsp",
// Set `rsp` to `new_stack`
"mov rsp, rsi",
restore_context!(),
options(noreturn)
);
}

Expand All @@ -87,7 +86,7 @@ pub(crate) unsafe extern "C" fn switch(_old_stack: *mut usize, _new_stack: usize
/// stack is stored. `new_stack` provides the stack pointer of the
/// next task.
pub(crate) unsafe extern "C" fn switch(_old_stack: *mut usize, _new_stack: usize) {
asm!(
naked_asm!(
// store all registers
"pushfd",
"pushad",
Expand All @@ -99,6 +98,5 @@ pub(crate) unsafe extern "C" fn switch(_old_stack: *mut usize, _new_stack: usize
"popad",
"popfd",
"ret",
options(noreturn)
);
}
10 changes: 1 addition & 9 deletions src/arch/x86/kernel/task.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
//! Architecture dependent interface to initialize a task

use crate::arch::processor::halt;
use crate::consts::*;
use crate::logging::*;
use crate::scheduler::do_exit;
use crate::scheduler::task::*;
use crate::scheduler::{do_exit, get_current_taskid};
use core::mem::size_of;
use core::ptr::write_bytes;

Expand Down Expand Up @@ -75,13 +73,7 @@ struct State {
}

extern "C" fn leave_task() -> ! {
debug!("finish task {}", get_current_taskid());

do_exit();

loop {
halt();
}
}

impl TaskFrame for Task {
Expand Down
5 changes: 5 additions & 0 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
//! Configuration parameter of the kernel eduOS-rs

/// Define the size of the kernel stack
#[cfg(target_arch = "x86_64")]
pub(crate) const STACK_SIZE: usize = 0x3000;

/// Define the size of the kernel stack
#[cfg(target_arch = "x86")]
pub(crate) const STACK_SIZE: usize = 0x2000;

/// Size of a cache line
Expand Down
7 changes: 0 additions & 7 deletions src/errno.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
// Copyright (c) 2017-2018 Stefan Lankes, RWTH Aachen University
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

use core::{fmt, result};

pub type Result<T> = result::Result<T, Error>;
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub mod errno;
pub mod mm;
pub mod scheduler;

// Using the Simple Chunk Allocator for heap managment of the kernel
// Using the Simple Chunk Allocator for heap management of the kernel
// see
const CHUNK_SIZE: usize = 256;
const CHUNK_AMOUNT: usize = HEAP_SIZE / CHUNK_SIZE;
Expand Down
2 changes: 1 addition & 1 deletion src/scheduler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn reschedule() {
}

/// Terminate the current running task
pub fn do_exit() {
pub fn do_exit() -> ! {
unsafe {
SCHEDULER.as_mut().unwrap().exit();
}
Expand Down
29 changes: 14 additions & 15 deletions src/scheduler/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use alloc::rc::Rc;
use core::cell::RefCell;
use core::sync::atomic::{AtomicU32, Ordering};

static NO_TASKS: AtomicU32 = AtomicU32::new(0);
static TID_COUNTER: AtomicU32 = AtomicU32::new(0);

pub(crate) struct Scheduler {
Expand Down Expand Up @@ -64,30 +63,31 @@ impl Scheduler {

// Create the new task.
let tid = self.get_tid();
let task = Rc::new(RefCell::new(Task::new(tid, TaskStatus::TaskReady, prio)));
let task = Rc::new(RefCell::new(Task::new(tid, TaskStatus::Ready, prio)));

task.borrow_mut().create_stack_frame(func);

// Add it to the task lists.
self.ready_queues[prio_number].push(task.clone());
self.prio_bitmap |= 1 << prio_number;
self.tasks.insert(tid, task);
NO_TASKS.fetch_add(1, Ordering::SeqCst);

info!("Creating task {}", tid);

Ok(tid)
}

pub fn exit(&mut self) {
if self.current_task.borrow().status != TaskStatus::TaskIdle {
pub fn exit(&mut self) -> ! {
if self.current_task.borrow().status != TaskStatus::Idle {
info!("finish task with id {}", self.current_task.borrow().id);
self.current_task.borrow_mut().status = TaskStatus::TaskFinished;
self.current_task.borrow_mut().status = TaskStatus::Finished;
} else {
panic!("unable to terminate idle task");
}

self.reschedule();

panic!("Terminated task gets computation time");
}

pub fn get_current_taskid(&self) -> TaskId {
Expand All @@ -112,7 +112,6 @@ impl Scheduler {
}

pub fn schedule(&mut self) {
info!("Schedule");
// do we have finished tasks? => drop tasks => deallocate implicitly the stack
while let Some(id) = self.finished_tasks.pop_front() {
if self.tasks.remove(&id).is_none() {
Expand All @@ -135,15 +134,15 @@ impl Scheduler {

// do we have a task, which is ready?
let mut next_task;
if current_status == TaskStatus::TaskRunning {
if current_status == TaskStatus::Running {
next_task = self.get_next_task(current_prio);
} else {
next_task = self.get_next_task(LOW_PRIORITY);
}

if next_task.is_none()
&& current_status != TaskStatus::TaskRunning
&& current_status != TaskStatus::TaskIdle
&& current_status != TaskStatus::Running
&& current_status != TaskStatus::Idle
{
debug!("Switch to idle task");
// current task isn't able to run and no other task available
Expand All @@ -154,18 +153,18 @@ impl Scheduler {
if let Some(next_task) = next_task {
let (new_id, new_stack_pointer) = {
let mut borrowed = next_task.borrow_mut();
borrowed.status = TaskStatus::TaskRunning;
borrowed.status = TaskStatus::Running;
(borrowed.id, borrowed.last_stack_pointer)
};

if current_status == TaskStatus::TaskRunning {
if current_status == TaskStatus::Running {
debug!("Add task {} to ready queue", current_id);
self.current_task.borrow_mut().status = TaskStatus::TaskReady;
self.current_task.borrow_mut().status = TaskStatus::Ready;
self.ready_queues[current_prio.into() as usize].push(self.current_task.clone());
self.prio_bitmap |= 1 << current_prio.into() as usize;
} else if current_status == TaskStatus::TaskFinished {
} else if current_status == TaskStatus::Finished {
debug!("Task {} finished", current_id);
self.current_task.borrow_mut().status = TaskStatus::TaskInvalid;
self.current_task.borrow_mut().status = TaskStatus::Invalid;
// release the task later, because the stack is required
// to call the function "switch"
// => push id to a queue and release the task later
Expand Down
34 changes: 16 additions & 18 deletions src/scheduler/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ use core::fmt;

/// The status of the task - used for scheduling
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum TaskStatus {
TaskInvalid,
TaskReady,
TaskRunning,
TaskBlocked,
TaskFinished,
TaskIdle,
pub(crate) enum TaskStatus {
Invalid,
Ready,
Running,
Finished,
Idle,
}

/// Unique identifier for a task (i.e. `pid`).
Expand Down Expand Up @@ -68,15 +67,14 @@ pub(crate) trait Stack {
}

#[derive(Copy, Clone)]
#[repr(align(64))]
#[repr(C)]
#[repr(C, align(64))]
pub(crate) struct TaskStack {
buffer: [u8; STACK_SIZE],
}

impl TaskStack {
pub const fn new() -> TaskStack {
TaskStack {
pub const fn new() -> Self {
Self {
buffer: [0; STACK_SIZE],
}
}
Expand Down Expand Up @@ -131,23 +129,23 @@ pub(crate) struct Task {
pub status: TaskStatus,
/// Last stack pointer before a context switch to another task
pub last_stack_pointer: usize,
// Stack of the task
/// Stack of the task
pub stack: Box<dyn Stack>,
}

impl Task {
pub fn new_idle(id: TaskId) -> Task {
Task {
pub fn new_idle(id: TaskId) -> Self {
Self {
id,
prio: LOW_PRIORITY,
status: TaskStatus::TaskIdle,
status: TaskStatus::Idle,
last_stack_pointer: 0,
stack: Box::new(crate::arch::mm::get_boot_stack()),
}
}

pub fn new(id: TaskId, status: TaskStatus, prio: TaskPriority) -> Task {
Task {
pub fn new(id: TaskId, status: TaskStatus, prio: TaskPriority) -> Self {
Self {
id,
prio,
status,
Expand All @@ -157,7 +155,7 @@ impl Task {
}
}

pub trait TaskFrame {
pub(crate) trait TaskFrame {
/// Create the initial stack frame for a new task
fn create_stack_frame(&mut self, func: extern "C" fn());
}

0 comments on commit b4bf6d9

Please sign in to comment.