Add ucontext_t

This commit is contained in:
Quentin Legot 2023-03-06 16:31:35 +01:00
parent 4dae299008
commit 6ca0b564c5
5 changed files with 103 additions and 11 deletions

7
Cargo.lock generated
View File

@ -7,6 +7,7 @@ name = "burritos"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"libc",
] ]
[[package]] [[package]]
@ -14,3 +15,9 @@ name = "lazy_static"
version = "1.4.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"

View File

@ -5,3 +5,4 @@ edition = "2021"
[dependencies] [dependencies]
lazy_static = "1.4.0" lazy_static = "1.4.0"
libc = { version = "0.2.139", features = ["extra_traits"] }

View File

@ -3,3 +3,4 @@ pub mod thread;
pub mod scheduler; pub mod scheduler;
pub mod mgerror; pub mod mgerror;
pub mod system; pub mod system;
mod ucontext;

View File

@ -1,14 +1,10 @@
use std::sync::Arc; use std::{sync::Arc};
use super::{process::Process, mgerror::ErrorCode, system::{ObjectType, G_ALIVE, G_SCHEDULER}}; use super::{process::Process, mgerror::ErrorCode, system::{ObjectType, G_ALIVE, G_SCHEDULER}, ucontext::UContextT};
use crate::{simulator::machine::{NUM_INT_REGS, NUM_FP_REGS, STACK_REG}}; use crate::{simulator::machine::{NUM_INT_REGS, NUM_FP_REGS, STACK_REG}};
const SIMULATORSTACKSIZE: usize = 32 * 1024; const SIMULATORSTACKSIZE: usize = 32 * 1024;
const STACK_FENCEPOST: u32 = 0xdeadbeef;
#[derive(PartialEq)]
struct SimulatorContext {
// todo
}
#[derive(PartialEq)] #[derive(PartialEq)]
struct ThreadContext { struct ThreadContext {
@ -21,7 +17,7 @@ struct ThreadContext {
pub struct Thread { pub struct Thread {
name: String, name: String,
process: Option<Process>, process: Option<Process>,
simulation_context: SimulatorContext, // simulation_context: UContextT,
thread_context: ThreadContext, thread_context: ThreadContext,
stack_pointer: i32, stack_pointer: i32,
object_type: ObjectType object_type: ObjectType
@ -33,7 +29,7 @@ impl Thread {
Self { Self {
name, name,
process: None, process: None,
simulation_context: SimulatorContext { }, // simulation_context: UContextT::new(),
thread_context: ThreadContext { thread_context: ThreadContext {
int_registers: [0; NUM_INT_REGS], int_registers: [0; NUM_INT_REGS],
float_registers: [0; NUM_FP_REGS], float_registers: [0; NUM_FP_REGS],
@ -79,7 +75,18 @@ impl Thread {
} }
fn init_simulator_context(&self, base_stack_addr: [i8; SIMULATORSTACKSIZE]) { fn init_simulator_context(&self, base_stack_addr: [i8; SIMULATORSTACKSIZE]) {
todo!(); // let res = self.simulation_context.get_context();
// if res != 0 {
// panic!("getcontext returns non-zero value {}", res);
// }
// self.simulation_context.buf.uc_stack.ss_sp = base_stack_addr;
// self.simulation_context.buf.uc_stack.ss_size = base_stack_addr.len();
// self.simulation_context.buf.uc_stack.ss_flags = 0;
// self.simulation_context.buf.uc_link = UContextT::new().buf;
// self.simulation_context.make_context(start_thread_execution, 0);
// self.simulation_context.stackBottom = base_stack_addr.to_vec();
// self.simulation_context.stackBottom[0] = STACK_FENCEPOST;
} }
/// Wait for another thread to finish its execution /// Wait for another thread to finish its execution
@ -148,3 +155,7 @@ impl Drop for Thread {
} }
} }
fn start_thread_execution() {
}

72
src/kernel/ucontext.rs Normal file
View File

@ -0,0 +1,72 @@
use std::mem::MaybeUninit;
use libc::{ucontext_t, getcontext, setcontext, makecontext};
/// Safe wrapper for ucontext_t struct of linux-gnu libc
///
/// setcontext and getcontext are unsafe function, this wrap unsafe libc functions
///
/// This struct doesn't work on windows, because this struct is unavailable
///
/// todo ucontext_t is not thread-safe (doesn't implements Send and Sync trait), and cannot be use in Threads as rust require var in Mutex (see system.rs) to have everything inside to implements thread-safe traits
#[derive(PartialEq)]
pub struct UContextT {
#[cfg(not(target_os = "windows"))] // struct non disponible sur la libc sur windows
pub buf: ucontext_t,
pub stackBottom: Vec<i8>
}
#[cfg(not(target_os = "windows"))]
impl UContextT {
pub fn new() -> Self {
let mut context = MaybeUninit::<ucontext_t>::uninit();
unsafe { getcontext(context.as_mut_ptr()) };
Self {
buf: unsafe { context.assume_init() },
stackBottom: Vec::default(),
}
}
/// Get user context and store it in variable pointed to by UCP.
///
/// Use `man getcontext` for more informations
pub fn get_context(&mut self) -> i32 {
unsafe {
getcontext(&mut self.buf)
}
}
/// Set user context from information of variable pointed to by UCP.
///
/// Use `man setcontext` for more informations
pub fn set_context(&mut self) -> i32 {
unsafe {
setcontext(&self.buf)
}
}
pub fn make_context(&mut self, func: extern "C" fn(), args: i32) {
unsafe {
makecontext(&mut self.buf, func, args)
}
}
}
#[cfg(target_os = "windows")]
impl UContextT {
pub fn new() -> Self {
Self {}
}
pub fn get_context(&mut self) {
// no op
}
pub fn set_context(&mut self) {
// no op
}
}