Renamed TCB predicates to convey access rights expressed by each predicate. Updated lemmas accordinly.

This commit is contained in:
Tobias Reinhard 2022-12-28 09:51:40 -05:00
parent 63154a4add
commit 6dc6c5dbbe
5 changed files with 121 additions and 131 deletions

View file

@ -96,14 +96,14 @@
#define taskCHECK_FOR_STACK_OVERFLOW() VF__taskCHECK_FOR_STACK_OVERFLOW() #define taskCHECK_FOR_STACK_OVERFLOW() VF__taskCHECK_FOR_STACK_OVERFLOW()
void VF__taskCHECK_FOR_STACK_OVERFLOW() void VF__taskCHECK_FOR_STACK_OVERFLOW()
/*@ requires prvSeg_TCB_p(?gCurrentTCB, ?ulFreeBytesOnStack) &*& /*@ requires TCB_stack_p(?gCurrentTCB, ?ulFreeBytesOnStack) &*&
coreLocalSeg_TCB_p(gCurrentTCB, ?uxCriticalNesting) &*& coreLocalSeg_TCB_p(gCurrentTCB, ?uxCriticalNesting) &*&
// chunks required by `pxCurrentTCB` aka `xTaskGetCurrentTaskHandle()` // chunks required by `pxCurrentTCB` aka `xTaskGetCurrentTaskHandle()`
interruptState_p(coreID_f(), ?state) &*& interruptState_p(coreID_f(), ?state) &*&
interruptsDisabled_f(state) == true &*& interruptsDisabled_f(state) == true &*&
pointer(&pxCurrentTCBs[coreID_f], gCurrentTCB); pointer(&pxCurrentTCBs[coreID_f], gCurrentTCB);
@*/ @*/
/*@ ensures prvSeg_TCB_p(gCurrentTCB, ulFreeBytesOnStack) &*& /*@ ensures TCB_stack_p(gCurrentTCB, ulFreeBytesOnStack) &*&
coreLocalSeg_TCB_p(gCurrentTCB, uxCriticalNesting) &*& coreLocalSeg_TCB_p(gCurrentTCB, uxCriticalNesting) &*&
// chunks required by `pxCurrentTCB` aka `xTaskGetCurrentTaskHandle()` // chunks required by `pxCurrentTCB` aka `xTaskGetCurrentTaskHandle()`
interruptState_p(coreID_f(), state) &*& interruptState_p(coreID_f(), state) &*&
@ -111,7 +111,7 @@
pointer(&pxCurrentTCBs[coreID_f], gCurrentTCB); \ pointer(&pxCurrentTCBs[coreID_f], gCurrentTCB); \
@*/ \ @*/ \
{ \ { \
/*@ open prvSeg_TCB_p(gCurrentTCB, ulFreeBytesOnStack); @*/ \ /*@ open TCB_stack_p(gCurrentTCB, ulFreeBytesOnStack); @*/ \
/*@ assert( stack_p(?pxStack, ?ulStackDepth, ?pxTopOfStack, \ /*@ assert( stack_p(?pxStack, ?ulStackDepth, ?pxTopOfStack, \
?ulFreeBytes, ?ulUsedCells, ?ulUnalignedBytes) ); \ ?ulFreeBytes, ?ulUsedCells, ?ulUnalignedBytes) ); \
@*/ \ @*/ \
@ -139,7 +139,7 @@
/*@ close stack_p(pxStack, ulStackDepth, pxTopOfStack, \ /*@ close stack_p(pxStack, ulStackDepth, pxTopOfStack, \
ulFreeBytes, ulUsedCells, ulUnalignedBytes); \ ulFreeBytes, ulUsedCells, ulUnalignedBytes); \
@*/ \ @*/ \
/*@ close prvSeg_TCB_p(gCurrentTCB, ulFreeBytesOnStack); @*/ \ /*@ close TCB_stack_p(gCurrentTCB, ulFreeBytesOnStack); @*/ \
TCB_t* tcb1 = pxCurrentTCB; \ TCB_t* tcb1 = pxCurrentTCB; \
TCB_t* tcb2 = pxCurrentTCB; \ TCB_t* tcb2 = pxCurrentTCB; \
vApplicationStackOverflowHook( ( TaskHandle_t ) tcb1, tcb2->pcTaskName ); \ vApplicationStackOverflowHook( ( TaskHandle_t ) tcb1, tcb2->pcTaskName ); \
@ -151,7 +151,7 @@
chars_split((char*) pxStack, ulFreeBytesOnStack); \ chars_split((char*) pxStack, ulFreeBytesOnStack); \
close stack_p(pxStack, ulStackDepth, pxTopOfStack, \ close stack_p(pxStack, ulStackDepth, pxTopOfStack, \
ulFreeBytes, ulUsedCells, ulUnalignedBytes); \ ulFreeBytes, ulUsedCells, ulUnalignedBytes); \
close prvSeg_TCB_p(gCurrentTCB, ulFreeBytesOnStack); \ close TCB_stack_p(gCurrentTCB, ulFreeBytesOnStack); \
} \ } \
@*/ \ @*/ \
} }

View file

@ -1863,10 +1863,10 @@ configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVIL
*/ */
void vApplicationStackOverflowHook( TaskHandle_t xTask, void vApplicationStackOverflowHook( TaskHandle_t xTask,
char * pcTaskName ); char * pcTaskName );
/*@ requires prvSeg_TCB_p(xTask, ?ulFreeBytesOnStack) &*& /*@ requires TCB_stack_p(xTask, ?ulFreeBytesOnStack) &*&
coreLocalSeg_TCB_p(xTask, ?uxCriticalNesting); coreLocalSeg_TCB_p(xTask, ?uxCriticalNesting);
@*/ @*/
/*@ ensures prvSeg_TCB_p(xTask, ulFreeBytesOnStack) &*& /*@ ensures TCB_stack_p(xTask, ulFreeBytesOnStack) &*&
coreLocalSeg_TCB_p(xTask, uxCriticalNesting); coreLocalSeg_TCB_p(xTask, uxCriticalNesting);
@*/ @*/

View file

@ -49,30 +49,20 @@ predicate TCB_p(TCB_t * tcb, uint32_t ulFreeBytesOnStack) =
@*/ @*/
/*@ /*@
// We have to segment TCBs into: // This predicate represents write access to a TCB's stack.
// (i) public parts that can be accessed by anyone after predicate TCB_stack_p(TCB_t* tcb, uint32_t ulFreeBytesOnStack) =
// following the appropriote synchronization steps and
// (ii) private parts that may only be used by the task itself
// which the TCB represents
//
// The predicates below will be expanded iteratively.
// This predicate captures the private part of a TCB that should only be
// accessed by the TCB represents or under specific circumstances where
// we are certain that the task is not running.
predicate prvSeg_TCB_p(TCB_t* tcb, uint32_t ulFreeBytesOnStack) =
tcb->pxStack |-> ?stackPtr &*& tcb->pxStack |-> ?stackPtr &*&
tcb->pxTopOfStack |-> ?topPtr &*& tcb->pxTopOfStack |-> ?topPtr &*&
stack_p(stackPtr, ?ulStackDepth, topPtr, stack_p(stackPtr, ?ulStackDepth, topPtr,
ulFreeBytesOnStack, ?ulUsedCells, ?ulUnalignedBytes); ulFreeBytesOnStack, ?ulUsedCells, ?ulUnalignedBytes);
// This predicate represents a shared part of a TCB that can be accessed by // This predicate represents write access to the run state of a TCB.
// anyone. Note that this predicate only contains the minimal access rights predicate TCB_runState_p(TCB_t* tcb, TaskRunning_t state;) =
// required by the `vTaskSwitchContext` proof. It can be extended in the future
// as needed.
predicate sharedSeg_TCB_p(TCB_t* tcb, TaskRunning_t state;) =
tcb->xTaskRunState |-> state; tcb->xTaskRunState |-> state;
// This predicate represents write access to the nesting level of a TCB.
// Entering a critical section increases the nesting level. Leaving it,
// decreases it.
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

@ -106,14 +106,14 @@ predicate _taskISRLockInv_p(UBaseType_t gTopReadyPriority) =
// (RP-All) Read permissions for every task // (RP-All) Read permissions for every task
// and recording of task states in state list // and recording of task states in state list
// (∀t ∈ gTasks. // (∀t ∈ gTasks.
// [1/2]sharedSeg_TCB_p(t, _)) // [1/2]TCB_runState_p(t, _))
// ∧ // ∧
// ∀i. ∀t. gTasks[i] == t -> gStates[i] == t->xTaskRunState // ∀i. ∀t. gTasks[i] == t -> gStates[i] == t->xTaskRunState
foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates)) foreach(gTasks, readOnly_TCB_runState_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, ?gCurrentTCB_state) &*& [1/2]TCB_runState_p(gCurrentTCB, ?gCurrentTCB_state) &*&
// gCurrentTCB_state != taskTASK_NOT_RUNNING &*& // gCurrentTCB_state != taskTASK_NOT_RUNNING &*&
(gCurrentTCB_state == coreID_f() || gCurrentTCB_state == taskTASK_YIELDING) &*& (gCurrentTCB_state == coreID_f() || gCurrentTCB_state == taskTASK_YIELDING) &*&
nth(index_of(gCurrentTCB, gTasks), gStates) == gCurrentTCB_state nth(index_of(gCurrentTCB, gTasks), gStates) == gCurrentTCB_state
@ -122,7 +122,7 @@ predicate _taskISRLockInv_p(UBaseType_t gTopReadyPriority) =
// (RP-All) + (RP-Unsched) => Write permissions for unscheduled tasks // (RP-All) + (RP-Unsched) => Write permissions for unscheduled tasks
// ∀t ∈ tasks. t->xTaskState == taskTASK_NOT_RUNNING // ∀t ∈ tasks. t->xTaskState == taskTASK_NOT_RUNNING
// -> [1/2]shared_TCB_p(t, taskTASK_NOT_RUNNING) // -> [1/2]shared_TCB_p(t, taskTASK_NOT_RUNNING)
foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates))
&*& &*&
readyLists_p(?gCellLists, ?gOwnerLists) readyLists_p(?gCellLists, ?gOwnerLists)
&*& &*&
@ -172,18 +172,18 @@ fixpoint bool mem_list_elem<t>(list<t> xs, t x) {
// Auxiliary predicate to allow foreach-quantification about fraction // Auxiliary predicate to allow foreach-quantification about fraction
// and reflection of `t->xTaskRunState` in state list. // and reflection of `t->xTaskRunState` in state list.
predicate_ctor readOnly_sharedSeg_TCB_p predicate_ctor readOnly_TCB_runState_p
(list<void*> tasks, list<TaskRunning_t> states) (list<void*> tasks, list<TaskRunning_t> states)
(TCB_t* t;) = (TCB_t* t;) =
mem(t, tasks) == true &*& mem(t, tasks) == true &*&
[1/2]sharedSeg_TCB_p(t, nth(index_of(t, tasks), states)); [1/2]TCB_runState_p(t, nth(index_of(t, tasks), states));
predicate_ctor readOnly_sharedSeg_TCB_IF_not_running_p predicate_ctor readOnly_TCB_runState_IF_not_running_p
(list<void*> tasks, list<TaskRunning_t> states) (list<void*> tasks, list<TaskRunning_t> states)
(TCB_t* t;) = (TCB_t* t;) =
mem(t, tasks) == true &*& mem(t, tasks) == true &*&
nth(index_of(t, tasks), states) == taskTASK_NOT_RUNNING nth(index_of(t, tasks), states) == taskTASK_NOT_RUNNING
? [1/2]sharedSeg_TCB_p(t, taskTASK_NOT_RUNNING) ? [1/2]TCB_runState_p(t, taskTASK_NOT_RUNNING)
: true; : true;
@*/ @*/
@ -201,16 +201,16 @@ lemma void nonauto_nth_update<t>(int i, int j, t y, list<t> xs);
// TODO: Move lemmas below to separate header file. // TODO: Move lemmas below to separate header file.
/*@ /*@
lemma void update_readOnly_sharedSeg_TCB(TCB_t* t, lemma void update_readOnly_TCB_runState(TCB_t* t,
list<void*> tasks, list<void*> tasks,
list<TaskRunning_t> states, list<TaskRunning_t> states,
int updatedIndex, int updatedIndex,
TaskRunning_t s) TaskRunning_t s)
requires readOnly_sharedSeg_TCB_p(tasks, states)(t) &*& requires readOnly_TCB_runState_p(tasks, states)(t) &*&
updatedIndex != index_of(t, tasks) &*& updatedIndex != index_of(t, tasks) &*&
mem(t, tasks) == true &*& mem(t, tasks) == true &*&
length(tasks) == length(states); length(tasks) == length(states);
ensures readOnly_sharedSeg_TCB_p(tasks, update(updatedIndex, s, states))(t); ensures readOnly_TCB_runState_p(tasks, update(updatedIndex, s, states))(t);
{ {
list<TaskRunning_t> states2 = update(updatedIndex, s, states); list<TaskRunning_t> states2 = update(updatedIndex, s, states);
int t_index = index_of(t, tasks); int t_index = index_of(t, tasks);
@ -218,20 +218,20 @@ ensures readOnly_sharedSeg_TCB_p(tasks, update(updatedIndex, s, states))(t);
if( updatedIndex < 0 || updatedIndex >= length(states) ) { if( updatedIndex < 0 || updatedIndex >= length(states) ) {
update_out_of_bounds(updatedIndex, s, states); update_out_of_bounds(updatedIndex, s, states);
} else { } else {
open readOnly_sharedSeg_TCB_p(tasks, states)(t); open readOnly_TCB_runState_p(tasks, states)(t);
open [1/2]sharedSeg_TCB_p(t, nth(t_index, states)); open [1/2]TCB_runState_p(t, nth(t_index, states));
mem_index_of(t, tasks); mem_index_of(t, tasks);
nth_update(t_index, updatedIndex, s, states); nth_update(t_index, updatedIndex, s, states);
assert( nth(t_index, states) == nth(t_index, states2) ); assert( nth(t_index, states) == nth(t_index, states2) );
close [1/2]sharedSeg_TCB_p(t, nth(t_index, states2)); close [1/2]TCB_runState_p(t, nth(t_index, states2));
close readOnly_sharedSeg_TCB_p(tasks, states2)(t); close readOnly_TCB_runState_p(tasks, states2)(t);
} }
} }
lemma void update_foreach_readOnly_sharedSeg_TCB(TCB_t* updatedTask, lemma void update_foreach_readOnly_TCB_runState(TCB_t* updatedTask,
list<void*> tasks, list<void*> tasks,
list<void*> subTasks, list<void*> subTasks,
list<TaskRunning_t> states, list<TaskRunning_t> states,
@ -240,37 +240,37 @@ lemma void update_foreach_readOnly_sharedSeg_TCB(TCB_t* updatedTask,
requires requires
mem(updatedTask, tasks) == true &*& mem(updatedTask, tasks) == true &*&
length(tasks) == length(states) &*& length(tasks) == length(states) &*&
foreach(subTasks, readOnly_sharedSeg_TCB_p(tasks, states)) &*& foreach(subTasks, readOnly_TCB_runState_p(tasks, states)) &*&
states2 == update(index_of(updatedTask, tasks), s, states) &*& states2 == update(index_of(updatedTask, tasks), s, states) &*&
distinct(tasks) == true &*& distinct(tasks) == true &*&
mem(updatedTask, subTasks) == false &*& mem(updatedTask, subTasks) == false &*&
subset(subTasks, tasks) == true; subset(subTasks, tasks) == true;
ensures ensures
foreach(subTasks, readOnly_sharedSeg_TCB_p(tasks, states2)); foreach(subTasks, readOnly_TCB_runState_p(tasks, states2));
{ {
switch(subTasks) { switch(subTasks) {
case nil: case nil:
open foreach(nil, readOnly_sharedSeg_TCB_p(tasks, states)); open foreach(nil, readOnly_TCB_runState_p(tasks, states));
close foreach(nil, readOnly_sharedSeg_TCB_p(tasks, states2)); close foreach(nil, readOnly_TCB_runState_p(tasks, states2));
case cons(h, rest): case cons(h, rest):
int index = index_of(updatedTask, tasks); int index = index_of(updatedTask, tasks);
// distinct_mem_remove(t, tasks); // distinct_mem_remove(t, tasks);
// neq_mem_remove(h, t, tasks); // neq_mem_remove(h, t, tasks);
// index_of_different(h, t, tasks); // index_of_different(h, t, tasks);
open foreach(subTasks, readOnly_sharedSeg_TCB_p(tasks, states)); open foreach(subTasks, readOnly_TCB_runState_p(tasks, states));
assert( updatedTask != h ); assert( updatedTask != h );
index_of_different(updatedTask, h, tasks); index_of_different(updatedTask, h, tasks);
assert( index != index_of(h, tasks) ); assert( index != index_of(h, tasks) );
update_readOnly_sharedSeg_TCB(h, tasks, states, index, s); update_readOnly_TCB_runState(h, tasks, states, index, s);
assert( mem(updatedTask, rest) == false ); assert( mem(updatedTask, rest) == false );
update_foreach_readOnly_sharedSeg_TCB(updatedTask, tasks, rest, update_foreach_readOnly_TCB_runState(updatedTask, tasks, rest,
states, states2, s); states, states2, s);
close foreach(subTasks, readOnly_sharedSeg_TCB_p(tasks, states2)); close foreach(subTasks, readOnly_TCB_runState_p(tasks, states2));
} }
} }
lemma void close_updated_foreach_readOnly_sharedSeg_TCB(TCB_t* updatedTask, lemma void close_updated_foreach_readOnly_TCB_runState(TCB_t* updatedTask,
list<void*> tasks, list<void*> tasks,
list<TaskRunning_t> states, list<TaskRunning_t> states,
list<TaskRunning_t> states2, list<TaskRunning_t> states2,
@ -279,45 +279,45 @@ requires
mem(updatedTask, tasks) == true &*& mem(updatedTask, tasks) == true &*&
length(states) == length(tasks) &*& length(states) == length(tasks) &*&
distinct(tasks) == true &*& distinct(tasks) == true &*&
foreach(remove(updatedTask, tasks), readOnly_sharedSeg_TCB_p(tasks, states)) &*& foreach(remove(updatedTask, tasks), readOnly_TCB_runState_p(tasks, states)) &*&
states2 == update(index_of(updatedTask, tasks), s, states) &*& states2 == update(index_of(updatedTask, tasks), s, states) &*&
[1/2]sharedSeg_TCB_p(updatedTask, s); [1/2]TCB_runState_p(updatedTask, s);
ensures ensures
foreach(tasks, readOnly_sharedSeg_TCB_p(tasks, states2)); foreach(tasks, readOnly_TCB_runState_p(tasks, states2));
{ {
distinct_mem_remove(updatedTask, tasks); distinct_mem_remove(updatedTask, tasks);
remove_result_subset(updatedTask, tasks); remove_result_subset(updatedTask, tasks);
close readOnly_sharedSeg_TCB_p(tasks, states2)(updatedTask); close readOnly_TCB_runState_p(tasks, states2)(updatedTask);
update_foreach_readOnly_sharedSeg_TCB(updatedTask, tasks, update_foreach_readOnly_TCB_runState(updatedTask, tasks,
remove(updatedTask, tasks), remove(updatedTask, tasks),
states, states2, s); states, states2, s);
foreach_unremove(updatedTask, tasks); foreach_unremove(updatedTask, tasks);
} }
lemma void stopUpdate_foreach_readOnly_sharedSeg_TCB_IF_not_running lemma void stopUpdate_foreach_readOnly_TCB_runState_IF_not_running
(TCB_t* stoppedTask, list<void*> tasks, list<void*> subTasks, (TCB_t* stoppedTask, list<void*> tasks, list<void*> subTasks,
list<TaskRunning_t> states, list<TaskRunning_t> states2) list<TaskRunning_t> states, list<TaskRunning_t> states2)
requires requires
distinct(tasks) == true &*& distinct(tasks) == true &*&
distinct(subTasks) == true &*& distinct(subTasks) == true &*&
length(tasks) == length(states) &*& length(tasks) == length(states) &*&
foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)) &*& foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, states)) &*&
states2 == update(index_of(stoppedTask, tasks), taskTASK_NOT_RUNNING, states) &*& states2 == update(index_of(stoppedTask, tasks), taskTASK_NOT_RUNNING, states) &*&
nth(index_of(stoppedTask, tasks), states) != taskTASK_NOT_RUNNING &*& nth(index_of(stoppedTask, tasks), states) != taskTASK_NOT_RUNNING &*&
subset(subTasks, tasks) == true &*& subset(subTasks, tasks) == true &*&
mem(stoppedTask, tasks) == true &*& mem(stoppedTask, tasks) == true &*&
mem(stoppedTask, subTasks) mem(stoppedTask, subTasks)
? [1/2]sharedSeg_TCB_p(stoppedTask, taskTASK_NOT_RUNNING) ? [1/2]TCB_runState_p(stoppedTask, taskTASK_NOT_RUNNING)
: true; : true;
ensures ensures
foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states2)); foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, states2));
{ {
switch(subTasks) { switch(subTasks) {
case nil: case nil:
open foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)); open foreach(nil, readOnly_TCB_runState_IF_not_running_p(tasks, states));
close foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states2)); close foreach(nil, readOnly_TCB_runState_IF_not_running_p(tasks, states2));
case cons(h, t): case cons(h, t):
if( h == stoppedTask ) { if( h == stoppedTask ) {
assert( remove(stoppedTask, subTasks) == t ); assert( remove(stoppedTask, subTasks) == t );
@ -333,17 +333,17 @@ ensures
} }
nth_update(index_of(stoppedTask, tasks), index_of(stoppedTask, tasks), taskTASK_NOT_RUNNING, states); nth_update(index_of(stoppedTask, tasks), index_of(stoppedTask, tasks), taskTASK_NOT_RUNNING, states);
open foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)); open foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, states));
open readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)(h); open readOnly_TCB_runState_IF_not_running_p(tasks, states)(h);
assert( nth(index_of(stoppedTask, tasks), states2) == taskTASK_NOT_RUNNING ); assert( nth(index_of(stoppedTask, tasks), states2) == taskTASK_NOT_RUNNING );
close readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states2)(h); close readOnly_TCB_runState_IF_not_running_p(tasks, states2)(h);
stopUpdate_foreach_readOnly_sharedSeg_TCB_IF_not_running stopUpdate_foreach_readOnly_TCB_runState_IF_not_running
(stoppedTask, tasks, t, states, states2); (stoppedTask, tasks, t, states, states2);
close foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states2)); close foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, states2));
} }
} }
lemma void updateUnaffectedStates_in_foreach_readOnly_sharedSeg_TCB_IF_not_running lemma void updateUnaffectedStates_in_foreach_readOnly_TCB_runState_IF_not_running
(TCB_t* updatedTask, list<void*> tasks, list<void*> subTasks, (TCB_t* updatedTask, list<void*> tasks, list<void*> subTasks,
list<TaskRunning_t> states, list<TaskRunning_t> updatedStates, list<TaskRunning_t> states, list<TaskRunning_t> updatedStates,
TaskRunning_t s) TaskRunning_t s)
@ -354,32 +354,32 @@ requires
mem(updatedTask, tasks) == true &*& mem(updatedTask, tasks) == true &*&
mem(updatedTask, subTasks) == false &*& mem(updatedTask, subTasks) == false &*&
subset(subTasks, tasks) == true &*& subset(subTasks, tasks) == true &*&
foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)) &*& foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, states)) &*&
updatedStates == update(index_of(updatedTask, tasks), s, states); updatedStates == update(index_of(updatedTask, tasks), s, states);
ensures ensures
foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)); foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates));
{ {
switch(subTasks) { switch(subTasks) {
case nil: case nil:
open foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)); open foreach(nil, readOnly_TCB_runState_IF_not_running_p(tasks, states));
close foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)); close foreach(nil, readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates));
case cons(h, t): case cons(h, t):
open foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)); open foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, states));
// Prove that update preserves state of `h`. // Prove that update preserves state of `h`.
index_of_different(h, updatedTask, tasks); index_of_different(h, updatedTask, tasks);
nth_update(index_of(h, tasks), index_of(updatedTask, tasks), s, states); nth_update(index_of(h, tasks), index_of(updatedTask, tasks), s, states);
assert( nth(index_of(h, tasks), states) == nth(index_of(h, tasks), updatedStates) ); assert( nth(index_of(h, tasks), states) == nth(index_of(h, tasks), updatedStates) );
open readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)(h); open readOnly_TCB_runState_IF_not_running_p(tasks, states)(h);
close readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)(h); close readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates)(h);
updateUnaffectedStates_in_foreach_readOnly_sharedSeg_TCB_IF_not_running updateUnaffectedStates_in_foreach_readOnly_TCB_runState_IF_not_running
(updatedTask, tasks, t, states, updatedStates, s); (updatedTask, tasks, t, states, updatedStates, s);
close foreach(subTasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)); close foreach(subTasks, readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates));
} }
} }
lemma void startUpdate_foreach_readOnly_sharedSeg_TCB_IF_not_running lemma void startUpdate_foreach_readOnly_TCB_runState_IF_not_running
(TCB_t* startedTask, list<void*> tasks, (TCB_t* startedTask, list<void*> tasks,
list<TaskRunning_t> states, list<TaskRunning_t> updatedStates, list<TaskRunning_t> states, list<TaskRunning_t> updatedStates,
int coreID) int coreID)
@ -387,25 +387,25 @@ requires
distinct(tasks) == true &*& distinct(tasks) == true &*&
length(tasks) == length(states) &*& length(tasks) == length(states) &*&
mem(startedTask, tasks) == true &*& mem(startedTask, tasks) == true &*&
foreach(remove(startedTask, tasks), readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)) &*& foreach(remove(startedTask, tasks), readOnly_TCB_runState_IF_not_running_p(tasks, states)) &*&
updatedStates == update(index_of(startedTask, tasks), coreID, states) &*& updatedStates == update(index_of(startedTask, tasks), coreID, states) &*&
0 <= coreID &*& coreID < configNUM_CORES; 0 <= coreID &*& coreID < configNUM_CORES;
ensures ensures
foreach(tasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)); foreach(tasks, readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates));
{ {
distinct_remove(startedTask, tasks); distinct_remove(startedTask, tasks);
distinct_mem_remove(startedTask, tasks); distinct_mem_remove(startedTask, tasks);
remove_result_subset(startedTask, tasks); remove_result_subset(startedTask, tasks);
updateUnaffectedStates_in_foreach_readOnly_sharedSeg_TCB_IF_not_running updateUnaffectedStates_in_foreach_readOnly_TCB_runState_IF_not_running
(startedTask, tasks, remove(startedTask, tasks), states, updatedStates, (startedTask, tasks, remove(startedTask, tasks), states, updatedStates,
coreID); coreID);
assert( foreach(remove(startedTask, tasks), readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)) ); assert( foreach(remove(startedTask, tasks), readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates)) );
close readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)(startedTask); close readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates)(startedTask);
foreach_unremove(startedTask, tasks); foreach_unremove(startedTask, tasks);
} }
lemma void scheduleRunning_in_foreach_readOnly_sharedSeg_TCB_IF_not_running lemma void scheduleRunning_in_foreach_readOnly_TCB_runState_IF_not_running
(TCB_t* runningTask, list<void*> tasks, (TCB_t* runningTask, list<void*> tasks,
list<TaskRunning_t> states, list<TaskRunning_t> updatedStates, list<TaskRunning_t> states, list<TaskRunning_t> updatedStates,
int coreID) int coreID)
@ -416,29 +416,29 @@ requires
(nth(index_of(runningTask, tasks), states) == coreID (nth(index_of(runningTask, tasks), states) == coreID
|| nth(index_of(runningTask, tasks), states) == taskTASK_YIELDING) || nth(index_of(runningTask, tasks), states) == taskTASK_YIELDING)
&*& &*&
foreach(tasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)) &*& foreach(tasks, readOnly_TCB_runState_IF_not_running_p(tasks, states)) &*&
updatedStates == update(index_of(runningTask, tasks), coreID, states) &*& updatedStates == update(index_of(runningTask, tasks), coreID, states) &*&
0 <= coreID &*& coreID < configNUM_CORES; 0 <= coreID &*& coreID < configNUM_CORES;
ensures ensures
foreach(tasks, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)) &*& foreach(tasks, readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates)) &*&
nth(index_of(runningTask, tasks), updatedStates) == coreID; nth(index_of(runningTask, tasks), updatedStates) == coreID;
{ {
switch(tasks) { switch(tasks) {
case nil: case nil:
open foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)); open foreach(nil, readOnly_TCB_runState_IF_not_running_p(tasks, states));
close foreach(nil, readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)); close foreach(nil, readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates));
case cons(h, t): case cons(h, t):
foreach_remove(runningTask, tasks); foreach_remove(runningTask, tasks);
distinct_remove(runningTask, tasks); distinct_remove(runningTask, tasks);
distinct_mem_remove(runningTask, tasks); distinct_mem_remove(runningTask, tasks);
remove_result_subset(runningTask, tasks); remove_result_subset(runningTask, tasks);
updateUnaffectedStates_in_foreach_readOnly_sharedSeg_TCB_IF_not_running updateUnaffectedStates_in_foreach_readOnly_TCB_runState_IF_not_running
(runningTask, tasks, remove(runningTask, tasks), (runningTask, tasks, remove(runningTask, tasks),
states, updatedStates, coreID); states, updatedStates, coreID);
open readOnly_sharedSeg_TCB_IF_not_running_p(tasks, states)(runningTask); open readOnly_TCB_runState_IF_not_running_p(tasks, states)(runningTask);
close readOnly_sharedSeg_TCB_IF_not_running_p(tasks, updatedStates)(runningTask); close readOnly_TCB_runState_IF_not_running_p(tasks, updatedStates)(runningTask);
foreach_unremove(runningTask, tasks); foreach_unremove(runningTask, tasks);
} }

View file

@ -909,7 +909,7 @@ static void prvYieldForTask( TCB_t * pxTCB,
// coreLocalSeg_TCB_p(gCurrentTCB0, 0) // coreLocalSeg_TCB_p(gCurrentTCB0, 0)
&*& &*&
// read access to current task's stack pointer, etc // read access to current task's stack pointer, etc
// prvSeg_TCB_p(gCurrentTCB0, ?ulFreeBytesOnStack); // TCB_stack_p(gCurrentTCB0, ?ulFreeBytesOnStack);
true; true;
@*/ @*/
/*@ ensures 0 <= xCoreID &*& xCoreID < configNUM_CORES &*& /*@ ensures 0 <= xCoreID &*& xCoreID < configNUM_CORES &*&
@ -927,7 +927,7 @@ static void prvYieldForTask( TCB_t * pxTCB,
// coreLocalSeg_TCB_p(gCurrentTCB, 0) // coreLocalSeg_TCB_p(gCurrentTCB, 0)
&*& &*&
// read access to current task's stack pointer, etc // read access to current task's stack pointer, etc
// prvSeg_TCB_p(gCurrentTCB, ulFreeBytesOnStack); // TCB_stack_p(gCurrentTCB, ulFreeBytesOnStack);
true; true;
@*/ @*/
{ {
@ -1059,15 +1059,15 @@ static void prvYieldForTask( TCB_t * pxTCB,
exists_in_taskISRLockInv_p(gTasks, ?gStates) exists_in_taskISRLockInv_p(gTasks, ?gStates)
&*& &*&
// Read permissions for every task // Read permissions for every task
foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates)) foreach(gTasks, readOnly_TCB_runState_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, ?gCurrentTCB_state) &*& [1/2]TCB_runState_p(gCurrentTCB, ?gCurrentTCB_state) &*&
(gCurrentTCB_state == coreID_f() || gCurrentTCB_state == taskTASK_YIELDING) &*& (gCurrentTCB_state == coreID_f() || gCurrentTCB_state == taskTASK_YIELDING) &*&
nth(index_of(gCurrentTCB, gTasks), gStates) == gCurrentTCB_state nth(index_of(gCurrentTCB, gTasks), gStates) == gCurrentTCB_state
&*& &*&
// Write permissions for unscheduled tasks // Write permissions for unscheduled tasks
foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates))
&*& &*&
subset(gOwners, gTasks) == true &*& subset(gOwners, gTasks) == true &*&
List_array_p(&pxReadyTasksLists, uxCurrentPriority, gPrefCellLists, List_array_p(&pxReadyTasksLists, uxCurrentPriority, gPrefCellLists,
@ -1126,7 +1126,7 @@ 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);
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates)) ); //@ assert( foreach(remove(pxTCB, gTasks), readOnly_TCB_runState_p(gTasks, gStates)) );
/*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() ); */
@ -1156,9 +1156,9 @@ static void prvYieldForTask( TCB_t * pxTCB,
{ {
//@ open exists_in_taskISRLockInv_p(gTasks, gStates); //@ open exists_in_taskISRLockInv_p(gTasks, gStates);
//@ assert( nth(index_of(pxTCB, gTasks), gStates) == taskTASK_NOT_RUNNING); //@ assert( nth(index_of(pxTCB, gTasks), gStates) == taskTASK_NOT_RUNNING);
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates)) ); //@ assert( foreach(remove(pxTCB, gTasks), readOnly_TCB_runState_p(gTasks, gStates)) );
//@ assert( gCurrentTCB == pxCurrentTCBs[ xCoreID ] ); //@ assert( gCurrentTCB == pxCurrentTCBs[ xCoreID ] );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates)) );
/* We could reuse the read permission to `pxTCB` we extracted before the if statement. /* We could reuse the read permission to `pxTCB` we extracted before the if statement.
* But putting permissions back as soon as we no longer need them simplifies the * But putting permissions back as soon as we no longer need them simplifies the
@ -1166,70 +1166,70 @@ static void prvYieldForTask( TCB_t * pxTCB,
*/ */
// Put read permission for `pxTCB` back // Put read permission for `pxTCB` back
//@ close [1/2]sharedSeg_TCB_p(pxTCB, _); //@ close [1/2]TCB_runState_p(pxTCB, _);
//@ close readOnly_sharedSeg_TCB_p(gTasks, gStates)(pxTCB); //@ close readOnly_TCB_runState_p(gTasks, gStates)(pxTCB);
//@ foreach_unremove(pxTCB, gTasks); //@ foreach_unremove(pxTCB, gTasks);
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_p(gTasks, gStates)) );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates)) );
// Get 2nd half of write permission for `gCurrentTCB` // Get 2nd half of write permission for `gCurrentTCB`
//@ foreach_remove(gCurrentTCB, gTasks); //@ foreach_remove(gCurrentTCB, gTasks);
//@ assert( foreach(remove(gCurrentTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates)) ); //@ assert( foreach(remove(gCurrentTCB, gTasks), readOnly_TCB_runState_p(gTasks, gStates)) );
/* If the task is not being executed by any core swap it in */ /* If the task is not being executed by any core swap it in */
pxCurrentTCBs[ xCoreID ]->xTaskRunState = taskTASK_NOT_RUNNING; pxCurrentTCBs[ xCoreID ]->xTaskRunState = taskTASK_NOT_RUNNING;
//@ assert( foreach(remove(gCurrentTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates)) ); //@ assert( foreach(remove(gCurrentTCB, gTasks), readOnly_TCB_runState_p(gTasks, gStates)) );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates)) );
// New states list reflects state update above. // New states list reflects state update above.
//@ list<TaskRunning_t> gStates1 = def_state1(gTasks, gStates, gCurrentTCB, pxTCB); //@ list<TaskRunning_t> gStates1 = def_state1(gTasks, gStates, gCurrentTCB, pxTCB);
//@ assert( nth(index_of(pxTCB, gTasks), gStates1) == taskTASK_NOT_RUNNING); //@ assert( nth(index_of(pxTCB, gTasks), gStates1) == taskTASK_NOT_RUNNING);
/*@ close_updated_foreach_readOnly_sharedSeg_TCB(gCurrentTCB, gTasks, gStates, /*@ close_updated_foreach_readOnly_TCB_runState(gCurrentTCB, gTasks, gStates,
gStates1, taskTASK_NOT_RUNNING); gStates1, taskTASK_NOT_RUNNING);
@*/ @*/
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates1)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_p(gTasks, gStates1)) );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates)) );
/*@ stopUpdate_foreach_readOnly_sharedSeg_TCB_IF_not_running /*@ stopUpdate_foreach_readOnly_TCB_runState_IF_not_running
(gCurrentTCB, gTasks, gTasks, gStates, gStates1); (gCurrentTCB, gTasks, gTasks, gStates, gStates1);
@*/ @*/
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates1)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates1)) );
// Get write permission for `pxTCB` // Get write permission for `pxTCB`
//@ foreach_remove(pxTCB, gTasks); //@ foreach_remove(pxTCB, gTasks);
//@ foreach_remove(pxTCB, gTasks); //@ foreach_remove(pxTCB, gTasks);
//@ open readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates1)(pxTCB); //@ open readOnly_TCB_runState_IF_not_running_p(gTasks, gStates1)(pxTCB);
#if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) ) #if ( ( configNUM_CORES > 1 ) && ( configUSE_CORE_AFFINITY == 1 ) )
pxPreviousTCB = pxCurrentTCBs[ xCoreID ]; pxPreviousTCB = pxCurrentTCBs[ xCoreID ];
#endif #endif
pxTCB->xTaskRunState = ( TaskRunning_t ) xCoreID; pxTCB->xTaskRunState = ( TaskRunning_t ) xCoreID;
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates1)) ); //@ assert( foreach(remove(pxTCB, gTasks), readOnly_TCB_runState_p(gTasks, gStates1)) );
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates1)) ); //@ assert( foreach(remove(pxTCB, gTasks), readOnly_TCB_runState_IF_not_running_p(gTasks, gStates1)) );
/*@ list<TaskRunning_t> gStates2 = /*@ list<TaskRunning_t> gStates2 =
def_state2(gTasks, gStates, gCurrentTCB, pxTCB, xCoreID); def_state2(gTasks, gStates, gCurrentTCB, pxTCB, xCoreID);
@*/ @*/
/*@ close_updated_foreach_readOnly_sharedSeg_TCB(pxTCB, gTasks, gStates1, /*@ close_updated_foreach_readOnly_TCB_runState(pxTCB, gTasks, gStates1,
gStates2, xCoreID); gStates2, xCoreID);
@*/ @*/
/*@ startUpdate_foreach_readOnly_sharedSeg_TCB_IF_not_running /*@ startUpdate_foreach_readOnly_TCB_runState_IF_not_running
(pxTCB, gTasks, gStates1, gStates2, xCoreID); (pxTCB, gTasks, gStates1, gStates2, xCoreID);
@*/ @*/
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates2)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_p(gTasks, gStates2)) );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates2)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates2)) );
pxCurrentTCBs[ xCoreID ] = pxTCB; pxCurrentTCBs[ xCoreID ] = pxTCB;
xTaskScheduled = pdTRUE; xTaskScheduled = pdTRUE;
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gStates2)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_p(gTasks, gStates2)) );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates2)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates2)) );
//@ close exists_in_taskISRLockInv_p(gTasks, gStates2); //@ close exists_in_taskISRLockInv_p(gTasks, gStates2);
// Putting back first have of write permission to `pxTCB` // Putting back first have of write permission to `pxTCB`
//@ close [1/2]sharedSeg_TCB_p(pxTCB, _); //@ close [1/2]TCB_runState_p(pxTCB, _);
} }
} }
else if( pxTCB == pxCurrentTCBs[ xCoreID ] ) else if( pxTCB == pxCurrentTCBs[ xCoreID ] )
@ -1242,9 +1242,9 @@ static void prvYieldForTask( TCB_t * pxTCB,
#endif #endif
{ {
//@ assert( pxTCB->xTaskRunState != taskTASK_NOT_RUNNING ); //@ assert( pxTCB->xTaskRunState != taskTASK_NOT_RUNNING );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStates)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStates)) );
//@ assert( nth(index_of(pxTCB, gTasks), gStates) != taskTASK_NOT_RUNNING); //@ assert( nth(index_of(pxTCB, gTasks), gStates) != taskTASK_NOT_RUNNING);
//@ assert( foreach(remove(pxTCB, gTasks), readOnly_sharedSeg_TCB_p(gTasks, gStates)) ); //@ assert( foreach(remove(pxTCB, gTasks), readOnly_TCB_runState_p(gTasks, gStates)) );
/* The task is already running on this core, mark it as scheduled */ /* The task is already running on this core, mark it as scheduled */
pxTCB->xTaskRunState = ( TaskRunning_t ) xCoreID; pxTCB->xTaskRunState = ( TaskRunning_t ) xCoreID;
@ -1254,13 +1254,13 @@ static void prvYieldForTask( TCB_t * pxTCB,
= update(index_of(pxTCB, gTasks), xCoreID, gStates); = update(index_of(pxTCB, gTasks), xCoreID, gStates);
@*/ @*/
//@ open exists_in_taskISRLockInv_p(gTasks, gStates); //@ open exists_in_taskISRLockInv_p(gTasks, gStates);
/*@ scheduleRunning_in_foreach_readOnly_sharedSeg_TCB_IF_not_running /*@ scheduleRunning_in_foreach_readOnly_TCB_runState_IF_not_running
(pxTCB, gTasks, gStates, gEquivStates, xCoreID); (pxTCB, gTasks, gStates, gEquivStates, xCoreID);
@*/ @*/
//@ distinct_mem_remove(pxTCB, gTasks); //@ distinct_mem_remove(pxTCB, gTasks);
//@ remove_result_subset(pxTCB, gTasks); //@ remove_result_subset(pxTCB, gTasks);
/*@ update_foreach_readOnly_sharedSeg_TCB /*@ update_foreach_readOnly_TCB_runState
(pxTCB, gTasks, remove(pxTCB, gTasks), (pxTCB, gTasks, remove(pxTCB, gTasks),
gStates, gEquivStates, xCoreID); gStates, gEquivStates, xCoreID);
@*/ @*/
@ -1270,16 +1270,16 @@ static void prvYieldForTask( TCB_t * pxTCB,
// Put read permission for `pxTCB` back // Put read permission for `pxTCB` back
//@ foreach_unremove(pxTCB, gTasks); //@ foreach_unremove(pxTCB, gTasks);
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_p(gTasks, gEquivStates)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_p(gTasks, gEquivStates)) );
//@ close [1/2]sharedSeg_TCB_p(pxTCB, _); //@ close [1/2]TCB_runState_p(pxTCB, _);
} }
} }
/*@ /*@
if( !gPxTCB_not_running && pxTCB != gCurrentTCB ) { if( !gPxTCB_not_running && pxTCB != gCurrentTCB ) {
assert( exists_in_taskISRLockInv_p(gTasks, gStates) ); assert( exists_in_taskISRLockInv_p(gTasks, gStates) );
// Put read permission for `pxTCB` back // Put read permission for `pxTCB` back
close [1/2]sharedSeg_TCB_p(pxTCB, _); close [1/2]TCB_runState_p(pxTCB, _);
close readOnly_sharedSeg_TCB_p(gTasks, gStates)(pxTCB); close readOnly_TCB_runState_p(gTasks, gStates)(pxTCB);
foreach_unremove(pxTCB, gTasks); foreach_unremove(pxTCB, gTasks);
} }
@*/ @*/
@ -1325,8 +1325,8 @@ static void prvYieldForTask( TCB_t * pxTCB,
} }
//@ 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_TCB_runState_p(gTasks, gStatesEnd)) );
//@ assert( foreach(gTasks, readOnly_sharedSeg_TCB_IF_not_running_p(gTasks, gStatesEnd)) ); //@ assert( foreach(gTasks, readOnly_TCB_runState_IF_not_running_p(gTasks, gStatesEnd)) );
} while( pxTaskItem != pxLastTaskItem ); } while( pxTaskItem != pxLastTaskItem );
/* - If the loop above terminated via the break-branch, /* - If the loop above terminated via the break-branch,
@ -4388,7 +4388,7 @@ void vTaskSwitchContext( BaseType_t xCoreID )
coreLocalSeg_TCB_p(gCurrentTCB, 0) coreLocalSeg_TCB_p(gCurrentTCB, 0)
&*& &*&
// read access to current task's stack pointer, etc // read access to current task's stack pointer, etc
prvSeg_TCB_p(gCurrentTCB, ?ulFreeBytesOnStack); TCB_stack_p(gCurrentTCB, ?ulFreeBytesOnStack);
@*/ @*/
/*@ ensures // all locks are released and interrupts remain disabled /*@ ensures // all locks are released and interrupts remain disabled
@ -4403,7 +4403,7 @@ void vTaskSwitchContext( BaseType_t xCoreID )
coreLocalSeg_TCB_p(gCurrentTCB, 0) coreLocalSeg_TCB_p(gCurrentTCB, 0)
&*& &*&
// read access to current task's stack pointer, etc // read access to current task's stack pointer, etc
prvSeg_TCB_p(gCurrentTCB, ulFreeBytesOnStack); TCB_stack_p(gCurrentTCB, ulFreeBytesOnStack);
// Remark: the part of the post condition relating to TCBs will have to change. // Remark: the part of the post condition relating to TCBs will have to change.
@*/ @*/
{ {