Skip to content

Commit 6a1a079

Browse files
committed
[Kernel - Rust] Add a spinlock API
1 parent c181640 commit 6a1a079

File tree

3 files changed

+45
-1
lines changed

3 files changed

+45
-1
lines changed

programs/subprojects/task_viewer/task_viewer.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef struct task_info {
2828
uint64_t user_mode_rip;
2929
bool has_amc_service;
3030
uint64_t pending_amc_messages;
31+
// TODO(PT): Add CPU ID here
3132
} task_info_t;
3233

3334
typedef struct task_viewer_get_task_info_response {
@@ -210,7 +211,7 @@ static void _layout_tasks() {
210211
_draw_string(&view->view, buf, cursor, font_size, color_black(), color_white(), 0, 0);
211212

212213
// Draw AMC service info, if available, else draw a blank space
213-
cursor = point_make(4, cursor.y + (font_size.height * 1.5));
214+
cursor = point_make(4, cursor.y + (font_size.height * 1));
214215
memset(buf, 0, sizeof(buf));
215216
if (task->has_amc_service) {
216217
snprintf(buf, sizeof(buf), " Pending messages: %d", task->pending_amc_messages);

rust_kernel_libs/acpi/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ mod apic;
3939
mod interrupts;
4040
mod scheduler;
4141
mod smp;
42+
mod spinlocks;
4243
mod structs;
4344
mod utils;
4445

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use alloc::collections::BTreeMap;
2+
use alloc::vec::Vec;
3+
use core::hint;
4+
use core::sync::atomic::{AtomicBool, Ordering};
5+
use ffi_bindings::Spinlock;
6+
use lazy_static::lazy_static;
7+
use spin::Mutex;
8+
9+
lazy_static! {
10+
// TODO(PT): Eventually, we could replace the C representation with an FFI-safe Rust-managed version entirely
11+
static ref SPINLOCKS: spin::Mutex<BTreeMap<&'static Spinlock, AtomicBool>> = Mutex::new(BTreeMap::new());
12+
}
13+
14+
unsafe fn track_lock_if_necessary(spinlock: &'static Spinlock) {
15+
let mut lock_ptrs_to_locks = SPINLOCKS.lock();
16+
if !lock_ptrs_to_locks.contains_key(&spinlock) {
17+
lock_ptrs_to_locks.insert(spinlock, AtomicBool::new(false));
18+
}
19+
}
20+
21+
#[no_mangle]
22+
pub unsafe fn spinlock_acquire_spin(spinlock_raw: *const Spinlock) {
23+
let spinlock: &'static Spinlock = &*spinlock_raw;
24+
track_lock_if_necessary(spinlock);
25+
let spinlocks = SPINLOCKS.lock();
26+
let is_locked = spinlocks.get(spinlock).unwrap();
27+
28+
// Keep spinning while the previous value was "already locked"
29+
while is_locked.swap(true, Ordering::Acquire) == true {
30+
hint::spin_loop();
31+
}
32+
// The lock is now ours
33+
}
34+
35+
#[no_mangle]
36+
pub unsafe fn spinlock_release_spin(spinlock_raw: *const Spinlock) {
37+
let spinlock: &'static Spinlock = &*spinlock_raw;
38+
// TODO(PT): Is SPINLOCKS.lock() itself going to act as a mutex?
39+
let spinlocks = SPINLOCKS.lock();
40+
let is_locked = spinlocks.get(spinlock).unwrap();
41+
is_locked.store(false, Ordering::Release);
42+
}

0 commit comments

Comments
 (0)