mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-13 15:15:08 -05:00
Verified runtime assertion that running task is either scheduled or yielding.
This commit is contained in:
parent
61bffc4617
commit
00bb9d4a17
2 changed files with 59 additions and 5 deletions
22
tasks.c
22
tasks.c
|
|
@ -1058,7 +1058,8 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
|||
&*&
|
||||
// Write permission for task scheduled on this core
|
||||
[1/2]sharedSeg_TCB_p(gCurrentTCB, ?gCurrentTCB_state) &*&
|
||||
gCurrentTCB_state != taskTASK_NOT_RUNNING &*&
|
||||
// gCurrentTCB_state != taskTASK_NOT_RUNNING &*&
|
||||
(gCurrentTCB_state == coreID_f() || gCurrentTCB_state == taskTASK_YIELDING) &*&
|
||||
nth(index_of(gCurrentTCB, gTasks), gStates) == gCurrentTCB_state
|
||||
&*&
|
||||
// TODO:
|
||||
|
|
@ -1221,7 +1222,6 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
|||
}
|
||||
else if( pxTCB == pxCurrentTCBs[ xCoreID ] )
|
||||
{
|
||||
//@ assume(false);
|
||||
configASSERT( ( pxTCB->xTaskRunState == xCoreID ) || ( pxTCB->xTaskRunState == taskTASK_YIELDING ) );
|
||||
#if ( configNUM_CORES > 1 )
|
||||
#if ( configUSE_CORE_AFFINITY == 1 )
|
||||
|
|
@ -1229,13 +1229,27 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
|||
#endif
|
||||
#endif
|
||||
{
|
||||
//@ assert( pxTCB->xTaskRunState != taskTASK_NOT_RUNNING );
|
||||
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) );
|
||||
//@ assert( nth(index_of(pxTCB, gTasks), gStates) != taskTASK_NOT_RUNNING);
|
||||
|
||||
/* The task is already running on this core, mark it as scheduled */
|
||||
pxTCB->xTaskRunState = ( TaskRunning_t ) xCoreID;
|
||||
xTaskScheduled = pdTRUE;
|
||||
|
||||
/*@ list<TaskRunning_t> gEquivStates
|
||||
= update(index_of(pxTCB, gTasks), xCoreID, gStates);
|
||||
@*/
|
||||
//@ open exists_in_taskISRLockInv_p(gTasks, gStates);
|
||||
/*@ scheduleRunning_in_foreach_readOnly_sharedSeg_TCB_IF_not_running
|
||||
(pxTCB, gTasks, gStates, gEquivStates, xCoreID);
|
||||
@*/
|
||||
//@ close exists_in_taskISRLockInv_p(gTasks, gEquivStates);
|
||||
}
|
||||
}
|
||||
/*@
|
||||
if( !gPxTCB_not_running ) { // else branch of swapping if-statement above
|
||||
if( !gPxTCB_not_running && pxTCB != gCurrentTCB ) {
|
||||
assert( exists_in_taskISRLockInv_p(gTasks, gStates) );
|
||||
// Put read permission for `pxTCB` back
|
||||
close [1/2]sharedSeg_TCB_p(pxTCB, _);
|
||||
close readOnly_sharedSeg_TCB_p(gTasks, gStates)(pxTCB);
|
||||
|
|
@ -1256,7 +1270,7 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
|||
break;
|
||||
}
|
||||
|
||||
//@ assert( exists_in_taskISRLockInv_p(gTasks, ?gStatesEnd) );
|
||||
//@ assert( exists_in_taskISRLockInv_p(gTasks, ?gStatesEnd) );
|
||||
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStatesEnd)) );
|
||||
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStatesEnd)) );
|
||||
} while( pxTaskItem != pxLastTaskItem );
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ predicate taskISRLockInv_p() =
|
|||
// (RP-Current) Read permission for task currently scheduled on this core
|
||||
// (RP-All) + (RP-Current) => Write permission for scheduled task
|
||||
[1/2]sharedSeg_TCB_p(gCurrentTCB, ?gCurrentTCB_state) &*&
|
||||
gCurrentTCB_state != taskTASK_NOT_RUNNING &*&
|
||||
// gCurrentTCB_state != taskTASK_NOT_RUNNING &*&
|
||||
(gCurrentTCB_state == coreID_f() || gCurrentTCB_state == taskTASK_YIELDING) &*&
|
||||
nth(index_of(gCurrentTCB, gTasks), gStates) == gCurrentTCB_state
|
||||
&*&
|
||||
// (RP-Unsched) Read permissions for unscheduled tasks
|
||||
|
|
@ -397,6 +398,45 @@ ensures
|
|||
close readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)(startedTask);
|
||||
foreach_unremove(startedTask, tasks);
|
||||
}
|
||||
|
||||
lemma void scheduleRunning_in_foreach_readOnly_sharedSeg_TCB_IF_not_running
|
||||
(TCB_t* runningTask, list<void*> tasks,
|
||||
list<TaskRunning_t> states, list<TaskRunning_t> updatedStates,
|
||||
int coreID)
|
||||
requires
|
||||
distinct(tasks) == true &*&
|
||||
length(tasks) == length(states) &*&
|
||||
mem(runningTask, tasks) == true &*&
|
||||
(nth(index_of(runningTask, tasks), states) == coreID
|
||||
|| nth(index_of(runningTask, tasks), states) == taskTASK_YIELDING)
|
||||
&*&
|
||||
foreach(tasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)) &*&
|
||||
updatedStates == update(index_of(runningTask, tasks), coreID, states) &*&
|
||||
0 <= coreID &*& coreID < configNUM_CORES;
|
||||
ensures
|
||||
foreach(tasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)) &*&
|
||||
nth(index_of(runningTask, tasks), updatedStates) == coreID;
|
||||
{
|
||||
switch(tasks) {
|
||||
case nil:
|
||||
open foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states));
|
||||
close foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates));
|
||||
case cons(h, t):
|
||||
foreach_remove(runningTask, tasks);
|
||||
|
||||
distinct_remove(runningTask, tasks);
|
||||
distinct_mem_remove(runningTask, tasks);
|
||||
remove_result_subset(runningTask, tasks);
|
||||
updateUnaffectedStates_in_foreach_readOnly_sharedSeg_TCB_IF_not_running
|
||||
(runningTask, tasks, remove(runningTask, tasks),
|
||||
states, updatedStates, coreID);
|
||||
|
||||
open readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)(runningTask);
|
||||
close readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)(runningTask);
|
||||
|
||||
foreach_unremove(runningTask, tasks);
|
||||
}
|
||||
}
|
||||
@*/
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue