veridian_kernel/sched/task_ptr.rs
1//! Safe wrapper for task pointers
2
3use core::ptr::NonNull;
4
5use super::task::Task;
6
7/// A wrapper around NonNull<Task> that implements Send and Sync
8///
9/// # Safety
10/// This is safe because:
11/// 1. Tasks are only accessed with proper synchronization (scheduler lock)
12/// 2. The scheduler ensures exclusive access during context switches
13/// 3. Task memory is managed by the kernel and won't be deallocated while
14/// referenced
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub struct TaskPtr(NonNull<Task>);
17
18impl TaskPtr {
19 /// Create a new TaskPtr from a NonNull<Task>
20 pub fn new(ptr: NonNull<Task>) -> Self {
21 Self(ptr)
22 }
23
24 /// Get the underlying NonNull<Task>
25 pub fn as_ptr(&self) -> NonNull<Task> {
26 self.0
27 }
28
29 /// Get a raw pointer to the task
30 pub fn as_raw(&self) -> *mut Task {
31 self.0.as_ptr()
32 }
33}
34
35// SAFETY: TaskPtr wraps a NonNull<Task> pointing to kernel-managed memory.
36// Tasks are only modified while holding the scheduler lock or per-CPU ready
37// queue lock, preventing data races. Sending a TaskPtr between threads is
38// safe because the underlying Task is protected by these locks.
39unsafe impl Send for TaskPtr {}
40// SAFETY: Shared references to TaskPtr only provide a NonNull<Task> which
41// itself requires unsafe to dereference. All actual Task access goes through
42// the scheduler lock or ready queue lock, ensuring synchronized access.
43unsafe impl Sync for TaskPtr {}
44
45impl From<NonNull<Task>> for TaskPtr {
46 fn from(ptr: NonNull<Task>) -> Self {
47 Self::new(ptr)
48 }
49}
50
51impl From<TaskPtr> for NonNull<Task> {
52 fn from(ptr: TaskPtr) -> Self {
53 ptr.0
54 }
55}