Skip to content

Commit 866d554

Browse files
committed
Refactor process_list and name it process_table
1 parent 4268d51 commit 866d554

File tree

11 files changed

+229
-212
lines changed

11 files changed

+229
-212
lines changed

common/src/mutex.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ impl<T> Mutex<T> {
2424
}
2525
}
2626

27+
pub fn with_lock<'a, R>(&'a self, f: impl FnOnce(MutexGuard<'a, T>) -> R) -> R {
28+
let lock = self.lock();
29+
f(lock)
30+
}
31+
2732
pub fn lock(&self) -> MutexGuard<T> {
2833
if self.disarmed.load(Ordering::SeqCst) {
2934
return MutexGuard { mutex: self };

kernel/src/cpu.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ pub fn wait_for_interrupt() {
6565
const SIE_STIE: usize = 5;
6666
const SSTATUS_SPP: usize = 8;
6767

68+
pub fn is_timer_enabled() -> bool {
69+
let sie: usize;
70+
unsafe { asm!("csrr {}, sie", out(reg) sie) }
71+
(sie & (1 << SIE_STIE)) > 0
72+
}
73+
6874
pub fn disable_timer_interrupt() {
6975
unsafe {
7076
asm!("

kernel/src/debugging/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
info,
33
klibc::sizes::MiB,
4-
processes::{process_list, scheduler::get_current_process},
4+
processes::{process_table, scheduler::get_current_process},
55
};
66

77
pub mod backtrace;
@@ -24,7 +24,7 @@ pub fn dump_current_state() {
2424
used_heap_pages, total_heap_pages
2525
);
2626

27-
process_list::dump();
27+
process_table::THE.lock().dump();
2828

2929
let current_process = get_current_process();
3030
if let Some(process) = current_process {

kernel/src/io/stdin_buf.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
use crate::processes::{process::Pid, process_list};
1+
use crate::{
2+
cpu,
3+
processes::{
4+
process::{Pid, ProcessState},
5+
process_table, timer,
6+
},
7+
};
28
use alloc::collections::{BTreeSet, VecDeque};
39
use common::mutex::Mutex;
410

@@ -22,14 +28,24 @@ impl StdinBuffer {
2228
}
2329

2430
pub fn push(&mut self, byte: u8) {
25-
let mut notified = false;
26-
for pid in &self.wakeup_queue {
27-
if process_list::notify_input(*pid, byte) {
28-
notified = true;
31+
let notified = !self.wakeup_queue.is_empty();
32+
process_table::THE.with_lock(|pt| {
33+
for pid in &self.wakeup_queue {
34+
if let Some(process) = pt.get_process(*pid) {
35+
process.with_lock(|mut p| {
36+
p.set_state(ProcessState::Runnable);
37+
p.set_syscall_return_code(byte as usize);
38+
})
39+
}
2940
}
30-
}
41+
});
3142
self.wakeup_queue.clear();
3243
if notified {
44+
if !cpu::is_timer_enabled() {
45+
// Enable timer because we were sleeping and waiting
46+
// for input
47+
timer::set_timer(0);
48+
}
3349
return;
3450
}
3551
self.data.push_back(byte);

kernel/src/processes/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub mod loader;
22
pub mod process;
3-
pub mod process_list;
3+
pub mod process_table;
44
pub mod scheduler;
55
pub mod timer;

kernel/src/processes/process.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ use crate::{
33
klibc::elf::ElfFile,
44
memory::{page::PinnedHeapPages, page_tables::RootPageTableHolder, PAGE_SIZE},
55
net::sockets::SharedAssignedSocket,
6-
processes::{
7-
loader::{self, LoadedElf},
8-
process_list,
9-
},
6+
processes::loader::{self, LoadedElf},
107
};
118
use alloc::{
129
collections::{BTreeMap, BTreeSet},
@@ -33,7 +30,7 @@ pub enum ProcessState {
3330
}
3431

3532
fn get_next_pid() -> Pid {
36-
static PID_COUNTER: AtomicU64 = AtomicU64::new(0);
33+
static PID_COUNTER: AtomicU64 = AtomicU64::new(1);
3734
let next_pid = PID_COUNTER.fetch_add(1, Ordering::Relaxed);
3835
assert_ne!(next_pid, u64::MAX, "We ran out of process pids");
3936
next_pid
@@ -79,6 +76,10 @@ impl Debug for Process {
7976
}
8077

8178
impl Process {
79+
pub fn get_notifies_on_die(&self) -> impl Iterator<Item = &Pid> {
80+
self.notify_on_die.iter()
81+
}
82+
8283
pub fn mmap_pages(&mut self, number_of_pages: usize) -> *mut u8 {
8384
let pages = PinnedHeapPages::new(number_of_pages);
8485
self.page_table.map_userspace(
@@ -196,9 +197,6 @@ impl Process {
196197

197198
impl Drop for Process {
198199
fn drop(&mut self) {
199-
for pid in &self.notify_on_die {
200-
process_list::wake_up(*pid);
201-
}
202200
debug!(
203201
"Drop process (PID: {}) (Allocated pages: {:?})",
204202
self.pid, self.allocated_pages

kernel/src/processes/process_list.rs

Lines changed: 0 additions & 121 deletions
This file was deleted.

kernel/src/processes/process_table.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use alloc::{collections::BTreeMap, sync::Arc};
2+
use common::mutex::Mutex;
3+
4+
use crate::{debug, info};
5+
6+
use super::process::{Pid, Process, ProcessState};
7+
8+
pub static THE: Mutex<ProcessTable> = Mutex::new(ProcessTable::new());
9+
10+
pub type ProcessRef = Arc<Mutex<Process>>;
11+
12+
pub struct ProcessTable {
13+
processes: BTreeMap<Pid, ProcessRef>,
14+
}
15+
16+
impl ProcessTable {
17+
const fn new() -> Self {
18+
Self {
19+
processes: BTreeMap::new(),
20+
}
21+
}
22+
23+
pub fn add_process(&mut self, process: Process) {
24+
self.processes
25+
.insert(process.get_pid(), Arc::new(Mutex::new(process)));
26+
}
27+
28+
pub fn is_empty(&self) -> bool {
29+
self.processes.is_empty()
30+
}
31+
32+
pub fn get_highest_pid_without_yash(&self) -> Option<Pid> {
33+
self.processes
34+
.iter()
35+
.filter(|(_, p)| p.lock().get_name() != "yash")
36+
.max_by_key(|(pid, _)| *pid)
37+
.map(|(pid, _)| *pid)
38+
}
39+
40+
pub fn dump(&self) {
41+
for (pid, process) in &self.processes {
42+
let process = process.lock();
43+
info!(
44+
"PID={} NAME={} STATE={:?}",
45+
*pid,
46+
process.get_name(),
47+
process.get_state()
48+
);
49+
}
50+
}
51+
52+
pub fn kill(&mut self, pid: Pid) {
53+
debug!("Removing pid={pid} from process table");
54+
if let Some(process) = self.processes.remove(&pid) {
55+
assert_eq!(
56+
Arc::strong_count(&process),
57+
1,
58+
"There should no more than one process handles be active"
59+
);
60+
for pid in process.lock().get_notifies_on_die() {
61+
self.wake_process_up(*pid);
62+
}
63+
}
64+
}
65+
66+
pub fn next_runnable(&self, old_pid: Pid) -> Option<ProcessRef> {
67+
let mut next_iter = self
68+
.processes
69+
.range(old_pid..)
70+
.skip(1)
71+
.filter_map(Self::filter_map_runnable_processes);
72+
73+
if let Some(next_process) = next_iter.next() {
74+
Some(next_process.clone())
75+
} else {
76+
self.processes
77+
.iter()
78+
.filter_map(Self::filter_map_runnable_processes)
79+
.next()
80+
.cloned()
81+
}
82+
}
83+
84+
fn filter_map_runnable_processes<'a>((_, p): (&Pid, &'a ProcessRef)) -> Option<&'a ProcessRef> {
85+
if p.lock().get_state() == ProcessState::Runnable {
86+
Some(p)
87+
} else {
88+
None
89+
}
90+
}
91+
92+
pub fn get_process(&self, pid: Pid) -> Option<&ProcessRef> {
93+
self.processes.get(&pid)
94+
}
95+
96+
pub fn does_pid_exist(&self, pid: Pid) -> bool {
97+
self.processes.contains_key(&pid)
98+
}
99+
100+
pub fn wake_process_up(&self, pid: Pid) {
101+
debug!("Waking process up with pid={pid}");
102+
let mut process = self.processes.get(&pid).expect("Process must exist").lock();
103+
assert_eq!(
104+
process.get_state(),
105+
ProcessState::Waiting,
106+
"Process must be in waiting state to be woken up"
107+
);
108+
process.set_state(ProcessState::Runnable);
109+
}
110+
}

0 commit comments

Comments
 (0)