Simplified Rc<RefCell<Thread>>
This commit is contained in:
parent
780ed4b461
commit
bb1d2383bb
@ -90,21 +90,27 @@ use crate::{
|
|||||||
MachineOk,
|
MachineOk,
|
||||||
MachineError
|
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
|
/// # Thread manager
|
||||||
///
|
///
|
||||||
/// An instance of this struct is responsible for managing threads on behalf of the system
|
/// An instance of this struct is responsible for managing threads on behalf of the system
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct ThreadManager {
|
pub struct ThreadManager {
|
||||||
/// Current running thread
|
/// Current running thread
|
||||||
pub g_current_thread: Option<Rc<RefCell<Thread>>>,
|
pub g_current_thread: Option<ThreadRef>,
|
||||||
/// The list of alive threads
|
/// 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
|
/// 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)
|
/// List of objects created by the thread manager (such as Locks and Semaphores)
|
||||||
obj_addrs: ObjAddr,
|
obj_addrs: ObjAddr,
|
||||||
/// If true, enables debug mode
|
/// If true, enables debug mode
|
||||||
@ -131,7 +137,7 @@ impl ThreadManager {
|
|||||||
/// ## Pamameter
|
/// ## Pamameter
|
||||||
///
|
///
|
||||||
/// **thread** is the thread to be put on the read list
|
/// **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);
|
self.ready_list.push(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +147,7 @@ impl ThreadManager {
|
|||||||
/// Thread is removed from the ready list.
|
/// Thread is removed from the ready list.
|
||||||
///
|
///
|
||||||
/// **return** Thread thread to be scheduled
|
/// **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()
|
self.ready_list.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +161,7 @@ impl ThreadManager {
|
|||||||
/// ## Parameter
|
/// ## Parameter
|
||||||
///
|
///
|
||||||
/// **next_thread** thread to dispatch to the CPU
|
/// **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() {
|
if let Some(old_thread) = self.get_g_current_thread() {
|
||||||
let old_thread = old_thread.clone();
|
let old_thread = old_thread.clone();
|
||||||
self.thread_save_processor_state(machine, 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
|
/// 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();
|
let mut thread_m = thread.borrow_mut();
|
||||||
assert_eq!(thread_m.process, Option::None);
|
assert_eq!(thread_m.process, Option::None);
|
||||||
thread_m.process = Option::Some(Rc::clone(&owner));
|
thread_m.process = Option::Some(Rc::clone(&owner));
|
||||||
@ -187,7 +193,7 @@ impl ThreadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for another thread to finish its execution
|
/// 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);
|
let waiting_for = Rc::clone(&waiting_for);
|
||||||
while self.get_g_alive().contains(&waiting_for) {
|
while self.get_g_alive().contains(&waiting_for) {
|
||||||
self.debug(format!("Joining \"{}\" to \"{}\"", waiter.borrow().get_name(), waiting_for.borrow().get_name()));
|
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.
|
/// Relinquish the CPU if any other thread is runnable.
|
||||||
///
|
///
|
||||||
/// Cannot use yield as a function name -> reserved name in rust
|
/// 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);
|
let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff);
|
||||||
|
|
||||||
self.debug(format!("Yeilding thread: {}", thread.borrow().get_name()));
|
self.debug(format!("Yeilding thread: {}", thread.borrow().get_name()));
|
||||||
@ -212,7 +218,7 @@ impl ThreadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Put the thread to sleep and relinquish the processor
|
/// 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!(Option::Some(Rc::clone(&thread)), self.g_current_thread);
|
||||||
debug_assert_eq!(machine.interrupt.get_status(), InterruptStatus::InterruptOff);
|
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
|
/// 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);
|
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
|
||||||
assert!(self.g_alive.remove(Rc::clone(&thread)));
|
assert!(self.g_alive.remove(Rc::clone(&thread)));
|
||||||
self.debug(format!("Sleeping thread {}", thread.borrow().get_name()));
|
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.
|
/// 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();
|
let mut t = thread.borrow_mut();
|
||||||
for i in 0..NUM_INT_REGS {
|
for i in 0..NUM_INT_REGS {
|
||||||
t.thread_context.int_registers[i] = machine.read_int_register(i);
|
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.
|
/// 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();
|
let t: Ref<_> = thread.borrow();
|
||||||
for i in 0..NUM_INT_REGS {
|
for i in 0..NUM_INT_REGS {
|
||||||
machine.write_int_register(i, t.thread_context.int_registers[i]);
|
machine.write_int_register(i, t.thread_context.int_registers[i]);
|
||||||
@ -372,17 +378,17 @@ impl ThreadManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Currently running thread
|
/// 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
|
&self.g_current_thread
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of alive threads
|
/// 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
|
&mut self.g_alive
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set currently running thread
|
/// 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
|
self.g_current_thread = thread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user