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