Merge branch 'bin-loader' into 'thread_scheduler'

Binary loader

See merge request simpleos/burritos!12
This commit is contained in:
Legot Quentin
2023-04-04 13:35:10 +00:00
15 changed files with 758 additions and 67 deletions

View File

@ -1,4 +1,4 @@
mod process;
pub mod process;
pub mod thread;
pub mod mgerror;
pub mod system;

View File

@ -16,7 +16,7 @@ macro_rules! get_new_thread {
pub struct ThreadContext {
pub int_registers: [i64; NUM_INT_REGS],
pub float_registers: [f32; NUM_FP_REGS],
pub pc: i64,
pub pc: u64,
}
#[derive(PartialEq, Debug)]
@ -47,10 +47,10 @@ 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: u64, arg: i64) {
self.thread_context.pc = initial_pc_reg;
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 as i64;
}
pub fn init_simulator_context(&self, base_stack_addr: [i8; SIMULATORSTACKSIZE]) {

View File

@ -78,17 +78,19 @@ impl ThreadManager {
}
},
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
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, 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);
let ptr = 0; // todo addrspace
let ptr = sp_loc; // todo addrspace
thread_m.init_thread_context(func_pc, ptr, argument);
let base_stack_addr: [i8; SIMULATORSTACKSIZE] = [0; SIMULATORSTACKSIZE]; // todo AllocBoundedArray
thread_m.init_simulator_context(base_stack_addr);
@ -153,6 +155,7 @@ impl ThreadManager {
for i in 0..NUM_FP_REGS {
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.
@ -161,6 +164,7 @@ impl ThreadManager {
for i in 0..NUM_INT_REGS {
machine.write_int_register(i, t.thread_context.int_registers[i]);
}
machine.pc = t.thread_context.pc;
}
/// Currently running thread
@ -196,28 +200,33 @@ impl ThreadManager {
mod test {
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]
#[ignore = "Pas encore terminé, contient des bugs"]
fn test_thread_context() {
let mut machine = Machine::init_machine();
let mut system = System::default();
let (loader, ptr) = loader::Loader::new("./test/riscv_instructions/simple_arithmetics/unsigned_addition", &mut machine, 0).expect("IO Error");
let start_pc = loader.elf_header.entrypoint;
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, thread1_func as i64, 0);
assert_eq!(thread1.borrow_mut().thread_context.pc, thread1_func as i64);
let to_run = system.get_thread_manager().find_next_to_run().unwrap();
assert_eq!(to_run, Rc::clone(&thread1));
assert!(system.get_thread_manager().get_g_alive().contains(&Rc::clone(&thread1)));
system.get_thread_manager().switch_to(&mut machine, Rc::clone(&to_run));
println!("{:#?}", thread1.borrow_mut().thread_context);
}
fn thread1_func() {
println!("Hello");
let owner = Process { num_thread: 0 };
system.get_thread_manager().start_thread(Rc::clone(&thread1), owner, start_pc, ptr, -1);
debug_assert_eq!(thread1.borrow_mut().thread_context.pc, start_pc);
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));
debug_assert_eq!(system.get_thread_manager().g_current_thread, Option::Some(Rc::clone(&thread1)));
debug_assert_eq!(machine.pc, start_pc);
machine.run();
}
}