Add debug field to thread_manager and tried to fix sc_join (not worked :-( )
This commit is contained in:
parent
f144438490
commit
232617c32e
@ -286,14 +286,15 @@ fn sc_join(machine: &mut Machine, system: &mut System) -> Result<MachineOk, Mach
|
||||
let tid = machine.read_int_register(10);
|
||||
let p_thread = system.get_thread_manager().get_obj_addrs().search_thread(tid as i32);
|
||||
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() {
|
||||
let rc = Rc::clone(current_thread);
|
||||
system.get_thread_manager().thread_join(machine, rc);
|
||||
let rc_curr = Rc::clone(current_thread);
|
||||
system.get_thread_manager().thread_join(machine, rc_curr, rc_waiting_for);
|
||||
|
||||
Ok(MachineOk::Ok)
|
||||
} else {
|
||||
Ok(MachineOk::Ok)
|
||||
Err("Current should not be None")?
|
||||
}
|
||||
},
|
||||
None => {
|
||||
@ -347,7 +348,7 @@ mod test {
|
||||
|
||||
machine.write_memory(4, 0, 0b000000000000_00000_000_00000_1110011); // ecall
|
||||
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);
|
||||
// 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
|
||||
@ -378,7 +379,7 @@ mod test {
|
||||
machine.write_memory(4, 4, 0b000000000000_00000_000_10001_0010011); // r17 <- SC_SHUTDOWN
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_lock_simple() {
|
||||
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")));
|
||||
tm.ready_to_run(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 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(&thread2));
|
||||
|
@ -20,6 +20,10 @@ pub struct System {
|
||||
|
||||
impl System {
|
||||
|
||||
pub fn new(debug: bool) -> Self {
|
||||
Self { thread_manager: ThreadManager::new(debug) }
|
||||
}
|
||||
|
||||
// GETTERS
|
||||
|
||||
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() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -42,7 +42,7 @@ fn main() {
|
||||
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 mut system = System::default();
|
||||
let mut system = System::new(args.debug);
|
||||
|
||||
let thread_exec = Thread::new(args.executable.as_str());
|
||||
let thread_exec = Rc::new(RefCell::new(thread_exec));
|
||||
|
@ -725,7 +725,7 @@ mod test {
|
||||
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();
|
||||
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);
|
||||
let expected_trace = fs::read_to_string(get_full_path!("reg_trace", $a)).unwrap();
|
||||
assert!(mem_cmp::MemChecker::compare_machine_memory(&memory_after, &m));
|
||||
|
Loading…
Reference in New Issue
Block a user