Commit 11dc1f74 authored by Nifou's avatar Nifou

Save the SSE state during signals and deallocate the stack and the SSE state...

Save the SSE state during signals and deallocate the stack and the SSE state area when a thread exits
parent 6401a5ac
Pipeline #173753121 passed with stages
in 9 minutes and 23 seconds
......@@ -15,7 +15,10 @@
* along with this program. If not, see https://www.gnu.org/licenses.
*/
//! Syscalls used for tasking (exit, ...)
use alloc::prelude::v1::ToString;
use alloc::{
prelude::v1::ToString,
alloc::{GlobalAlloc, Layout},
};
use core::sync::atomic::Ordering;
use goblin::elf::Elf;
......@@ -23,14 +26,18 @@ use super::{
error::{Error, Result},
get_string, Syscall,
};
use crate::elf::loader::ElfLoader;
use crate::initfs;
use crate::tasking::{
memory::ProcessMemory,
process::{Pid, NEXT_PID},
scheduler::{exit, PROCESSES, SCHEDULER},
thread::Thread,
signal::{Signal, SigAction, SigActionFlags, SI_TKILL, SigInfo, SigMask, send_signal_to, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK},
use crate::{
initfs,
memory::heap::HEAP_ALLOCATOR,
elf::loader::ElfLoader,
tasking::{
memory::ProcessMemory,
process::{Pid, NEXT_PID},
scheduler::{exit, PROCESSES, SCHEDULER},
thread::{Thread, FX_SIZE},
signal::{Signal, SigAction, SigActionFlags, SI_TKILL, SigInfo, SigMask, send_signal_to, SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK},
context::Fx,
},
};
impl Syscall {
......@@ -228,7 +235,17 @@ impl Syscall {
process.signal_mask.remove(SigMask::from(saved.1));
}
// Restore the context
*self.stack = saved.0;
// Restore the SSE state
Fx::restore(saved.3);
// Deallocate the SSE area
unsafe {
HEAP_ALLOCATOR.dealloc(saved.3 as *mut u8, Layout::from_size_align_unchecked(FX_SIZE, 16));
}
Ok(saved.0.rax)
}
......
......@@ -15,10 +15,15 @@
* along with this program. If not, see https://www.gnu.org/licenses.
*/
//! A trait which make the addition of other scheduler algorithms easier
use alloc::{
prelude::v1::Box,
alloc::{GlobalAlloc, Layout},
};
use core::mem::{transmute, size_of};
use crate::memory::heap::HEAP_ALLOCATOR;
use super::{
thread::{Thread, Tid},
thread::{Thread, Tid, FX_SIZE},
context::Fx,
scheduler::PROCESSES,
signal::{DEFAULT_ACTIONS, SIGDFL, SIGIGN, SigActionFlags, SigInfo, SigMask},
......@@ -86,9 +91,12 @@ pub trait SchedulerAlgo {
let kstack = thread.get_kstack();
// Save the context
process.signal_saved = Some((*kstack, signal.0, *action));
// TODO: Save and restore the SSE state
// Save the context, the SSE state, the signal number and the action
let fx =
Box::into_raw(unsafe { Box::from_raw(HEAP_ALLOCATOR.alloc(Layout::from_size_align_unchecked(FX_SIZE, 16)) as *mut [u8; FX_SIZE]) }) as u64;
Fx::save(fx);
process.signal_saved = Some((*kstack, signal.0, *action, fx));
// Change the instruction pointer
kstack.rip = action.sa_handler;
......
......@@ -103,7 +103,8 @@ pub struct Process {
/// The saved things before the execution of the signal handler
/// * The context
/// * The signal's action
pub signal_saved: Option<(Registers, Signal, SigAction)>,
/// * The SSE state
pub signal_saved: Option<(Registers, Signal, SigAction, u64)>,
/// The signal mask for blocked signals
pub signal_mask: SigMask,
......
......@@ -57,20 +57,25 @@ unsafe impl Send for SchedulerCurrentAlgo {}
/// (does the job of the `exit_group` syscall)
pub fn exit(all_threads: bool) {
let mut processes = PROCESSES.write();
let tid = SCHEDULER.get().current().expect("No current process").tid;
let pid = SCHEDULER
.get()
.current()
.expect("No current process")
.process;
// Remove the current thread
SCHEDULER.get().remove(tid);
// Remove the thread in the process
if all_threads {
// Remove all threads of the process
processes.get_mut(&pid).unwrap().threads.iter().for_each(|t| {
SCHEDULER.get().get(*t).unwrap().exit();
SCHEDULER.get().remove(*t);
});
processes.get_mut(&pid).unwrap().threads.clear();
} else {
// Remove the current thread
let tid = SCHEDULER.get().current().expect("No current process").tid;
SCHEDULER.get().remove(tid);
processes
.get_mut(&pid)
.unwrap()
......
......@@ -44,7 +44,9 @@ use crate::{
pub static NEXT_TID: AtomicUsize = AtomicUsize::new(0);
const KSTACK_SIZE: usize = 4096;
const FX_SIZE: usize = 512;
/// The size of the Streaming SIMD Extensions area
pub const FX_SIZE: usize = 512;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
/// A thread ID
......@@ -77,7 +79,7 @@ impl Thread {
let kstack_pointer =
Box::into_raw(unsafe { Box::from_raw(HEAP_ALLOCATOR.alloc(Layout::from_size_align_unchecked(KSTACK_SIZE, 4096)) as *mut [u8; KSTACK_SIZE]) }) as u64 + KSTACK_SIZE as u64;
let fx =
Box::into_raw(unsafe { Box::from_raw(HEAP_ALLOCATOR.alloc(Layout::from_size_align_unchecked(FX_SIZE, 16)) as *mut [u8; KSTACK_SIZE]) }) as u64;
Box::into_raw(unsafe { Box::from_raw(HEAP_ALLOCATOR.alloc(Layout::from_size_align_unchecked(FX_SIZE, 16)) as *mut [u8; FX_SIZE]) }) as u64;
// Create a new set of registers
let mut regs = Registers::default();
......@@ -153,4 +155,14 @@ impl Thread {
mapping,
)
}
/// Exit the thread
///
/// This function deallocates the kernel stack and the SSE area
pub fn exit(&self) {
unsafe {
HEAP_ALLOCATOR.dealloc((self.kstack - KSTACK_SIZE + size_of::<Registers>()) as *mut u8, Layout::from_size_align_unchecked(KSTACK_SIZE, 4096));
HEAP_ALLOCATOR.dealloc((self.fx) as *mut u8, Layout::from_size_align_unchecked(FX_SIZE, 16));
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment