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