@@ -174,12 +174,36 @@ impl State {
174
174
}
175
175
}
176
176
177
- pub fn init < System : Kernel > ( & self ) {
177
+ /// Initialize the user-mode scheduling system and boot the kernel.
178
+ pub fn port_boot < System : Kernel > ( & self ) -> ! {
178
179
// Create a UMS thread group.
179
180
let ( thread_group, join_handle) = ums:: ThreadGroup :: new ( sched:: SchedState :: new :: < System > ( ) ) ;
180
181
181
182
self . thread_group . set ( thread_group) . ok ( ) . unwrap ( ) ;
182
183
* self . join_handle . lock ( ) = Some ( join_handle) ;
184
+
185
+ // Create the initial UMS worker thread, where the boot phase of the
186
+ // kernel runs
187
+ let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
188
+ let thread_id = lock. spawn ( |_| {
189
+ // Safety: We are a port, so it's okay to call this
190
+ unsafe {
191
+ <System as PortToKernel >:: boot ( ) ;
192
+ }
193
+ } ) ;
194
+ log:: trace!( "startup thread = {:?}" , thread_id) ;
195
+ lock. scheduler ( ) . task_thread = Some ( thread_id) ;
196
+ lock. scheduler ( ) . recycle_thread ( thread_id) ;
197
+ lock. preempt ( ) ;
198
+ drop ( lock) ;
199
+
200
+ // Wait until the thread group shuts down
201
+ let join_handle = self . join_handle . lock ( ) . take ( ) . unwrap ( ) ;
202
+ if let Err ( e) = join_handle. join ( ) {
203
+ std:: panic:: resume_unwind ( e) ;
204
+ }
205
+
206
+ panic ! ( "the system has been shut down" )
183
207
}
184
208
185
209
pub unsafe fn dispatch_first_task < System : PortInstance > ( & ' static self ) -> !
@@ -211,17 +235,11 @@ impl State {
211
235
self . thread_group. get( ) . unwrap( ) ,
212
236
& mut lock
213
237
) ) ;
214
- lock. preempt ( ) ;
215
238
drop ( lock) ;
216
239
217
- // Wait until the thread group shuts down
218
- let join_handle = self . join_handle . lock ( ) . take ( ) . unwrap ( ) ;
219
- if let Err ( e) = join_handle. join ( ) {
220
- std:: panic:: resume_unwind ( e) ;
221
- }
222
-
223
- // TODO: Expose a function to shut down the system
224
- panic ! ( "the system has been shut down" ) ;
240
+ // Safety: The requirement of `dispatch_first_task` explicitly allows
241
+ // discarding the context.
242
+ unsafe { ums:: exit_thread ( ) } ;
225
243
}
226
244
227
245
extern "C" fn dispatch_handler < System : PortInstance > ( )
@@ -637,12 +655,7 @@ macro_rules! use_port {
637
655
638
656
$crate:: env_logger:: init( ) ;
639
657
640
- port_std_impl:: PORT_STATE . init:: <$sys>( ) ;
641
-
642
- // Safety: We are a port, so it's okay to call these
643
- unsafe {
644
- <$sys as PortToKernel >:: boot( ) ;
645
- }
658
+ port_std_impl:: PORT_STATE . port_boot:: <$sys>( ) ;
646
659
}
647
660
} ;
648
661
}
0 commit comments