55//! C header: [`include/linux/sched.h`](../../../../include/linux/sched.h).
66
77use crate :: { bindings, types:: Opaque } ;
8- use core:: ptr;
8+ use core:: { marker:: PhantomData , ops:: Deref , ptr} ;
9+
10+ /// Returns the currently running task.
11+ #[ macro_export]
12+ macro_rules! current {
13+ ( ) => {
14+ // SAFETY: Deref + addr-of below create a temporary `TaskRef` that cannot outlive the
15+ // caller.
16+ unsafe { & * $crate:: task:: Task :: current( ) }
17+ } ;
18+ }
919
1020/// Wraps the kernel's `struct task_struct`.
1121///
@@ -15,6 +25,42 @@ use core::ptr;
1525///
1626/// Instances of this type are always ref-counted, that is, a call to `get_task_struct` ensures
1727/// 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+ /// ```
1864#[ repr( transparent) ]
1965pub struct Task ( pub ( crate ) Opaque < bindings:: task_struct > ) ;
2066
@@ -27,6 +73,40 @@ unsafe impl Sync for Task {}
2773type Pid = bindings:: pid_t ;
2874
2975impl Task {
76+ /// Returns a task reference for the currently executing task/thread.
77+ ///
78+ /// The recommended way to get the current task/thread is to use the
79+ /// [`current`](crate::current) macro because it is safe.
80+ ///
81+ /// # Safety
82+ ///
83+ /// Callers must ensure that the returned object doesn't outlive the current task/thread.
84+ pub unsafe fn current ( ) -> impl Deref < Target = Task > {
85+ struct TaskRef < ' a > {
86+ task : & ' a Task ,
87+ _not_send : PhantomData < * mut ( ) > ,
88+ }
89+
90+ impl Deref for TaskRef < ' _ > {
91+ type Target = Task ;
92+
93+ fn deref ( & self ) -> & Self :: Target {
94+ self . task
95+ }
96+ }
97+
98+ // SAFETY: Just an FFI call with no additional safety requirements.
99+ let ptr = unsafe { bindings:: get_current ( ) } ;
100+
101+ TaskRef {
102+ // SAFETY: If the current thread is still running, the current task is valid. Given
103+ // that `TaskRef` is not `Send`, we know it cannot be transferred to another thread
104+ // (where it could potentially outlive the caller).
105+ task : unsafe { & * ptr. cast ( ) } ,
106+ _not_send : PhantomData ,
107+ }
108+ }
109+
30110 /// Returns the group leader of the given task.
31111 pub fn group_leader ( & self ) -> & Task {
32112 // SAFETY: By the type invariant, we know that `self.0` is a valid task. Valid tasks always
0 commit comments