Simplified Rc<RefCell<Thread>>

This commit is contained in:
François Autin 2023-04-20 11:31:25 +02:00
parent 780ed4b461
commit bb1d2383bb

View File

@ -90,21 +90,27 @@ use crate::{
MachineOk,
MachineError
}
},
kernel::{
thread::Thread,
process::Process
}
};
use super::{thread::Thread, process::Process};
/// Using this type alias to simplify struct and method definitions
type ThreadRef = Rc<RefCell<Thread>>;
/// # Thread manager
///
/// An instance of this struct is responsible for managing threads on behalf of the system
#[derive(PartialEq)]
pub struct ThreadManager {
/// Current running thread
pub g_current_thread: Option<Rc<RefCell<Thread>>>,
pub g_current_thread: Option<ThreadRef>,
/// The list of alive threads
pub g_alive: List<Rc<RefCell<Thread>>>,
pub g_alive: List<ThreadRef>,
/// Thread in ready state waiting to become active
ready_list: List<Rc<RefCell<Thread>>>,
ready_list: List<ThreadRef>,
/// List of objects created by the thread manager (such as Locks and Semaphores)
obj_addrs: ObjAddr,
/// If true, enables debug mode
@ -131,7 +137,7 @@ impl ThreadManager {
/// ## Pamameter
///
/// **thread** is the thread to be put on the read list
pub fn ready_to_run(&mut self, thread: Rc<RefCell<Thread>>) {
pub fn ready_to_run(&mut self, thread: ThreadRef) {
self.ready_list.push(thread);
}
@ -141,7 +147,7 @@ impl ThreadManager {
/// Thread is removed from the ready list.
///
/// **return** Thread thread to be scheduled
pub fn find_next_to_run(&mut self) -> Option<Rc<RefCell<Thread>>> {
pub fn find_next_to_run(&mut self) -> Option<ThreadRef> {
self.ready_list.pop()
}
@ -155,7 +161,7 @@ impl ThreadManager {
/// ## Parameter
///
/// **next_thread** thread to dispatch to the CPU
pub fn switch_to(&mut self, machine: &mut Machine, next_thread: Rc<RefCell<Thread>>) {
pub fn switch_to(&mut self, machine: &mut Machine, next_thread: ThreadRef) {
if let Some(old_thread) = self.get_g_current_thread() {
let old_thread = old_thread.clone();
self.thread_save_processor_state(machine, old_thread.clone());
@ -175,7 +181,7 @@ impl ThreadManager {
}
/// Start a thread, attaching it to a process
pub fn start_thread(&mut self, thread: Rc<RefCell<Thread>>, owner: Rc<RefCell<Process>>, func_pc: u64, sp_loc: u64, argument: i64) {
pub fn start_thread(&mut self, thread: ThreadRef, owner: Rc<RefCell<Process>>, func_pc: u64, sp_loc: u64, argument: i64) {
let mut thread_m = thread.borrow_mut();
assert_eq!(thread_m.process, Option::None);
thread_m.process = Option::Some(Rc::clone(&owner));
@ -187,7 +193,7 @@ impl ThreadManager {
}
/// Wait for another thread to finish its execution
pub fn thread_join(&mut self, machine: &mut Machine, waiter: Rc<RefCell<Thread>>, waiting_for: Rc<RefCell<Thread>>) {
pub fn thread_join(&mut self, machine: &mut Machine, waiter: ThreadRef, waiting_for: ThreadRef) {
let waiting_for = Rc::clone(&waiting_for);
while self.get_g_alive().contains(&waiting_for) {
self.debug(format!("Joining \"{}\" to \"{}\"", waiter.borrow().get_name(), waiting_for.borrow().get_name()));
@ -198,7 +204,7 @@ impl ThreadManager {
/// Relinquish the CPU if any other thread is runnable.
///
/// Cannot use yield as a function name -> reserved name in rust
pub fn thread_yield(&mut self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) {
pub fn thread_yield(&mut self, machine: &mut Machine, thread: ThreadRef) {
let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff);
self.debug(format!("Yeilding thread: {}", thread.borrow().get_name()));
@ -212,7 +218,7 @@ impl ThreadManager {
}
/// Put the thread to sleep and relinquish the processor
pub fn thread_sleep(&mut self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) {
pub fn thread_sleep(&mut self, machine: &mut Machine, thread: ThreadRef) {
debug_assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread);
debug_assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff);
@ -227,7 +233,7 @@ impl ThreadManager {
}
/// Finish the execution of the thread and prepare its deallocation
pub fn thread_finish(&mut self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) {
pub fn thread_finish(&mut self, machine: &mut Machine, thread: ThreadRef) {
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
assert!(self.g_alive.remove(Rc::clone(&thread)));
self.debug(format!("Sleeping thread {}", thread.borrow().get_name()));
@ -237,7 +243,7 @@ impl ThreadManager {
}
/// Save the CPU state of a user program on a context switch.
pub fn thread_save_processor_state(&mut self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) {
pub fn thread_save_processor_state(&mut self, machine: &mut Machine, thread: ThreadRef) {
let mut t = thread.borrow_mut();
for i in 0..NUM_INT_REGS {
t.thread_context.int_registers[i] = machine.read_int_register(i);
@ -249,7 +255,7 @@ impl ThreadManager {
}
/// Restore the CPU state of a user program on a context switch.
pub fn thread_restore_processor_state(&self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) {
pub fn thread_restore_processor_state(&self, machine: &mut Machine, thread: ThreadRef) {
let t: Ref<_> = thread.borrow();
for i in 0..NUM_INT_REGS {
machine.write_int_register(i, t.thread_context.int_registers[i]);
@ -372,17 +378,17 @@ impl ThreadManager {
}
/// Currently running thread
pub fn get_g_current_thread(&mut self) -> &Option<Rc<RefCell<Thread>>> {
pub fn get_g_current_thread(&mut self) -> &Option<ThreadRef> {
&self.g_current_thread
}
/// List of alive threads
pub fn get_g_alive(&mut self) -> &mut List<Rc<RefCell<Thread>>> {
pub fn get_g_alive(&mut self) -> &mut List<ThreadRef> {
&mut self.g_alive
}
/// Set currently running thread
pub fn set_g_current_thread(&mut self, thread: Option<Rc<RefCell<Thread>>>) {
pub fn set_g_current_thread(&mut self, thread: Option<ThreadRef>) {
self.g_current_thread = thread
}