@@ -103,6 +103,7 @@ enum Tsm {
103
103
#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
104
104
enum ThreadRole {
105
105
Unknown ,
106
+ Boot ,
106
107
/// The backing thread for an interrupt context.
107
108
Interrupt ,
108
109
/// The backing thread for a task.
@@ -131,7 +132,7 @@ impl TaskState {
131
132
assert_eq ! ( ums:: current_thread( ) , Some ( expected_thread_id) ) ;
132
133
}
133
134
134
- unsafe fn exit_and_dispatch ( & self , state : & ' static State ) -> ! {
135
+ unsafe fn exit_and_dispatch < System : PortInstance > ( & self , state : & ' static State ) -> ! {
135
136
log:: trace!( "exit_and_dispatch({:p}) enter" , self ) ;
136
137
self . assert_current_thread ( ) ;
137
138
@@ -157,7 +158,7 @@ impl TaskState {
157
158
drop ( lock) ;
158
159
159
160
// Invoke the dispatcher
160
- unsafe { state. yield_cpu ( ) } ;
161
+ unsafe { state. yield_cpu :: < System > ( ) } ;
161
162
162
163
log:: trace!( "exit_and_dispatch({:p}) calling exit_thread" , self ) ;
163
164
unsafe { ums:: exit_thread ( ) } ;
@@ -188,6 +189,8 @@ impl State {
188
189
// kernel runs
189
190
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
190
191
let thread_id = lock. spawn ( |_| {
192
+ THREAD_ROLE . with ( |role| role. set ( ThreadRole :: Boot ) ) ;
193
+
191
194
// Safety: We are a port, so it's okay to call this
192
195
unsafe {
193
196
<System as PortToKernel >:: boot ( ) ;
@@ -212,7 +215,8 @@ impl State {
212
215
System :: TaskReadyQueue : std:: borrow:: BorrowMut < [ StaticListHead < TaskCb < System > > ] > ,
213
216
{
214
217
log:: trace!( "dispatch_first_task" ) ;
215
- assert ! ( self . is_cpu_lock_active( ) ) ;
218
+ assert_eq ! ( expect_worker_thread:: <System >( ) , ThreadRole :: Boot ) ;
219
+ assert ! ( self . is_cpu_lock_active:: <System >( ) ) ;
216
220
217
221
// Create a UMS worker thread for the dispatcher
218
222
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
@@ -255,9 +259,11 @@ impl State {
255
259
// FIXME: Work-around for <https://github.com/rust-lang/rust/issues/43475>
256
260
System :: TaskReadyQueue : std:: borrow:: BorrowMut < [ StaticListHead < TaskCb < System > > ] > ,
257
261
{
258
- unsafe { self . enter_cpu_lock ( ) } ;
262
+ assert_eq ! ( expect_worker_thread:: <System >( ) , ThreadRole :: Interrupt ) ;
263
+
264
+ unsafe { self . enter_cpu_lock :: < System > ( ) } ;
259
265
unsafe { System :: choose_running_task ( ) } ;
260
- unsafe { self . leave_cpu_lock ( ) } ;
266
+ unsafe { self . leave_cpu_lock :: < System > ( ) } ;
261
267
262
268
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
263
269
@@ -271,10 +277,10 @@ impl State {
271
277
Tsm :: Dormant => {
272
278
// Spawn a UMS worker thread for this task
273
279
let thread = lock. spawn ( move |_| {
274
- assert ! ( !self . is_cpu_lock_active( ) ) ;
275
- log:: debug!( "task {:p} is now running" , task) ;
276
-
277
280
THREAD_ROLE . with ( |role| role. set ( ThreadRole :: Task ) ) ;
281
+ assert ! ( !self . is_cpu_lock_active:: <System >( ) ) ;
282
+
283
+ log:: debug!( "task {:p} is now running" , task) ;
278
284
279
285
// Safety: The port can call this
280
286
unsafe {
@@ -303,35 +309,40 @@ impl State {
303
309
} ;
304
310
}
305
311
306
- pub unsafe fn yield_cpu ( & ' static self ) {
312
+ pub unsafe fn yield_cpu < System : PortInstance > ( & ' static self ) {
307
313
log:: trace!( "yield_cpu" ) ;
308
- assert ! ( !self . is_cpu_lock_active( ) ) ;
314
+ expect_worker_thread :: < System > ( ) ;
315
+ assert ! ( !self . is_cpu_lock_active:: <System >( ) ) ;
309
316
310
- self . pend_interrupt_line ( INTERRUPT_LINE_DISPATCH ) . unwrap ( ) ;
317
+ self . pend_interrupt_line :: < System > ( INTERRUPT_LINE_DISPATCH )
318
+ . unwrap ( ) ;
311
319
}
312
320
313
321
pub unsafe fn exit_and_dispatch < System : PortInstance > (
314
322
& ' static self ,
315
323
task : & ' static TaskCb < System > ,
316
324
) -> ! {
317
325
log:: trace!( "exit_and_dispatch" ) ;
318
- assert ! ( self . is_cpu_lock_active( ) ) ;
326
+ assert_eq ! ( expect_worker_thread:: <System >( ) , ThreadRole :: Task ) ;
327
+ assert ! ( self . is_cpu_lock_active:: <System >( ) ) ;
319
328
320
329
unsafe {
321
- task. port_task_state . exit_and_dispatch ( self ) ;
330
+ task. port_task_state . exit_and_dispatch :: < System > ( self ) ;
322
331
}
323
332
}
324
333
325
- pub unsafe fn enter_cpu_lock ( & self ) {
334
+ pub unsafe fn enter_cpu_lock < System : PortInstance > ( & self ) {
326
335
log:: trace!( "enter_cpu_lock" ) ;
336
+ expect_worker_thread :: < System > ( ) ;
327
337
328
338
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
329
339
assert ! ( !lock. scheduler( ) . cpu_lock) ;
330
340
lock. scheduler ( ) . cpu_lock = true ;
331
341
}
332
342
333
- pub unsafe fn leave_cpu_lock ( & ' static self ) {
343
+ pub unsafe fn leave_cpu_lock < System : PortInstance > ( & ' static self ) {
334
344
log:: trace!( "leave_cpu_lock" ) ;
345
+ expect_worker_thread :: < System > ( ) ;
335
346
336
347
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
337
348
assert ! ( lock. scheduler( ) . cpu_lock) ;
@@ -348,6 +359,8 @@ impl State {
348
359
task : & ' static TaskCb < System > ,
349
360
) {
350
361
log:: trace!( "initialize_task_state {:p}" , task) ;
362
+ expect_worker_thread :: < System > ( ) ;
363
+ assert ! ( self . is_cpu_lock_active:: <System >( ) ) ;
351
364
352
365
let pts = & task. port_task_state ;
353
366
let mut tsm = pts. tsm . lock ( ) ;
@@ -362,26 +375,34 @@ impl State {
362
375
}
363
376
}
364
377
365
- pub fn is_cpu_lock_active ( & self ) -> bool {
378
+ pub fn is_cpu_lock_active < System : PortInstance > ( & self ) -> bool {
379
+ expect_worker_thread :: < System > ( ) ;
380
+
366
381
( self . thread_group . get ( ) . unwrap ( ) . lock ( ) )
367
382
. scheduler ( )
368
383
. cpu_lock
369
384
}
370
385
371
- pub fn is_interrupt_context ( & self ) -> bool {
386
+ pub fn is_interrupt_context < System : PortInstance > ( & self ) -> bool {
387
+ expect_worker_thread :: < System > ( ) ;
388
+
372
389
THREAD_ROLE . with ( |role| match role. get ( ) {
373
390
ThreadRole :: Interrupt => true ,
374
391
ThreadRole :: Task => false ,
375
392
_ => panic ! ( "`is_interrupt_context` was called from an unknown thread" ) ,
376
393
} )
377
394
}
378
395
379
- pub fn set_interrupt_line_priority < System : Kernel > (
396
+ pub fn set_interrupt_line_priority < System : PortInstance > (
380
397
& ' static self ,
381
398
num : InterruptNum ,
382
399
priority : InterruptPriority ,
383
400
) -> Result < ( ) , SetInterruptLinePriorityError > {
384
401
log:: trace!( "set_interrupt_line_priority{:?}" , ( num, priority) ) ;
402
+ assert ! ( matches!(
403
+ expect_worker_thread:: <System >( ) ,
404
+ ThreadRole :: Boot | ThreadRole :: Task
405
+ ) ) ;
385
406
386
407
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
387
408
lock. scheduler ( )
@@ -396,11 +417,12 @@ impl State {
396
417
Ok ( ( ) )
397
418
}
398
419
399
- pub fn enable_interrupt_line < System : Kernel > (
420
+ pub fn enable_interrupt_line < System : PortInstance > (
400
421
& ' static self ,
401
422
num : InterruptNum ,
402
423
) -> Result < ( ) , EnableInterruptLineError > {
403
424
log:: trace!( "enable_interrupt_line{:?}" , ( num, ) ) ;
425
+ expect_worker_thread :: < System > ( ) ;
404
426
405
427
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
406
428
lock. scheduler ( )
@@ -415,23 +437,25 @@ impl State {
415
437
Ok ( ( ) )
416
438
}
417
439
418
- pub fn disable_interrupt_line (
440
+ pub fn disable_interrupt_line < System : PortInstance > (
419
441
& self ,
420
442
num : InterruptNum ,
421
443
) -> Result < ( ) , EnableInterruptLineError > {
422
444
log:: trace!( "disable_interrupt_line{:?}" , ( num, ) ) ;
445
+ expect_worker_thread :: < System > ( ) ;
423
446
424
447
( self . thread_group . get ( ) . unwrap ( ) . lock ( ) )
425
448
. scheduler ( )
426
449
. update_line ( num, |line| line. enable = false )
427
450
. map_err ( |sched:: BadIntLineError | EnableInterruptLineError :: BadParam )
428
451
}
429
452
430
- pub fn pend_interrupt_line (
453
+ pub fn pend_interrupt_line < System : PortInstance > (
431
454
& ' static self ,
432
455
num : InterruptNum ,
433
456
) -> Result < ( ) , PendInterruptLineError > {
434
457
log:: trace!( "pend_interrupt_line{:?}" , ( num, ) ) ;
458
+ expect_worker_thread :: < System > ( ) ;
435
459
436
460
let mut lock = self . thread_group . get ( ) . unwrap ( ) . lock ( ) ;
437
461
lock. scheduler ( )
@@ -446,19 +470,25 @@ impl State {
446
470
Ok ( ( ) )
447
471
}
448
472
449
- pub fn clear_interrupt_line ( & self , num : InterruptNum ) -> Result < ( ) , ClearInterruptLineError > {
473
+ pub fn clear_interrupt_line < System : PortInstance > (
474
+ & self ,
475
+ num : InterruptNum ,
476
+ ) -> Result < ( ) , ClearInterruptLineError > {
450
477
log:: trace!( "clear_interrupt_line{:?}" , ( num, ) ) ;
478
+ expect_worker_thread :: < System > ( ) ;
451
479
452
480
( self . thread_group . get ( ) . unwrap ( ) . lock ( ) )
453
481
. scheduler ( )
454
482
. update_line ( num, |line| line. pended = false )
455
483
. map_err ( |sched:: BadIntLineError | ClearInterruptLineError :: BadParam )
456
484
}
457
485
458
- pub fn is_interrupt_line_pending (
486
+ pub fn is_interrupt_line_pending < System : PortInstance > (
459
487
& self ,
460
488
num : InterruptNum ,
461
489
) -> Result < bool , QueryInterruptLineError > {
490
+ expect_worker_thread :: < System > ( ) ;
491
+
462
492
( self . thread_group . get ( ) . unwrap ( ) . lock ( ) )
463
493
. scheduler ( )
464
494
. is_line_pended ( num)
@@ -469,7 +499,9 @@ impl State {
469
499
pub const MAX_TICK_COUNT : UTicks = UTicks :: MAX ;
470
500
pub const MAX_TIMEOUT : UTicks = UTicks :: MAX / 2 ;
471
501
472
- pub fn tick_count ( & self ) -> UTicks {
502
+ pub fn tick_count < System : PortInstance > ( & self ) -> UTicks {
503
+ expect_worker_thread :: < System > ( ) ;
504
+
473
505
let origin = if let Some ( x) = self . origin . load ( Ordering :: Acquire ) {
474
506
x
475
507
} else {
@@ -516,15 +548,26 @@ impl State {
516
548
( micros as UTicks ) . wrapping_add ( get_random_number ( ) )
517
549
}
518
550
519
- pub fn pend_tick_after ( & self , tick_count_delta : UTicks ) {
551
+ pub fn pend_tick_after < System : PortInstance > ( & self , tick_count_delta : UTicks ) {
552
+ expect_worker_thread :: < System > ( ) ;
520
553
// TODO
521
554
}
522
555
523
- pub fn pend_tick ( & self ) {
556
+ pub fn pend_tick < System : PortInstance > ( & self ) {
557
+ expect_worker_thread :: < System > ( ) ;
524
558
// TODO
525
559
}
526
560
}
527
561
562
+ /// Assert that the current thread is a worker thread of `System`.
563
+ fn expect_worker_thread < System : PortInstance > ( ) -> ThreadRole {
564
+ // TODO: Check that the current worker thread belongs to
565
+ // `System::port_state().thread_group`
566
+ let role = THREAD_ROLE . with ( |r| r. get ( ) ) ;
567
+ assert_ne ! ( role, ThreadRole :: Unknown ) ;
568
+ role
569
+ }
570
+
528
571
/// Initiate graceful shutdown.
529
572
///
530
573
/// The shutdown completes when all threads complete execution. Usually, the
@@ -551,7 +594,11 @@ pub fn pend_interrupt_line<System: PortInstance>(
551
594
) -> Result < ( ) , PendInterruptLineError > {
552
595
log:: trace!( "external-pend_interrupt_line{:?}" , ( num, ) ) ;
553
596
554
- assert_eq ! ( THREAD_ROLE . with( |r| r. get( ) ) , ThreadRole :: Unknown ) ;
597
+ assert_eq ! (
598
+ THREAD_ROLE . with( |r| r. get( ) ) ,
599
+ ThreadRole :: Unknown ,
600
+ "this method cannot be called from a port-managed thread"
601
+ ) ;
555
602
556
603
let state = System :: port_state ( ) ;
557
604
let mut lock = state. thread_group . get ( ) . unwrap ( ) . lock ( ) ;
@@ -600,31 +647,31 @@ macro_rules! use_port {
600
647
}
601
648
602
649
unsafe fn yield_cpu( ) {
603
- PORT_STATE . yield_cpu( )
650
+ PORT_STATE . yield_cpu:: < Self > ( )
604
651
}
605
652
606
653
unsafe fn exit_and_dispatch( task: & ' static TaskCb <Self >) -> ! {
607
- PORT_STATE . exit_and_dispatch( task) ;
654
+ PORT_STATE . exit_and_dispatch:: < Self > ( task) ;
608
655
}
609
656
610
657
unsafe fn enter_cpu_lock( ) {
611
- PORT_STATE . enter_cpu_lock( )
658
+ PORT_STATE . enter_cpu_lock:: < Self > ( )
612
659
}
613
660
614
661
unsafe fn leave_cpu_lock( ) {
615
- PORT_STATE . leave_cpu_lock( )
662
+ PORT_STATE . leave_cpu_lock:: < Self > ( )
616
663
}
617
664
618
665
unsafe fn initialize_task_state( task: & ' static TaskCb <Self >) {
619
- PORT_STATE . initialize_task_state( task)
666
+ PORT_STATE . initialize_task_state:: < Self > ( task)
620
667
}
621
668
622
669
fn is_cpu_lock_active( ) -> bool {
623
- PORT_STATE . is_cpu_lock_active( )
670
+ PORT_STATE . is_cpu_lock_active:: < Self > ( )
624
671
}
625
672
626
673
fn is_interrupt_context( ) -> bool {
627
- PORT_STATE . is_interrupt_context( )
674
+ PORT_STATE . is_interrupt_context:: < Self > ( )
628
675
}
629
676
}
630
677
@@ -644,21 +691,21 @@ macro_rules! use_port {
644
691
}
645
692
646
693
unsafe fn disable_interrupt_line( line: InterruptNum ) -> Result <( ) , EnableInterruptLineError > {
647
- PORT_STATE . disable_interrupt_line( line)
694
+ PORT_STATE . disable_interrupt_line:: < Self > ( line)
648
695
}
649
696
650
697
unsafe fn pend_interrupt_line( line: InterruptNum ) -> Result <( ) , PendInterruptLineError > {
651
- PORT_STATE . pend_interrupt_line( line)
698
+ PORT_STATE . pend_interrupt_line:: < Self > ( line)
652
699
}
653
700
654
701
unsafe fn clear_interrupt_line( line: InterruptNum ) -> Result <( ) , ClearInterruptLineError > {
655
- PORT_STATE . clear_interrupt_line( line)
702
+ PORT_STATE . clear_interrupt_line:: < Self > ( line)
656
703
}
657
704
658
705
unsafe fn is_interrupt_line_pending(
659
706
line: InterruptNum ,
660
707
) -> Result <bool , QueryInterruptLineError > {
661
- PORT_STATE . is_interrupt_line_pending( line)
708
+ PORT_STATE . is_interrupt_line_pending:: < Self > ( line)
662
709
}
663
710
}
664
711
@@ -667,15 +714,15 @@ macro_rules! use_port {
667
714
const MAX_TIMEOUT : UTicks = State :: MAX_TIMEOUT ;
668
715
669
716
unsafe fn tick_count( ) -> UTicks {
670
- PORT_STATE . tick_count( )
717
+ PORT_STATE . tick_count:: < Self > ( )
671
718
}
672
719
673
720
unsafe fn pend_tick_after( tick_count_delta: UTicks ) {
674
- PORT_STATE . pend_tick_after( tick_count_delta)
721
+ PORT_STATE . pend_tick_after:: < Self > ( tick_count_delta)
675
722
}
676
723
677
724
unsafe fn pend_tick( ) {
678
- PORT_STATE . pend_tick( )
725
+ PORT_STATE . pend_tick:: < Self > ( )
679
726
}
680
727
}
681
728
}
0 commit comments