Commit 3fe175da authored by Nifou's avatar Nifou

Better thread and process IDs

*  The process IDs are allocated according to the IDs already used in the processes' list
*  The thread IDs are allocated according to the IDs already used in the scheduler
parent 3ab24add
Pipeline #174125312 passed with stages
in 8 minutes and 53 seconds
......@@ -19,7 +19,6 @@ use alloc::{
prelude::v1::ToString,
alloc::{GlobalAlloc, Layout},
};
use core::sync::atomic::Ordering;
use goblin::elf::Elf;
use super::{
......@@ -32,7 +31,7 @@ use crate::{
elf::loader::ElfLoader,
tasking::{
memory::ProcessMemory,
process::{Pid, NEXT_PID},
process::Pid,
scheduler::{exit, PROCESSES, SCHEDULER},
thread::{Thread, FX_SIZE},
signal::{
......@@ -340,15 +339,15 @@ impl Syscall {
// Use the kernel's page table
crate::memory::switch_to_kernel_page_table();
// Get the PID of the new process
let pid = usize::from(Pid::get_new());
// List of processes
let mut processes = PROCESSES.write();
// Get the current process
let parent_process = SCHEDULER.get().current().unwrap().process;
// Get the PID of the new process
let pid = NEXT_PID.fetch_add(1, Ordering::Relaxed);
// Clone the current process (thank you Rust's traits for this awesome implementation ;-))
let mut child_process = processes.get(&parent_process).unwrap().clone();
......@@ -409,9 +408,6 @@ impl Syscall {
crate::memory::switch_to_kernel_page_table();
if let Ok(data) = initfs::INITFS.get_binary_file(path.to_string().clone()) {
let mut processes = PROCESSES.write();
let current = SCHEDULER.get().current().unwrap().process;
// Load the binary
match Elf::parse(data) {
Ok(binary) => {
......@@ -427,6 +423,9 @@ impl Syscall {
// TODO: Args and env
let mut processes = PROCESSES.write();
let current = SCHEDULER.get().current().unwrap().process;
// Kill all threads
for thread in processes.get(&current).unwrap().threads.clone() {
SCHEDULER.get().remove(thread);
......
......@@ -49,6 +49,9 @@ pub trait SchedulerAlgo {
/// Choose the next thread which will be executed
fn choose(&mut self) -> Option<Thread>;
/// Indicates if a thread ID is used or not
fn contains(&self, tid: &Tid) -> bool;
/// Get the current thread
fn current(&self) -> Option<&Thread>;
......
......@@ -16,7 +16,6 @@
*/
//! Definition of a Process which regroups a set of resources (memory, ...)
use alloc::prelude::v1::{Vec, String};
use core::sync::atomic::{AtomicUsize, Ordering};
use x86_64::structures::paging::{page_table::PageTableFlags as Flags, FrameDeallocator};
use super::{
......@@ -47,13 +46,26 @@ pub const DATA_SEGMENT_SIZE: usize = 65536;
/// The size of the process' signal stack
pub const SIGNAL_STACK_SIZE: usize = 65536;
/// The next Process ID which will be used
pub static NEXT_PID: AtomicUsize = AtomicUsize::new(0);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
/// A process ID
pub struct Pid(pub usize);
impl Pid {
/// Get a new PID
pub fn get_new() -> Self {
let processes = PROCESSES.read();
Self((0..)
.find(|i| !processes.contains_key(&Pid(*i)))
.unwrap())
}
}
impl From<Pid> for usize {
fn from(pid: Pid) -> Self {
pid.0
}
}
#[derive(PartialEq, Debug, Clone, Copy)]
/// The state of the process (killed or alive)
pub enum ProcessState {
......@@ -124,7 +136,7 @@ impl Process {
pub fn new(info: ProcessInfo) -> Self {
Self {
name: info.args[0].clone(),
pid: Pid(NEXT_PID.fetch_add(1, Ordering::Relaxed)),
pid: Pid::get_new(),
state: ProcessState::Alive,
memory: ProcessMemory::new(),
info: info.clone(),
......
......@@ -15,7 +15,10 @@
* along with this program. If not, see https://www.gnu.org/licenses.
*/
//! The [Round Robin](https://en.wikipedia.org/wiki/Round-robin_scheduling) scheduling algorithm
use alloc::collections::vec_deque::VecDeque;
use alloc::{
collections::vec_deque::VecDeque,
prelude::v1::Vec,
};
use crate::tasking::{
algo::SchedulerAlgo,
......@@ -55,6 +58,10 @@ impl SchedulerAlgo for RoundRobinScheduler {
thread
}
fn contains(&self, tid: &Tid) -> bool {
self.threads.iter().map(|t| t.tid).collect::<Vec<Tid>>().contains(tid)
}
fn remove(&mut self, tid: Tid) {
assert!(!self.threads.is_empty());
let mut index = 0;
......
......@@ -22,16 +22,18 @@ use alloc::{
GlobalAlloc,
},
};
use core::{
mem::{size_of, transmute},
sync::atomic::{AtomicUsize, Ordering},
};
use core::mem::{size_of, transmute};
use x86_64::{
structures::paging::{Mapper, Page, Size4KiB},
VirtAddr,
};
use super::{context::Registers, info::StackWriter, process::Pid};
use super::{
context::Registers,
info::StackWriter,
process::Pid,
scheduler::SCHEDULER,
};
use crate::{
gdt,
memory::{
......@@ -40,9 +42,6 @@ use crate::{
},
};
/// The next Thread ID which will be used
pub static NEXT_TID: AtomicUsize = AtomicUsize::new(0);
const KSTACK_SIZE: usize = 4096;
/// The size of the Streaming SIMD Extensions area
......@@ -52,6 +51,15 @@ pub const FX_SIZE: usize = 512;
/// A thread ID
pub struct Tid(pub usize);
impl Tid {
/// Get a new PID
pub fn get_new() -> Self {
Self((0..)
.find(|i| !SCHEDULER.get().contains(&Tid(*i)))
.unwrap())
}
}
#[derive(Debug, Clone)]
/// A thread which is chosen by the scheduler
pub struct Thread {
......@@ -101,7 +109,7 @@ impl Thread {
let sp = writer.sp;
Self {
tid: Tid(NEXT_TID.fetch_add(1, Ordering::Relaxed)),
tid: Tid::get_new(),
first_time: true,
process,
kstack: sp,
......@@ -146,7 +154,7 @@ impl Thread {
(
Self {
tid: Tid(NEXT_TID.fetch_add(1, Ordering::Relaxed)),
tid: Tid::get_new(),
first_time: true,
process,
kstack: sp,
......
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