Prove buffer lemmas (#124)

* Prove buffer lemmas

* Update queue proofs to latest kernel source

All changes were syntactic due to uncrustify code-formatting

* Strengthen prvCopyDataToQueue proof

* Add extract script for diff comparison

Co-authored-by: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com>
This commit is contained in:
Nathan Chong 2020-07-21 12:51:20 -04:00 committed by GitHub
parent c720c18ada
commit 8e36bee30e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 2021 additions and 1762 deletions

View file

@ -21,142 +21,142 @@
*/
#include "proof/queue.h"
#define taskENTER_CRITICAL() setInterruptMask(pxQueue)
#define taskEXIT_CRITICAL() clearInterruptMask(pxQueue)
#define taskENTER_CRITICAL() setInterruptMask( pxQueue )
#define taskEXIT_CRITICAL() clearInterruptMask( pxQueue )
/* VeriFast: we make one major change. We merge the critical regions for
decrementing `cTxLock` and `cRxLock`. */
* decrementing `cTxLock` and `cRxLock`. */
static void prvUnlockQueue( Queue_t * const pxQueue )
/*@requires [1/2]queuehandle(pxQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
[1/2]pxQueue->locked |-> ?m &*&
mutex_held(m, queue_locked_invariant(pxQueue), currentThread, 1/2) &*&
queue_locked_invariant(pxQueue)();@*/
[1/2]pxQueue->locked |-> ?m &*&
mutex_held(m, queue_locked_invariant(pxQueue), currentThread, 1/2) &*&
queue_locked_invariant(pxQueue)();@*/
/*@ensures [1/2]queuehandle(pxQueue, N, M, is_isr) &*&
[1/2]queuelock(pxQueue);@*/
[1/2]queuelock(pxQueue);@*/
{
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
/* The lock counts contains the number of extra data items placed or
removed from the queue while the queue was locked. When a queue is
locked items can be added or removed, but the event lists cannot be
updated. */
taskENTER_CRITICAL();
/*@open queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, _, ?abs);@*/
{
int8_t cTxLock = pxQueue->cTxLock;
/* The lock counts contains the number of extra data items placed or
* removed from the queue while the queue was locked. When a queue is
* locked items can be added or removed, but the event lists cannot be
* updated. */
taskENTER_CRITICAL();
/*@open queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, _, ?abs);@*/
{
int8_t cTxLock = pxQueue->cTxLock;
/* See if data was added to the queue while it was locked. */
while( cTxLock > queueLOCKED_UNMODIFIED )
/*@invariant queuelists(pxQueue);@*/
{
/* Data was posted while the queue was locked. Are any tasks
blocked waiting for data to become available? */
#if ( configUSE_QUEUE_SETS == 1 )
{
if( pxQueue->pxQueueSetContainer != NULL )
{
if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )
{
/* The queue is a member of a queue set, and posting to
the queue set caused a higher priority task to unblock.
A context switch is required. */
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
/* Tasks that are removed from the event list will get
added to the pending ready list as the scheduler is still
suspended. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that a
context switch is required. */
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
break;
}
}
}
#else /* configUSE_QUEUE_SETS */
{
/* Tasks that are removed from the event list will get added to
the pending ready list as the scheduler is still suspended. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that
a context switch is required. */
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
break;
}
}
#endif /* configUSE_QUEUE_SETS */
/* See if data was added to the queue while it was locked. */
while( cTxLock > queueLOCKED_UNMODIFIED )
/*@invariant queuelists(pxQueue);@*/
{
/* Data was posted while the queue was locked. Are any tasks
* blocked waiting for data to become available? */
#if ( configUSE_QUEUE_SETS == 1 )
{
if( pxQueue->pxQueueSetContainer != NULL )
{
if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )
{
/* The queue is a member of a queue set, and posting to
* the queue set caused a higher priority task to unblock.
* A context switch is required. */
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
/* Tasks that are removed from the event list will get
* added to the pending ready list as the scheduler is still
* suspended. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that a
* context switch is required. */
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
break;
}
}
}
#else /* configUSE_QUEUE_SETS */
{
/* Tasks that are removed from the event list will get added to
* the pending ready list as the scheduler is still suspended. */
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
{
/* The task waiting has a higher priority so record that
* a context switch is required. */
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
else
{
break;
}
}
#endif /* configUSE_QUEUE_SETS */
--cTxLock;
}
--cTxLock;
}
pxQueue->cTxLock = queueUNLOCKED;
}
pxQueue->cTxLock = queueUNLOCKED;
}
#ifndef VERIFAST /*< ***merge cTxLock and cRxLock critical regions*** */
taskEXIT_CRITICAL();
taskEXIT_CRITICAL();
/* Do the same for the Rx lock. */
taskENTER_CRITICAL();
/* Do the same for the Rx lock. */
taskENTER_CRITICAL();
#endif
{
int8_t cRxLock = pxQueue->cRxLock;
{
int8_t cRxLock = pxQueue->cRxLock;
while( cRxLock > queueLOCKED_UNMODIFIED )
/*@invariant queuelists(pxQueue);@*/
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
while( cRxLock > queueLOCKED_UNMODIFIED )
/*@invariant queuelists(pxQueue);@*/
{
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
{
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
{
vTaskMissedYield();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
--cRxLock;
}
else
{
break;
}
}
--cRxLock;
}
else
{
break;
}
}
pxQueue->cRxLock = queueUNLOCKED;
}
/*@close queue(pxQueue, Storage, N, M, W, R, K, false, abs);@*/
taskEXIT_CRITICAL();
pxQueue->cRxLock = queueUNLOCKED;
}
/*@close queue(pxQueue, Storage, N, M, W, R, K, false, abs);@*/
taskEXIT_CRITICAL();
#ifdef VERIFAST /*< ghost action */
mutex_release(pxQueue->locked);
mutex_release( pxQueue->locked );
#endif
}