⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

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}