mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-11 14:15:12 -05:00
Added states list to lock invariant.
This commit is contained in:
parent
e4db1f8aba
commit
dda2dbda6f
3 changed files with 37 additions and 18 deletions
15
tasks.c
15
tasks.c
|
|
@ -988,7 +988,7 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//@ open taskISRLockInv_p();
|
//@ open taskISRLockInv_p();
|
||||||
//@ assert( exists_in_taskISRLockInv_p(?gTasks) );
|
//@ assert( exists_in_taskISRLockInv_p(?gTasks, ?gStates) );
|
||||||
|
|
||||||
//@ open readyLists_p(?gCellLists, ?gOwnerLists);
|
//@ open readyLists_p(?gCellLists, ?gOwnerLists);
|
||||||
//@ List_array_p_index_within_limits(&pxReadyTasksLists, uxCurrentPriority);
|
//@ List_array_p_index_within_limits(&pxReadyTasksLists, uxCurrentPriority);
|
||||||
|
|
@ -1052,10 +1052,14 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
xLIST(gReadyList, gSize, gIndex, gEnd, gCells, gVals, gOwners) &*&
|
xLIST(gReadyList, gSize, gIndex, gEnd, gCells, gVals, gOwners) &*&
|
||||||
gSize > 0 &*&
|
gSize > 0 &*&
|
||||||
// Read permissions for every task
|
// Read permissions for every task
|
||||||
foreach(gTasks, readOnly_sharedSeg_TCB_p)
|
foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates))
|
||||||
&*&
|
&*&
|
||||||
// Write permission for task scheduled on this core
|
// Write permission for task scheduled on this core
|
||||||
[1/2]sharedSeg_TCB_p(gCurrentTCB)
|
[1/2]sharedSeg_TCB_p(gCurrentTCB, ?gCurrentTCB_state)
|
||||||
|
&*&
|
||||||
|
// TODO:
|
||||||
|
// Write permissions for unscheduled tasks
|
||||||
|
true
|
||||||
&*&
|
&*&
|
||||||
subset(gOwners, gTasks) == true;
|
subset(gOwners, gTasks) == true;
|
||||||
|
|
||||||
|
|
@ -1107,7 +1111,6 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
//@ assert( subset(gOwners, gTasks) == true );
|
//@ assert( subset(gOwners, gTasks) == true );
|
||||||
//@ mem_subset(pxTCB, gOwners, gTasks);
|
//@ mem_subset(pxTCB, gOwners, gTasks);
|
||||||
//@ foreach_remove(pxTCB, gTasks);
|
//@ foreach_remove(pxTCB, gTasks);
|
||||||
//@ open sharedSeg_TCB_p(pxTCB);
|
|
||||||
|
|
||||||
/*debug_printf("Attempting to schedule %s on core %d\n", pxTCB->pcTaskName, portGET_CORE_ID() ); */
|
/*debug_printf("Attempting to schedule %s on core %d\n", pxTCB->pcTaskName, portGET_CORE_ID() ); */
|
||||||
|
|
||||||
|
|
@ -1134,7 +1137,7 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p) );
|
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates)) );
|
||||||
//@ assert( gCurrentTCB == pxCurrentTCBs[ xCoreID ] );
|
//@ assert( gCurrentTCB == pxCurrentTCBs[ xCoreID ] );
|
||||||
/*@
|
/*@
|
||||||
if( gCurrentTCB == pxTCB ) {
|
if( gCurrentTCB == pxTCB ) {
|
||||||
|
|
@ -1168,7 +1171,7 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
|
|
||||||
// Ensure we restored the collection as it was
|
// Ensure we restored the collection as it was
|
||||||
// at the beginning of the block.
|
// at the beginning of the block.
|
||||||
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p) );
|
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates)) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( pxTCB == pxCurrentTCBs[ xCoreID ] )
|
else if( pxTCB == pxCurrentTCBs[ xCoreID ] )
|
||||||
|
|
|
||||||
|
|
@ -108,12 +108,8 @@ predicate prvSeg_TCB_p(TCB_t* tcb, uint32_t ulFreeBytesOnStack) =
|
||||||
stack_p_2(stackPtr, ?ulStackDepth, topPtr,
|
stack_p_2(stackPtr, ?ulStackDepth, topPtr,
|
||||||
ulFreeBytesOnStack, ?ulUsedCells, ?ulUnalignedBytes);
|
ulFreeBytesOnStack, ?ulUsedCells, ?ulUnalignedBytes);
|
||||||
|
|
||||||
predicate sharedSeg_TCB_p(TCB_t* tcb;) =
|
predicate sharedSeg_TCB_p(TCB_t* tcb, TaskRunning_t state;) =
|
||||||
tcb->xTaskRunState |-> ?gTaskRunState;
|
tcb->xTaskRunState |-> state;
|
||||||
|
|
||||||
// Auxiliary predicate to allow foreach-quantification about fraction
|
|
||||||
predicate readOnly_sharedSeg_TCB_p(TCB_t* tcb;) =
|
|
||||||
[1/2]sharedSeg_TCB_p(tcb);
|
|
||||||
|
|
||||||
predicate coreLocalSeg_TCB_p(TCB_t* tcb, UBaseType_t uxCriticalNesting) =
|
predicate coreLocalSeg_TCB_p(TCB_t* tcb, UBaseType_t uxCriticalNesting) =
|
||||||
tcb->uxCriticalNesting |-> uxCriticalNesting;
|
tcb->uxCriticalNesting |-> uxCriticalNesting;
|
||||||
|
|
|
||||||
|
|
@ -95,15 +95,24 @@ predicate taskISRLockInv_p() =
|
||||||
0 <= gTopReadyPriority &*& gTopReadyPriority < configMAX_PRIORITIES
|
0 <= gTopReadyPriority &*& gTopReadyPriority < configMAX_PRIORITIES
|
||||||
&*&
|
&*&
|
||||||
// tasks / TCBs
|
// tasks / TCBs
|
||||||
exists_in_taskISRLockInv_p(?gTasks)
|
exists_in_taskISRLockInv_p(?gTasks, ?gStates)
|
||||||
&*&
|
&*&
|
||||||
// (RP-All) Read permissions for every task
|
// (RP-All) Read permissions for every task
|
||||||
// ∀t ∈ gTasks. [1/2]sharedSeg_TCB_p(t)
|
// and recording of task states in state list
|
||||||
foreach(gTasks, readOnly_sharedSeg_TCB_p)
|
// (∀t ∈ gTasks.
|
||||||
|
// [1/2]sharedSeg_TCB_p(t, _))
|
||||||
|
// ∧
|
||||||
|
// ∀i. ∀t. gTasks[i] == t -> gStates[i] == t->xTaskRunState
|
||||||
|
foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates))
|
||||||
&*&
|
&*&
|
||||||
// (RP-Current) Read permission for task currently scheduled on this core
|
// (RP-Current) Read permission for task currently scheduled on this core
|
||||||
// (RP-All) + (RP-Current) => Write permission for scheduled task
|
// (RP-All) + (RP-Current) => Write permission for scheduled task
|
||||||
[1/2]sharedSeg_TCB_p(gCurrentTCB)
|
[1/2]sharedSeg_TCB_p(gCurrentTCB, ?gCurrentTCB_state)
|
||||||
|
&*&
|
||||||
|
// TODO:
|
||||||
|
// (RP-Unsched) Read permissions for unscheduled tasks
|
||||||
|
// (RP-All) + (RP-Unsched) => Write permissions for unscheduled tasks
|
||||||
|
true
|
||||||
&*&
|
&*&
|
||||||
readyLists_p(?gCellLists, ?gOwnerLists)
|
readyLists_p(?gCellLists, ?gOwnerLists)
|
||||||
&*&
|
&*&
|
||||||
|
|
@ -133,8 +142,11 @@ ensures locked_p(otherLocks);
|
||||||
// Auxiliary predicate to assing names to existentially quantified variables.
|
// Auxiliary predicate to assing names to existentially quantified variables.
|
||||||
// Having multiple `exists` chunks on the heap makes matching against their
|
// Having multiple `exists` chunks on the heap makes matching against their
|
||||||
// arguments ambiguous in most cases.
|
// arguments ambiguous in most cases.
|
||||||
predicate exists_in_taskISRLockInv_p(list<void*> gTasks) =
|
predicate exists_in_taskISRLockInv_p(list<void*> gTasks,
|
||||||
exists(gTasks);
|
list<TaskRunning_t> gStates) =
|
||||||
|
exists(gTasks) &*&
|
||||||
|
exists(gStates) &*&
|
||||||
|
length(gTasks) == length(gStates);
|
||||||
|
|
||||||
// Auxiliary function that allows us to partially apply the list argument.
|
// Auxiliary function that allows us to partially apply the list argument.
|
||||||
//
|
//
|
||||||
|
|
@ -146,6 +158,14 @@ predicate exists_in_taskISRLockInv_p(list<void*> gTasks) =
|
||||||
fixpoint bool mem_list_elem<t>(list<t> xs, t x) {
|
fixpoint bool mem_list_elem<t>(list<t> xs, t x) {
|
||||||
return mem(x, xs);
|
return mem(x, xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Auxiliary predicate to allow foreach-quantification about fraction
|
||||||
|
// and reflection of `t->xTaskRunState` in state list.
|
||||||
|
predicate_ctor readOnly_sharedSeg_TCB_p
|
||||||
|
(list<void*> tasks, list<TaskRunning_t> states)
|
||||||
|
(TCB_t* t;) =
|
||||||
|
mem(t, tasks) == true &*&
|
||||||
|
[1/2]sharedSeg_TCB_p(t, nth(index_of(t, tasks), states));
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue