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 super::thread::{Thread, ThreadId};
 | 
			
		||||
@ -77,6 +78,7 @@ impl Scheduler {
 | 
			
		||||
            started: true,
 | 
			
		||||
            rsp: 0,
 | 
			
		||||
            base_stack: 0,
 | 
			
		||||
            is_blocked: false,
 | 
			
		||||
        };
 | 
			
		||||
        res.register(Arc::new(RefCell::new(k_thread)));
 | 
			
		||||
        res
 | 
			
		||||
@ -86,10 +88,19 @@ impl Scheduler {
 | 
			
		||||
        while let Some(id) = self.thread_queue.next().await {
 | 
			
		||||
            if let Some(thread) = self.get_thread(id) {
 | 
			
		||||
                // Thread still exists
 | 
			
		||||
                unsafe {
 | 
			
		||||
                    (&mut *thread.as_ptr()).run();
 | 
			
		||||
                let blocked: bool;
 | 
			
		||||
                {
 | 
			
		||||
                    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) {
 | 
			
		||||
        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 mut scheduler = SCHEDULER.lock().await;
 | 
			
		||||
        let mut scheduler = SCHEDULER.try_lock().unwrap();
 | 
			
		||||
        k_thread = scheduler.get_thread(K_THREAD_ID).unwrap().as_ptr();
 | 
			
		||||
    } // Drop scheduler mutex guard
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,7 @@ pub async fn resume_k_thread() {
 | 
			
		||||
pub fn routine() {
 | 
			
		||||
    println!("Routine executed");
 | 
			
		||||
    crate::syscalls::syscall_routine(crate::syscalls::EXIT_ID); // Call exit
 | 
			
		||||
    println!("SHOULD NEVER BE DISPLAYED");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Thread {
 | 
			
		||||
@ -48,6 +49,7 @@ pub struct Thread {
 | 
			
		||||
    pub started: bool,
 | 
			
		||||
    pub rsp: u64,
 | 
			
		||||
    pub base_stack: u64,
 | 
			
		||||
    pub is_blocked: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Thread {
 | 
			
		||||
@ -60,6 +62,7 @@ impl Thread {
 | 
			
		||||
                started: false,
 | 
			
		||||
                rsp: stack_bottom + STACK_SIZE as u64,
 | 
			
		||||
                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::scheduler::SCHEDULER;
 | 
			
		||||
use crate::task::executor::EXECUTOR;
 | 
			
		||||
use crate::task::Task;
 | 
			
		||||
 | 
			
		||||
@ -19,25 +21,47 @@ pub struct SyscallContext {
 | 
			
		||||
    thread_id: crate::proc::thread::ThreadId,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn syscall_dispatcher(context: SyscallContextT) -> Task {
 | 
			
		||||
    match context.borrow().id {
 | 
			
		||||
        EXIT_ID => Task::new(proc::exit(context.clone())),
 | 
			
		||||
        _ => Task::new(bad_syscall()),
 | 
			
		||||
impl SyscallContext {
 | 
			
		||||
    pub async fn run(&mut self) {
 | 
			
		||||
        println!("Running async syscall runner");
 | 
			
		||||
        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 {
 | 
			
		||||
    println!("Running syscall");
 | 
			
		||||
    let context: SyscallContextT = Arc::new(RefCell::new(SyscallContext {
 | 
			
		||||
        id: syscall_id,
 | 
			
		||||
        res: 0,
 | 
			
		||||
        thread_id: *RUNNING_THREAD.try_lock().unwrap(),
 | 
			
		||||
    }));
 | 
			
		||||
    
 | 
			
		||||
    println!("Spawning async syscall runner");
 | 
			
		||||
    EXECUTOR
 | 
			
		||||
        .try_lock()
 | 
			
		||||
        .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();
 | 
			
		||||
 | 
			
		||||
    let res = context.borrow().res;
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
use crate::println;
 | 
			
		||||
use crate::proc::scheduler::SCHEDULER;
 | 
			
		||||
 | 
			
		||||
use super::SyscallContextT;
 | 
			
		||||
use super::SyscallContext;
 | 
			
		||||
 | 
			
		||||
pub async fn exit(context: SyscallContextT) {
 | 
			
		||||
    println!("Exiting thread");
 | 
			
		||||
pub async fn exit(context: &SyscallContext) {
 | 
			
		||||
    println!("Running exit(2)");
 | 
			
		||||
    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