Add mutexes

This commit is contained in:
pjht 2024-11-28 13:40:23 -06:00
parent dceb0768c2
commit 7284cef45a
Signed by: pjht
GPG Key ID: CA239FC6934E6F3A
2 changed files with 57 additions and 7 deletions

View File

@ -796,12 +796,19 @@ extern "C" fn syscall_handler() {
29 => {
retval = u64(TASKING.new_tls_key());
}
30 => {
TASKING.set_tls_key(usize(regs.rcx), regs.rdx)
}
30 => TASKING.set_tls_key(usize(regs.rcx), regs.rdx),
31 => {
retval = TASKING.get_tls_key(usize(regs.rcx));
}
32 => {
retval = u64(TASKING.new_mutex());
}
33 => TASKING.lock_mutex(usize(regs.rcx)),
34 => {
retval = u64::from(TASKING.try_lock_mutex(usize(regs.rcx)));
}
35 => TASKING.unlock_mutex(usize(regs.rcx)),
36 => TASKING.drop_mutex(usize(regs.rcx)),
_ => (),
};
unsafe { SYSCALL_REGS = regs };

View File

@ -4,7 +4,7 @@ use crate::{
println,
virtual_memory::{ASpaceMutex, AddressSpace, PagingError, ACTIVE_SPACE, KERNEL_SPACE},
};
use alloc::{boxed::Box, collections::VecDeque, vec::Vec, vec};
use alloc::{boxed::Box, collections::VecDeque, vec, vec::Vec};
use cast::{u64, usize};
use core::{
arch::naked_asm,
@ -13,7 +13,7 @@ use core::{
};
use crossbeam_queue::SegQueue;
use slab::Slab;
use spin::{Lazy, Mutex, RwLock};
use spin::{mutex, Lazy, Mutex, RwLock};
use x86_64::{
structures::paging::{Page, PageTableFlags},
VirtAddr,
@ -84,6 +84,7 @@ pub enum SleepReason {
NewProcess,
Exited,
JoinThread(usize),
LockedMutex(usize),
}
#[derive(Debug)]
@ -96,6 +97,7 @@ pub struct Process {
main_thread: usize,
num_threads: usize,
num_tls: usize,
mutexes: Mutex<Slab<bool>>,
}
impl Process {
@ -112,6 +114,7 @@ impl Process {
main_thread: 0,
num_threads: 0,
num_tls: 0,
mutexes: Mutex::new(Slab::new()),
};
let main_thread = proc.new_thread(entry_point, 0)?;
proc.main_thread = main_thread;
@ -628,11 +631,51 @@ impl Tasking {
}
pub fn get_tls_key(&self, key: usize) -> u64 {
self.current_thread(|thread| {
thread.tls_values.lock()[key]
self.current_thread(|thread| thread.tls_values.lock()[key])
}
pub fn new_mutex(&self) -> usize {
self.current_process(|process| process.mutexes.lock().insert(false))
}
pub fn lock_mutex(&self, mutex: usize) {
loop {
if self.try_lock_mutex(mutex) {
break;
}
self.sleep(SleepReason::LockedMutex(mutex));
}
}
pub fn try_lock_mutex(&self, mutex: usize) -> bool {
self.current_process(|process| {
let mut mutexes = process.mutexes.lock();
if !mutexes[mutex] {
mutexes[mutex] = true;
true
} else {
false
}
})
}
pub fn unlock_mutex(&self, mutex: usize) {
self.current_process(|process| {
let mut mutexes = process.mutexes.lock();
mutexes[mutex] = false;
for (tid, thread) in &*process.threads().read() {
if *thread.sleeping.read() == Some(SleepReason::LockedMutex(mutex)) {
self.wake(self.current_pid().unwrap(), tid, SleepReason::LockedMutex(mutex));
break;
}
}
});
}
pub fn drop_mutex(&self, mutex: usize) {
self.current_process(|process| process.mutexes.lock().remove(mutex));
}
//pub fn print_stats(&self) {
// let mut total = KERNEL_SPACE.lock().get_bytes_allocated();
// println!(