Add debug field to thread_manager and tried to fix sc_join (not worked :-( )

This commit is contained in:
Quentin Legot
2023-04-13 02:05:21 +02:00
parent f144438490
commit 232617c32e
6 changed files with 44 additions and 35 deletions

View File

@ -19,19 +19,21 @@ pub struct ThreadManager {
pub g_alive: List<Rc<RefCell<Thread>>>,
/// Thread in ready state waiting to become active
ready_list: List<Rc<RefCell<Thread>>>,
obj_addrs: ObjAddr
obj_addrs: ObjAddr,
debug: bool
}
impl ThreadManager {
/// Thread manager constructor
pub fn new() -> Self {
pub fn new(debug: bool) -> Self {
Self {
g_current_thread: Option::None,
g_thread_to_be_destroyed: Option::None,
g_alive: List::default(),
ready_list: List::default(),
obj_addrs: ObjAddr::init(),
debug
}
}
@ -74,6 +76,7 @@ impl ThreadManager {
self.thread_save_processor_state(machine, old1);
// old_thread.save_simulator_state();
if old2 != next_thread {
self.debug(format!("switching from \"{}\" to \"{}\"", old2.borrow().get_name(), next_thread.borrow().get_name()));
self.thread_restore_processor_state(machine, Rc::clone(&next_thread));
// next_thread.restore_simulator_state();
self.set_g_current_thread(Some(next_thread));
@ -85,28 +88,30 @@ impl ThreadManager {
self.set_g_current_thread(Some(next_thread));
}
}
if let Some(th) = self.get_g_thread_to_be_destroyed() {
drop(th);
self.g_thread_to_be_destroyed = None
}
}
/// 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) {
let mut thread_m = thread.borrow_mut();
assert_eq!(thread_m.process, Option::None);
thread_m.process = Option::Some(owner);
thread_m.process = Option::Some(Rc::clone(&owner));
let ptr = sp_loc; // todo addrspace
thread_m.init_thread_context(func_pc, ptr, argument);
if let Some(process) = &thread_m.process {
process.borrow_mut().num_thread += 1;
} else {
}
owner.borrow_mut().num_thread += 1;
self.get_g_alive().push(Rc::clone(&thread));
self.ready_to_run(Rc::clone(&thread));
}
/// Wait for another thread to finish its execution
pub fn thread_join(&mut self, machine: &mut Machine, id_thread: Rc<RefCell<Thread>>) {
while self.get_g_alive().contains(&Rc::clone(&id_thread)) {
self.thread_yield(machine, Rc::clone(&id_thread));
pub fn thread_join(&mut self, machine: &mut Machine, waiter: Rc<RefCell<Thread>>, waiting_for: Rc<RefCell<Thread>>) {
let waiting_for = Rc::clone(&waiting_for);
while self.get_g_alive().contains(&waiting_for) {
self.thread_yield(machine, Rc::clone(&waiter));
}
}
@ -116,7 +121,9 @@ impl ThreadManager {
pub fn thread_yield(&mut self, machine: &mut Machine, thread: Rc<RefCell<Thread>>) {
let old_status = machine.interrupt.set_status(crate::simulator::interrupt::InterruptStatus::InterruptOff);
assert_eq!(Option::Some(Rc::clone(&thread)), self.g_current_thread);
self.debug(format!("Yeilding thread: {}", thread.borrow().get_name()));
debug_assert_eq!(&Option::Some(Rc::clone(&thread)), self.get_g_current_thread());
let next_thread = self.find_next_to_run();
if let Some(next_thread) = next_thread {
self.ready_to_run(thread);
@ -145,8 +152,7 @@ impl ThreadManager {
let old_status = machine.interrupt.set_status(InterruptStatus::InterruptOff);
self.set_g_thread_to_be_destroyed(Option::Some(Rc::clone(&thread)));
self.g_alive.remove(Rc::clone(&thread));
#[cfg(debug_assertions)]
println!("Sleeping thread {}", thread.borrow().get_name());
self.debug(format!("Sleeping thread {}", thread.borrow().get_name()));
// g_objets_addrs->removeObject(self.thread) // a ajouté plus tard
self.thread_sleep(machine, Rc::clone(&thread));
machine.interrupt.set_status(old_status);
@ -305,6 +311,12 @@ impl ThreadManager {
&mut self.obj_addrs
}
fn debug(&self, message: String) {
if self.debug {
println!("{}", message);
}
}
}
#[cfg(test)]
@ -319,7 +331,7 @@ mod test {
let (loader, ptr) = loader::Loader::new("./target/guac/halt.guac", &mut machine, 0).expect("IO Error");
let start_pc = loader.elf_header.entrypoint;
let system = &mut System::default();
let system = &mut System::new(true);
let thread1 = Thread::new("th1");
let thread1 = Rc::new(RefCell::new(thread1));
@ -345,7 +357,7 @@ mod test {
fn test_semaphore_single() {
// Init
let mut machine = Machine::new(true);
let mut thread_manager = ThreadManager::new();
let mut thread_manager = ThreadManager::new(true);
let semaphore = Semaphore::new(1);
let sema_id = thread_manager.get_obj_addrs().add_semaphore(semaphore);
let thread = Rc::new(RefCell::new(Thread::new("test_semaphore")));
@ -370,7 +382,7 @@ mod test {
#[test]
fn test_semaphore_multiple() {
// Init
let mut tm = ThreadManager::new();
let mut tm = ThreadManager::new(true);
let mut machine = Machine::new(true);
let semaphore = Semaphore::new(2);
let sema_id = tm.get_obj_addrs().add_semaphore(semaphore);