@@ -106,55 +106,74 @@ pub struct Task<S, F: Future, STO> {
106
106
storage : PhantomData < STO > ,
107
107
}
108
108
109
- /// The task's header.
110
- ///
111
- /// This contains the *untyped* components of the task which are identical
112
- /// regardless of the task's future, output, and scheduler types: the
113
- /// [vtable], [state cell], and [run queue links].
114
- ///
115
- /// The header is the data at which a [`TaskRef`] points, and will likely be
116
- /// prefetched when dereferencing a [`TaskRef`] pointer.[^1] Therefore, the
117
- /// header should contain the task's most frequently accessed data, and should
118
- /// ideally fit within a CPU cache line.
119
- ///
120
- /// # Safety
121
- ///
122
- /// The [run queue links] *must* be the first field in this type, in order for
123
- /// the [`Linked::links` implementation] for this type to be sound. Therefore,
124
- /// the `#[repr(C)]` attribute on this struct is load-bearing.
125
- ///
126
- /// [vtable]: Vtable
127
- /// [state cell]: StateCell
128
- /// [run queue links]: cordyceps::mpsc_queue::Links
129
- /// [`Linked::links` implementation]: #method.links
130
- ///
131
- /// [^1]: On CPU architectures which support spatial prefetch, at least...
132
- #[ repr( C ) ]
133
- #[ derive( Debug ) ]
134
- pub struct Header {
135
- /// The task's links in the intrusive run queue.
109
+ pub ( crate ) mod header {
110
+ use super :: * ;
111
+ /// The task's header.
112
+ ///
113
+ /// This contains the *untyped* components of the task which are identical
114
+ /// regardless of the task's future, output, and scheduler types: the
115
+ /// [vtable], [state cell], and [run queue links].
116
+ ///
117
+ /// The header is the data at which a [`TaskRef`] points, and will likely be
118
+ /// prefetched when dereferencing a [`TaskRef`] pointer.[^1] Therefore, the
119
+ /// header should contain the task's most frequently accessed data, and should
120
+ /// ideally fit within a CPU cache line.
121
+ ///
122
+ /// # /!\ EXTREMELY SERIOUS WARNING /!\
123
+ ///
124
+ /// This is NOT a public API type and is *not* part of this crate's stable
125
+ /// interface. It must be made `pub` as a workaround for a [compiler
126
+ /// error][97708] where functions in the stub task vtable are improperly culled
127
+ /// by the compiler if they are not `pub`, which requires that the `Header` type
128
+ /// must be `pub` (as it's part of the type signature of one of those
129
+ /// functions).
130
+ ///
131
+ /// User code should NEVER interact with this type directly. Fortunately,
132
+ /// there's no way for you to construct it... :)
136
133
///
137
134
/// # Safety
138
135
///
139
- /// This MUST be the first field in this struct.
140
- run_queue : mpsc_queue:: Links < Header > ,
141
-
142
- /// The task's state, which can be atomically updated.
143
- state : StateCell ,
144
-
145
- /// The task vtable for this task.
136
+ /// The [run queue links] *must* be the first field in this type, in order for
137
+ /// the [`Linked::links` implementation] for this type to be sound. Therefore,
138
+ /// the `#[repr(C)]` attribute on this struct is load-bearing.
146
139
///
147
- /// Note that this is different from the [waker vtable], which contains
148
- /// pointers to the waker methods (and depends primarily on the task's
149
- /// scheduler type). The task vtable instead contains methods for
150
- /// interacting with the task's future, such as polling it and reading the
151
- /// task's output. These depend primarily on the type of the future rather
152
- /// than the scheduler.
140
+ /// [vtable]: Vtable
141
+ /// [state cell]: StateCell
142
+ /// [run queue links]: cordyceps::mpsc_queue::Links
143
+ /// [`Linked::links` implementation]: #method.links
144
+ /// [97708]: https://github.com/rust-lang/rust/issues/97708
153
145
///
154
- /// [waker vtable]: core::task::RawWakerVTable
155
- vtable : & ' static Vtable ,
146
+ /// [^1]: On CPU architectures which support spatial prefetch, at least...
147
+ #[ repr( C ) ]
148
+ #[ derive( Debug ) ]
149
+ pub struct Header {
150
+ /// The task's links in the intrusive run queue.
151
+ ///
152
+ /// # Safety
153
+ ///
154
+ /// This MUST be the first field in this struct.
155
+ pub ( super ) run_queue : mpsc_queue:: Links < Header > ,
156
+
157
+ /// The task's state, which can be atomically updated.
158
+ pub ( super ) state : StateCell ,
159
+
160
+ /// The task vtable for this task.
161
+ ///
162
+ /// Note that this is different from the [waker vtable], which contains
163
+ /// pointers to the waker methods (and depends primarily on the task's
164
+ /// scheduler type). The task vtable instead contains methods for
165
+ /// interacting with the task's future, such as polling it and reading the
166
+ /// task's output. These depend primarily on the type of the future rather
167
+ /// than the scheduler.
168
+ ///
169
+ /// [waker vtable]: core::task::RawWakerVTable
170
+ pub ( super ) vtable : & ' static Vtable ,
171
+ }
156
172
}
157
173
174
+ #[ doc( inline) ]
175
+ pub ( crate ) use self :: header:: Header ;
176
+
158
177
enum Cell < F : Future > {
159
178
Future ( F ) ,
160
179
Finished ( F :: Output ) ,
@@ -523,26 +542,45 @@ feature! {
523
542
feature ! {
524
543
#![ not( loom) ]
525
544
526
- mod nop {
527
- use super :: * ;
528
- pub unsafe fn nop( _ptr: TaskRef ) -> Poll <( ) > {
529
- #[ cfg( debug_assertions) ]
530
- unreachable!( "stub task ({_ptr:?}) should never be polled!" ) ;
531
- #[ cfg( not( debug_assertions) ) ]
532
- Poll :: Pending
533
- }
534
-
535
-
536
- pub unsafe fn nop_deallocate( ptr: NonNull <Header >) {
537
- unreachable!( "stub task ({ptr:p}) should never be deallocated!" ) ;
538
- }
539
-
545
+ /// # /!\ EXTREMELY SERIOUS WARNING /!\
546
+ ///
547
+ /// This is NOT a public API and is *not* part of this crate's stable
548
+ /// interface. It must be made `pub` as a workaround for a [compiler
549
+ /// error][97708] where functions in the stub task vtable are improperly
550
+ /// culled as dead code by the compiler if they are not `pub`.
551
+ ///
552
+ /// User code should NEVER call this function directly. If you *do* call
553
+ /// it...please note that it doesn't do anything interesting.
554
+ ///
555
+ /// [97708]: https://github.com/rust-lang/rust/issues/97708
556
+ #[ doc( hidden) ]
557
+ pub unsafe fn nop( _ptr: TaskRef ) -> Poll <( ) > {
558
+ #[ cfg( debug_assertions) ]
559
+ unreachable!( "stub task ({_ptr:?}) should never be polled!" ) ;
560
+ #[ cfg( not( debug_assertions) ) ]
561
+ Poll :: Pending
562
+ }
563
+
564
+ /// # /!\ EXTREMELY SERIOUS WARNING /!\
565
+ ///
566
+ /// This is NOT a public API and is *not* part of this crate's stable
567
+ /// interface. It must be made `pub` as a workaround for a [compiler
568
+ /// error][97708] where functions in the stub task vtable are improperly
569
+ /// culled as dead code by the compiler if they are not `pub`.
570
+ ///
571
+ /// User code should NEVER call this function directly. If you *do* call
572
+ /// it...please note that it will always panic.
573
+ ///
574
+ /// [97708]: https://github.com/rust-lang/rust/issues/97708
575
+ #[ doc( hidden) ]
576
+ pub unsafe fn nop_deallocate( ptr: NonNull <Header >) {
577
+ unreachable!( "stub task ({ptr:p}) should never be deallocated!" ) ;
540
578
}
541
579
542
580
impl Vtable {
543
581
const STUB : Vtable = Vtable {
544
- poll: nop:: nop ,
545
- deallocate: nop :: nop_deallocate,
582
+ poll: nop,
583
+ deallocate: nop_deallocate,
546
584
} ;
547
585
}
548
586
0 commit comments