mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-12-11 14:15:12 -05:00
Added lemmas to simplify opening and closing DLS for cases of the form pxTask->pxNext
This commit is contained in:
parent
f44473b47c
commit
9d1b47c5e5
2 changed files with 130 additions and 26 deletions
36
tasks.c
36
tasks.c
|
|
@ -1096,17 +1096,8 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
* - Prove `mem(gTaskItem_3, gCells) == true`
|
* - Prove `mem(gTaskItem_3, gCells) == true`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//@ assert( pxTaskItem == gTaskItem_0 );
|
|
||||||
/* Open DLS predicate to justify accessing `gTaskItem_0->pxNext`.
|
//@ DLS_next_open(gReadyList, gTaskItem_0);
|
||||||
* Note: Case distinction required by `split` lemma.
|
|
||||||
*/
|
|
||||||
/*@
|
|
||||||
if( gTaskItem_0 == gListEnd ) {
|
|
||||||
DLS_end_next_open(gReadyList, gTaskItem_0);
|
|
||||||
} else {
|
|
||||||
DLS_nonEndItem_next_open(gReadyList, gTaskItem_0);
|
|
||||||
}
|
|
||||||
@*/
|
|
||||||
pxTaskItem = pxTaskItem->pxNext;
|
pxTaskItem = pxTaskItem->pxNext;
|
||||||
|
|
||||||
//@ int gTaskItemIndex_1 = index_of(pxTaskItem, gCells);
|
//@ int gTaskItemIndex_1 = index_of(pxTaskItem, gCells);
|
||||||
|
|
@ -1115,33 +1106,32 @@ static void prvYieldForTask( TCB_t * pxTCB,
|
||||||
//@ assert( mem(gTaskItem_1, gCells) == true );
|
//@ assert( mem(gTaskItem_1, gCells) == true );
|
||||||
//@ close xLIST_ITEM(gTaskItem_0, _, _, _, gReadyList);
|
//@ close xLIST_ITEM(gTaskItem_0, _, _, _, gReadyList);
|
||||||
|
|
||||||
/*@
|
//@ DLS_next_close(gReadyList, gTaskItem_0, gCells, gVals, gListEnd, gEndPrev2);
|
||||||
if( gTaskItem_0 == gListEnd ) {
|
|
||||||
DLS_end_next_close(gReadyList, gTaskItem_0);
|
|
||||||
} else {
|
|
||||||
DLS_nonEndItem_next_close(gReadyList, gTaskItem_0, gCells, gVals);
|
|
||||||
}
|
|
||||||
@*/
|
|
||||||
// unifying ghost branches
|
|
||||||
//@ assert( DLS(gListEnd, gEndPrev2, gListEnd, gEndPrev2, gCells, gVals, gReadyList) );
|
|
||||||
|
|
||||||
//@ assume(false);
|
|
||||||
|
|
||||||
if( ( void * ) pxTaskItem == ( void * ) &( pxReadyList->xListEnd ) )
|
if( ( void * ) pxTaskItem == ( void * ) &( pxReadyList->xListEnd ) )
|
||||||
{
|
{
|
||||||
//@ assert( pxTaskItem == gTaskItem_1 );
|
//@ assert( pxTaskItem == gTaskItem_1 );
|
||||||
|
//@ DLS_next_open(gReadyList, gTaskItem_1);
|
||||||
|
|
||||||
pxTaskItem = pxTaskItem->pxNext;
|
pxTaskItem = pxTaskItem->pxNext;
|
||||||
//@ int gTaskItemIndex_2 = index_of(pxTaskItem, gCells);
|
//@ int gTaskItemIndex_2 = index_of(pxTaskItem, gCells);
|
||||||
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_2 = pxTaskItem;
|
||||||
|
|
||||||
|
//@ close xLIST_ITEM(gTaskItem_1, _, _, _, gReadyList);
|
||||||
|
//@ DLS_next_close(gReadyList, gTaskItem_1, gCells, gVals, gListEnd, gEndPrev2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@ int gTaskItemIndex_3 = index_of(pxTaskItem, gCells);
|
//@ int gTaskItemIndex_3 = index_of(pxTaskItem, gCells);
|
||||||
//@ struct xLIST_ITEM* gTaskItem_3 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_3 = pxTaskItem;
|
||||||
|
|
||||||
|
//@ assert( DLS(gListEnd, gEndPrev2, gListEnd, gEndPrev2, gCells, gVals, gReadyList) );
|
||||||
|
//@ assert( mem(gTaskItem_3, gCells) == true );
|
||||||
|
|
||||||
|
|
||||||
// TODO: Remove
|
// TODO: Remove
|
||||||
// Ensure that we coveredd all cases until this point
|
// Ensure that we covered all cases until this point
|
||||||
//@ assume(false);
|
//@ assume(false);
|
||||||
pxTCB = pxTaskItem->pvOwner;
|
pxTCB = pxTaskItem->pvOwner;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,116 @@ ensures
|
||||||
assert( gValsRes == gVals );
|
assert( gValsRes == gVals );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lemma void DLS_next_open(struct xLIST* pxList, struct xLIST_ITEM* pxItem)
|
||||||
|
requires
|
||||||
|
DLS(?gEnd, ?gEndPrev, gEnd, gEndPrev, ?gCells, ?gVals, pxList) &*&
|
||||||
|
mem(pxItem, gCells) == true &*&
|
||||||
|
gEnd == head(gCells) &*&
|
||||||
|
length(gCells) == length(gVals) &*&
|
||||||
|
length(gCells) > 1;
|
||||||
|
ensures
|
||||||
|
pxItem == gEnd
|
||||||
|
? (
|
||||||
|
xLIST_ITEM(gEnd, head(gVals), ?gItem_next, gEndPrev, pxList) &*&
|
||||||
|
DLS(gItem_next, gEnd, gEnd, gEndPrev, drop(1, gCells), drop(1, gVals), pxList ) &*&
|
||||||
|
mem(gItem_next, gCells) == true
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
// DLS prefix
|
||||||
|
DLS(gEnd, gEndPrev, pxItem, ?gItem_prev,
|
||||||
|
take(index_of(pxItem, gCells), gCells),
|
||||||
|
take(index_of(pxItem, gCells), gVals),
|
||||||
|
pxList)
|
||||||
|
&*&
|
||||||
|
// item of interest
|
||||||
|
xLIST_ITEM(pxItem, ?gItemVal, ?pxItem_next, gItem_prev, pxList) &*&
|
||||||
|
gItemVal == nth(index_of(pxItem, gCells), gVals)
|
||||||
|
&*&
|
||||||
|
// DLS suffix
|
||||||
|
(pxItem != gEndPrev
|
||||||
|
? DLS(pxItem_next, pxItem, gEnd, gEndPrev,
|
||||||
|
drop(1, drop(index_of(pxItem, gCells), gCells)),
|
||||||
|
drop(1, drop(index_of(pxItem, gCells), gVals)),
|
||||||
|
pxList)
|
||||||
|
: (pxItem_next == gEnd &*&
|
||||||
|
index_of(pxItem, gCells) == length(gCells) - 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
&*&
|
||||||
|
mem(pxItem_next, gCells) == true
|
||||||
|
);
|
||||||
|
{
|
||||||
|
if( pxItem == gEnd ) {
|
||||||
|
DLS_end_next_open(pxList, pxItem);
|
||||||
|
} else {
|
||||||
|
DLS_nonEndItem_next_open(pxList, pxItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
lemma void DLS_next_close(struct xLIST* pxList, struct xLIST_ITEM* pxItem,
|
||||||
|
list<struct xLIST_ITEM*> gCells,
|
||||||
|
list<TickType_t> gVals,
|
||||||
|
struct xLIST_ITEM* gEnd,
|
||||||
|
struct xLIST_ITEM* gEndPrev)
|
||||||
|
requires
|
||||||
|
head(gCells) == gEnd &*&
|
||||||
|
length(gCells) > 1 &*&
|
||||||
|
length(gCells) == length(gVals) &*&
|
||||||
|
pxItem == gEnd
|
||||||
|
? (
|
||||||
|
xLIST_ITEM(gEnd, ?gItemVal, ?gItem_next, gEndPrev, pxList) &*&
|
||||||
|
DLS(gItem_next, gEnd, gEnd, gEndPrev, drop(1, gCells), drop(1, gVals), pxList) &*&
|
||||||
|
length(gCells) == length(gVals) &*&
|
||||||
|
length(gCells) > 0 &*&
|
||||||
|
head(gVals) == gItemVal
|
||||||
|
)
|
||||||
|
: (
|
||||||
|
length(gCells) == length(gVals) &*&
|
||||||
|
length(gCells) > 1
|
||||||
|
&*&
|
||||||
|
// DLS prefix
|
||||||
|
DLS(gEnd, gEndPrev, pxItem, ?gItem_prev, ?gCellsPrefix, ?gValsPrefix,
|
||||||
|
pxList)
|
||||||
|
&*&
|
||||||
|
mem(pxItem, gCells) == true &*&
|
||||||
|
gCellsPrefix == take(index_of(pxItem, gCells), gCells) &*&
|
||||||
|
gValsPrefix == take(index_of(pxItem, gCells), gVals)
|
||||||
|
&*&
|
||||||
|
// item of interest
|
||||||
|
pxItem != gEnd &*&
|
||||||
|
xLIST_ITEM(pxItem, ?gItemVal, ?gItem_next, gItem_prev, pxList) &*&
|
||||||
|
mem(gItemVal, gVals) == true &*&
|
||||||
|
gItemVal == nth(index_of(pxItem, gCells), gVals)
|
||||||
|
&*&
|
||||||
|
// DLS suffix
|
||||||
|
(pxItem != gEndPrev
|
||||||
|
? DLS(gItem_next, pxItem, gEnd, gEndPrev,
|
||||||
|
drop(1, drop(index_of(pxItem, gCells), gCells)),
|
||||||
|
drop(1, drop(index_of(pxItem, gCells), gVals)),
|
||||||
|
pxList)
|
||||||
|
: (gItem_next == gEnd &*&
|
||||||
|
index_of(pxItem, gCells) == length(gCells) - 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
&*&
|
||||||
|
mem(gItem_next, gCells) == true
|
||||||
|
);
|
||||||
|
ensures
|
||||||
|
DLS(gEnd, gEndPrev, gEnd, gEndPrev, gCells, gVals, pxList);
|
||||||
|
{
|
||||||
|
if( pxItem == gEnd ) {
|
||||||
|
DLS_end_next_close(pxList, pxItem);
|
||||||
|
|
||||||
|
// why is this necessary?
|
||||||
|
assert( gCells == cons( _, _) );
|
||||||
|
assert( gVals == cons(_, _) );
|
||||||
|
} else {
|
||||||
|
DLS_nonEndItem_next_close(pxList, pxItem, gCells, gVals);
|
||||||
|
}
|
||||||
|
}
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
/* By verifying the following function, we can validate that the above lemmas
|
/* By verifying the following function, we can validate that the above lemmas
|
||||||
|
|
@ -262,7 +372,7 @@ void lemma_validation__DLS_item_next(struct xLIST_ITEM* pxTaskItem)
|
||||||
{
|
{
|
||||||
//@ struct xLIST_ITEM* gTaskItem_0 = pxTaskItem;
|
//@ struct xLIST_ITEM* gTaskItem_0 = pxTaskItem;
|
||||||
|
|
||||||
/*@
|
/* @
|
||||||
if( gTaskItem_0 == gEnd ) {
|
if( gTaskItem_0 == gEnd ) {
|
||||||
DLS_end_next_open(gList, gTaskItem_0);
|
DLS_end_next_open(gList, gTaskItem_0);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -270,13 +380,17 @@ void lemma_validation__DLS_item_next(struct xLIST_ITEM* pxTaskItem)
|
||||||
}
|
}
|
||||||
@*/
|
@*/
|
||||||
|
|
||||||
|
//@ DLS_next_open(gList, gTaskItem_0);
|
||||||
|
|
||||||
pxTaskItem = pxTaskItem->pxNext;
|
pxTaskItem = pxTaskItem->pxNext;
|
||||||
//@ struct xLIST_ITEM* pxItem_1 = pxTaskItem;
|
//@ struct xLIST_ITEM* pxItem_1 = pxTaskItem;
|
||||||
|
|
||||||
|
|
||||||
//@ close xLIST_ITEM(gTaskItem_0, ?gTaskItemVal, _, _, gList);
|
//@ close xLIST_ITEM(gTaskItem_0, ?gTaskItemVal, _, _, gList);
|
||||||
/*@
|
|
||||||
|
//@ DLS_next_close(gList, gTaskItem_0, gCells, gVals, gEnd, gEndPrev);
|
||||||
|
|
||||||
|
/* @
|
||||||
if( gTaskItem_0 == gEnd ) {
|
if( gTaskItem_0 == gEnd ) {
|
||||||
DLS_end_next_close(gList, gTaskItem_0);
|
DLS_end_next_close(gList, gTaskItem_0);
|
||||||
assert( DLS(gEnd, gEndPrev, gEnd, gEndPrev, ?gCells2, ?gVals2, gList) );
|
assert( DLS(gEnd, gEndPrev, gEnd, gEndPrev, ?gCells2, ?gVals2, gList) );
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue