Added states list to lock invariant.

This commit is contained in:
Tobias Reinhard 2022-12-03 10:04:04 -05:00
parent e4db1f8aba
commit dda2dbda6f
3 changed files with 37 additions and 18 deletions

15
tasks.c
View file

@ -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 ] )

View file

@ -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;

View file

@ -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));
@*/ @*/