Skip to content

Commit

Permalink
v0.9.0: update process manager & mutex
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed May 18, 2022
1 parent 90127bb commit b365b5f
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

109 changes: 95 additions & 14 deletions pkg/app/mutex/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,131 @@ use sync::SpinLock;

static mut LOCK: SpinLock = SpinLock::new();
static mut BURGER: isize = 0;
static mut BURGER_SEM: isize = 0;

fn main() -> usize {
let pid = sys_fork();

if pid == 0 {
unsafe {
boy();
}
try_semaphore();
} else {
unsafe {
mother();
}
try_spin();
sys_wait_pid(pid);
}

0
}

unsafe fn mother() {
fn try_spin() {
let pid = sys_fork();

if pid == 0 {
unsafe { boy_spin() };
} else {
unsafe { mother_spin() };
sys_wait_pid(pid);
}
}

unsafe fn mother_spin() {
LOCK.lock();

println!("Mother: Start to make cheese burger, there are {} cheese burger now", &BURGER);
println!(
"Mother - SPIN : Start to make cheese burger, there are {} cheese burger now",
&BURGER
);

BURGER += 10;

println!("Mother: Oh, I have to hang clothes out.");
println!("Mother - SPIN : Oh, I have to hang clothes out.");

let now = sys_time();
let mut current = now;
while current - now < lib::Duration::seconds(1) {
while current - now < lib::Duration::seconds(3) {
core::hint::spin_loop();
current = sys_time();
}

println!("Mother: Oh, Jesus! There are {} cheese burgers", &BURGER);
println!(
"Mother - SPIN : Oh, Jesus! There are {} cheese burgers",
&BURGER
);

LOCK.unlock();
}

unsafe fn boy() {
unsafe fn boy_spin() {

let now = sys_time();
let mut current = now;
while current - now < lib::Duration::milliseconds(200) {
core::hint::spin_loop();
current = sys_time();
}

LOCK.lock();

println!("Boy : Look what I found!");
println!("Boy - SPIN : Look what I found!");
BURGER -= 10;

LOCK.unlock();
}

fn try_semaphore() {
sys_new_sem(0x2323);

let pid = sys_fork();

if pid == 0 {
unsafe { boy_semaphore() };
} else {
unsafe { mother_semaphore() };
sys_wait_pid(pid);
sys_rm_sem(0x2323);
}
}

unsafe fn mother_semaphore() {
sys_sem_down(0x2323);

println!(
"Mother - SEMA : Start to make cheese burger, there are {} cheese burger now",
&BURGER_SEM
);

BURGER_SEM += 10;

println!("Mother - SEMA : Oh, I have to hang clothes out.");

let now = sys_time();
let mut current = now;
while current - now < lib::Duration::seconds(3) {
core::hint::spin_loop();
current = sys_time();
}

println!(
"Mother - SEMA : Oh, Jesus! There are {} cheese burgers",
&BURGER_SEM
);

sys_sem_up(0x2323);
}

unsafe fn boy_semaphore() {

let now = sys_time();
let mut current = now;
while current - now < lib::Duration::milliseconds(200) {
core::hint::spin_loop();
current = sys_time();
}

sys_sem_down(0x2323);

println!("Boy - SEMA : Look what I found!");
BURGER_SEM -= 10;

sys_sem_up(0x2323);
}

entry!(main);
2 changes: 1 addition & 1 deletion pkg/kernel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ggos_kernel"
version = "0.8.7"
version = "0.9.0"
edition = "2021"
authors = ["GZTime <[email protected]>"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
3 changes: 3 additions & 0 deletions pkg/kernel/src/interrupt/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub enum Syscall {
GetPid = 14,
Fork = 15,
Kill = 16,
Sem = 17,
#[num_enum(default)]
None = 255,
}
Expand Down Expand Up @@ -78,6 +79,8 @@ pub fn dispatcher(regs: &mut Registers, sf: &mut InterruptStackFrame) {
Syscall::Fork => sys_fork(regs, sf),
// pid: arg0 as u16
Syscall::Kill => sys_kill(&args, regs, sf),
// op: u8, key: u32, val: usize -> ret: any
Syscall::Sem => sys_sem(&args, regs, sf),
// None
Syscall::None => {}
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/kernel/src/interrupt/syscall/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,13 @@ pub fn sys_kill(args: &SyscallArgs, regs: &mut Registers, sf: &mut InterruptStac
let pid = ProcessId(args.arg0 as u16);
crate::process::kill(pid, regs, sf);
}

pub fn sys_sem(args: &SyscallArgs, regs: &mut Registers, sf: &mut InterruptStackFrame) {
match args.arg0 {
0 => regs.set_rax(crate::process::new_sem(args.arg1 as u32) as usize),
1 => regs.set_rax(crate::process::sem_up(args.arg1 as u32) as usize),
2 => crate::process::sem_down(args.arg1 as u32, regs, sf),
3 => regs.set_rax(crate::process::remove_sem(args.arg1 as u32) as usize),
_ => regs.set_rax(usize::MAX)
}
}
37 changes: 28 additions & 9 deletions pkg/kernel/src/process/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,24 @@ impl ProcessManager {
}

fn get_next_pos(&self) -> usize {
let next_pos = self
let cur_pos = self
.processes
.iter()
.position(|x| x.pid() == self.cur_pid)
.unwrap_or(0)
+ 1;
if next_pos >= self.processes.len() {
0
} else {
next_pos
.unwrap_or(0);

let mut next_pos = (cur_pos + 1) % self.processes.len();

while self.processes[next_pos].status() != ProgramStatus::Ready {
next_pos = (next_pos + 1) % self.processes.len();
}

next_pos
}

pub fn wait_pid(&mut self, pid: ProcessId) -> isize {
if self.exit_code.contains_key(&pid) {
self.exit_code.remove(&pid).unwrap()
*self.exit_code.get(&pid).unwrap()
} else {
-1
}
Expand Down Expand Up @@ -166,6 +168,7 @@ impl ProcessManager {
VirtAddr::new_truncate(STACK_BOT + STACK_SIZE),
);
p.init_elf(&elf);
trace!("{:#?}", &p);
// info!("Spawn process: {}#{}", p.name(), p.pid());
// info!("Spawn process:\n\n{:?}\n", p);
let pid = p.pid();
Expand Down Expand Up @@ -214,8 +217,24 @@ impl ProcessManager {
self.kill(self.cur_pid, ret);
}

pub fn unblock(&mut self, pid: ProcessId) {
self.processes.iter_mut().for_each(|p| {
if p.pid() == pid {
p.pause()
}
});
}

pub fn block(&mut self, pid: ProcessId) {
self.processes.iter_mut().for_each(|p| {
if p.pid() == pid {
p.block()
}
});
}

pub fn kill(&mut self, pid: ProcessId, ret: isize) {
debug!("Killing process #{} with ret code: {}", pid, ret);
trace!("Killing process #{} with ret code: {}", pid, ret);

let p = self.processes.iter().find(|x| x.pid() == pid);

Expand Down
72 changes: 70 additions & 2 deletions pkg/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
mod manager;
mod process;
mod scheduler;
mod sync;

use core::sync::atomic::{AtomicU16, Ordering};

use fs::File;
use manager::*;
use process::*;
use sync::*;

pub use process::ProcessData;
pub use scheduler::*;

use crate::{filesystem::get_volume, Registers, Resource};
use alloc::{string::String, vec};
use alloc::{string::String, vec, collections::BTreeMap};
use x86_64::{
registers::control::{Cr3, Cr2},
structures::idt::InterruptStackFrame,
};
use x86_64::structures::idt::PageFaultErrorCode;

use self::manager::init_PROCESS_MANAGER;
use self::sync::init_SEMAPHORES;

const STACK_BOT: u64 = 0x0000_2000_0000_0000;
const STACK_PAGES: u64 = 0x100;
Expand Down Expand Up @@ -77,7 +80,7 @@ pub fn init() {
kproc.resume();
kproc.set_page_table_with_cr3();
init_PROCESS_MANAGER(ProcessManager::new(kproc));

init_SEMAPHORES(BTreeMap::new());
info!("Process Manager Initialized.");
}

Expand Down Expand Up @@ -149,6 +152,71 @@ pub fn kill(pid: ProcessId, regs: &mut Registers, sf: &mut InterruptStackFrame)
})
}

pub fn new_sem(key: u32) -> isize {
if let Some(mut sems) = get_sem_manager() {
let sid = SemaphoreId::new(key);
trace!("New Semaphore#{}", key);
if !sems.contains_key(&sid) {
sems.insert(sid, Semaphore::new());
0
} else {
-1
}
} else {
-1
}
}

pub fn sem_up(key: u32) -> isize {
if let Some(mut sems) = get_sem_manager() {
let key = SemaphoreId::new(key);
if let Some(sem) = sems.get_mut(&key) {
trace!("{}", sem);
if let Some(pid) = sem.up() {
debug!("Semaphore up -> unblock process: #{}", pid);
let mut manager = get_process_manager_for_sure();
manager.unblock(pid);
}
return 0;
}
}
return -1;
}

pub fn sem_down(key: u32, regs: &mut Registers, sf: &mut InterruptStackFrame) {
if let Some(mut sems) = get_sem_manager() {
let key = SemaphoreId::new(key);
if let Some(sem) = sems.get_mut(&key) {
trace!("{}", sem);
let mut manager = get_process_manager_for_sure();
let pid = manager.current_pid();
if let Err(()) = sem.down(pid) {
debug!("Semaphore down -> block process: #{}", pid);
regs.set_rax(0);
manager.save_current(regs, sf);
manager.block(pid);
manager.switch_next(regs, sf);
}
regs.set_rax(0);
}
}
regs.set_rax(usize::MAX);

}

pub fn remove_sem(key: u32) -> isize {
if let Some(mut sems) = get_sem_manager() {
let key = SemaphoreId::new(key);
if let Some(_) = sems.remove(&key) {
0
} else {
-1
}
} else {
-1
}
}

pub fn try_resolve_page_fault(_err_code: PageFaultErrorCode, _sf: &mut InterruptStackFrame) -> Result<(),()> {
let addr = Cr2::read();
debug!("Trying to access address: {:?}", addr);
Expand Down
Loading

0 comments on commit b365b5f

Please sign in to comment.