fix save_processor_state, move test to thread_manager
This commit is contained in:
parent
08ba0154f7
commit
2f986da7ae
@ -16,7 +16,7 @@ macro_rules! get_new_thread {
|
|||||||
pub struct ThreadContext {
|
pub struct ThreadContext {
|
||||||
pub int_registers: [i64; NUM_INT_REGS],
|
pub int_registers: [i64; NUM_INT_REGS],
|
||||||
pub float_registers: [f32; NUM_FP_REGS],
|
pub float_registers: [f32; NUM_FP_REGS],
|
||||||
pub pc: i64,
|
pub pc: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
@ -47,7 +47,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_thread_context(&mut self, initial_pc_reg: i64, initial_sp: i64, arg: i64) {
|
pub fn init_thread_context(&mut self, initial_pc_reg: u64, initial_sp: i64, arg: i64) {
|
||||||
self.thread_context.pc = initial_pc_reg;
|
self.thread_context.pc = initial_pc_reg;
|
||||||
self.thread_context.int_registers[10] = arg;
|
self.thread_context.int_registers[10] = arg;
|
||||||
self.thread_context.int_registers[STACK_REG] = initial_sp;
|
self.thread_context.int_registers[STACK_REG] = initial_sp;
|
||||||
|
@ -78,13 +78,15 @@ impl ThreadManager {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
self.thread_restore_processor_state(machine, Rc::clone(&next_thread));
|
||||||
|
// next_thread.restore_simulator_state();
|
||||||
|
self.set_g_current_thread(Some(next_thread));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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: Process, func_pc: i64, argument: i64) {
|
pub fn start_thread(&mut self, thread: Rc<RefCell<Thread>>, owner: Process, func_pc: 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(owner);
|
||||||
@ -153,6 +155,7 @@ impl ThreadManager {
|
|||||||
for i in 0..NUM_FP_REGS {
|
for i in 0..NUM_FP_REGS {
|
||||||
t.thread_context.float_registers[i] = machine.read_fp_register(i);
|
t.thread_context.float_registers[i] = machine.read_fp_register(i);
|
||||||
}
|
}
|
||||||
|
t.thread_context.pc = machine.pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restore the CPU state of a user program on a context switch.
|
/// Restore the CPU state of a user program on a context switch.
|
||||||
@ -161,6 +164,7 @@ impl ThreadManager {
|
|||||||
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]);
|
||||||
}
|
}
|
||||||
|
machine.pc = t.thread_context.pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Currently running thread
|
/// Currently running thread
|
||||||
@ -196,28 +200,26 @@ impl ThreadManager {
|
|||||||
mod test {
|
mod test {
|
||||||
use std::{rc::Rc, cell::RefCell};
|
use std::{rc::Rc, cell::RefCell};
|
||||||
|
|
||||||
use crate::{simulator::machine::Machine, kernel::{system::System, thread::Thread, process::Process}};
|
use crate::{simulator::{machine::Machine, loader}, kernel::{system::System, thread::Thread, process::Process}};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_thread_context() {
|
fn test_thread_context() {
|
||||||
let mut machine = Machine::init_machine();
|
let mut machine = Machine::init_machine();
|
||||||
let mut system = System::default();
|
loader::load("../test.o", &mut machine, 0).expect("IO Error");
|
||||||
|
let system = &mut System::default();
|
||||||
let thread1 = Thread::new("th1");
|
let thread1 = Thread::new("th1");
|
||||||
let thread1 = Rc::new(RefCell::new(thread1));
|
let thread1 = Rc::new(RefCell::new(thread1));
|
||||||
system.get_thread_manager().get_g_alive().push(Rc::clone(&thread1));
|
system.get_thread_manager().get_g_alive().push(Rc::clone(&thread1));
|
||||||
let owner = Process { num_thread: 0 };
|
let owner = Process { num_thread: 0 };
|
||||||
system.get_thread_manager().start_thread(Rc::clone(&thread1), owner, thread1_func as i64, 0);
|
system.get_thread_manager().start_thread(Rc::clone(&thread1), owner, 0x94 as u64, 0);
|
||||||
assert_eq!(thread1.borrow_mut().thread_context.pc, thread1_func as i64);
|
debug_assert_eq!(thread1.borrow_mut().thread_context.pc, 0x94 as u64);
|
||||||
let to_run = system.get_thread_manager().find_next_to_run().unwrap();
|
let to_run = system.get_thread_manager().find_next_to_run().unwrap();
|
||||||
assert_eq!(to_run, Rc::clone(&thread1));
|
debug_assert_eq!(to_run, Rc::clone(&thread1));
|
||||||
assert!(system.get_thread_manager().get_g_alive().contains(&Rc::clone(&thread1)));
|
debug_assert!(system.get_thread_manager().get_g_alive().contains(&Rc::clone(&thread1)));
|
||||||
system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run));
|
system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run));
|
||||||
|
debug_assert_eq!(system.get_thread_manager().g_current_thread, Option::Some(Rc::clone(&thread1)));
|
||||||
println!("{:#?}", thread1.borrow_mut().thread_context);
|
debug_assert_eq!(machine.pc, 0x94);
|
||||||
}
|
machine.run();
|
||||||
|
|
||||||
fn thread1_func() {
|
|
||||||
println!("Hello");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
20
src/main.rs
20
src/main.rs
@ -13,28 +13,10 @@ mod kernel;
|
|||||||
/// module containing useful tools which can be use in most part of the OS to ease the development of the OS
|
/// module containing useful tools which can be use in most part of the OS to ease the development of the OS
|
||||||
pub mod utility;
|
pub mod utility;
|
||||||
|
|
||||||
use std::{rc::Rc, cell::RefCell};
|
|
||||||
|
|
||||||
use kernel::system::System;
|
use kernel::system::System;
|
||||||
use simulator::{machine::Machine, loader};
|
use simulator::machine::Machine;
|
||||||
|
|
||||||
use crate::kernel::{thread::Thread, process::Process};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut machine = Machine::init_machine();
|
let mut machine = Machine::init_machine();
|
||||||
loader::load("test.o", &mut machine, 0).expect("IO Error");
|
|
||||||
let system = &mut System::default();
|
let system = &mut System::default();
|
||||||
let thread1 = Thread::new("th1");
|
|
||||||
let thread1 = Rc::new(RefCell::new(thread1));
|
|
||||||
system.get_thread_manager().get_g_alive().push(Rc::clone(&thread1));
|
|
||||||
let owner = Process { num_thread: 0 };
|
|
||||||
system.get_thread_manager().start_thread(Rc::clone(&thread1), owner, 0 as i64, 0);
|
|
||||||
debug_assert_eq!(thread1.borrow_mut().thread_context.pc, 0 as i64);
|
|
||||||
let to_run = system.get_thread_manager().find_next_to_run().unwrap();
|
|
||||||
debug_assert_eq!(to_run, Rc::clone(&thread1));
|
|
||||||
debug_assert!(system.get_thread_manager().get_g_alive().contains(&Rc::clone(&thread1)));
|
|
||||||
system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run));
|
|
||||||
|
|
||||||
machine.run();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user