add statefull scheduler and syscall routine
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Signed-off-by: Julien CLEMENT <julien.clement@epita.fr>
This commit is contained in:
parent
689f7c8810
commit
1bb4074e2f
@ -1,3 +1,4 @@
|
|||||||
|
use crate::println;
|
||||||
use crate::utils::mutex::AsyncMutex;
|
use crate::utils::mutex::AsyncMutex;
|
||||||
|
|
||||||
use super::thread::{Thread, ThreadId};
|
use super::thread::{Thread, ThreadId};
|
||||||
@ -77,6 +78,7 @@ impl Scheduler {
|
|||||||
started: true,
|
started: true,
|
||||||
rsp: 0,
|
rsp: 0,
|
||||||
base_stack: 0,
|
base_stack: 0,
|
||||||
|
is_blocked: false,
|
||||||
};
|
};
|
||||||
res.register(Arc::new(RefCell::new(k_thread)));
|
res.register(Arc::new(RefCell::new(k_thread)));
|
||||||
res
|
res
|
||||||
@ -86,10 +88,19 @@ impl Scheduler {
|
|||||||
while let Some(id) = self.thread_queue.next().await {
|
while let Some(id) = self.thread_queue.next().await {
|
||||||
if let Some(thread) = self.get_thread(id) {
|
if let Some(thread) = self.get_thread(id) {
|
||||||
// Thread still exists
|
// Thread still exists
|
||||||
unsafe {
|
let blocked: bool;
|
||||||
(&mut *thread.as_ptr()).run();
|
{
|
||||||
|
blocked = thread.borrow().is_blocked;
|
||||||
|
} // Drop thread borrow
|
||||||
|
if !blocked {
|
||||||
|
unsafe {
|
||||||
|
(&mut *thread.as_ptr()).run();
|
||||||
|
}
|
||||||
|
|
||||||
|
if !thread.borrow().is_blocked {
|
||||||
|
self.thread_queue.register(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.thread_queue.register(id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,6 +115,21 @@ impl Scheduler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn block(&mut self, id: ThreadId) {
|
||||||
|
if let Some(thread) = self.get_thread(id) {
|
||||||
|
thread.borrow_mut().is_blocked = true;
|
||||||
|
println!("Blocked thread {:?}", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unblock(&mut self, id: ThreadId) {
|
||||||
|
if let Some(thread) = self.get_thread(id) {
|
||||||
|
thread.borrow_mut().is_blocked = false;
|
||||||
|
self.thread_queue.register(id);
|
||||||
|
println!("Unblocked thread {:?}", id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn exit(&mut self, id: ThreadId) {
|
pub fn exit(&mut self, id: ThreadId) {
|
||||||
self.threads.remove(&id).unwrap().borrow().exit();
|
self.threads.remove(&id).unwrap().borrow().exit();
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,10 @@ impl ThreadId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn resume_k_thread() {
|
pub fn resume_k_thread() {
|
||||||
let k_thread: *mut Thread;
|
let k_thread: *mut Thread;
|
||||||
{
|
{
|
||||||
let mut scheduler = SCHEDULER.lock().await;
|
let mut scheduler = SCHEDULER.try_lock().unwrap();
|
||||||
k_thread = scheduler.get_thread(K_THREAD_ID).unwrap().as_ptr();
|
k_thread = scheduler.get_thread(K_THREAD_ID).unwrap().as_ptr();
|
||||||
} // Drop scheduler mutex guard
|
} // Drop scheduler mutex guard
|
||||||
|
|
||||||
@ -40,6 +40,7 @@ pub async fn resume_k_thread() {
|
|||||||
pub fn routine() {
|
pub fn routine() {
|
||||||
println!("Routine executed");
|
println!("Routine executed");
|
||||||
crate::syscalls::syscall_routine(crate::syscalls::EXIT_ID); // Call exit
|
crate::syscalls::syscall_routine(crate::syscalls::EXIT_ID); // Call exit
|
||||||
|
println!("SHOULD NEVER BE DISPLAYED");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Thread {
|
pub struct Thread {
|
||||||
@ -48,6 +49,7 @@ pub struct Thread {
|
|||||||
pub started: bool,
|
pub started: bool,
|
||||||
pub rsp: u64,
|
pub rsp: u64,
|
||||||
pub base_stack: u64,
|
pub base_stack: u64,
|
||||||
|
pub is_blocked: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Thread {
|
impl Thread {
|
||||||
@ -60,6 +62,7 @@ impl Thread {
|
|||||||
started: false,
|
started: false,
|
||||||
rsp: stack_bottom + STACK_SIZE as u64,
|
rsp: stack_bottom + STACK_SIZE as u64,
|
||||||
base_stack: stack_bottom,
|
base_stack: stack_bottom,
|
||||||
|
is_blocked: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
use crate::println;
|
||||||
use crate::proc::thread::{resume_k_thread, RUNNING_THREAD};
|
use crate::proc::thread::{resume_k_thread, RUNNING_THREAD};
|
||||||
|
use crate::proc::scheduler::SCHEDULER;
|
||||||
use crate::task::executor::EXECUTOR;
|
use crate::task::executor::EXECUTOR;
|
||||||
use crate::task::Task;
|
use crate::task::Task;
|
||||||
|
|
||||||
@ -19,25 +21,47 @@ pub struct SyscallContext {
|
|||||||
thread_id: crate::proc::thread::ThreadId,
|
thread_id: crate::proc::thread::ThreadId,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn syscall_dispatcher(context: SyscallContextT) -> Task {
|
impl SyscallContext {
|
||||||
match context.borrow().id {
|
pub async fn run(&mut self) {
|
||||||
EXIT_ID => Task::new(proc::exit(context.clone())),
|
println!("Running async syscall runner");
|
||||||
_ => Task::new(bad_syscall()),
|
self.dispatch().await;
|
||||||
|
println!("Syscall end, unblocking thread");
|
||||||
|
SCHEDULER.lock().await.unblock(self.thread_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn dispatch(&mut self) {
|
||||||
|
match self.id {
|
||||||
|
EXIT_ID => proc::exit(self).await,
|
||||||
|
_ => bad_syscall().await,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async fn syscall_runner(context: SyscallContextT) {
|
||||||
|
context.borrow_mut().run().await;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn syscall_routine(syscall_id: SyscallId) -> u64 {
|
pub fn syscall_routine(syscall_id: SyscallId) -> u64 {
|
||||||
|
println!("Running syscall");
|
||||||
let context: SyscallContextT = Arc::new(RefCell::new(SyscallContext {
|
let context: SyscallContextT = Arc::new(RefCell::new(SyscallContext {
|
||||||
id: syscall_id,
|
id: syscall_id,
|
||||||
res: 0,
|
res: 0,
|
||||||
thread_id: *RUNNING_THREAD.try_lock().unwrap(),
|
thread_id: *RUNNING_THREAD.try_lock().unwrap(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
println!("Spawning async syscall runner");
|
||||||
EXECUTOR
|
EXECUTOR
|
||||||
.try_lock()
|
.try_lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.spawn(syscall_dispatcher(context.clone()));
|
.spawn(Task::new(syscall_runner(context.clone())));
|
||||||
|
|
||||||
|
println!("Blocking thread");
|
||||||
|
SCHEDULER
|
||||||
|
.try_lock()
|
||||||
|
.unwrap()
|
||||||
|
.block(context.borrow().thread_id);
|
||||||
|
println!("Returning to scheduler");
|
||||||
resume_k_thread();
|
resume_k_thread();
|
||||||
|
|
||||||
let res = context.borrow().res;
|
let res = context.borrow().res;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::println;
|
use crate::println;
|
||||||
use crate::proc::scheduler::SCHEDULER;
|
use crate::proc::scheduler::SCHEDULER;
|
||||||
|
|
||||||
use super::SyscallContextT;
|
use super::SyscallContext;
|
||||||
|
|
||||||
pub async fn exit(context: SyscallContextT) {
|
pub async fn exit(context: &SyscallContext) {
|
||||||
println!("Exiting thread");
|
println!("Running exit(2)");
|
||||||
let mut scheduler = SCHEDULER.lock().await;
|
let mut scheduler = SCHEDULER.lock().await;
|
||||||
scheduler.exit(context.borrow().thread_id);
|
scheduler.exit(context.thread_id);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user