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

@ -286,14 +286,15 @@ fn sc_join(machine: &mut Machine, system: &mut System) -> Result<MachineOk, Mach
let tid = machine.read_int_register(10); let tid = machine.read_int_register(10);
let p_thread = system.get_thread_manager().get_obj_addrs().search_thread(tid as i32); let p_thread = system.get_thread_manager().get_obj_addrs().search_thread(tid as i32);
match p_thread { match p_thread {
Some(_) => { Some(waiting_for) => {
let rc_waiting_for = Rc::clone(waiting_for);
if let Some(current_thread) = system.get_thread_manager().get_g_current_thread() { if let Some(current_thread) = system.get_thread_manager().get_g_current_thread() {
let rc = Rc::clone(current_thread); let rc_curr = Rc::clone(current_thread);
system.get_thread_manager().thread_join(machine, rc); system.get_thread_manager().thread_join(machine, rc_curr, rc_waiting_for);
Ok(MachineOk::Ok) Ok(MachineOk::Ok)
} else { } else {
Ok(MachineOk::Ok) Err("Current should not be None")?
} }
}, },
None => { None => {
@ -347,7 +348,7 @@ mod test {
machine.write_memory(4, 0, 0b000000000000_00000_000_00000_1110011); // ecall machine.write_memory(4, 0, 0b000000000000_00000_000_00000_1110011); // ecall
machine.write_memory(4, 4, 0b000000001010_00000_000_00001_0010011); // r1 <- 10 machine.write_memory(4, 4, 0b000000001010_00000_000_00001_0010011); // r1 <- 10
let mut system = System::default(); let mut system = System::new(true);
machine.run(&mut system); machine.run(&mut system);
// If the machine was stopped with no error, the shutdown worked // If the machine was stopped with no error, the shutdown worked
assert_ne!(machine.read_int_register(1), 10); // Check if the next instruction was executed assert_ne!(machine.read_int_register(1), 10); // Check if the next instruction was executed
@ -378,7 +379,7 @@ mod test {
machine.write_memory(4, 4, 0b000000000000_00000_000_10001_0010011); // r17 <- SC_SHUTDOWN machine.write_memory(4, 4, 0b000000000000_00000_000_10001_0010011); // r17 <- SC_SHUTDOWN
machine.write_memory(4, 8, 0b000000000000_00000_000_00000_1110011); // ecall machine.write_memory(4, 8, 0b000000000000_00000_000_00000_1110011); // ecall
let mut system = System::default(); let mut system = System::new(true);
machine.run(&mut system); machine.run(&mut system);
} }

View File

@ -233,7 +233,7 @@ mod test {
#[test] #[test]
fn test_lock_simple() { fn test_lock_simple() {
let mut machine = Machine::new(true); let mut machine = Machine::new(true);
let mut tm = ThreadManager::new(); let mut tm = ThreadManager::new(true);
let thread = Rc::new(RefCell::new(Thread::new("test_lock"))); let thread = Rc::new(RefCell::new(Thread::new("test_lock")));
tm.ready_to_run(Rc::clone(&thread)); tm.ready_to_run(Rc::clone(&thread));
tm.set_g_current_thread(Some(Rc::clone(&thread))); tm.set_g_current_thread(Some(Rc::clone(&thread)));
@ -255,7 +255,7 @@ mod test {
let thread2 = Rc::new(RefCell::new(Thread::new("test_lock2"))); let thread2 = Rc::new(RefCell::new(Thread::new("test_lock2")));
let mut machine = Machine::new(true); let mut machine = Machine::new(true);
let mut tm = ThreadManager::new(); let mut tm = ThreadManager::new(true);
tm.ready_to_run(Rc::clone(&thread1)); tm.ready_to_run(Rc::clone(&thread1));
tm.ready_to_run(Rc::clone(&thread2)); tm.ready_to_run(Rc::clone(&thread2));

View File

@ -20,6 +20,10 @@ pub struct System {
impl System { impl System {
pub fn new(debug: bool) -> Self {
Self { thread_manager: ThreadManager::new(debug) }
}
// GETTERS // GETTERS
pub fn get_thread_manager(&mut self) -> &mut ThreadManager { pub fn get_thread_manager(&mut self) -> &mut ThreadManager {
@ -27,11 +31,3 @@ impl System {
} }
} }
impl Default for System {
/// System constructor
fn default() -> Self {
Self { thread_manager: ThreadManager::new() }
}
}

View File

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

View File

@ -42,7 +42,7 @@ fn main() {
let mut machine = Machine::new(args.debug); let mut machine = Machine::new(args.debug);
let (loader, ptr) = loader::Loader::new(args.executable.as_str(), &mut machine, 0).expect("An error occured while parsing the program"); let (loader, ptr) = loader::Loader::new(args.executable.as_str(), &mut machine, 0).expect("An error occured while parsing the program");
let mut system = System::default(); let mut system = System::new(args.debug);
let thread_exec = Thread::new(args.executable.as_str()); let thread_exec = Thread::new(args.executable.as_str());
let thread_exec = Rc::new(RefCell::new(thread_exec)); let thread_exec = Rc::new(RefCell::new(thread_exec));

View File

@ -725,7 +725,7 @@ mod test {
let memory_before = mem_cmp::MemChecker::from(get_full_path!("memory", $a)).unwrap(); let memory_before = mem_cmp::MemChecker::from(get_full_path!("memory", $a)).unwrap();
let memory_after = mem_cmp::MemChecker::from(get_full_path!("memory", &end_file_name)).unwrap(); let memory_after = mem_cmp::MemChecker::from(get_full_path!("memory", &end_file_name)).unwrap();
mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m); mem_cmp::MemChecker::fill_memory_from_mem_checker(&memory_before, &mut m);
let mut system = crate::kernel::system::System::default(); let mut system = crate::kernel::system::System::new(true);
m._run_debug(&mut system); m._run_debug(&mut system);
let expected_trace = fs::read_to_string(get_full_path!("reg_trace", $a)).unwrap(); let expected_trace = fs::read_to_string(get_full_path!("reg_trace", $a)).unwrap();
assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m)); assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m));