@@ -57,8 +57,11 @@ struct picoRTOS_task_sub {
57
57
#define L1_CACHE_ALIGN (x , a ) L1_CACHE_ALIGN_MASK((x), ((a) - 1))
58
58
#define L1_CACHE_ALIGN_MASK (x , mask ) (((x) + (mask)) & ~(mask))
59
59
60
+ #define F_RUNNING (1 << 0)
61
+ #define F_POSTPONED (1 << 1)
62
+
60
63
struct picoRTOS_core {
61
- bool is_running ;
64
+ int flags ;
62
65
picoRTOS_pid_t index ;
63
66
picoRTOS_tick_t tick ;
64
67
picoRTOS_pid_t pid_count ;
@@ -192,7 +195,7 @@ void picoRTOS_init(void)
192
195
picoRTOS .tick = (picoRTOS_tick_t )- 1 ; /* 1st tick will be 0 */
193
196
194
197
/* RTOS status */
195
- picoRTOS .is_running = false ;
198
+ picoRTOS .flags = 0 ;
196
199
}
197
200
198
201
/* Function: picoRTOS_task_init
@@ -395,7 +398,7 @@ void picoRTOS_start(void)
395
398
core_arrange_shared_priorities ();
396
399
397
400
arch_init ();
398
- picoRTOS .is_running = true ;
401
+ picoRTOS .flags |= F_RUNNING ;
399
402
arch_start_first_task (TASK_BY_PID (TASK_IDLE_PID ).sp );
400
403
}
401
404
@@ -404,7 +407,7 @@ void picoRTOS_start(void)
404
407
*/
405
408
void picoRTOS_suspend (void )
406
409
{
407
- picoRTOS_assert_fatal (picoRTOS .is_running , return );
410
+ picoRTOS_assert_fatal (( picoRTOS .flags & F_RUNNING ) != 0 , return );
408
411
arch_suspend ();
409
412
}
410
413
@@ -413,19 +416,17 @@ void picoRTOS_suspend(void)
413
416
*/
414
417
void picoRTOS_resume (void )
415
418
{
416
- picoRTOS_assert_fatal (picoRTOS .is_running , return );
419
+ picoRTOS_assert_fatal (( picoRTOS .flags & F_RUNNING ) != 0 , return );
417
420
arch_resume ();
418
421
}
419
422
420
- /* Function: picoRTOS_schedule
421
- * Puts the current task to sleep until next tick
423
+ /* Function: picoRTOS_postpone
424
+ * Puts the current task back in the scheduler's FIFO (don't wait for next tick)
422
425
*/
423
- void picoRTOS_schedule (void )
426
+ void picoRTOS_postpone (void )
424
427
{
425
- static const struct syscall_sleep delay = { (picoRTOS_tick_t )1 };
426
-
427
- picoRTOS_assert_fatal (picoRTOS .is_running , return );
428
- arch_syscall (SYSCALL_SLEEP , (struct syscall_sleep * )& delay );
428
+ picoRTOS_assert_fatal ((picoRTOS .flags & F_RUNNING ) != 0 , return );
429
+ arch_syscall (SYSCALL_SWITCH_CONTEXT , NULL );
429
430
}
430
431
431
432
/* Function: picoRTOS_sleep
@@ -437,7 +438,7 @@ void picoRTOS_schedule(void)
437
438
*/
438
439
void picoRTOS_sleep (picoRTOS_tick_t delay )
439
440
{
440
- picoRTOS_assert_fatal (picoRTOS .is_running , return );
441
+ picoRTOS_assert_fatal (( picoRTOS .flags & F_RUNNING ) != 0 , return );
441
442
arch_syscall (SYSCALL_SLEEP , (struct syscall_sleep * )& delay );
442
443
}
443
444
@@ -465,7 +466,7 @@ void picoRTOS_sleep(picoRTOS_tick_t delay)
465
466
void picoRTOS_sleep_until (picoRTOS_tick_t * ref , picoRTOS_tick_t period )
466
467
{
467
468
picoRTOS_assert_fatal (period > 0 , return );
468
- picoRTOS_assert_fatal (picoRTOS .is_running , return );
469
+ picoRTOS_assert_fatal (( picoRTOS .flags & F_RUNNING ) != 0 , return );
469
470
470
471
struct syscall_sleep_until sc = { * ref , period };
471
472
@@ -478,7 +479,7 @@ void picoRTOS_sleep_until(picoRTOS_tick_t *ref, picoRTOS_tick_t period)
478
479
*/
479
480
void picoRTOS_kill (void )
480
481
{
481
- picoRTOS_assert_fatal (picoRTOS .is_running , return );
482
+ picoRTOS_assert_fatal (( picoRTOS .flags & F_RUNNING ) != 0 , return );
482
483
arch_syscall (SYSCALL_KILL , NULL );
483
484
}
484
485
@@ -487,7 +488,7 @@ void picoRTOS_kill(void)
487
488
*/
488
489
picoRTOS_pid_t picoRTOS_self (void )
489
490
{
490
- picoRTOS_assert_fatal (picoRTOS .is_running , return (picoRTOS_pid_t )- 1 );
491
+ picoRTOS_assert_fatal (( picoRTOS .flags & F_RUNNING ) != 0 , return (picoRTOS_pid_t )- 1 );
491
492
return (picoRTOS_pid_t )picoRTOS .index ;
492
493
}
493
494
@@ -496,7 +497,7 @@ picoRTOS_pid_t picoRTOS_self(void)
496
497
*/
497
498
picoRTOS_tick_t picoRTOS_get_tick (void )
498
499
{
499
- picoRTOS_assert_fatal (picoRTOS .is_running , return (picoRTOS_tick_t )- 1 );
500
+ picoRTOS_assert_fatal (( picoRTOS .flags & F_RUNNING ) != 0 , return (picoRTOS_tick_t )- 1 );
500
501
return picoRTOS .tick ;
501
502
}
502
503
@@ -544,21 +545,35 @@ static void syscall_kill(struct picoRTOS_task_core *task)
544
545
static struct picoRTOS_task_core *
545
546
syscall_switch_context (struct picoRTOS_task_core * task )
546
547
{
548
+ int count = 2 ;
549
+
547
550
/* stats */
548
551
task_core_stat_finish (task );
549
552
550
- /* choose next task to run */
551
- do {
552
- picoRTOS .index ++ ;
553
- picoRTOS_assert_void_fatal (picoRTOS .index < (picoRTOS_pid_t )TASK_COUNT );
554
- /* ignore sleeping, empty tasks & out-of-round sub-tasks */
555
- } while (!task_core_is_available (& TASK_CURRENT ()));
556
-
557
- /* refresh current task pointer */
558
- task = & TASK_CURRENT ();
553
+ while (count -- != 0 ) {
554
+ /* choose next task to run */
555
+ do {
556
+ picoRTOS .index ++ ;
557
+ picoRTOS_assert_void_fatal (picoRTOS .index < (picoRTOS_pid_t )TASK_COUNT );
558
+ /* ignore sleeping, empty tasks & out-of-round sub-tasks */
559
+ } while (!task_core_is_available (& TASK_CURRENT ()));
560
+
561
+ /* refresh current task pointer */
562
+ task = & TASK_CURRENT ();
563
+
564
+ /* postponed tasks management */
565
+ if (picoRTOS .index == (picoRTOS_pid_t )TASK_IDLE_PID &&
566
+ (picoRTOS .flags & F_POSTPONED ) != 0 ) {
567
+ /* reset flags & index */
568
+ picoRTOS .flags &= ~F_POSTPONED ;
569
+ picoRTOS .index = (picoRTOS_pid_t )- 1 ;
570
+ }else
571
+ /* next task or idle */
572
+ break ;
573
+ }
559
574
560
- /* stats */
561
- task_core_stat_start (task );
575
+ picoRTOS_assert_void_fatal ( count != -1 ); /* check */
576
+ task_core_stat_start (task ); /* stats */
562
577
563
578
return task ;
564
579
}
@@ -592,6 +607,7 @@ picoRTOS_stack_t *picoRTOS_syscall(picoRTOS_stack_t *sp, syscall_t syscall, void
592
607
593
608
default :
594
609
/* SYSCALL_SWITCH_CONTEXT */
610
+ picoRTOS .flags |= F_POSTPONED ;
595
611
break ;
596
612
}
597
613
0 commit comments