| 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | //! Tasks (threads and processes). |
| 4 | //! |
| 5 | //! C header: [`include/linux/sched.h`](../../../../include/linux/sched.h). |
| 6 | |
| 7 | use crate::; |
| 8 | use ; |
| 9 | |
| 10 | /// Returns the currently running task. |
| 11 | |
| 12 | |
| 13 | => |
| 14 | // SAFETY: Deref + addr-of below create a temporary `TaskRef` that cannot outlive the |
| 15 | // caller. |
| 16 | unsafe |
| 17 | }; |
| 18 | |
| 19 | |
| 20 | /// Wraps the kernel's `struct task_struct`. |
| 21 | /// |
| 22 | /// # Invariants |
| 23 | /// |
| 24 | /// All instances are valid tasks created by the C portion of the kernel. |
| 25 | /// |
| 26 | /// Instances of this type are always ref-counted, that is, a call to `get_task_struct` ensures |
| 27 | /// that the allocation remains valid at least until the matching call to `put_task_struct`. |
| 28 | /// |
| 29 | /// # Examples |
| 30 | /// |
| 31 | /// The following is an example of getting the PID of the current thread with zero additional cost |
| 32 | /// when compared to the C version: |
| 33 | /// |
| 34 | /// ``` |
| 35 | /// let pid = current!().pid(); |
| 36 | /// ``` |
| 37 | /// |
| 38 | /// Getting the PID of the current process, also zero additional cost: |
| 39 | /// |
| 40 | /// ``` |
| 41 | /// let pid = current!().group_leader().pid(); |
| 42 | /// ``` |
| 43 | /// |
| 44 | /// Getting the current task and storing it in some struct. The reference count is automatically |
| 45 | /// incremented when creating `State` and decremented when it is dropped: |
| 46 | /// |
| 47 | /// ``` |
| 48 | /// use kernel::{task::Task, types::ARef}; |
| 49 | /// |
| 50 | /// struct State { |
| 51 | /// creator: ARef<Task>, |
| 52 | /// index: u32, |
| 53 | /// } |
| 54 | /// |
| 55 | /// impl State { |
| 56 | /// fn new() -> Self { |
| 57 | /// Self { |
| 58 | /// creator: current!().into(), |
| 59 | /// index: 0, |
| 60 | /// } |
| 61 | /// } |
| 62 | /// } |
| 63 | /// ``` |
| 64 | |
| 65 | ); |
| 66 | |
| 67 | // SAFETY: By design, the only way to access a `Task` is via the `current` function or via an |
| 68 | // `ARef<Task>` obtained through the `AlwaysRefCounted` impl. This means that the only situation in |
| 69 | // which a `Task` can be accessed mutably is when the refcount drops to zero and the destructor |
| 70 | // runs. It is safe for that to happen on any thread, so it is ok for this type to be `Send`. |
| 71 | unsafe |
| 72 | |
| 73 | // SAFETY: It's OK to access `Task` through shared references from other threads because we're |
| 74 | // either accessing properties that don't change (e.g., `pid`, `group_leader`) or that are properly |
| 75 | // synchronised by C code (e.g., `signal_pending`). |
| 76 | unsafe |
| 77 | |
| 78 | /// The type of process identifiers (PIDs). |
| 79 | type Pid = pid_t; |
| 80 | |
| 81 | |
| 82 | /// Returns a task reference for the currently executing task/thread. |
| 83 | /// |
| 84 | /// The recommended way to get the current task/thread is to use the |
| 85 | /// [`current`] macro because it is safe. |
| 86 | /// |
| 87 | /// # Safety |
| 88 | /// |
| 89 | /// Callers must ensure that the returned object doesn't outlive the current task/thread. |
| 90 | pub unsafe |
| 91 | |
| 92 | task: &'a Task, |
| 93 | _not_send: mut ()>, |
| 94 | |
| 95 | |
| 96 | |
| 97 | type Target = Task; |
| 98 | |
| 99 | |
| 100 | self.task |
| 101 | |
| 102 | |
| 103 | |
| 104 | // SAFETY: Just an FFI call with no additional safety requirements. |
| 105 | let ptr = unsafe ; |
| 106 | |
| 107 | TaskRef |
| 108 | // SAFETY: If the current thread is still running, the current task is valid. Given |
| 109 | // that `TaskRef` is not `Send`, we know it cannot be transferred to another thread |
| 110 | // (where it could potentially outlive the caller). |
| 111 | task: unsafe , |
| 112 | _not_send: PhantomData, |
| 113 | |
| 114 | |
| 115 | |
| 116 | /// Returns the group leader of the given task. |
| 117 | |
| 118 | // SAFETY: By the type invariant, we know that `self.0` is a valid task. Valid tasks always |
| 119 | // have a valid group_leader. |
| 120 | let ptr = unsafe ; |
| 121 | |
| 122 | // SAFETY: The lifetime of the returned task reference is tied to the lifetime of `self`, |
| 123 | // and given that a task has a reference to its group leader, we know it must be valid for |
| 124 | // the lifetime of the returned task reference. |
| 125 | unsafe |
| 126 | |
| 127 | |
| 128 | /// Returns the PID of the given task. |
| 129 | |
| 130 | // SAFETY: By the type invariant, we know that `self.0` is a valid task. Valid tasks always |
| 131 | // have a valid pid. |
| 132 | unsafe |
| 133 | |
| 134 | |
| 135 | /// Determines whether the given task has pending signals. |
| 136 | |
| 137 | // SAFETY: By the type invariant, we know that `self.0` is valid. |
| 138 | unsafe |
| 139 | |
| 140 | |
| 141 | /// Wakes up the task. |
| 142 | |
| 143 | // SAFETY: By the type invariant, we know that `self.0.get()` is non-null and valid. |
| 144 | // And `wake_up_process` is safe to be called for any valid task, even if the task is |
| 145 | // running. |
| 146 | unsafe ; |
| 147 | |
| 148 | |
| 149 | |
| 150 | // SAFETY: The type invariants guarantee that `Task` is always ref-counted. |
| 151 | unsafe |
| 152 | |
| 153 | // SAFETY: The existence of a shared reference means that the refcount is nonzero. |
| 154 | unsafe ; |
| 155 | |
| 156 | |
| 157 | unsafe |
| 158 | // SAFETY: The safety requirements guarantee that the refcount is nonzero. |
| 159 | unsafe |
| 160 | |
| 161 |