mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-10-18 10:47:47 -04:00
Update VeriFast proofs (#836)
* Undo syntax changes preventing VeriFast parsing * Update proofs inline with source changes Outstanding: - xQueueGenericReset return code - Not using prvIncrementQueueTxLock or prvIncrementQueueRxLock macros * Remove git hash check * Document new changes between proven code and implementation * Update copyright header * VeriFast proofs: turn off uncrustify checks Uncrustify requires formatting of comments that is at odds with VeriFast's proof annotations, which are contained within comments. * Update ci.yml Co-authored-by: Joseph Julicher <jjulicher@mac.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>
This commit is contained in:
parent
4e0fecaadd
commit
4f87f485d5
32 changed files with 1877 additions and 1864 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -114,7 +114,7 @@ jobs:
|
||||||
# Add path to the tool to the environment variable.
|
# Add path to the tool to the environment variable.
|
||||||
PATH=$PATH:commonCI/spellings/tools
|
PATH=$PATH:commonCI/spellings/tools
|
||||||
# Make sure that only Amazon licenced files are checked.
|
# Make sure that only Amazon licenced files are checked.
|
||||||
sed -i 's/`find $DIRNAME \\( -iname \\\*\.\[ch\] -o -iname \\\*\.dox \\) -type f`/`grep -ril "copyright \(c\) \[0-9\]\[0-9\]\[0-9\]\[0-9\] amazon.com" | grep "\\.\[ch\]"`/g' commonCI/spellings/tools/find-unknown-comment-words
|
sed -i 's/`find $DIRNAME \\( -iname \\\*\.\[ch\] -o -iname \\\*\.dox \\) -type f`/`grep -ril "copyright \(c\) \[0-9\]\[0-9\]\[0-9\]\[0-9\] amazon.com" | grep "\\.\[ch\]" | grep -v "FreeRTOS\/FreeRTOS\/Test\/VeriFast"`/g' commonCI/spellings/tools/find-unknown-comment-words
|
||||||
# Run the spell check script.
|
# Run the spell check script.
|
||||||
find-unknown-comment-words --directory FreeRTOS/ --lexicon FreeRTOS/lexicon.txt
|
find-unknown-comment-words --directory FreeRTOS/ --lexicon FreeRTOS/lexicon.txt
|
||||||
# Check the exit status.
|
# Check the exit status.
|
||||||
|
|
|
@ -18,7 +18,7 @@ all: queue list
|
||||||
|
|
||||||
.PHONY: queue
|
.PHONY: queue
|
||||||
queue:
|
queue:
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) queue/create.c | $(call check_coverage,325)
|
@$(VERIFAST) $(VERIFAST_ARGS) -disable_overflow_check queue/create.c | $(call check_coverage,315)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) queue/prvCopyDataFromQueue.c | $(call check_coverage,308)
|
@$(VERIFAST) $(VERIFAST_ARGS) queue/prvCopyDataFromQueue.c | $(call check_coverage,308)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) -disable_overflow_check queue/prvCopyDataToQueue.c | $(call check_coverage,336)
|
@$(VERIFAST) $(VERIFAST_ARGS) -disable_overflow_check queue/prvCopyDataToQueue.c | $(call check_coverage,336)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) queue/prvIsQueueEmpty.c | $(call check_coverage,289)
|
@$(VERIFAST) $(VERIFAST_ARGS) queue/prvIsQueueEmpty.c | $(call check_coverage,289)
|
||||||
|
@ -41,7 +41,7 @@ queue:
|
||||||
list:
|
list:
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) list/listLIST_IS_EMPTY.c | $(call check_coverage,314)
|
@$(VERIFAST) $(VERIFAST_ARGS) list/listLIST_IS_EMPTY.c | $(call check_coverage,314)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) list/uxListRemove.c | $(call check_coverage,440)
|
@$(VERIFAST) $(VERIFAST_ARGS) list/uxListRemove.c | $(call check_coverage,440)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) list/vListInitialise.c | $(call check_coverage,325)
|
@$(VERIFAST) $(VERIFAST_ARGS) list/vListInitialise.c | $(call check_coverage,329)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) list/vListInitialiseItem.c | $(call check_coverage,316)
|
@$(VERIFAST) $(VERIFAST_ARGS) list/vListInitialiseItem.c | $(call check_coverage,316)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) -disable_overflow_check list/vListInsertEnd.c | $(call check_coverage,410)
|
@$(VERIFAST) $(VERIFAST_ARGS) -disable_overflow_check list/vListInsertEnd.c | $(call check_coverage,410)
|
||||||
@$(VERIFAST) $(VERIFAST_ARGS) -disable_overflow_check list/vListInsert.c | $(call check_coverage,456)
|
@$(VERIFAST) $(VERIFAST_ARGS) -disable_overflow_check list/vListInsert.c | $(call check_coverage,456)
|
||||||
|
@ -49,18 +49,3 @@ list:
|
||||||
.PHONY: proof_changes
|
.PHONY: proof_changes
|
||||||
proof_changes:
|
proof_changes:
|
||||||
@git grep "if[n]*def VERIFAST" | cut -f 3- -d ' ' | sort | uniq
|
@git grep "if[n]*def VERIFAST" | cut -f 3- -d ' ' | sort | uniq
|
||||||
|
|
||||||
GIT?=git
|
|
||||||
NO_CHANGE_CHECKOUT_DIR=no-change-check-freertos-kernel
|
|
||||||
NO_CHANGE_EXPECTED_HASH_QUEUE = ec62f69dab7
|
|
||||||
NO_CHANGE_EXPECTED_HASH_QUEUE_HEADER = ec62f69dab7
|
|
||||||
NO_CHANGE_EXPECTED_HASH_LIST = ec62f69dab7
|
|
||||||
NO_CHANGE_EXPECTED_HASH_LIST_HEADER = ec62f69dab7
|
|
||||||
.PHONY: synced_with_source_check
|
|
||||||
synced_with_source_check:
|
|
||||||
@rm -rf $(NO_CHANGE_CHECKOUT_DIR)
|
|
||||||
@$(GIT) clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git $(NO_CHANGE_CHECKOUT_DIR)
|
|
||||||
@cd $(NO_CHANGE_CHECKOUT_DIR) && $(GIT) diff --quiet $(NO_CHANGE_EXPECTED_HASH_QUEUE) queue.c
|
|
||||||
@cd $(NO_CHANGE_CHECKOUT_DIR) && $(GIT) diff --quiet $(NO_CHANGE_EXPECTED_HASH_QUEUE_HEADER) include/queue.h
|
|
||||||
@cd $(NO_CHANGE_CHECKOUT_DIR) && $(GIT) diff --quiet $(NO_CHANGE_EXPECTED_HASH_LIST) list.c
|
|
||||||
@cd $(NO_CHANGE_CHECKOUT_DIR) && $(GIT) diff --quiet $(NO_CHANGE_EXPECTED_HASH_LIST_HEADER) include/list.h
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ Then click `Verify` and `Verify Program` (or press F5). Note that the following
|
||||||
proofs require arithmetic overflow checking to be turned off (click `Verify`
|
proofs require arithmetic overflow checking to be turned off (click `Verify`
|
||||||
and uncheck `Check arithmetic overflow`).
|
and uncheck `Check arithmetic overflow`).
|
||||||
|
|
||||||
|
- `queue/create.c`
|
||||||
- `queue/prvCopyDataToQueue.c`
|
- `queue/prvCopyDataToQueue.c`
|
||||||
- `queue/xQueueGenericSendFromISR.c`
|
- `queue/xQueueGenericSendFromISR.c`
|
||||||
- `queue/xQueueReceiveFromISR.c`
|
- `queue/xQueueReceiveFromISR.c`
|
||||||
|
|
|
@ -71,16 +71,19 @@ A side-by-side diff with respect to the source code can be generated. See
|
||||||
The main queue changes are:
|
The main queue changes are:
|
||||||
|
|
||||||
- merge cTxLock and cRxLock critical regions: under approximate queue
|
- merge cTxLock and cRxLock critical regions: under approximate queue
|
||||||
unlock behavior to atomically set `cTxLock` and `cRxLock` to unlocked in a
|
unlock behavior to atomically set `cTxLock` and `cRxLock` to unlocked in a
|
||||||
single critical region instead of two separate critical regions. In
|
single critical region instead of two separate critical regions. In
|
||||||
practice, this is not an issue since no ISR function reads-from both
|
practice, this is not an issue since no ISR function reads-from both
|
||||||
cTxLock and cRxLock.
|
cTxLock and cRxLock.
|
||||||
- model single malloc of struct and buffer: split the single malloc of the
|
- model single malloc of struct and buffer: split the single malloc of the
|
||||||
queue struct and storage into two separate mallocs.
|
queue struct and storage into two separate mallocs.
|
||||||
- xQueueGenericReset happens-before concurrent behavior: assume that queue
|
- xQueueGenericReset happens-before concurrent behavior: assume that queue
|
||||||
initialisation is not concurrent.
|
initialisation is not concurrent.
|
||||||
- do not model pxIndex and xListEnd of xLIST struct: ignore these fields in
|
- do not model pxIndex and xListEnd of xLIST struct: ignore these fields in
|
||||||
the list structs of the queue implementation
|
the list structs of the queue implementation.
|
||||||
|
- we do not use the prvIncrementQueueTxLock or prvIncrementQueueRxLock macros
|
||||||
|
in xQueueGenericSendFromISR and xQueueReceiveFromISR functions.
|
||||||
|
- we prove an older version of xQueueGenericReset that always resets a queue
|
||||||
|
|
||||||
The main list changes are:
|
The main list changes are:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,20 +24,22 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#ifndef LIST_H
|
#ifndef LIST_H
|
||||||
#define LIST_H
|
#define LIST_H
|
||||||
|
|
||||||
#define VERIFAST
|
#define VERIFAST
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
/*@#include "common.gh" */
|
//@#include "common.gh"
|
||||||
|
|
||||||
typedef size_t TickType_t;
|
typedef size_t TickType_t;
|
||||||
typedef size_t UBaseType_t;
|
typedef size_t UBaseType_t;
|
||||||
typedef ssize_t BaseType_t;
|
typedef ssize_t BaseType_t;
|
||||||
|
|
||||||
#define pdTRUE 1
|
#define pdTRUE 1
|
||||||
#define pdFALSE 0
|
#define pdFALSE 0
|
||||||
|
|
||||||
/* Empty/no-op macros */
|
/* Empty/no-op macros */
|
||||||
#define mtCOVERAGE_TEST_MARKER()
|
#define mtCOVERAGE_TEST_MARKER()
|
||||||
|
@ -50,327 +52,325 @@ typedef ssize_t BaseType_t;
|
||||||
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxListItem )
|
#define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxListItem )
|
||||||
|
|
||||||
/* Max value stored in sentinel xListEnd element */
|
/* Max value stored in sentinel xListEnd element */
|
||||||
#define portMAX_DELAY UINT_MAX
|
#define portMAX_DELAY UINT_MAX
|
||||||
|
|
||||||
struct xLIST;
|
struct xLIST;
|
||||||
|
|
||||||
struct xLIST_ITEM
|
struct xLIST_ITEM {
|
||||||
{
|
TickType_t xItemValue;
|
||||||
TickType_t xItemValue;
|
struct xLIST_ITEM * pxNext;
|
||||||
struct xLIST_ITEM * pxNext;
|
struct xLIST_ITEM * pxPrevious;
|
||||||
struct xLIST_ITEM * pxPrevious;
|
void * pvOwner;
|
||||||
void * pvOwner;
|
struct xLIST *pxContainer;
|
||||||
struct xLIST * pxContainer;
|
|
||||||
};
|
};
|
||||||
typedef struct xLIST_ITEM ListItem_t;
|
typedef struct xLIST_ITEM ListItem_t;
|
||||||
|
|
||||||
typedef struct xLIST
|
typedef struct xLIST {
|
||||||
{
|
UBaseType_t uxNumberOfItems;
|
||||||
UBaseType_t uxNumberOfItems;
|
struct xLIST_ITEM *pxIndex;
|
||||||
struct xLIST_ITEM * pxIndex;
|
#ifdef VERIFAST /*< ***change MiniList_t to ListItem_t*** */
|
||||||
#ifdef VERIFAST /*< ***change MiniList_t to ListItem_t*** */
|
struct xLIST_ITEM xListEnd;
|
||||||
struct xLIST_ITEM xListEnd;
|
#else
|
||||||
#else
|
MiniListItem_t xListEnd;
|
||||||
MiniListItem_t xListEnd;
|
#endif
|
||||||
#endif
|
|
||||||
} List_t;
|
} List_t;
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate xLIST_ITEM(
|
predicate xLIST_ITEM(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* TickType_t xItemValue,
|
TickType_t xItemValue,
|
||||||
* struct xLIST_ITEM *pxNext,
|
struct xLIST_ITEM *pxNext,
|
||||||
* struct xLIST_ITEM *pxPrevious,
|
struct xLIST_ITEM *pxPrevious,
|
||||||
* struct xLIST *pxContainer;) =
|
struct xLIST *pxContainer;) =
|
||||||
* n->xItemValue |-> xItemValue &*&
|
n->xItemValue |-> xItemValue &*&
|
||||||
* n->pxNext |-> pxNext &*&
|
n->pxNext |-> pxNext &*&
|
||||||
* n->pxPrevious |-> pxPrevious &*&
|
n->pxPrevious |-> pxPrevious &*&
|
||||||
* n->pvOwner |-> _ &*&
|
n->pvOwner |-> _ &*&
|
||||||
* n->pxContainer |-> pxContainer;
|
n->pxContainer |-> pxContainer;
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* Ferreira et al. (STTT'14) doubly-linked list segment (DLS). */
|
/* Ferreira et al. (STTT'14) doubly-linked list segment (DLS). */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate DLS(
|
predicate DLS(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* struct xLIST_ITEM *nprev,
|
struct xLIST_ITEM *nprev,
|
||||||
* struct xLIST_ITEM *mnext,
|
struct xLIST_ITEM *mnext,
|
||||||
* struct xLIST_ITEM *m,
|
struct xLIST_ITEM *m,
|
||||||
* list<struct xLIST_ITEM * > cells,
|
list<struct xLIST_ITEM * > cells,
|
||||||
* list<TickType_t > vals,
|
list<TickType_t > vals,
|
||||||
* struct xLIST *pxContainer) =
|
struct xLIST *pxContainer) =
|
||||||
* n == m
|
n == m
|
||||||
* ? cells == cons(n, nil) &*&
|
? cells == cons(n, nil) &*&
|
||||||
* vals == cons(?v, nil) &*&
|
vals == cons(?v, nil) &*&
|
||||||
* xLIST_ITEM(n, v, mnext, nprev, pxContainer)
|
xLIST_ITEM(n, v, mnext, nprev, pxContainer)
|
||||||
* : cells == cons(n, ?cells0) &*&
|
: cells == cons(n, ?cells0) &*&
|
||||||
* vals == cons(?v, ?vals0) &*&
|
vals == cons(?v, ?vals0) &*&
|
||||||
* xLIST_ITEM(n, v, ?o, nprev, pxContainer) &*& DLS(o, n, mnext, m, cells0, vals0, pxContainer);
|
xLIST_ITEM(n, v, ?o, nprev, pxContainer) &*& DLS(o, n, mnext, m, cells0, vals0, pxContainer);
|
||||||
*
|
|
||||||
* lemma void dls_star_item(
|
lemma void dls_star_item(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* struct xLIST_ITEM *m,
|
struct xLIST_ITEM *m,
|
||||||
* struct xLIST_ITEM *o)
|
struct xLIST_ITEM *o)
|
||||||
* requires DLS(n, ?nprev, ?mnext, m, ?cells, ?vals, ?l) &*& xLIST_ITEM(o, ?v, ?onext, ?oprev, ?l2);
|
requires DLS(n, ?nprev, ?mnext, m, ?cells, ?vals, ?l) &*& xLIST_ITEM(o, ?v, ?onext, ?oprev, ?l2);
|
||||||
* ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& xLIST_ITEM(o, v, onext, oprev, l2) &*& mem(o, cells) == false;
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& xLIST_ITEM(o, v, onext, oprev, l2) &*& mem(o, cells) == false;
|
||||||
* {
|
{
|
||||||
* open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* if (n == m) {
|
if (n == m) {
|
||||||
* assert xLIST_ITEM(n, _, _, _, _);
|
assert xLIST_ITEM(n, _, _, _, _);
|
||||||
* open xLIST_ITEM(n, _, _, _, _);
|
open xLIST_ITEM(n, _, _, _, _);
|
||||||
* open xLIST_ITEM(o, _, _, _, _);
|
open xLIST_ITEM(o, _, _, _, _);
|
||||||
* assert n != o;
|
assert n != o;
|
||||||
* close xLIST_ITEM(o, _, _, _, _);
|
close xLIST_ITEM(o, _, _, _, _);
|
||||||
* close xLIST_ITEM(n, _, _, _, _);
|
close xLIST_ITEM(n, _, _, _, _);
|
||||||
* close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* }
|
}
|
||||||
* else {
|
else {
|
||||||
* assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
* dls_star_item(nnext, m, o);
|
dls_star_item(nnext, m, o);
|
||||||
* open xLIST_ITEM(n, _, _, _, _);
|
open xLIST_ITEM(n, _, _, _, _);
|
||||||
* open xLIST_ITEM(o, _, _, _, _);
|
open xLIST_ITEM(o, _, _, _, _);
|
||||||
* assert n != o;
|
assert n != o;
|
||||||
* close xLIST_ITEM(o, _, _, _, _);
|
close xLIST_ITEM(o, _, _, _, _);
|
||||||
* close xLIST_ITEM(n, _, _, _, _);
|
close xLIST_ITEM(n, _, _, _, _);
|
||||||
* close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void dls_distinct(
|
lemma void dls_distinct(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* struct xLIST_ITEM *nprev,
|
struct xLIST_ITEM *nprev,
|
||||||
* struct xLIST_ITEM *mnext,
|
struct xLIST_ITEM *mnext,
|
||||||
* struct xLIST_ITEM *m,
|
struct xLIST_ITEM *m,
|
||||||
* list<struct xLIST_ITEM * > cells)
|
list<struct xLIST_ITEM * > cells)
|
||||||
* requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
||||||
* ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& distinct(cells) == true;
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& distinct(cells) == true;
|
||||||
* {
|
{
|
||||||
* if (n == m) {
|
if (n == m) {
|
||||||
* open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* } else {
|
} else {
|
||||||
* open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
assert DLS(?nnext, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
* dls_distinct(nnext, n, mnext, m, tail(cells));
|
dls_distinct(nnext, n, mnext, m, tail(cells));
|
||||||
* dls_star_item(nnext, m, n);
|
dls_star_item(nnext, m, n);
|
||||||
* close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* predicate xLIST(
|
predicate xLIST(
|
||||||
* struct xLIST *l,
|
struct xLIST *l,
|
||||||
* int uxNumberOfItems,
|
int uxNumberOfItems,
|
||||||
* struct xLIST_ITEM *pxIndex,
|
struct xLIST_ITEM *pxIndex,
|
||||||
* struct xLIST_ITEM *xListEnd,
|
struct xLIST_ITEM *xListEnd,
|
||||||
* list<struct xLIST_ITEM *>cells,
|
list<struct xLIST_ITEM *>cells,
|
||||||
* list<TickType_t >vals) =
|
list<TickType_t >vals) =
|
||||||
* l->uxNumberOfItems |-> uxNumberOfItems &*&
|
l->uxNumberOfItems |-> uxNumberOfItems &*&
|
||||||
* l->pxIndex |-> pxIndex &*&
|
l->pxIndex |-> pxIndex &*&
|
||||||
* mem(pxIndex, cells) == true &*&
|
mem(pxIndex, cells) == true &*&
|
||||||
* xListEnd == &(l->xListEnd) &*&
|
xListEnd == &(l->xListEnd) &*&
|
||||||
* xListEnd == head(cells) &*&
|
xListEnd == head(cells) &*&
|
||||||
* portMAX_DELAY == head(vals) &*&
|
portMAX_DELAY == head(vals) &*&
|
||||||
* struct_xLIST_ITEM_padding(&l->xListEnd) &*&
|
struct_xLIST_ITEM_padding(&l->xListEnd) &*&
|
||||||
* length(cells) == length(vals) &*&
|
length(cells) == length(vals) &*&
|
||||||
* uxNumberOfItems + 1 == length(cells) &*&
|
uxNumberOfItems + 1 == length(cells) &*&
|
||||||
* DLS(xListEnd, ?endprev, xListEnd, endprev, cells, vals, l);
|
DLS(xListEnd, ?endprev, xListEnd, endprev, cells, vals, l);
|
||||||
*
|
|
||||||
* lemma void xLIST_distinct_cells(struct xLIST *l)
|
lemma void xLIST_distinct_cells(struct xLIST *l)
|
||||||
* requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals);
|
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals);
|
||||||
* ensures xLIST(l, n, idx, end, cells, vals) &*& distinct(cells) == true;
|
ensures xLIST(l, n, idx, end, cells, vals) &*& distinct(cells) == true;
|
||||||
* {
|
{
|
||||||
* open xLIST(l, n, idx, end, cells, vals);
|
open xLIST(l, n, idx, end, cells, vals);
|
||||||
* assert DLS(end, ?endprev, end, _, cells, vals, l);
|
assert DLS(end, ?endprev, end, _, cells, vals, l);
|
||||||
* dls_distinct(end, endprev, end, endprev, cells);
|
dls_distinct(end, endprev, end, endprev, cells);
|
||||||
* close xLIST(l, n, idx, end, cells, vals);
|
close xLIST(l, n, idx, end, cells, vals);
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void xLIST_star_item(struct xLIST *l, struct xLIST_ITEM *x)
|
lemma void xLIST_star_item(struct xLIST *l, struct xLIST_ITEM *x)
|
||||||
* requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals) &*& xLIST_ITEM(x, ?v, ?xnext, ?xprev, ?l2);
|
requires xLIST(l, ?n, ?idx, ?end, ?cells, ?vals) &*& xLIST_ITEM(x, ?v, ?xnext, ?xprev, ?l2);
|
||||||
* ensures xLIST(l, n, idx, end, cells, vals) &*& xLIST_ITEM(x, v, xnext, xprev, l2) &*& mem(x, cells) == false;
|
ensures xLIST(l, n, idx, end, cells, vals) &*& xLIST_ITEM(x, v, xnext, xprev, l2) &*& mem(x, cells) == false;
|
||||||
* {
|
{
|
||||||
* open xLIST(l, n, idx, end, cells, vals);
|
open xLIST(l, n, idx, end, cells, vals);
|
||||||
* assert DLS(end, ?endprev, end, _, cells, vals, l);
|
assert DLS(end, ?endprev, end, _, cells, vals, l);
|
||||||
* dls_distinct(end, endprev, end, endprev, cells);
|
dls_distinct(end, endprev, end, endprev, cells);
|
||||||
* dls_star_item(end, endprev, x);
|
dls_star_item(end, endprev, x);
|
||||||
* close xLIST(l, n, idx, end, cells, vals);
|
close xLIST(l, n, idx, end, cells, vals);
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void dls_first_mem(
|
lemma void dls_first_mem(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* struct xLIST_ITEM *nprev,
|
struct xLIST_ITEM *nprev,
|
||||||
* struct xLIST_ITEM *mnext,
|
struct xLIST_ITEM *mnext,
|
||||||
* struct xLIST_ITEM *m,
|
struct xLIST_ITEM *m,
|
||||||
* list<struct xLIST_ITEM * > cells)
|
list<struct xLIST_ITEM * > cells)
|
||||||
* requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
||||||
* ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(n, cells) == true &*& index_of(n, cells) == 0;
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(n, cells) == true &*& index_of(n, cells) == 0;
|
||||||
* {
|
{
|
||||||
* open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* if (n == m) {
|
if (n == m) {
|
||||||
* assert cells == cons(n, nil);
|
assert cells == cons(n, nil);
|
||||||
* close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* } else {
|
} else {
|
||||||
* assert cells == cons(n, ?tail);
|
assert cells == cons(n, ?tail);
|
||||||
* close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void dls_not_empty(
|
lemma void dls_not_empty(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* struct xLIST_ITEM *m,
|
struct xLIST_ITEM *m,
|
||||||
* list<struct xLIST_ITEM * > cells,
|
list<struct xLIST_ITEM * > cells,
|
||||||
* struct xLIST_ITEM *x)
|
struct xLIST_ITEM *x)
|
||||||
* requires DLS(n, m, n, m, cells, ?vals, ?l) &*& mem(x, cells) == true &*& x != n;
|
requires DLS(n, m, n, m, cells, ?vals, ?l) &*& mem(x, cells) == true &*& x != n;
|
||||||
* ensures DLS(n, m, n, m, cells, vals, l) &*& n != m;
|
ensures DLS(n, m, n, m, cells, vals, l) &*& n != m;
|
||||||
* {
|
{
|
||||||
* open DLS(n, m, n, m, cells, vals, l);
|
open DLS(n, m, n, m, cells, vals, l);
|
||||||
* close DLS(n, m, n, m, cells, vals, l);
|
close DLS(n, m, n, m, cells, vals, l);
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void dls_last_mem(
|
lemma void dls_last_mem(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* struct xLIST_ITEM *nprev,
|
struct xLIST_ITEM *nprev,
|
||||||
* struct xLIST_ITEM *mnext,
|
struct xLIST_ITEM *mnext,
|
||||||
* struct xLIST_ITEM *m,
|
struct xLIST_ITEM *m,
|
||||||
* list<struct xLIST_ITEM * > cells)
|
list<struct xLIST_ITEM * > cells)
|
||||||
* requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
requires DLS(n, nprev, mnext, m, cells, ?vals, ?l);
|
||||||
* ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(m, cells) == true &*& index_of(m, cells) == length(cells) - 1;
|
ensures DLS(n, nprev, mnext, m, cells, vals, l) &*& mem(m, cells) == true &*& index_of(m, cells) == length(cells) - 1;
|
||||||
* {
|
{
|
||||||
* open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* if (n == m) {
|
if (n == m) {
|
||||||
* // trivial
|
// trivial
|
||||||
* } else {
|
} else {
|
||||||
* open xLIST_ITEM(n, _, ?nnext, _, l);
|
open xLIST_ITEM(n, _, ?nnext, _, l);
|
||||||
* assert DLS(?o, n, mnext, m, tail(cells), tail(vals), l);
|
assert DLS(?o, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
* dls_last_mem(o, n, mnext, m, tail(cells));
|
dls_last_mem(o, n, mnext, m, tail(cells));
|
||||||
* close xLIST_ITEM(n, _, nnext, _, l);
|
close xLIST_ITEM(n, _, nnext, _, l);
|
||||||
* }
|
}
|
||||||
* close DLS(n, nprev, mnext, m, cells, vals, l);
|
close DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void split(
|
lemma void split(
|
||||||
* struct xLIST_ITEM *n,
|
struct xLIST_ITEM *n,
|
||||||
* struct xLIST_ITEM *nprev,
|
struct xLIST_ITEM *nprev,
|
||||||
* struct xLIST_ITEM *mnext,
|
struct xLIST_ITEM *mnext,
|
||||||
* struct xLIST_ITEM *m,
|
struct xLIST_ITEM *m,
|
||||||
* list<struct xLIST_ITEM * > cells,
|
list<struct xLIST_ITEM * > cells,
|
||||||
* list<TickType_t > vals,
|
list<TickType_t > vals,
|
||||||
* struct xLIST_ITEM *x,
|
struct xLIST_ITEM *x,
|
||||||
* int i)
|
int i)
|
||||||
* requires DLS(n, nprev, mnext, m, cells, vals, ?l) &*& x != n &*& mem(x, cells) == true &*& index_of(x,cells) == i;
|
requires DLS(n, nprev, mnext, m, cells, vals, ?l) &*& x != n &*& mem(x, cells) == true &*& index_of(x,cells) == i;
|
||||||
* ensures DLS(n, nprev, x, ?xprev, take(i, cells), take(i, vals), l) &*& DLS(x, xprev, mnext, m, drop(i, cells), drop(i, vals), l) &*& xprev == nth(i-1, cells);
|
ensures DLS(n, nprev, x, ?xprev, take(i, cells), take(i, vals), l) &*& DLS(x, xprev, mnext, m, drop(i, cells), drop(i, vals), l) &*& xprev == nth(i-1, cells);
|
||||||
* {
|
{
|
||||||
* open DLS(n, nprev, mnext, m, cells, vals, l);
|
open DLS(n, nprev, mnext, m, cells, vals, l);
|
||||||
* assert n != m;
|
assert n != m;
|
||||||
* assert xLIST_ITEM(n, ?v, ?nnext, _, _);
|
assert xLIST_ITEM(n, ?v, ?nnext, _, _);
|
||||||
* assert DLS(nnext, n, mnext, m, tail(cells), tail(vals), l);
|
assert DLS(nnext, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
* if (nnext == x) {
|
if (nnext == x) {
|
||||||
* close DLS(n, nprev, x, n, singleton(n), singleton(v), l);
|
close DLS(n, nprev, x, n, singleton(n), singleton(v), l);
|
||||||
* open DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
open DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
* open xLIST_ITEM(x, _, ?xnext, ?xprev, l);
|
open xLIST_ITEM(x, _, ?xnext, ?xprev, l);
|
||||||
* close xLIST_ITEM(x, _, xnext, xprev, l);
|
close xLIST_ITEM(x, _, xnext, xprev, l);
|
||||||
* close DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
close DLS(x, n, mnext, m, tail(cells), tail(vals), l);
|
||||||
* } else {
|
} else {
|
||||||
* assert nnext != x;
|
assert nnext != x;
|
||||||
* split(nnext, n, mnext, m, tail(cells), tail(vals), x, i - 1);
|
split(nnext, n, mnext, m, tail(cells), tail(vals), x, i - 1);
|
||||||
* assert DLS(nnext, n, x, ?xprev, take(i-1, tail(cells)), take(i-1, tail(vals)), l);
|
assert DLS(nnext, n, x, ?xprev, take(i-1, tail(cells)), take(i-1, tail(vals)), l);
|
||||||
* dls_distinct(nnext, n, x, xprev, take(i-1, tail(cells)));
|
dls_distinct(nnext, n, x, xprev, take(i-1, tail(cells)));
|
||||||
* dls_star_item(nnext, xprev, n);
|
dls_star_item(nnext, xprev, n);
|
||||||
* dls_last_mem(nnext, n, x, xprev, take(i-1, tail(cells)));
|
dls_last_mem(nnext, n, x, xprev, take(i-1, tail(cells)));
|
||||||
* assert n != xprev;
|
assert n != xprev;
|
||||||
* close DLS(n, nprev, x, xprev, take(i, cells), take(i, vals), l);
|
close DLS(n, nprev, x, xprev, take(i, cells), take(i, vals), l);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void join(
|
lemma void join(
|
||||||
* struct xLIST_ITEM *n1,
|
struct xLIST_ITEM *n1,
|
||||||
* struct xLIST_ITEM *nprev1,
|
struct xLIST_ITEM *nprev1,
|
||||||
* struct xLIST_ITEM *mnext1,
|
struct xLIST_ITEM *mnext1,
|
||||||
* struct xLIST_ITEM *m1,
|
struct xLIST_ITEM *m1,
|
||||||
* list<struct xLIST_ITEM * > cells1,
|
list<struct xLIST_ITEM * > cells1,
|
||||||
* list<TickType_t > vals1,
|
list<TickType_t > vals1,
|
||||||
* struct xLIST_ITEM *n2,
|
struct xLIST_ITEM *n2,
|
||||||
* struct xLIST_ITEM *nprev2,
|
struct xLIST_ITEM *nprev2,
|
||||||
* struct xLIST_ITEM *mnext2,
|
struct xLIST_ITEM *mnext2,
|
||||||
* struct xLIST_ITEM *m2,
|
struct xLIST_ITEM *m2,
|
||||||
* list<struct xLIST_ITEM * > cells2,
|
list<struct xLIST_ITEM * > cells2,
|
||||||
* list<TickType_t > vals2)
|
list<TickType_t > vals2)
|
||||||
* requires
|
requires
|
||||||
* DLS(n1, nprev1, mnext1, m1, cells1, vals1, ?l) &*&
|
DLS(n1, nprev1, mnext1, m1, cells1, vals1, ?l) &*&
|
||||||
* DLS(n2, nprev2, mnext2, m2, cells2, vals2, l) &*&
|
DLS(n2, nprev2, mnext2, m2, cells2, vals2, l) &*&
|
||||||
* mnext1 == n2 &*& m1 == nprev2;
|
mnext1 == n2 &*& m1 == nprev2;
|
||||||
* ensures DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
ensures DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
||||||
* {
|
{
|
||||||
* if (n1 == m1) {
|
if (n1 == m1) {
|
||||||
* dls_first_mem(n1, nprev1, mnext1, m1, cells1);
|
dls_first_mem(n1, nprev1, mnext1, m1, cells1);
|
||||||
* dls_last_mem(n2, nprev2, mnext2, m2, cells2);
|
dls_last_mem(n2, nprev2, mnext2, m2, cells2);
|
||||||
* open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
||||||
* dls_star_item(n2, m2, n1);
|
dls_star_item(n2, m2, n1);
|
||||||
* close DLS(n1, nprev1, mnext2, m2, append(singleton(n1), cells2), append(vals1, vals2), l);
|
close DLS(n1, nprev1, mnext2, m2, append(singleton(n1), cells2), append(vals1, vals2), l);
|
||||||
* } else {
|
} else {
|
||||||
* open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
open DLS(n1, nprev1, mnext1, m1, cells1, vals1, l);
|
||||||
* assert DLS(?o, n1, mnext1, m1, ?cells1_tail, ?vals1_tail, l);
|
assert DLS(?o, n1, mnext1, m1, ?cells1_tail, ?vals1_tail, l);
|
||||||
* join(o, n1, mnext1, m1, cells1_tail, vals1_tail,
|
join(o, n1, mnext1, m1, cells1_tail, vals1_tail,
|
||||||
* n2, nprev2, mnext2, m2, cells2, vals2);
|
n2, nprev2, mnext2, m2, cells2, vals2);
|
||||||
* assert DLS(o, n1, mnext2, m2, append(cells1_tail, cells2), append(vals1_tail, vals2), l);
|
assert DLS(o, n1, mnext2, m2, append(cells1_tail, cells2), append(vals1_tail, vals2), l);
|
||||||
* dls_last_mem(o, n1, mnext2, m2, append(cells1_tail, cells2));
|
dls_last_mem(o, n1, mnext2, m2, append(cells1_tail, cells2));
|
||||||
* dls_star_item(o, m2, n1);
|
dls_star_item(o, m2, n1);
|
||||||
* close DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
close DLS(n1, nprev1, mnext2, m2, append(cells1, cells2), append(vals1, vals2), l);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void idx_remains_in_list<t>(
|
lemma void idx_remains_in_list<t>(
|
||||||
* list<t> cells,
|
list<t> cells,
|
||||||
* t idx,
|
t idx,
|
||||||
* t x,
|
t x,
|
||||||
* int ix)
|
int ix)
|
||||||
* requires
|
requires
|
||||||
* idx != x &*&
|
idx != x &*&
|
||||||
* mem(idx, cells) == true &*&
|
mem(idx, cells) == true &*&
|
||||||
* mem(x, cells) == true &*&
|
mem(x, cells) == true &*&
|
||||||
* index_of(x, cells) == ix;
|
index_of(x, cells) == ix;
|
||||||
* ensures mem(idx, remove_nth(ix, cells)) == true;
|
ensures mem(idx, remove_nth(ix, cells)) == true;
|
||||||
* {
|
{
|
||||||
* neq_mem_remove(idx, x, cells);
|
neq_mem_remove(idx, x, cells);
|
||||||
* remove_remove_nth(cells, x);
|
remove_remove_nth(cells, x);
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* Following lemma from `verifast/examples/shared_boxes/concurrentqueue.c`.
|
/* Following lemma from `verifast/examples/shared_boxes/concurrentqueue.c`.
|
||||||
* Used in the uxListRemove proof to show that the item to remove `x` must
|
Used in the uxListRemove proof to show that the item to remove `x` must
|
||||||
* have value `nth(i, vals)` where `i == index_of(x, cells)`. */
|
have value `nth(i, vals)` where `i == index_of(x, cells)`. */
|
||||||
|
/*@
|
||||||
|
lemma void drop_nth_index_of<t>(list<t> vs, int i)
|
||||||
|
requires
|
||||||
|
0 <= i && i < length(vs);
|
||||||
|
ensures
|
||||||
|
head(drop(i , vs)) == nth(i, vs);
|
||||||
|
{
|
||||||
|
switch(vs) {
|
||||||
|
case nil:
|
||||||
|
case cons(h, t):
|
||||||
|
if (i == 0) {
|
||||||
|
// trivial
|
||||||
|
} else {
|
||||||
|
drop_nth_index_of(t, i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@*/
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* lemma void drop_nth_index_of<t>(list<t> vs, int i)
|
lemma void remove_append<t>(t x, list<t> l1, list<t> l2)
|
||||||
* requires
|
requires mem(x, l1) == false;
|
||||||
* 0 <= i && i < length(vs);
|
ensures remove(x, append(l1, l2)) == append(l1, remove(x, l2));
|
||||||
* ensures
|
{
|
||||||
* head(drop(i , vs)) == nth(i, vs);
|
switch(l1) {
|
||||||
* {
|
case nil:
|
||||||
* switch(vs) {
|
case cons(h1, t1):
|
||||||
* case nil:
|
remove_append(x, t1, l2);
|
||||||
* case cons(h, t):
|
}
|
||||||
* if (i == 0) {
|
}
|
||||||
* // trivial
|
@*/
|
||||||
* } else {
|
|
||||||
* drop_nth_index_of(t, i - 1);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* @*/
|
|
||||||
|
|
||||||
/*@
|
|
||||||
* lemma void remove_append<t>(t x, list<t> l1, list<t> l2)
|
|
||||||
* requires mem(x, l1) == false;
|
|
||||||
* ensures remove(x, append(l1, l2)) == append(l1, remove(x, l2));
|
|
||||||
* {
|
|
||||||
* switch(l1) {
|
|
||||||
* case nil:
|
|
||||||
* case cons(h1, t1):
|
|
||||||
* remove_append(x, t1, l2);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* @*/
|
|
||||||
|
|
||||||
#endif /* LIST_H */
|
#endif /* LIST_H */
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#ifndef QUEUE_H
|
#ifndef QUEUE_H
|
||||||
#define QUEUE_H
|
#define QUEUE_H
|
||||||
|
|
||||||
|
@ -34,51 +36,51 @@
|
||||||
#include <threading.h>
|
#include <threading.h>
|
||||||
/*@#include "common.gh"@*/
|
/*@#include "common.gh"@*/
|
||||||
|
|
||||||
typedef size_t TickType_t;
|
typedef size_t TickType_t;
|
||||||
typedef size_t UBaseType_t;
|
typedef size_t UBaseType_t;
|
||||||
typedef ssize_t BaseType_t;
|
typedef ssize_t BaseType_t;
|
||||||
|
|
||||||
/* Empty/no-op macros */
|
/* Empty/no-op macros */
|
||||||
/* Tracing */
|
/* Tracing */
|
||||||
#define traceBLOCKING_ON_QUEUE_PEEK( x )
|
#define traceBLOCKING_ON_QUEUE_PEEK(x)
|
||||||
#define traceBLOCKING_ON_QUEUE_RECEIVE( x )
|
#define traceBLOCKING_ON_QUEUE_RECEIVE(x)
|
||||||
#define traceBLOCKING_ON_QUEUE_SEND( x )
|
#define traceBLOCKING_ON_QUEUE_SEND(x)
|
||||||
#define traceQUEUE_CREATE( x )
|
#define traceQUEUE_CREATE(x)
|
||||||
#define traceQUEUE_CREATE_FAILED( x )
|
#define traceQUEUE_CREATE_FAILED(x)
|
||||||
#define traceQUEUE_DELETE( x )
|
#define traceQUEUE_DELETE(x)
|
||||||
#define traceQUEUE_PEEK( x )
|
#define traceQUEUE_PEEK(x)
|
||||||
#define traceQUEUE_PEEK_FAILED( x )
|
#define traceQUEUE_PEEK_FAILED(x)
|
||||||
#define traceQUEUE_PEEK_FROM_ISR( x )
|
#define traceQUEUE_PEEK_FROM_ISR(x)
|
||||||
#define traceQUEUE_PEEK_FROM_ISR_FAILED( x )
|
#define traceQUEUE_PEEK_FROM_ISR_FAILED(x)
|
||||||
#define traceQUEUE_RECEIVE( x )
|
#define traceQUEUE_RECEIVE(x)
|
||||||
#define traceQUEUE_RECEIVE_FAILED( x )
|
#define traceQUEUE_RECEIVE_FAILED(x)
|
||||||
#define traceQUEUE_RECEIVE_FROM_ISR( x )
|
#define traceQUEUE_RECEIVE_FROM_ISR(x)
|
||||||
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( x )
|
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED(x)
|
||||||
#define traceQUEUE_SEND( x )
|
#define traceQUEUE_SEND(x)
|
||||||
#define traceQUEUE_SEND_FAILED( x )
|
#define traceQUEUE_SEND_FAILED(x)
|
||||||
#define traceQUEUE_SEND_FROM_ISR( x )
|
#define traceQUEUE_SEND_FROM_ISR(x)
|
||||||
#define traceQUEUE_SEND_FROM_ISR_FAILED( x )
|
#define traceQUEUE_SEND_FROM_ISR_FAILED(x)
|
||||||
/* Coverage */
|
/* Coverage */
|
||||||
#define mtCOVERAGE_TEST_MARKER()
|
#define mtCOVERAGE_TEST_MARKER()
|
||||||
/* Asserts */
|
/* Asserts */
|
||||||
#define configASSERT( x )
|
#define configASSERT(x)
|
||||||
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
|
||||||
|
|
||||||
/* Map portable memory management functions */
|
/* Map portable memory management functions */
|
||||||
#define pvPortMalloc malloc
|
#define pvPortMalloc malloc
|
||||||
#define vPortFree free
|
#define vPortFree free
|
||||||
|
|
||||||
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
|
#define queueSEND_TO_BACK ( ( BaseType_t ) 0 )
|
||||||
#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 )
|
#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 )
|
||||||
#define queueOVERWRITE ( ( BaseType_t ) 2 )
|
#define queueOVERWRITE ( ( BaseType_t ) 2 )
|
||||||
|
|
||||||
#define pdTRUE 1
|
#define pdTRUE 1
|
||||||
#define pdFALSE 0
|
#define pdFALSE 0
|
||||||
|
|
||||||
#define pdPASS pdTRUE
|
#define pdPASS pdTRUE
|
||||||
#define pdFAIL pdFALSE
|
#define pdFAIL pdFALSE
|
||||||
#define errQUEUE_FULL 0
|
#define errQUEUE_FULL 0
|
||||||
#define errQUEUE_EMPTY 0
|
#define errQUEUE_EMPTY 0
|
||||||
|
|
||||||
/* Constants used with the cRxLock and cTxLock structure members. */
|
/* Constants used with the cRxLock and cTxLock structure members. */
|
||||||
#define queueUNLOCKED ( ( int8_t ) -1 )
|
#define queueUNLOCKED ( ( int8_t ) -1 )
|
||||||
|
@ -93,28 +95,26 @@ typedef struct QueuePointers
|
||||||
|
|
||||||
typedef struct SemaphoreData
|
typedef struct SemaphoreData
|
||||||
{
|
{
|
||||||
#ifdef VERIFAST /*< do not model xMutexHolder */
|
#ifdef VERIFAST /*< do not model xMutexHolder */
|
||||||
void * xMutexHolder;
|
void *xMutexHolder;
|
||||||
#else
|
#else
|
||||||
TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */
|
TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */
|
||||||
#endif
|
#endif
|
||||||
UBaseType_t uxRecursiveCallCount; /*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */
|
UBaseType_t uxRecursiveCallCount; /*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */
|
||||||
} SemaphoreData_t;
|
} SemaphoreData_t;
|
||||||
|
|
||||||
/* VeriFast does not support unions so we replace with a struct */
|
/* VeriFast does not support unions so we replace with a struct */
|
||||||
struct fake_union_t
|
struct fake_union_t {
|
||||||
{
|
|
||||||
QueuePointers_t xQueue;
|
QueuePointers_t xQueue;
|
||||||
SemaphoreData_t xSemaphore;
|
SemaphoreData_t xSemaphore;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct xLIST
|
typedef struct xLIST {
|
||||||
{
|
|
||||||
UBaseType_t uxNumberOfItems;
|
UBaseType_t uxNumberOfItems;
|
||||||
#ifndef VERIFAST /*< do not model pxIndex and xListEnd of xLIST struct */
|
#ifndef VERIFAST /*< do not model pxIndex and xListEnd of xLIST struct */
|
||||||
struct xLIST_ITEM * pxIndex;
|
struct xLIST_ITEM *pxIndex;
|
||||||
MiniListItem_t xListEnd;
|
MiniListItem_t xListEnd;
|
||||||
#endif
|
#endif
|
||||||
} List_t;
|
} List_t;
|
||||||
|
|
||||||
typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */
|
||||||
|
@ -122,15 +122,15 @@ typedef struct QueueDefinition /* The old naming convention is used to prevent b
|
||||||
int8_t * pcHead; /*< Points to the beginning of the queue storage area. */
|
int8_t * pcHead; /*< Points to the beginning of the queue storage area. */
|
||||||
int8_t * pcWriteTo; /*< Points to the free next place in the storage area. */
|
int8_t * pcWriteTo; /*< Points to the free next place in the storage area. */
|
||||||
|
|
||||||
#ifdef VERIFAST /*< VeriFast does not model unions */
|
#ifdef VERIFAST /*< VeriFast does not model unions */
|
||||||
struct fake_union_t u;
|
struct fake_union_t u;
|
||||||
#else
|
#else
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */
|
QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */
|
||||||
SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */
|
SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */
|
||||||
} u;
|
} u;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
|
List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */
|
||||||
List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
|
List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */
|
||||||
|
@ -160,278 +160,271 @@ typedef struct QueueDefinition /* The old naming convention is used to prevent b
|
||||||
/*@struct mutex *locked;@*/ /*< Ghost mutex simulates the effect of queue locking */
|
/*@struct mutex *locked;@*/ /*< Ghost mutex simulates the effect of queue locking */
|
||||||
} xQUEUE;
|
} xQUEUE;
|
||||||
|
|
||||||
typedef xQUEUE Queue_t;
|
typedef xQUEUE Queue_t;
|
||||||
|
|
||||||
typedef struct QueueDefinition * QueueHandle_t;
|
typedef struct QueueDefinition * QueueHandle_t;
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
#define QUEUE_SHAPE(q, Storage, N, M, K) \
|
#define QUEUE_SHAPE(q, Storage, N, M, K) \
|
||||||
* malloc_block_QueueDefinition(q) &*& \
|
malloc_block_QueueDefinition(q) &*& \
|
||||||
* q->pcHead |-> Storage &*& \
|
q->pcHead |-> Storage &*& \
|
||||||
* q->pcWriteTo |-> ?WPtr &*& \
|
q->pcWriteTo |-> ?WPtr &*& \
|
||||||
* q->u.xQueue.pcTail |-> ?End &*& \
|
q->u.xQueue.pcTail |-> ?End &*& \
|
||||||
* q->u.xQueue.pcReadFrom |-> ?RPtr &*& \
|
q->u.xQueue.pcReadFrom |-> ?RPtr &*& \
|
||||||
* q->uxItemSize |-> M &*& \
|
q->uxItemSize |-> M &*& \
|
||||||
* q->uxLength |-> N &*& \
|
q->uxLength |-> N &*& \
|
||||||
* q->uxMessagesWaiting |-> K &*& \
|
q->uxMessagesWaiting |-> K &*& \
|
||||||
* q->cRxLock |-> ?rxLock &*& \
|
q->cRxLock |-> ?rxLock &*& \
|
||||||
* q->cTxLock |-> ?txLock &*& \
|
q->cTxLock |-> ?txLock &*& \
|
||||||
* struct_QueuePointers_padding(&q->u.xQueue) &*& \
|
struct_QueuePointers_padding(&q->u.xQueue) &*& \
|
||||||
* struct_SemaphoreData_padding(&q->u.xSemaphore) &*& \
|
struct_SemaphoreData_padding(&q->u.xSemaphore) &*& \
|
||||||
* struct_fake_union_t_padding(&q->u) &*& \
|
struct_fake_union_t_padding(&q->u) &*& \
|
||||||
* struct_xLIST_padding(&q->xTasksWaitingToSend) &*& \
|
struct_xLIST_padding(&q->xTasksWaitingToSend) &*& \
|
||||||
* struct_xLIST_padding(&q->xTasksWaitingToReceive) &*& \
|
struct_xLIST_padding(&q->xTasksWaitingToReceive) &*& \
|
||||||
* q->u.xSemaphore.xMutexHolder |-> _ &*& \
|
q->u.xSemaphore.xMutexHolder |-> _ &*& \
|
||||||
* q->u.xSemaphore.uxRecursiveCallCount |-> _ &*& \
|
q->u.xSemaphore.uxRecursiveCallCount |-> _ &*& \
|
||||||
* true
|
true
|
||||||
*
|
|
||||||
* predicate queue(QueueHandle_t q, int8_t *Storage, size_t N, size_t M, size_t W, size_t R, size_t K, bool is_locked; list<list<char> >abs) =
|
predicate queue(QueueHandle_t q, int8_t *Storage, size_t N, size_t M, size_t W, size_t R, size_t K, bool is_locked; list<list<char> >abs) =
|
||||||
* QUEUE_SHAPE(q, Storage, N, M, K) &*&
|
QUEUE_SHAPE(q, Storage, N, M, K) &*&
|
||||||
* 0 < N &*&
|
0 < N &*&
|
||||||
* 0 < M &*&
|
0 < M &*&
|
||||||
* 0 <= W &*& W < N &*&
|
0 <= W &*& W < N &*&
|
||||||
* 0 <= R &*& R < N &*&
|
0 <= R &*& R < N &*&
|
||||||
* 0 <= K &*& K <= N &*&
|
0 <= K &*& K <= N &*&
|
||||||
* W == (R + 1 + K) % N &*&
|
W == (R + 1 + K) % N &*&
|
||||||
* (-1) <= rxLock &*&
|
(-1) <= rxLock &*&
|
||||||
* (-1) <= txLock &*&
|
(-1) <= txLock &*&
|
||||||
* (is_locked ? 0 <= rxLock : (-1) == rxLock) &*&
|
(is_locked ? 0 <= rxLock : (-1) == rxLock) &*&
|
||||||
* (is_locked ? 0 <= txLock : (-1) == txLock) &*&
|
(is_locked ? 0 <= txLock : (-1) == txLock) &*&
|
||||||
* WPtr == Storage + (W*M) &*&
|
WPtr == Storage + (W*M) &*&
|
||||||
* RPtr == Storage + (R*M) &*&
|
RPtr == Storage + (R*M) &*&
|
||||||
* End == Storage + (N*M) &*&
|
End == Storage + (N*M) &*&
|
||||||
* buffer(Storage, N, M, ?contents) &*&
|
buffer(Storage, N, M, ?contents) &*&
|
||||||
* length(contents) == N &*&
|
length(contents) == N &*&
|
||||||
* abs == take(K, rotate_left((R+1)%N, contents)) &*&
|
abs == take(K, rotate_left((R+1)%N, contents)) &*&
|
||||||
* malloc_block(Storage, N*M) &*&
|
malloc_block(Storage, N*M) &*&
|
||||||
* true
|
true
|
||||||
* ;
|
;
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* A buffer allows us to interpret a flat character array of `N*M` bytes as a
|
/* A buffer allows us to interpret a flat character array of `N*M` bytes as a
|
||||||
* list of `N` elements where each element is `M` bytes */
|
list of `N` elements where each element is `M` bytes */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate buffer(char *buffer, size_t N, size_t M; list<list<char> > elements) =
|
predicate buffer(char *buffer, size_t N, size_t M; list<list<char> > elements) =
|
||||||
* N == 0
|
N == 0
|
||||||
* ? elements == nil
|
? elements == nil
|
||||||
* : chars(buffer, M, ?x) &*& buffer(buffer + M, N - 1, M, ?xs) &*& elements == cons(x, xs);
|
: chars(buffer, M, ?x) &*& buffer(buffer + M, N - 1, M, ?xs) &*& elements == cons(x, xs);
|
||||||
*
|
|
||||||
* lemma void buffer_length(char *buffer, size_t N, size_t M)
|
lemma void buffer_length(char *buffer, size_t N, size_t M)
|
||||||
* requires buffer(buffer, N, M, ?elements);
|
requires buffer(buffer, N, M, ?elements);
|
||||||
* ensures buffer(buffer, N, M, elements) &*& length(elements) == N;
|
ensures buffer(buffer, N, M, elements) &*& length(elements) == N;
|
||||||
* {
|
{
|
||||||
* if (N == 0) {
|
if (N == 0) {
|
||||||
* open buffer(buffer, N, M, elements);
|
open buffer(buffer, N, M, elements);
|
||||||
* close buffer(buffer, N, M, elements);
|
close buffer(buffer, N, M, elements);
|
||||||
* } else {
|
} else {
|
||||||
* open buffer(buffer, N, M, elements);
|
open buffer(buffer, N, M, elements);
|
||||||
* buffer_length(buffer+M, N-1, M);
|
buffer_length(buffer+M, N-1, M);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is no need in the queue proofs to preserve a relationship between `cs`
|
There is no need in the queue proofs to preserve a relationship between `cs`
|
||||||
* and `elements` (i.e., `flatten(elements) == cs`) because we only move in one
|
and `elements` (i.e., `flatten(elements) == cs`) because we only move in one
|
||||||
* direction from `cs` to `elements` during queue creation when the contents is
|
direction from `cs` to `elements` during queue creation when the contents is
|
||||||
* fresh from `malloc` (i.e., uninitialized). If we needed to do a roundtrip from
|
fresh from `malloc` (i.e., uninitialized). If we needed to do a roundtrip from
|
||||||
* elements back to cs then this would require a stronger lemma.
|
elements back to cs then this would require a stronger lemma.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* lemma void buffer_from_chars(char *buffer, size_t N, size_t M)
|
lemma void buffer_from_chars(char *buffer, size_t N, size_t M)
|
||||||
* requires chars(buffer, N*M, ?cs) &*& 0 <= N &*& 0 < M;
|
requires chars(buffer, N*M, ?cs) &*& 0 <= N &*& 0 < M;
|
||||||
* ensures exists<list<list<char> > >(?elements) &*& buffer(buffer, N, M, elements) &*& length(elements) == N;
|
ensures exists<list<list<char> > >(?elements) &*& buffer(buffer, N, M, elements) &*& length(elements) == N;
|
||||||
* {
|
{
|
||||||
* if (N == 0) {
|
if (N == 0) {
|
||||||
* close exists(nil);
|
close exists(nil);
|
||||||
* } else {
|
} else {
|
||||||
* int i = 0;
|
int i = 0;
|
||||||
* while (i < N)
|
while (i < N)
|
||||||
* invariant 0 <= i &*& i <= N &*&
|
invariant 0 <= i &*& i <= N &*&
|
||||||
* chars(buffer, (N-i)*M, ?xs) &*& xs == take((N-i)*M, cs) &*&
|
chars(buffer, (N-i)*M, ?xs) &*& xs == take((N-i)*M, cs) &*&
|
||||||
* buffer(buffer + (N-i)*M, i, M, ?ys);
|
buffer(buffer + (N-i)*M, i, M, ?ys);
|
||||||
* decreases N-i;
|
decreases N-i;
|
||||||
* {
|
{
|
||||||
* mul_mono_l(0, N-i-1, M);
|
mul_mono_l(0, N-i-1, M);
|
||||||
* chars_split(buffer, (N-i-1)*M);
|
chars_split(buffer, (N-i-1)*M);
|
||||||
* mul_mono_l(i, N, M);
|
mul_mono_l(i, N, M);
|
||||||
* mul_mono_l(N-i, N, M);
|
mul_mono_l(N-i, N, M);
|
||||||
* take_take((N-i-1)*M, (N-i)*M, cs);
|
take_take((N-i-1)*M, (N-i)*M, cs);
|
||||||
* i++;
|
i++;
|
||||||
* }
|
}
|
||||||
* close exists(ys);
|
close exists(ys);
|
||||||
* buffer_length(buffer, N, M);
|
buffer_length(buffer, N, M);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void append_buffer(char *buffer, size_t N1, size_t N2, size_t M)
|
lemma void append_buffer(char *buffer, size_t N1, size_t N2, size_t M)
|
||||||
* requires
|
requires
|
||||||
* buffer(buffer, N1, M, ?elements1) &*&
|
buffer(buffer, N1, M, ?elements1) &*&
|
||||||
* buffer(buffer + N1 * M, N2, M, ?elements2) &*&
|
buffer(buffer + N1 * M, N2, M, ?elements2) &*&
|
||||||
* 0 <= N1 &*& 0 <= N2;
|
0 <= N1 &*& 0 <= N2;
|
||||||
* ensures buffer(buffer, N1+N2, M, append(elements1, elements2));
|
ensures buffer(buffer, N1+N2, M, append(elements1, elements2));
|
||||||
* {
|
{
|
||||||
* if (N1 == 0) {
|
if (N1 == 0) {
|
||||||
* open buffer(buffer, 0, M, _);
|
open buffer(buffer, 0, M, _);
|
||||||
* } else if (N2 == 0) {
|
} else if (N2 == 0) {
|
||||||
* open buffer(buffer + N1 * M, 0, M, _);
|
open buffer(buffer + N1 * M, 0, M, _);
|
||||||
* } else {
|
} else {
|
||||||
* open buffer(buffer, N1, M, elements1);
|
open buffer(buffer, N1, M, elements1);
|
||||||
* append_buffer(buffer + M, N1-1, N2, M);
|
append_buffer(buffer + M, N1-1, N2, M);
|
||||||
* close buffer(buffer, N1+N2, M, cons(?x, append(xs, elements2)));
|
close buffer(buffer, N1+N2, M, cons(?x, append(xs, elements2)));
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void split_element<t>(char *buffer, size_t N, size_t M, size_t i)
|
lemma void split_element<t>(char *buffer, size_t N, size_t M, size_t i)
|
||||||
* requires buffer(buffer, N, M, ?elements) &*& 0 <= i &*& i < N;
|
requires buffer(buffer, N, M, ?elements) &*& 0 <= i &*& i < N;
|
||||||
* ensures
|
ensures
|
||||||
* buffer(buffer, i, M, take(i, elements)) &*&
|
buffer(buffer, i, M, take(i, elements)) &*&
|
||||||
* chars(buffer + i * M, M, nth(i, elements)) &*&
|
chars(buffer + i * M, M, nth(i, elements)) &*&
|
||||||
* buffer(buffer + (i + 1) * M, (N-1-i), M, drop(i+1, elements));
|
buffer(buffer + (i + 1) * M, (N-1-i), M, drop(i+1, elements));
|
||||||
* {
|
{
|
||||||
* if (i == 0) {
|
if (i == 0) {
|
||||||
* // straightforward
|
// straightforward
|
||||||
* } else {
|
} else {
|
||||||
* buffer_length(buffer, N, M);
|
buffer_length(buffer, N, M);
|
||||||
* int j = 0;
|
int j = 0;
|
||||||
* while (j < i)
|
while (j < i)
|
||||||
* invariant 0 <= j &*& j <= i &*&
|
invariant 0 <= j &*& j <= i &*&
|
||||||
* buffer(buffer, j, M, take(j, elements)) &*&
|
buffer(buffer, j, M, take(j, elements)) &*&
|
||||||
* buffer(buffer + j * M, N-j, M, drop(j, elements));
|
buffer(buffer + j * M, N-j, M, drop(j, elements));
|
||||||
* decreases i-j;
|
decreases i-j;
|
||||||
* {
|
{
|
||||||
* drop_drop(1, j, elements);
|
drop_drop(1, j, elements);
|
||||||
* nth_drop2(elements, j);
|
nth_drop2(elements, j);
|
||||||
* open buffer(buffer + j * M, N-j, M, drop(j, elements));
|
open buffer(buffer + j * M, N-j, M, drop(j, elements));
|
||||||
* assert chars(buffer + j * M, M, ?x) &*& x == nth(j, elements);
|
assert chars(buffer + j * M, M, ?x) &*& x == nth(j, elements);
|
||||||
* close buffer(buffer + j * M, 1, M, singleton(x));
|
close buffer(buffer + j * M, 1, M, singleton(x));
|
||||||
* append_buffer(buffer, j, 1, M);
|
append_buffer(buffer, j, 1, M);
|
||||||
* take_plus_one(j, elements);
|
take_plus_one(j, elements);
|
||||||
* j++;
|
j++;
|
||||||
* }
|
}
|
||||||
* drop_drop(1, j, elements);
|
drop_drop(1, j, elements);
|
||||||
* nth_drop2(elements, i);
|
nth_drop2(elements, i);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* lemma void join_element(char *buffer, size_t N, size_t M, size_t i)
|
lemma void join_element(char *buffer, size_t N, size_t M, size_t i)
|
||||||
* requires
|
requires
|
||||||
* 0 <= i &*& i < N &*&
|
0 <= i &*& i < N &*&
|
||||||
* buffer(buffer, i, M, ?prefix) &*&
|
buffer(buffer, i, M, ?prefix) &*&
|
||||||
* chars(buffer + i * M, M, ?element) &*&
|
chars(buffer + i * M, M, ?element) &*&
|
||||||
* buffer(buffer + (i + 1) * M, (N-1-i), M, ?suffix);
|
buffer(buffer + (i + 1) * M, (N-1-i), M, ?suffix);
|
||||||
* ensures buffer(buffer, N, M, append(prefix, cons(element, suffix)));
|
ensures buffer(buffer, N, M, append(prefix, cons(element, suffix)));
|
||||||
* {
|
{
|
||||||
* if (i == 0) {
|
if (i == 0) {
|
||||||
* open buffer(buffer, i, M, prefix);
|
open buffer(buffer, i, M, prefix);
|
||||||
* assert prefix == nil;
|
assert prefix == nil;
|
||||||
* close buffer(buffer, N, M, cons(element, suffix));
|
close buffer(buffer, N, M, cons(element, suffix));
|
||||||
* } else {
|
} else {
|
||||||
* close buffer(buffer + i * M, N-i, M, cons(element, suffix));
|
close buffer(buffer + i * M, N-i, M, cons(element, suffix));
|
||||||
* append_buffer(buffer, i, N-i, M);
|
append_buffer(buffer, i, N-i, M);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* predicate list(List_t *l;) =
|
predicate list(List_t *l;) =
|
||||||
* l->uxNumberOfItems |-> _;
|
l->uxNumberOfItems |-> _;
|
||||||
*
|
|
||||||
* predicate queuelists(QueueHandle_t q;) =
|
predicate queuelists(QueueHandle_t q;) =
|
||||||
* list(&q->xTasksWaitingToSend) &*&
|
list(&q->xTasksWaitingToSend) &*&
|
||||||
* list(&q->xTasksWaitingToReceive);
|
list(&q->xTasksWaitingToReceive);
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* Because prvCopyDataFromQueue does *not* decrement uxMessagesWaiting (K) the
|
/* Because prvCopyDataFromQueue does *not* decrement uxMessagesWaiting (K) the
|
||||||
* queue predicate above does not hold as a postcondition. If the caller
|
queue predicate above does not hold as a postcondition. If the caller
|
||||||
* subsequently decrements K then the queue predicate can be reinstated. */
|
subsequently decrements K then the queue predicate can be reinstated. */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate queue_after_prvCopyDataFromQueue(QueueHandle_t q, int8_t *Storage, size_t N, size_t M, size_t W, size_t R, size_t K, bool is_locked; list<list<char> >abs) =
|
predicate queue_after_prvCopyDataFromQueue(QueueHandle_t q, int8_t *Storage, size_t N, size_t M, size_t W, size_t R, size_t K, bool is_locked; list<list<char> >abs) =
|
||||||
* QUEUE_SHAPE(q, Storage, N, M, K) &*&
|
QUEUE_SHAPE(q, Storage, N, M, K) &*&
|
||||||
* 0 < N &*&
|
0 < N &*&
|
||||||
* 0 < M &*&
|
0 < M &*&
|
||||||
* 0 <= W &*& W < N &*&
|
0 <= W &*& W < N &*&
|
||||||
* 0 <= R &*& R < N &*&
|
0 <= R &*& R < N &*&
|
||||||
* 0 <= K &*& K <= N &*&
|
0 <= K &*& K <= N &*&
|
||||||
* W == (R + K) % N &*& //< Differs from queue predicate
|
W == (R + K) % N &*& //< Differs from queue predicate
|
||||||
* (-1) <= rxLock &*&
|
(-1) <= rxLock &*&
|
||||||
* (-1) <= txLock &*&
|
(-1) <= txLock &*&
|
||||||
* (is_locked ? 0 <= rxLock : (-1) == rxLock) &*&
|
(is_locked ? 0 <= rxLock : (-1) == rxLock) &*&
|
||||||
* (is_locked ? 0 <= txLock : (-1) == txLock) &*&
|
(is_locked ? 0 <= txLock : (-1) == txLock) &*&
|
||||||
* WPtr == Storage + (W*M) &*&
|
WPtr == Storage + (W*M) &*&
|
||||||
* RPtr == Storage + (R*M) &*&
|
RPtr == Storage + (R*M) &*&
|
||||||
* End == Storage + (N*M) &*&
|
End == Storage + (N*M) &*&
|
||||||
* buffer(Storage, N, M, ?contents) &*&
|
buffer(Storage, N, M, ?contents) &*&
|
||||||
* length(contents) == N &*&
|
length(contents) == N &*&
|
||||||
* abs == take(K, rotate_left(R, contents)) &*& //< Differs from queue predicate
|
abs == take(K, rotate_left(R, contents)) &*& //< Differs from queue predicate
|
||||||
* malloc_block(Storage, N*M) &*&
|
malloc_block(Storage, N*M) &*&
|
||||||
* true
|
true
|
||||||
* ;
|
;
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* Can't be called `mutex` as this clashes with VeriFast's predicate */
|
/* Can't be called `mutex` as this clashes with VeriFast's predicate */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate freertos_mutex(QueueHandle_t q, int8_t *Storage, size_t N, size_t K;) =
|
predicate freertos_mutex(QueueHandle_t q, int8_t *Storage, size_t N, size_t K;) =
|
||||||
* QUEUE_SHAPE(q, Storage, N, 0, K) &*&
|
QUEUE_SHAPE(q, Storage, N, 0, K) &*&
|
||||||
* queuelists(q) &*&
|
queuelists(q) &*&
|
||||||
* 0 < N &*&
|
0 < N &*&
|
||||||
* 0 <= K &*& K <= N &*&
|
0 <= K &*& K <= N &*&
|
||||||
* (-1) <= rxLock &*&
|
(-1) <= rxLock &*&
|
||||||
* (-1) <= txLock &*&
|
(-1) <= txLock &*&
|
||||||
* WPtr == Storage &*&
|
WPtr == Storage &*&
|
||||||
* RPtr == Storage &*&
|
RPtr == Storage &*&
|
||||||
* End == Storage &*&
|
End == Storage &*&
|
||||||
* malloc_block(Storage, 0) &*&
|
malloc_block(Storage, 0) &*&
|
||||||
* chars(Storage, 0, _) &*&
|
chars(Storage, 0, _) &*&
|
||||||
* true
|
true
|
||||||
* ;
|
;
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* A queuehandle can be shared between tasks and ISRs. Acquiring the ghost
|
/* A queuehandle can be shared between tasks and ISRs. Acquiring the ghost
|
||||||
* `irqMask` gives access to the core queue resources. The permissions granted
|
`irqMask` gives access to the core queue resources. The permissions granted
|
||||||
* after masking interrupts depends on the caller:
|
after masking interrupts depends on the caller:
|
||||||
* - A task has access to the queue and the queuelists
|
- A task has access to the queue and the queuelists
|
||||||
* - An ISR has access to the queue and, if the queue is unlocked, the queuelists */
|
- An ISR has access to the queue and, if the queue is unlocked, the queuelists */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate queuehandle(QueueHandle_t q, size_t N, size_t M, bool is_isr;) =
|
predicate queuehandle(QueueHandle_t q, size_t N, size_t M, bool is_isr;) =
|
||||||
* q->irqMask |-> ?m &*& mutex(m, irqs_masked_invariant(q, N, M, is_isr));
|
q->irqMask |-> ?m &*& mutex(m, irqs_masked_invariant(q, N, M, is_isr));
|
||||||
*
|
|
||||||
* predicate_ctor irqs_masked_invariant(QueueHandle_t queue, size_t N, size_t M, bool is_isr)() =
|
predicate_ctor irqs_masked_invariant(QueueHandle_t queue, size_t N, size_t M, bool is_isr)() =
|
||||||
* queue(queue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
queue(queue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* (is_isr && is_locked ? true : queuelists(queue));
|
(is_isr && is_locked ? true : queuelists(queue));
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* A queuesuspend can be shared between tasks. Acquiring the ghost `schedulerSuspend` gives access to the `locked` mutex. */
|
/* A queuesuspend can be shared between tasks. Acquiring the ghost `schedulerSuspend` gives access to the `locked` mutex. */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate_ctor scheduler_suspended_invariant(QueueHandle_t queue)() =
|
predicate_ctor scheduler_suspended_invariant(QueueHandle_t queue)() =
|
||||||
* queue->locked |-> ?m &*&
|
queue->locked |-> ?m &*&
|
||||||
* mutex(m, queue_locked_invariant(queue));
|
mutex(m, queue_locked_invariant(queue));
|
||||||
*
|
|
||||||
* predicate queuesuspend(QueueHandle_t q;) =
|
predicate queuesuspend(QueueHandle_t q;) =
|
||||||
* q->schedulerSuspend |-> ?m &*&
|
q->schedulerSuspend |-> ?m &*&
|
||||||
* mutex(m, scheduler_suspended_invariant(q));
|
mutex(m, scheduler_suspended_invariant(q));
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* A queuelock is exclusively acquired by a task. Acquiring the ghost `queuelock` gives access to the queue list resources. */
|
/* A queuelock is exclusively acquired by a task. Acquiring the ghost `queuelock` gives access to the queue list resources. */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate queuelock(QueueHandle_t q;) =
|
predicate queuelock(QueueHandle_t q;) =
|
||||||
* q->locked |-> ?m &*&
|
q->locked |-> ?m &*&
|
||||||
* mutex(m, queue_locked_invariant(q));
|
mutex(m, queue_locked_invariant(q));
|
||||||
*
|
|
||||||
* predicate_ctor queue_locked_invariant(QueueHandle_t queue)() =
|
|
||||||
* queuelists(queue);
|
|
||||||
* @*/
|
|
||||||
|
|
||||||
BaseType_t vListInitialise( List_t * list );
|
predicate_ctor queue_locked_invariant(QueueHandle_t queue)() =
|
||||||
|
queuelists(queue);
|
||||||
|
@*/
|
||||||
|
|
||||||
|
BaseType_t vListInitialise(List_t *list);
|
||||||
/*@requires list(list);@*/
|
/*@requires list(list);@*/
|
||||||
/*@ensures list(list);@*/
|
/*@ensures list(list);@*/
|
||||||
|
|
||||||
BaseType_t listLIST_IS_EMPTY( List_t * list );
|
BaseType_t listLIST_IS_EMPTY(List_t *list);
|
||||||
/*@requires list->uxNumberOfItems |-> ?len;@*/
|
/*@requires list->uxNumberOfItems |-> ?len;@*/
|
||||||
/*@ensures list->uxNumberOfItems |-> len &*& result == (len == 0 ? pdTRUE : pdFALSE);@*/
|
/*@ensures list->uxNumberOfItems |-> len &*& result == (len == 0 ? pdTRUE : pdFALSE);@*/
|
||||||
|
|
||||||
|
@ -442,27 +435,25 @@ typedef struct xTIME_OUT
|
||||||
} TimeOut_t;
|
} TimeOut_t;
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate xTIME_OUT(struct xTIME_OUT *to;) =
|
predicate xTIME_OUT(struct xTIME_OUT *to;) =
|
||||||
* to->xOverflowCount |-> _ &*&
|
to->xOverflowCount |-> _ &*&
|
||||||
* to->xTimeOnEntering |-> _ &*&
|
to->xTimeOnEntering |-> _ &*&
|
||||||
* struct_xTIME_OUT_padding(to);
|
struct_xTIME_OUT_padding(to);
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
void vTaskInternalSetTimeOutState( TimeOut_t * x );
|
void vTaskInternalSetTimeOutState( TimeOut_t * x);
|
||||||
/*@requires xTIME_OUT(x);@*/
|
/*@requires xTIME_OUT(x);@*/
|
||||||
/*@ensures xTIME_OUT(x);@*/
|
/*@ensures xTIME_OUT(x);@*/
|
||||||
|
|
||||||
BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
|
BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait );
|
||||||
TickType_t * const pxTicksToWait );
|
|
||||||
/*@requires xTIME_OUT(pxTimeOut) &*& u_integer(pxTicksToWait, _);@*/
|
/*@requires xTIME_OUT(pxTimeOut) &*& u_integer(pxTicksToWait, _);@*/
|
||||||
/*@ensures xTIME_OUT(pxTimeOut) &*& u_integer(pxTicksToWait, _);@*/
|
/*@ensures xTIME_OUT(pxTimeOut) &*& u_integer(pxTicksToWait, _);@*/
|
||||||
|
|
||||||
BaseType_t xTaskRemoveFromEventList( List_t * list );
|
BaseType_t xTaskRemoveFromEventList(List_t *list);
|
||||||
/*@requires list(list);@*/
|
/*@requires list(list);@*/
|
||||||
/*@ensures list(list);@*/
|
/*@ensures list(list);@*/
|
||||||
|
|
||||||
void vTaskPlaceOnEventList( List_t * const pxEventList,
|
void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait );
|
||||||
const TickType_t xTicksToWait );
|
|
||||||
/*@requires list(pxEventList);@*/
|
/*@requires list(pxEventList);@*/
|
||||||
/*@ensures list(pxEventList);@*/
|
/*@ensures list(pxEventList);@*/
|
||||||
|
|
||||||
|
@ -471,107 +462,96 @@ void vTaskMissedYield();
|
||||||
/*@ensures true;@*/
|
/*@ensures true;@*/
|
||||||
|
|
||||||
void vTaskSuspendAll();
|
void vTaskSuspendAll();
|
||||||
|
|
||||||
/*@requires exists<QueueHandle_t>(?xQueue) &*&
|
/*@requires exists<QueueHandle_t>(?xQueue) &*&
|
||||||
* [1/2]xQueue->schedulerSuspend |-> ?m &*&
|
[1/2]xQueue->schedulerSuspend |-> ?m &*&
|
||||||
* [1/2]mutex(m, scheduler_suspended_invariant(xQueue));@*/
|
[1/2]mutex(m, scheduler_suspended_invariant(xQueue));@*/
|
||||||
|
|
||||||
/*@ensures [1/2]xQueue->schedulerSuspend |-> m &*&
|
/*@ensures [1/2]xQueue->schedulerSuspend |-> m &*&
|
||||||
* mutex_held(m, scheduler_suspended_invariant(xQueue), currentThread, 1/2) &*&
|
mutex_held(m, scheduler_suspended_invariant(xQueue), currentThread, 1/2) &*&
|
||||||
* xQueue->locked |-> ?m2 &*&
|
xQueue->locked |-> ?m2 &*&
|
||||||
* mutex(m2, queue_locked_invariant(xQueue));@*/
|
mutex(m2, queue_locked_invariant(xQueue));@*/
|
||||||
|
|
||||||
BaseType_t xTaskResumeAll( void );
|
BaseType_t xTaskResumeAll( void );
|
||||||
|
|
||||||
/*@requires exists<QueueHandle_t>(?xQueue) &*&
|
/*@requires exists<QueueHandle_t>(?xQueue) &*&
|
||||||
* [1/2]xQueue->schedulerSuspend |-> ?m &*&
|
[1/2]xQueue->schedulerSuspend |-> ?m &*&
|
||||||
* mutex_held(m, scheduler_suspended_invariant(xQueue), currentThread, 1/2) &*&
|
mutex_held(m, scheduler_suspended_invariant(xQueue), currentThread, 1/2) &*&
|
||||||
* xQueue->locked |-> ?m2 &*&
|
xQueue->locked |-> ?m2 &*&
|
||||||
* mutex(m2, queue_locked_invariant(xQueue));@*/
|
mutex(m2, queue_locked_invariant(xQueue));@*/
|
||||||
|
|
||||||
/*@ensures [1/2]xQueue->schedulerSuspend |-> m &*&
|
/*@ensures [1/2]xQueue->schedulerSuspend |-> m &*&
|
||||||
* [1/2]mutex(m, scheduler_suspended_invariant(xQueue));@*/
|
[1/2]mutex(m, scheduler_suspended_invariant(xQueue));@*/
|
||||||
|
|
||||||
void prvLockQueue( QueueHandle_t xQueue );
|
void prvLockQueue( QueueHandle_t xQueue );
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
||||||
* [1/2]queuelock(xQueue); @*/
|
[1/2]queuelock(xQueue); @*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]xQueue->locked |-> ?m &*&
|
[1/2]xQueue->locked |-> ?m &*&
|
||||||
* mutex_held(m, queue_locked_invariant(xQueue), currentThread, 1/2) &*&
|
mutex_held(m, queue_locked_invariant(xQueue), currentThread, 1/2) &*&
|
||||||
* queue_locked_invariant(xQueue)();@*/
|
queue_locked_invariant(xQueue)();@*/
|
||||||
|
|
||||||
void prvUnlockQueue( QueueHandle_t xQueue );
|
void prvUnlockQueue( QueueHandle_t xQueue );
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
||||||
* [1/2]xQueue->locked |-> ?m &*&
|
[1/2]xQueue->locked |-> ?m &*&
|
||||||
* mutex_held(m, queue_locked_invariant(xQueue), currentThread, 1/2) &*&
|
mutex_held(m, queue_locked_invariant(xQueue), currentThread, 1/2) &*&
|
||||||
* queue_locked_invariant(xQueue)();@*/
|
queue_locked_invariant(xQueue)();@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]queuelock(xQueue);@*/
|
[1/2]queuelock(xQueue);@*/
|
||||||
|
|
||||||
void setInterruptMask( QueueHandle_t xQueue )
|
void setInterruptMask(QueueHandle_t xQueue)
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false;@*/
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false;@*/
|
||||||
|
|
||||||
/*@ensures [1/2]xQueue->irqMask |-> ?m &*&
|
/*@ensures [1/2]xQueue->irqMask |-> ?m &*&
|
||||||
* mutex_held(m, irqs_masked_invariant(xQueue, N, M, is_isr), currentThread, 1/2) &*&
|
mutex_held(m, irqs_masked_invariant(xQueue, N, M, is_isr), currentThread, 1/2) &*&
|
||||||
* queue(xQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
queue(xQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* queuelists(xQueue);@*/
|
queuelists(xQueue);@*/
|
||||||
{
|
{
|
||||||
/*@open queuehandle(xQueue, N, M, is_isr);@*/
|
/*@open queuehandle(xQueue, N, M, is_isr);@*/
|
||||||
mutex_acquire( xQueue->irqMask );
|
mutex_acquire(xQueue->irqMask);
|
||||||
/*@open irqs_masked_invariant(xQueue, N, M, is_isr)();@*/
|
/*@open irqs_masked_invariant(xQueue, N, M, is_isr)();@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearInterruptMask( QueueHandle_t xQueue )
|
void clearInterruptMask(QueueHandle_t xQueue)
|
||||||
|
|
||||||
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* [1/2]xQueue->irqMask |-> ?m &*&
|
[1/2]xQueue->irqMask |-> ?m &*&
|
||||||
* mutex_held(m, irqs_masked_invariant(xQueue, N, M, false), currentThread, 1/2) &*&
|
mutex_held(m, irqs_masked_invariant(xQueue, N, M, false), currentThread, 1/2) &*&
|
||||||
* queuelists(xQueue);@*/
|
queuelists(xQueue);@*/
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, false);@*/
|
/*@ensures [1/2]queuehandle(xQueue, N, M, false);@*/
|
||||||
{
|
{
|
||||||
/*@close irqs_masked_invariant(xQueue, N, M, false)();@*/
|
/*@close irqs_masked_invariant(xQueue, N, M, false)();@*/
|
||||||
mutex_release( xQueue->irqMask );
|
mutex_release(xQueue->irqMask);
|
||||||
/*@close [1/2]queuehandle(xQueue, N, M, false);@*/
|
/*@close [1/2]queuehandle(xQueue, N, M, false);@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#define taskENTER_CRITICAL() setInterruptMask( xQueue )
|
#define taskENTER_CRITICAL() setInterruptMask(xQueue)
|
||||||
#define taskEXIT_CRITICAL() clearInterruptMask( xQueue )
|
#define taskEXIT_CRITICAL() clearInterruptMask(xQueue)
|
||||||
#define portYIELD_WITHIN_API()
|
#define portYIELD_WITHIN_API()
|
||||||
#define queueYIELD_IF_USING_PREEMPTION()
|
#define queueYIELD_IF_USING_PREEMPTION()
|
||||||
|
|
||||||
UBaseType_t setInterruptMaskFromISR( QueueHandle_t xQueue )
|
UBaseType_t setInterruptMaskFromISR(QueueHandle_t xQueue)
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true;@*/
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true;@*/
|
||||||
|
|
||||||
/*@ensures [1/2]xQueue->irqMask |-> ?m &*&
|
/*@ensures [1/2]xQueue->irqMask |-> ?m &*&
|
||||||
* mutex_held(m, irqs_masked_invariant(xQueue, N, M, is_isr), currentThread, 1/2) &*&
|
mutex_held(m, irqs_masked_invariant(xQueue, N, M, is_isr), currentThread, 1/2) &*&
|
||||||
* queue(xQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
queue(xQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* (is_locked ? true : queuelists(xQueue));@*/
|
(is_locked ? true : queuelists(xQueue));@*/
|
||||||
{
|
{
|
||||||
/*@open queuehandle(xQueue, N, M, is_isr);@*/
|
/*@open queuehandle(xQueue, N, M, is_isr);@*/
|
||||||
mutex_acquire( xQueue->irqMask );
|
mutex_acquire(xQueue->irqMask);
|
||||||
/*@open irqs_masked_invariant(xQueue, N, M, is_isr)();@*/
|
/*@open irqs_masked_invariant(xQueue, N, M, is_isr)();@*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearInterruptMaskFromISR( QueueHandle_t xQueue,
|
void clearInterruptMaskFromISR(QueueHandle_t xQueue, UBaseType_t uxSavedInterruptStatus)
|
||||||
UBaseType_t uxSavedInterruptStatus )
|
|
||||||
|
|
||||||
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* [1/2]xQueue->irqMask |-> ?m &*&
|
[1/2]xQueue->irqMask |-> ?m &*&
|
||||||
* mutex_held(m, irqs_masked_invariant(xQueue, N, M, true), currentThread, 1/2) &*&
|
mutex_held(m, irqs_masked_invariant(xQueue, N, M, true), currentThread, 1/2) &*&
|
||||||
* (is_locked ? true : queuelists(xQueue));@*/
|
(is_locked ? true : queuelists(xQueue));@*/
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, true);@*/
|
/*@ensures [1/2]queuehandle(xQueue, N, M, true);@*/
|
||||||
{
|
{
|
||||||
/*@close irqs_masked_invariant(xQueue, N, M, true)();@*/
|
/*@close irqs_masked_invariant(xQueue, N, M, true)();@*/
|
||||||
mutex_release( xQueue->irqMask );
|
mutex_release(xQueue->irqMask);
|
||||||
/*@close [1/2]queuehandle(xQueue, N, M, true);@*/
|
/*@close [1/2]queuehandle(xQueue, N, M, true);@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() setInterruptMaskFromISR( xQueue )
|
#define portSET_INTERRUPT_MASK_FROM_ISR() setInterruptMaskFromISR(xQueue)
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ) clearInterruptMaskFromISR( xQueue, uxSavedInterruptStatus )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(uxSavedInterruptStatus) clearInterruptMaskFromISR(xQueue, uxSavedInterruptStatus)
|
||||||
|
|
||||||
#endif /* QUEUE_H */
|
#endif /* QUEUE_H */
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,37 +24,33 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#ifndef QUEUECONTRACTS_H
|
#ifndef QUEUECONTRACTS_H
|
||||||
#define QUEUECONTRACTS_H
|
#define QUEUECONTRACTS_H
|
||||||
|
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
void prvCopyDataFromQueue( Queue_t * const pxQueue,
|
void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer );
|
||||||
void * const pvBuffer );
|
|
||||||
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*& 0 < K &*& chars(pvBuffer, M, _);@*/
|
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*& 0 < K &*& chars(pvBuffer, M, _);@*/
|
||||||
|
|
||||||
/*@ensures queue_after_prvCopyDataFromQueue(pxQueue, Storage, N, M, W, (R+1)%N, K, is_locked, abs) &*&
|
/*@ensures queue_after_prvCopyDataFromQueue(pxQueue, Storage, N, M, W, (R+1)%N, K, is_locked, abs) &*&
|
||||||
* chars(pvBuffer, M, head(abs));@*/
|
chars(pvBuffer, M, head(abs));@*/
|
||||||
|
|
||||||
BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
|
||||||
const void * pvItemToQueue,
|
|
||||||
const BaseType_t xPosition );
|
|
||||||
|
|
||||||
|
BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition );
|
||||||
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* (K < N || xPosition == queueOVERWRITE) &*&
|
(K < N || xPosition == queueOVERWRITE) &*&
|
||||||
* chars(pvItemToQueue, M, ?x) &*&
|
chars(pvItemToQueue, M, ?x) &*&
|
||||||
* (xPosition == queueSEND_TO_BACK || xPosition == queueSEND_TO_FRONT || (xPosition == queueOVERWRITE && N == 1));@*/
|
(xPosition == queueSEND_TO_BACK || xPosition == queueSEND_TO_FRONT || (xPosition == queueOVERWRITE && N == 1));@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* (xPosition == queueSEND_TO_BACK
|
(xPosition == queueSEND_TO_BACK
|
||||||
* ? queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)))
|
? queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)))
|
||||||
* : (xPosition == queueSEND_TO_FRONT
|
: (xPosition == queueSEND_TO_FRONT
|
||||||
* ? (R == 0
|
? (R == 0
|
||||||
* ? queue(pxQueue, Storage, N, M, W, (N-1), (K+1), is_locked, cons(x, abs))
|
? queue(pxQueue, Storage, N, M, W, (N-1), (K+1), is_locked, cons(x, abs))
|
||||||
* : queue(pxQueue, Storage, N, M, W, (R-1), (K+1), is_locked, cons(x, abs)))
|
: queue(pxQueue, Storage, N, M, W, (R-1), (K+1), is_locked, cons(x, abs)))
|
||||||
* : xPosition == queueOVERWRITE &*& queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x)))
|
: xPosition == queueOVERWRITE &*& queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x)))
|
||||||
* ) &*&
|
) &*&
|
||||||
* chars(pvItemToQueue, M, x);@*/
|
chars(pvItemToQueue, M, x);@*/
|
||||||
|
|
||||||
BaseType_t prvIsQueueEmpty( Queue_t * pxQueue );
|
BaseType_t prvIsQueueEmpty( Queue_t * pxQueue );
|
||||||
/*@requires [1/2]queuehandle(pxQueue, ?N, ?M, ?is_isr) &*& is_isr == false;@*/
|
/*@requires [1/2]queuehandle(pxQueue, ?N, ?M, ?is_isr) &*& is_isr == false;@*/
|
||||||
|
@ -65,3 +61,5 @@ BaseType_t prvIsQueueFull( Queue_t * pxQueue );
|
||||||
/*@ensures [1/2]queuehandle(pxQueue, N, M, is_isr);@*/
|
/*@ensures [1/2]queuehandle(pxQueue, N, M, is_isr);@*/
|
||||||
|
|
||||||
#endif /* QUEUECONTRACTS_H */
|
#endif /* QUEUECONTRACTS_H */
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,18 +24,21 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/list.h"
|
#include "proof/list.h"
|
||||||
|
|
||||||
/* Wrap the macro in a function call so we can give a function contract */
|
/* Wrap the macro in a function call so we can give a function contract */
|
||||||
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
|
||||||
|
|
||||||
BaseType_t wrapper_listLIST_IS_EMPTY( List_t * pxList )
|
BaseType_t wrapper_listLIST_IS_EMPTY( List_t * pxList )
|
||||||
/*@requires xLIST(pxList, ?len, ?idx, ?end, ?cells, ?vals);@*/
|
/*@requires xLIST(pxList, ?len, ?idx, ?end, ?cells, ?vals);@*/
|
||||||
|
|
||||||
/*@ensures xLIST(pxList, len, idx, end, cells, vals) &*&
|
/*@ensures xLIST(pxList, len, idx, end, cells, vals) &*&
|
||||||
* result == ((len == 0) ? pdTRUE : pdFALSE); @*/
|
result == ((len == 0) ? pdTRUE : pdFALSE); @*/
|
||||||
{
|
{
|
||||||
/*@open xLIST(pxList, len, _, _, _, _);@*/
|
/*@open xLIST(pxList, len, _, _, _, _);@*/
|
||||||
return listLIST_IS_EMPTY( pxList );
|
return listLIST_IS_EMPTY( pxList );
|
||||||
/*@close xLIST(pxList, len, _, _, cells, vals);@*/
|
/*@close xLIST(pxList, len, _, _, cells, vals);@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,21 +24,21 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/list.h"
|
#include "proof/list.h"
|
||||||
|
|
||||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
|
|
||||||
/*@requires
|
/*@requires
|
||||||
* exists<struct xLIST * >(?l) &*&
|
exists<struct xLIST * >(?l) &*&
|
||||||
* xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
||||||
* end != pxItemToRemove &*&
|
end != pxItemToRemove &*&
|
||||||
* mem(pxItemToRemove, cells) == true;@*/
|
mem(pxItemToRemove, cells) == true;@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* result == len-1 &*&
|
result == len-1 &*&
|
||||||
* xLIST_ITEM(pxItemToRemove, nth(index_of(pxItemToRemove, cells), vals), _, ?pxItemToRemovePrevious, NULL) &*&
|
xLIST_ITEM(pxItemToRemove, nth(index_of(pxItemToRemove, cells), vals), _, ?pxItemToRemovePrevious, NULL) &*&
|
||||||
* pxItemToRemovePrevious == nth(index_of(pxItemToRemove, cells)-1, cells) &*&
|
pxItemToRemovePrevious == nth(index_of(pxItemToRemove, cells)-1, cells) &*&
|
||||||
* xLIST(l, result, idx == pxItemToRemove ? pxItemToRemovePrevious : idx, end, remove(pxItemToRemove, cells), remove_nth(index_of(pxItemToRemove, cells), vals));@*/
|
xLIST(l, result, idx == pxItemToRemove ? pxItemToRemovePrevious : idx, end, remove(pxItemToRemove, cells), remove_nth(index_of(pxItemToRemove, cells), vals));@*/
|
||||||
{
|
{
|
||||||
/* For brevity we alias x to pxItemToRemove */
|
/* For brevity we alias x to pxItemToRemove */
|
||||||
/*@struct xLIST_ITEM *x = pxItemToRemove;@*/
|
/*@struct xLIST_ITEM *x = pxItemToRemove;@*/
|
||||||
|
@ -50,7 +50,7 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
/*@dls_not_empty(end, endprev, cells, x);@*/
|
/*@dls_not_empty(end, endprev, cells, x);@*/
|
||||||
|
|
||||||
/* We know the xLIST is a DLS: end...endprev
|
/* We know the xLIST is a DLS: end...endprev
|
||||||
* Split this into DLS1:end...xprev and DLS2:x...endprev */
|
Split this into DLS1:end...xprev and DLS2:x...endprev */
|
||||||
/*@int i = index_of(x, cells);@*/
|
/*@int i = index_of(x, cells);@*/
|
||||||
/*@split(end, endprev, end, endprev, cells, vals, x, i);@*/
|
/*@split(end, endprev, end, endprev, cells, vals, x, i);@*/
|
||||||
/*@list<struct xLIST_ITEM *> ys = take(i, cells);@*/
|
/*@list<struct xLIST_ITEM *> ys = take(i, cells);@*/
|
||||||
|
@ -63,107 +63,106 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
/*@assert DLS(x, xprev, end, endprev, zs, ws, l);@*/ /*< DLS2 (zs, ws) */
|
/*@assert DLS(x, xprev, end, endprev, zs, ws, l);@*/ /*< DLS2 (zs, ws) */
|
||||||
|
|
||||||
/* Now case split to open DLS1 and DLS2 appropriately */
|
/* Now case split to open DLS1 and DLS2 appropriately */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (end == xprev)
|
if (end == xprev)
|
||||||
* {
|
{
|
||||||
* if (x == endprev)
|
if (x == endprev)
|
||||||
* {
|
{
|
||||||
* //Case A
|
//Case A
|
||||||
* //DLS1: extract end=prev=next
|
//DLS1: extract end=prev=next
|
||||||
* open DLS(end, endprev, x, xprev, ys, vs, l);
|
open DLS(end, endprev, x, xprev, ys, vs, l);
|
||||||
* open xLIST_ITEM(end, portMAX_DELAY, x, endprev, l);
|
open xLIST_ITEM(end, portMAX_DELAY, x, endprev, l);
|
||||||
* //DLS2: extract x
|
//DLS2: extract x
|
||||||
* open DLS(x, xprev, end, endprev, zs, ws, l);
|
open DLS(x, xprev, end, endprev, zs, ws, l);
|
||||||
* //Lengths
|
//Lengths
|
||||||
* assert length(ys) == 1;
|
assert length(ys) == 1;
|
||||||
* assert length(zs) == 1;
|
assert length(zs) == 1;
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* //Case B
|
//Case B
|
||||||
* //DLS1: extract end=prev
|
//DLS1: extract end=prev
|
||||||
* open DLS(end, endprev, x, xprev, ys, vs, l);
|
open DLS(end, endprev, x, xprev, ys, vs, l);
|
||||||
* open xLIST_ITEM(end, portMAX_DELAY, x, endprev, l);
|
open xLIST_ITEM(end, portMAX_DELAY, x, endprev, l);
|
||||||
* //DLS2: extract next and x
|
//DLS2: extract next and x
|
||||||
* open DLS(x, end, end, endprev, zs, ws, l);
|
open DLS(x, end, end, endprev, zs, ws, l);
|
||||||
* assert DLS(?xnext, x, end, endprev, tail(zs), tail(ws), l);
|
assert DLS(?xnext, x, end, endprev, tail(zs), tail(ws), l);
|
||||||
* open DLS(xnext, x, end, endprev, tail(zs), tail(ws), l);
|
open DLS(xnext, x, end, endprev, tail(zs), tail(ws), l);
|
||||||
* open xLIST_ITEM(xnext, _, _, x, l);
|
open xLIST_ITEM(xnext, _, _, x, l);
|
||||||
* //Lengths
|
//Lengths
|
||||||
* assert length(ys) == 1;
|
assert length(ys) == 1;
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* if (x == endprev)
|
if (x == endprev)
|
||||||
* {
|
{
|
||||||
* //Case C
|
//Case C
|
||||||
* //DLS1: extract end=next and prev
|
//DLS1: extract end=next and prev
|
||||||
* dls_last_mem(end, endprev, x, xprev, ys);
|
dls_last_mem(end, endprev, x, xprev, ys);
|
||||||
* assert mem(xprev, ys) == true;
|
assert mem(xprev, ys) == true;
|
||||||
* open DLS(end, endprev, x, xprev, ys, vs, l);
|
open DLS(end, endprev, x, xprev, ys, vs, l);
|
||||||
* open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, l);
|
open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, l);
|
||||||
* if (endnext == xprev)
|
if (endnext == xprev)
|
||||||
* {
|
{
|
||||||
* open DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
open DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
||||||
* open xLIST_ITEM(xprev, _, x, _, l);
|
open xLIST_ITEM(xprev, _, x, _, l);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
assert DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
||||||
* int k = index_of(xprev, tail(ys));
|
int k = index_of(xprev, tail(ys));
|
||||||
* dls_last_mem(endnext, end, x, xprev, tail(ys));
|
dls_last_mem(endnext, end, x, xprev, tail(ys));
|
||||||
* split(endnext, end, x, xprev, tail(ys), tail(vs), xprev, k);
|
split(endnext, end, x, xprev, tail(ys), tail(vs), xprev, k);
|
||||||
* open DLS(xprev, _, x, xprev, _, _, l);
|
open DLS(xprev, _, x, xprev, _, _, l);
|
||||||
* open xLIST_ITEM(xprev, _, x, _, l);
|
open xLIST_ITEM(xprev, _, x, _, l);
|
||||||
* }
|
}
|
||||||
* //DLS2: extract x
|
//DLS2: extract x
|
||||||
* open DLS(x, xprev, end, endprev, zs, ws, l);
|
open DLS(x, xprev, end, endprev, zs, ws, l);
|
||||||
* //Lengths
|
//Lengths
|
||||||
* assert length(zs) == 1;
|
assert length(zs) == 1;
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* //Case D
|
//Case D
|
||||||
* //DLS1: extract prev
|
//DLS1: extract prev
|
||||||
* dls_last_mem(end, endprev, x, xprev, ys);
|
dls_last_mem(end, endprev, x, xprev, ys);
|
||||||
* int j = index_of(xprev, ys);
|
int j = index_of(xprev, ys);
|
||||||
* open DLS(end, endprev, x, xprev, ys, vs, l);
|
open DLS(end, endprev, x, xprev, ys, vs, l);
|
||||||
* open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, l);
|
open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, l);
|
||||||
* if (endnext == xprev)
|
if (endnext == xprev)
|
||||||
* {
|
{
|
||||||
* open DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
open DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
||||||
* assert tail(ys) == singleton(xprev);
|
assert tail(ys) == singleton(xprev);
|
||||||
* open xLIST_ITEM(xprev, _, x, _, l);
|
open xLIST_ITEM(xprev, _, x, _, l);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
assert DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
|
||||||
* int k = index_of(xprev, tail(ys));
|
int k = index_of(xprev, tail(ys));
|
||||||
* dls_last_mem(endnext, end, x, xprev, tail(ys));
|
dls_last_mem(endnext, end, x, xprev, tail(ys));
|
||||||
* split(endnext, end, x, xprev, tail(ys), tail(vs), xprev, k);
|
split(endnext, end, x, xprev, tail(ys), tail(vs), xprev, k);
|
||||||
* open DLS(xprev, _, x, xprev, _, _, l);
|
open DLS(xprev, _, x, xprev, _, _, l);
|
||||||
* open xLIST_ITEM(xprev, _, x, _, l);
|
open xLIST_ITEM(xprev, _, x, _, l);
|
||||||
* }
|
}
|
||||||
* //DLS2: extract next and x
|
//DLS2: extract next and x
|
||||||
* open DLS(x, xprev, end, endprev, zs, ws, l);
|
open DLS(x, xprev, end, endprev, zs, ws, l);
|
||||||
* assert xLIST_ITEM(x, _, ?xnext, _, l);
|
assert xLIST_ITEM(x, _, ?xnext, _, l);
|
||||||
* open DLS(xnext, x, end, endprev, tail(zs), tail(ws), l);
|
open DLS(xnext, x, end, endprev, tail(zs), tail(ws), l);
|
||||||
* open xLIST_ITEM(xnext, _, _, x, l);
|
open xLIST_ITEM(xnext, _, _, x, l);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
/*@drop_nth_index_of(vals, i);@*/
|
/*@drop_nth_index_of(vals, i);@*/
|
||||||
/*@open xLIST_ITEM(x, nth(i, vals), ?xnext, xprev, l);@*/
|
/*@open xLIST_ITEM(x, nth(i, vals), ?xnext, xprev, l);@*/
|
||||||
|
|
||||||
/* The list item knows which list it is in. Obtain the list from the list
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
* item. */
|
* item. */
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
List_t * pxList = pxItemToRemove->pxContainer;
|
List_t * pxList = pxItemToRemove->pxContainer;
|
||||||
#else
|
#else
|
||||||
List_t * const pxList = pxItemToRemove->pxContainer;
|
List_t * const pxList = pxItemToRemove->pxContainer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
@ -187,105 +186,101 @@ UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
return pxList->uxNumberOfItems;
|
return pxList->uxNumberOfItems;
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* // Reassemble DLS1 and a modified DLS2, which no longer includes x
|
// Reassemble DLS1 and a modified DLS2, which no longer includes x
|
||||||
* if (end == xprev)
|
if (end == xprev)
|
||||||
* {
|
{
|
||||||
* if (x == endprev)
|
if (x == endprev)
|
||||||
* {
|
{
|
||||||
* //Case A
|
//Case A
|
||||||
* close xLIST_ITEM(end, portMAX_DELAY, _, _, _);
|
close xLIST_ITEM(end, portMAX_DELAY, _, _, _);
|
||||||
* close DLS(end, end, end, end, singleton(end), singleton(portMAX_DELAY), l);
|
close DLS(end, end, end, end, singleton(end), singleton(portMAX_DELAY), l);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* //Case B
|
//Case B
|
||||||
* close xLIST_ITEM(xprev, _, xnext, endprev, l);
|
close xLIST_ITEM(xprev, _, xnext, endprev, l);
|
||||||
* close DLS(end, endprev, xnext, xprev, singleton(end), singleton(portMAX_DELAY), l);
|
close DLS(end, endprev, xnext, xprev, singleton(end), singleton(portMAX_DELAY), l);
|
||||||
* close xLIST_ITEM(xnext, _, _, xprev, l);
|
close xLIST_ITEM(xnext, _, _, xprev, l);
|
||||||
* close DLS(xnext, xprev, end, endprev, tail(zs), tail(ws), l);
|
close DLS(xnext, xprev, end, endprev, tail(zs), tail(ws), l);
|
||||||
* join(end, endprev, xnext, xprev, singleton(end), singleton(portMAX_DELAY),
|
join(end, endprev, xnext, xprev, singleton(end), singleton(portMAX_DELAY),
|
||||||
* xnext, xprev, end, endprev, tail(zs), tail(ws));
|
xnext, xprev, end, endprev, tail(zs), tail(ws));
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* if (x == endprev)
|
if (x == endprev)
|
||||||
* {
|
{
|
||||||
* //Case C
|
//Case C
|
||||||
* close xLIST_ITEM(end, _, ?endnext, xprev, l);
|
close xLIST_ITEM(end, _, ?endnext, xprev, l);
|
||||||
* close xLIST_ITEM(xprev, ?xprev_val, end, _, l);
|
close xLIST_ITEM(xprev, ?xprev_val, end, _, l);
|
||||||
* if (endnext == xprev)
|
if (endnext == xprev)
|
||||||
* {
|
{
|
||||||
* close DLS(xprev, end, end, xprev, singleton(xprev), singleton(xprev_val), l);
|
close DLS(xprev, end, end, xprev, singleton(xprev), singleton(xprev_val), l);
|
||||||
* close DLS(end, xprev, end, xprev, cons(end, singleton(xprev)), cons(portMAX_DELAY, singleton(xprev_val)), l);
|
close DLS(end, xprev, end, xprev, cons(end, singleton(xprev)), cons(portMAX_DELAY, singleton(xprev_val)), l);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* close DLS(xprev, ?xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
|
close DLS(xprev, ?xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
|
||||||
* assert DLS(endnext, end, xprev, xprevprev, ?cells_endnext_to_xprevprev, ?vals_endnext_to_xprevprev, l);
|
assert DLS(endnext, end, xprev, xprevprev, ?cells_endnext_to_xprevprev, ?vals_endnext_to_xprevprev, l);
|
||||||
* join(endnext, end, xprev, xprevprev, cells_endnext_to_xprevprev, vals_endnext_to_xprevprev,
|
join(endnext, end, xprev, xprevprev, cells_endnext_to_xprevprev, vals_endnext_to_xprevprev,
|
||||||
* xprev, xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val));
|
xprev, xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val));
|
||||||
* close DLS(end, xprev, end, xprev, ys, vs, l);
|
close DLS(end, xprev, end, xprev, ys, vs, l);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* //Case D
|
//Case D
|
||||||
* close xLIST_ITEM(xnext, _, ?xnextnext, xprev, l);
|
close xLIST_ITEM(xnext, _, ?xnextnext, xprev, l);
|
||||||
* close DLS(xnext, xprev, end, endprev, tail(zs), tail(ws), l);
|
close DLS(xnext, xprev, end, endprev, tail(zs), tail(ws), l);
|
||||||
* close xLIST_ITEM(end, _, ?endnext, endprev, l);
|
close xLIST_ITEM(end, _, ?endnext, endprev, l);
|
||||||
* close xLIST_ITEM(xprev, ?xprev_val, xnext, _, l);
|
close xLIST_ITEM(xprev, ?xprev_val, xnext, _, l);
|
||||||
* if (endnext == xprev)
|
if (endnext == xprev)
|
||||||
* {
|
{
|
||||||
* close DLS(xprev, _, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
|
close DLS(xprev, _, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
|
||||||
* close DLS(end, endprev, xnext, xprev, ys, vs, l);
|
close DLS(end, endprev, xnext, xprev, ys, vs, l);
|
||||||
* join(end, endprev, xnext, xprev, ys, vs,
|
join(end, endprev, xnext, xprev, ys, vs,
|
||||||
* xnext, xprev, end, endprev, tail(zs), tail(ws));
|
xnext, xprev, end, endprev, tail(zs), tail(ws));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* close DLS(xprev, ?xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
|
close DLS(xprev, ?xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
|
||||||
* assert DLS(endnext, end, xprev, xprevprev, ?cells_endnext_to_xprevprev, ?vals_endnext_to_xprevprev, l);
|
assert DLS(endnext, end, xprev, xprevprev, ?cells_endnext_to_xprevprev, ?vals_endnext_to_xprevprev, l);
|
||||||
* join(endnext, end, xprev, xprevprev, cells_endnext_to_xprevprev, vals_endnext_to_xprevprev,
|
join(endnext, end, xprev, xprevprev, cells_endnext_to_xprevprev, vals_endnext_to_xprevprev,
|
||||||
* xprev, xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val));
|
xprev, xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val));
|
||||||
* close DLS(end, endprev, xnext, xprev, ys, vs, l);
|
close DLS(end, endprev, xnext, xprev, ys, vs, l);
|
||||||
* join(end, endprev, xnext, xprev, ys, vs,
|
join(end, endprev, xnext, xprev, ys, vs,
|
||||||
* xnext, xprev, end, endprev, tail(zs), tail(ws));
|
xnext, xprev, end, endprev, tail(zs), tail(ws));
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
/*@remove_remove_nth(cells, x);@*/
|
/*@remove_remove_nth(cells, x);@*/
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (idx == x)
|
if (idx == x)
|
||||||
* {
|
{
|
||||||
* close xLIST(l, len-1, xprev, end, append(ys, tail(zs)), append(vs, tail(ws)));
|
close xLIST(l, len-1, xprev, end, append(ys, tail(zs)), append(vs, tail(ws)));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* idx_remains_in_list(cells, idx, x, i);
|
idx_remains_in_list(cells, idx, x, i);
|
||||||
* close xLIST(l, len-1, idx, end, append(ys, tail(zs)), append(vs, tail(ws)));
|
close xLIST(l, len-1, idx, end, append(ys, tail(zs)), append(vs, tail(ws)));
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
/*@close xLIST_ITEM(x, nth(i, vals), xnext, xprev, NULL);@*/
|
/*@close xLIST_ITEM(x, nth(i, vals), xnext, xprev, NULL);@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItem_t * client_example( List_t * l )
|
ListItem_t * client_example( List_t * l )
|
||||||
|
|
||||||
/*@requires
|
/*@requires
|
||||||
* xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
||||||
* idx != end &*&
|
idx != end &*&
|
||||||
* cells == cons(end, cons(idx, ?cells_tl)) &*&
|
cells == cons(end, cons(idx, ?cells_tl)) &*&
|
||||||
* vals == cons(portMAX_DELAY, cons(42, ?vals_tl));@*/
|
vals == cons(portMAX_DELAY, cons(42, ?vals_tl));@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* xLIST(l, len - 1, _, end, cons(end, cells_tl), cons(portMAX_DELAY, vals_tl)) &*&
|
xLIST(l, len - 1, _, end, cons(end, cells_tl), cons(portMAX_DELAY, vals_tl)) &*&
|
||||||
* xLIST_ITEM(result, 42, _, _, NULL);@*/
|
xLIST_ITEM(result, 42, _, _, NULL);@*/
|
||||||
{
|
{
|
||||||
/*@open xLIST(l, len, idx, end, cells, vals);@*/
|
/*@open xLIST(l, len, idx, end, cells, vals);@*/
|
||||||
ListItem_t * index = l->pxIndex;
|
ListItem_t *index = l->pxIndex;
|
||||||
|
|
||||||
/*@close xLIST(l, len, idx, end, cells, vals);@*/
|
/*@close xLIST(l, len, idx, end, cells, vals);@*/
|
||||||
/*@close exists(l);@*/
|
/*@close exists(l);@*/
|
||||||
uxListRemove( index );
|
uxListRemove( index );
|
||||||
|
@ -293,22 +288,19 @@ ListItem_t * client_example( List_t * l )
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_example2( List_t * l )
|
void client_example2( List_t * l )
|
||||||
|
|
||||||
/*@requires
|
/*@requires
|
||||||
* xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
||||||
* cells == cons(end, cons(?x1, cons(?x2, ?cells_tl))) &*&
|
cells == cons(end, cons(?x1, cons(?x2, ?cells_tl))) &*&
|
||||||
* idx == x2 &*&
|
idx == x2 &*&
|
||||||
* vals == cons(portMAX_DELAY, cons(1, cons(2, ?vals_tl)));@*/
|
vals == cons(portMAX_DELAY, cons(1, cons(2, ?vals_tl)));@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* xLIST(l, len-2, end, end, cons(end, cells_tl), cons(portMAX_DELAY, vals_tl)) &*&
|
xLIST(l, len-2, end, end, cons(end, cells_tl), cons(portMAX_DELAY, vals_tl)) &*&
|
||||||
* xLIST_ITEM(_, 1, _, _, NULL) &*&
|
xLIST_ITEM(_, 1, _, _, NULL) &*&
|
||||||
* xLIST_ITEM(_, 2, _, _, NULL);@*/
|
xLIST_ITEM(_, 2, _, _, NULL);@*/
|
||||||
{
|
{
|
||||||
/*@xLIST_distinct_cells(l);@*/
|
/*@xLIST_distinct_cells(l);@*/
|
||||||
/*@open xLIST(l, len, idx, end, cells, vals);@*/
|
/*@open xLIST(l, len, idx, end, cells, vals);@*/
|
||||||
ListItem_t * index = l->pxIndex;
|
ListItem_t *index = l->pxIndex;
|
||||||
|
|
||||||
/*@close xLIST(l, len, idx, end, cells, vals);@*/
|
/*@close xLIST(l, len, idx, end, cells, vals);@*/
|
||||||
/*@close exists(l);@*/
|
/*@close exists(l);@*/
|
||||||
uxListRemove( index );
|
uxListRemove( index );
|
||||||
|
@ -318,3 +310,5 @@ void client_example2( List_t * l )
|
||||||
/*@close exists(l);@*/
|
/*@close exists(l);@*/
|
||||||
uxListRemove( index );
|
uxListRemove( index );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,19 +24,21 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/list.h"
|
#include "proof/list.h"
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate xLIST_uninitialised(struct xLIST *l) =
|
predicate xLIST_uninitialised(struct xLIST *l) =
|
||||||
* l->uxNumberOfItems |-> _ &*&
|
l->uxNumberOfItems |-> _ &*&
|
||||||
* l->pxIndex |-> _ &*&
|
l->pxIndex |-> _ &*&
|
||||||
* l->xListEnd.xItemValue |-> _ &*&
|
l->xListEnd.xItemValue |-> _ &*&
|
||||||
* l->xListEnd.pxNext |-> _ &*&
|
l->xListEnd.pxNext |-> _ &*&
|
||||||
* l->xListEnd.pxPrevious |-> _ &*&
|
l->xListEnd.pxPrevious |-> _ &*&
|
||||||
* l->xListEnd.pvOwner |-> _ &*&
|
l->xListEnd.pvOwner |-> _ &*&
|
||||||
* l->xListEnd.pxContainer |-> _ &*&
|
l->xListEnd.pxContainer |-> _ &*&
|
||||||
* struct_xLIST_ITEM_padding(&l->xListEnd);
|
struct_xLIST_ITEM_padding(&l->xListEnd);
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
void vListInitialise( List_t * const pxList )
|
void vListInitialise( List_t * const pxList )
|
||||||
/*@requires xLIST_uninitialised(pxList);@*/
|
/*@requires xLIST_uninitialised(pxList);@*/
|
||||||
|
@ -49,6 +51,8 @@ void vListInitialise( List_t * const pxList )
|
||||||
* as the only list entry. */
|
* as the only list entry. */
|
||||||
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
|
listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
|
||||||
|
|
||||||
/* The list end value is the highest possible value in the list to
|
/* The list end value is the highest possible value in the list to
|
||||||
* ensure it remains at the end of the list. */
|
* ensure it remains at the end of the list. */
|
||||||
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||||
|
@ -58,6 +62,15 @@ void vListInitialise( List_t * const pxList )
|
||||||
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
|
/* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */
|
||||||
|
#if ( configUSE_MINI_LIST_ITEM == 0 )
|
||||||
|
{
|
||||||
|
pxList->xListEnd.pvOwner = NULL;
|
||||||
|
pxList->xListEnd.pxContainer = NULL;
|
||||||
|
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
||||||
|
|
||||||
/* Write known values into the list if
|
/* Write known values into the list if
|
||||||
|
@ -65,11 +78,13 @@ void vListInitialise( List_t * const pxList )
|
||||||
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
|
||||||
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
|
||||||
|
|
||||||
#ifdef VERIFAST /*< ***change MiniList_t to ListItem_t*** */
|
#ifdef VERIFAST /*< ***change MiniList_t to ListItem_t*** */
|
||||||
pxList->xListEnd.pxContainer = pxList;
|
pxList->xListEnd.pxContainer = pxList;
|
||||||
#endif
|
#endif
|
||||||
/*@ListItem_t *end = &(pxList->xListEnd);@*/
|
/*@ListItem_t *end = &(pxList->xListEnd);@*/
|
||||||
/*@close xLIST_ITEM(end, portMAX_DELAY, _, _, pxList);@*/
|
/*@close xLIST_ITEM(end, portMAX_DELAY, _, _, pxList);@*/
|
||||||
/*@close DLS(end, end, end, end, singleton(end), singleton(portMAX_DELAY), pxList);@*/
|
/*@close DLS(end, end, end, end, singleton(end), singleton(portMAX_DELAY), pxList);@*/
|
||||||
/*@close xLIST(pxList, 0, end, end, singleton(end), singleton(portMAX_DELAY));@*/
|
/*@close xLIST(pxList, 0, end, end, singleton(end), singleton(portMAX_DELAY));@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/list.h"
|
#include "proof/list.h"
|
||||||
|
|
||||||
void vListInitialiseItem( ListItem_t * const pxItem )
|
void vListInitialiseItem( ListItem_t * const pxItem )
|
||||||
|
@ -39,3 +41,5 @@ void vListInitialiseItem( ListItem_t * const pxItem )
|
||||||
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
|
||||||
/*@close xLIST_ITEM(pxItem, _, _, _, NULL);@*/
|
/*@close xLIST_ITEM(pxItem, _, _, _, NULL);@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,24 +24,23 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/list.h"
|
#include "proof/list.h"
|
||||||
|
|
||||||
|
|
||||||
ListItem_t * choose( List_t * list );
|
ListItem_t * choose(List_t * list);
|
||||||
/*@ requires DLS(&(list->xListEnd), ?endprev, &(list->xListEnd), endprev, ?cells, ?vals, ?container);@*/
|
/*@ requires DLS(&(list->xListEnd), ?endprev, &(list->xListEnd), endprev, ?cells, ?vals, ?container);@*/
|
||||||
|
|
||||||
/*@ ensures DLS(&(list->xListEnd), endprev, &(list->xListEnd), endprev, cells, vals, container) &*&
|
/*@ ensures DLS(&(list->xListEnd), endprev, &(list->xListEnd), endprev, cells, vals, container) &*&
|
||||||
* mem(result, cells) == true;@*/
|
mem(result, cells) == true;@*/
|
||||||
|
|
||||||
void vListInsert( List_t * const pxList,
|
void vListInsert( List_t * const pxList,
|
||||||
ListItem_t * const pxNewListItem )
|
ListItem_t * const pxNewListItem )
|
||||||
|
|
||||||
/*@requires xLIST(pxList, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
/*@requires xLIST(pxList, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
||||||
* xLIST_ITEM(pxNewListItem, ?val, _, _, _);@*/
|
xLIST_ITEM(pxNewListItem, ?val, _, _, _);@*/
|
||||||
|
|
||||||
/*@ensures xLIST(pxList, len+1, idx, end, ?new_cells, ?new_vals) &*&
|
/*@ensures xLIST(pxList, len+1, idx, end, ?new_cells, ?new_vals) &*&
|
||||||
* remove(pxNewListItem, new_cells) == cells
|
remove(pxNewListItem, new_cells) == cells
|
||||||
* ;@*/
|
;@*/
|
||||||
{
|
{
|
||||||
/*@xLIST_star_item(pxList, pxNewListItem);@*/
|
/*@xLIST_star_item(pxList, pxNewListItem);@*/
|
||||||
/*@open xLIST_ITEM(pxNewListItem, _, _, _, _);@*/
|
/*@open xLIST_ITEM(pxNewListItem, _, _, _, _);@*/
|
||||||
|
@ -68,24 +67,23 @@ void vListInsert( List_t * const pxList,
|
||||||
{
|
{
|
||||||
/*@open DLS(end, endprev, end, endprev, cells, vals, pxList);@*/
|
/*@open DLS(end, endprev, end, endprev, cells, vals, pxList);@*/
|
||||||
/*@open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, pxList);@*/
|
/*@open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, pxList);@*/
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (end != endprev)
|
if (end != endprev)
|
||||||
* {
|
{
|
||||||
* assert DLS(endnext, end, end, endprev, tail(cells), tail(vals), pxList);
|
assert DLS(endnext, end, end, endprev, tail(cells), tail(vals), pxList);
|
||||||
* if (endnext == endprev)
|
if (endnext == endprev)
|
||||||
* {
|
{
|
||||||
* // done
|
// done
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* dls_last_mem(endnext, end, end, endprev, tail(cells));
|
dls_last_mem(endnext, end, end, endprev, tail(cells));
|
||||||
* split(endnext, end, end, endprev, tail(cells), tail(vals), endprev, index_of(endprev, tail(cells)));
|
split(endnext, end, end, endprev, tail(cells), tail(vals), endprev, index_of(endprev, tail(cells)));
|
||||||
* }
|
}
|
||||||
* open DLS(endprev, _, _, _, _, _, _);
|
open DLS(endprev, _, _, _, _, _, _);
|
||||||
* open xLIST_ITEM(endprev, _, _, _, _);
|
open xLIST_ITEM(endprev, _, _, _, _);
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
pxIterator = pxList->xListEnd.pxPrevious;
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -110,55 +108,57 @@ void vListInsert( List_t * const pxList,
|
||||||
* 4) Using a queue or semaphore before it has been initialised or
|
* 4) Using a queue or semaphore before it has been initialised or
|
||||||
* before the scheduler has been started (are interrupts firing
|
* before the scheduler has been started (are interrupts firing
|
||||||
* before vTaskStartScheduler() has been called?).
|
* before vTaskStartScheduler() has been called?).
|
||||||
|
* 5) If the FreeRTOS port supports interrupt nesting then ensure that
|
||||||
|
* the priority of the tick interrupt is at or below
|
||||||
|
* configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#ifdef VERIFAST /*< ***over-approximate list insert loop*** */
|
#ifdef VERIFAST /*< ***over-approximate list insert loop*** */
|
||||||
pxIterator = choose( pxList );
|
pxIterator = choose(pxList);
|
||||||
#else
|
#else
|
||||||
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
|
||||||
{
|
{
|
||||||
/* There is nothing to do here, just iterating to the wanted
|
/* There is nothing to do here, just iterating to the wanted
|
||||||
* insertion position. */
|
* insertion position. */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*@int i = index_of(pxIterator, cells);@*/
|
/*@int i = index_of(pxIterator, cells);@*/
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (pxIterator == end)
|
if (pxIterator == end)
|
||||||
* {
|
{
|
||||||
* open DLS(end, endprev, end, endprev, cells, vals, pxList);
|
open DLS(end, endprev, end, endprev, cells, vals, pxList);
|
||||||
* open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, pxList);
|
open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, pxList);
|
||||||
* if (end != endprev)
|
if (end != endprev)
|
||||||
* {
|
{
|
||||||
* assert DLS(endnext, end, end, endprev, tail(cells), tail(vals), pxList);
|
assert DLS(endnext, end, end, endprev, tail(cells), tail(vals), pxList);
|
||||||
* open DLS(endnext, _, _, _, _, _, _);
|
open DLS(endnext, _, _, _, _, _, _);
|
||||||
* open xLIST_ITEM(endnext, _, _, _, _);
|
open xLIST_ITEM(endnext, _, _, _, _);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(end, endprev, end, endprev, cells, vals, pxList);
|
assert DLS(end, endprev, end, endprev, cells, vals, pxList);
|
||||||
* dls_first_mem(end, endprev, end, endprev, cells);
|
dls_first_mem(end, endprev, end, endprev, cells);
|
||||||
* assert pxIterator != end;
|
assert pxIterator != end;
|
||||||
* assert index_of(end, cells) == 0;
|
assert index_of(end, cells) == 0;
|
||||||
* split(end, endprev, end, endprev, cells, vals, pxIterator, i);
|
split(end, endprev, end, endprev, cells, vals, pxIterator, i);
|
||||||
* assert DLS(end, endprev, pxIterator, ?iterprev, take(i, cells), take(i, vals), pxList);
|
assert DLS(end, endprev, pxIterator, ?iterprev, take(i, cells), take(i, vals), pxList);
|
||||||
* assert DLS(pxIterator, iterprev, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
assert DLS(pxIterator, iterprev, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
||||||
* open DLS(pxIterator, iterprev, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
open DLS(pxIterator, iterprev, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
||||||
* open xLIST_ITEM(pxIterator, _, ?iternext, iterprev, pxList);
|
open xLIST_ITEM(pxIterator, _, ?iternext, iterprev, pxList);
|
||||||
* if (pxIterator == endprev)
|
if (pxIterator == endprev)
|
||||||
* {
|
{
|
||||||
* open DLS(end, endprev, pxIterator, iterprev, take(i, cells), take(i, vals), pxList);
|
open DLS(end, endprev, pxIterator, iterprev, take(i, cells), take(i, vals), pxList);
|
||||||
* take_take(1, i, vals);
|
take_take(1, i, vals);
|
||||||
* assert xLIST_ITEM(end, portMAX_DELAY, _, _, _);
|
assert xLIST_ITEM(end, portMAX_DELAY, _, _, _);
|
||||||
* open xLIST_ITEM(iternext, _, _, pxIterator, _);
|
open xLIST_ITEM(iternext, _, _, pxIterator, _);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* open DLS(iternext, pxIterator, end, endprev, _, _, _);
|
open DLS(iternext, pxIterator, end, endprev, _, _, _);
|
||||||
* open xLIST_ITEM(iternext, _, _, pxIterator, _);
|
open xLIST_ITEM(iternext, _, _, pxIterator, _);
|
||||||
* }
|
}
|
||||||
* }@*/
|
}@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
pxNewListItem->pxNext = pxIterator->pxNext;
|
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||||
|
@ -174,153 +174,154 @@ void vListInsert( List_t * const pxList,
|
||||||
|
|
||||||
/*@close xLIST_ITEM(pxNewListItem, val, ?iternext, pxIterator, pxList);@*/
|
/*@close xLIST_ITEM(pxNewListItem, val, ?iternext, pxIterator, pxList);@*/
|
||||||
/*@close xLIST_ITEM(pxIterator, ?iterval, pxNewListItem, ?iterprev, pxList);@*/
|
/*@close xLIST_ITEM(pxIterator, ?iterval, pxNewListItem, ?iterprev, pxList);@*/
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if( xValueOfInsertion == portMAX_DELAY )
|
if( xValueOfInsertion == portMAX_DELAY )
|
||||||
* {
|
{
|
||||||
* assert iternext == end;
|
assert iternext == end;
|
||||||
* assert pxIterator == endprev;
|
assert pxIterator == endprev;
|
||||||
* if (end == endprev)
|
if (end == endprev)
|
||||||
* {
|
{
|
||||||
* close DLS(end, pxNewListItem, pxNewListItem, end, cells, vals, pxList);
|
close DLS(end, pxNewListItem, pxNewListItem, end, cells, vals, pxList);
|
||||||
* close DLS(pxNewListItem, end, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
close DLS(pxNewListItem, end, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
||||||
* join(end, pxNewListItem, pxNewListItem, end, cells, vals,
|
join(end, pxNewListItem, pxNewListItem, end, cells, vals,
|
||||||
* pxNewListItem, end, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
pxNewListItem, end, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* close xLIST_ITEM(end, portMAX_DELAY, ?endnext, pxNewListItem, pxList);
|
close xLIST_ITEM(end, portMAX_DELAY, ?endnext, pxNewListItem, pxList);
|
||||||
* close DLS(pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
close DLS(pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
||||||
* if (endnext == endprev)
|
if (endnext == endprev)
|
||||||
* {
|
{
|
||||||
* assert xLIST_ITEM(endnext, ?endnextval, pxNewListItem, end, pxList);
|
assert xLIST_ITEM(endnext, ?endnextval, pxNewListItem, end, pxList);
|
||||||
* close DLS(end, pxNewListItem, endnext, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
close DLS(end, pxNewListItem, endnext, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
||||||
* close DLS(endnext, end, pxNewListItem, endnext, singleton(endnext), singleton(endnextval), pxList);
|
close DLS(endnext, end, pxNewListItem, endnext, singleton(endnext), singleton(endnextval), pxList);
|
||||||
* join(end, pxNewListItem, endnext, end, singleton(end), singleton(portMAX_DELAY),
|
join(end, pxNewListItem, endnext, end, singleton(end), singleton(portMAX_DELAY),
|
||||||
* endnext, end, pxNewListItem, endnext, singleton(endnext), singleton(endnextval));
|
endnext, end, pxNewListItem, endnext, singleton(endnext), singleton(endnextval));
|
||||||
* assert DLS(end, pxNewListItem, pxNewListItem, endnext, cells, vals, pxList);
|
assert DLS(end, pxNewListItem, pxNewListItem, endnext, cells, vals, pxList);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(endnext, end, endprev, ?endprevprev, ?cells_endnext_to_endprevprev, ?vals_endnext_to_endprevprev, pxList);
|
assert DLS(endnext, end, endprev, ?endprevprev, ?cells_endnext_to_endprevprev, ?vals_endnext_to_endprevprev, pxList);
|
||||||
* assert cells_endnext_to_endprevprev == take(index_of(endprev, tail(cells)), tail(cells));
|
assert cells_endnext_to_endprevprev == take(index_of(endprev, tail(cells)), tail(cells));
|
||||||
* assert index_of(endprev, tail(cells)) == length(tail(cells)) - 1;
|
assert index_of(endprev, tail(cells)) == length(tail(cells)) - 1;
|
||||||
* assert cells_endnext_to_endprevprev == take(length(tail(cells)) - 1, tail(cells));
|
assert cells_endnext_to_endprevprev == take(length(tail(cells)) - 1, tail(cells));
|
||||||
* assert xLIST_ITEM(endprev, ?endprevval, pxNewListItem, endprevprev, pxList);
|
assert xLIST_ITEM(endprev, ?endprevval, pxNewListItem, endprevprev, pxList);
|
||||||
* close DLS(endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval), pxList);
|
close DLS(endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval), pxList);
|
||||||
* dls_last_mem(endnext, end, endprev, endprevprev, cells_endnext_to_endprevprev);
|
dls_last_mem(endnext, end, endprev, endprevprev, cells_endnext_to_endprevprev);
|
||||||
* dls_star_item(endnext, endprevprev, end);
|
dls_star_item(endnext, endprevprev, end);
|
||||||
* close DLS(end, pxNewListItem, endprev, endprevprev, cons(end, cells_endnext_to_endprevprev), cons(portMAX_DELAY, vals_endnext_to_endprevprev), pxList);
|
close DLS(end, pxNewListItem, endprev, endprevprev, cons(end, cells_endnext_to_endprevprev), cons(portMAX_DELAY, vals_endnext_to_endprevprev), pxList);
|
||||||
* join(end, pxNewListItem, endprev, endprevprev, cons(end, cells_endnext_to_endprevprev), cons(portMAX_DELAY, vals_endnext_to_endprevprev),
|
join(end, pxNewListItem, endprev, endprevprev, cons(end, cells_endnext_to_endprevprev), cons(portMAX_DELAY, vals_endnext_to_endprevprev),
|
||||||
* endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval));
|
endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval));
|
||||||
* assert DLS(end, pxNewListItem, pxNewListItem, endprev, cells, vals, pxList);
|
assert DLS(end, pxNewListItem, pxNewListItem, endprev, cells, vals, pxList);
|
||||||
*
|
|
||||||
* }
|
}
|
||||||
* join(end, pxNewListItem, pxNewListItem, endprev, cells, vals,
|
join(end, pxNewListItem, pxNewListItem, endprev, cells, vals,
|
||||||
* pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
||||||
* remove_append(pxNewListItem, cells, singleton(pxNewListItem));
|
remove_append(pxNewListItem, cells, singleton(pxNewListItem));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* if (pxIterator == end)
|
if (pxIterator == end)
|
||||||
* {
|
{
|
||||||
* if (iternext == end)
|
if (iternext == end)
|
||||||
* {
|
{
|
||||||
* close DLS(end, pxNewListItem, pxNewListItem, end, cells, vals, pxList);
|
close DLS(end, pxNewListItem, pxNewListItem, end, cells, vals, pxList);
|
||||||
* close DLS(pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
close DLS(pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
||||||
* join(end, pxNewListItem, pxNewListItem, end, cells, vals,
|
join(end, pxNewListItem, pxNewListItem, end, cells, vals,
|
||||||
* pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* close xLIST_ITEM(iternext, ?iternextval, _, pxNewListItem, pxList);
|
close xLIST_ITEM(iternext, ?iternextval, _, pxNewListItem, pxList);
|
||||||
* if (iternext == endprev)
|
if (iternext == endprev)
|
||||||
* {
|
{
|
||||||
* close DLS(iternext, pxNewListItem, end, endprev, singleton(iternext), singleton(iternextval), pxList);
|
close DLS(iternext, pxNewListItem, end, endprev, singleton(iternext), singleton(iternextval), pxList);
|
||||||
* dls_last_mem(iternext, pxNewListItem, end, endprev, singleton(iternext));
|
dls_last_mem(iternext, pxNewListItem, end, endprev, singleton(iternext));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(?iternextnext, iternext, end, endprev, ?cells_iternextnext_to_endprev, ?vals_iternextnext_to_endprev, pxList);
|
assert DLS(?iternextnext, iternext, end, endprev, ?cells_iternextnext_to_endprev, ?vals_iternextnext_to_endprev, pxList);
|
||||||
* close DLS(iternext, pxNewListItem, end, endprev, cons(iternext, cells_iternextnext_to_endprev), cons(iternextval, vals_iternextnext_to_endprev), pxList);
|
close DLS(iternext, pxNewListItem, end, endprev, cons(iternext, cells_iternextnext_to_endprev), cons(iternextval, vals_iternextnext_to_endprev), pxList);
|
||||||
* dls_last_mem(iternext, pxNewListItem, end, endprev, cons(iternext, cells_iternextnext_to_endprev));
|
dls_last_mem(iternext, pxNewListItem, end, endprev, cons(iternext, cells_iternextnext_to_endprev));
|
||||||
* }
|
}
|
||||||
* close DLS(end, endprev, pxNewListItem, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
close DLS(end, endprev, pxNewListItem, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
||||||
* assert DLS(iternext, pxNewListItem, end, endprev, ?cells_iternext_to_endprev, ?vals_iternext_to_endprev, pxList);
|
assert DLS(iternext, pxNewListItem, end, endprev, ?cells_iternext_to_endprev, ?vals_iternext_to_endprev, pxList);
|
||||||
* dls_star_item(iternext, endprev, pxNewListItem);
|
dls_star_item(iternext, endprev, pxNewListItem);
|
||||||
* close DLS(pxNewListItem, pxIterator, end, endprev, cons(pxNewListItem, cells_iternext_to_endprev), cons(val, vals_iternext_to_endprev), pxList);
|
close DLS(pxNewListItem, pxIterator, end, endprev, cons(pxNewListItem, cells_iternext_to_endprev), cons(val, vals_iternext_to_endprev), pxList);
|
||||||
* join(end, endprev, pxNewListItem, end, singleton(end), singleton(portMAX_DELAY),
|
join(end, endprev, pxNewListItem, end, singleton(end), singleton(portMAX_DELAY),
|
||||||
* pxNewListItem, pxIterator, end, endprev, cons(pxNewListItem, cells_iternext_to_endprev), cons(val, vals_iternext_to_endprev));
|
pxNewListItem, pxIterator, end, endprev, cons(pxNewListItem, cells_iternext_to_endprev), cons(val, vals_iternext_to_endprev));
|
||||||
* close xLIST(pxList, len+1, idx, end, cons(end, cons(pxNewListItem, cells_iternext_to_endprev)), cons(portMAX_DELAY, cons(val, vals_iternext_to_endprev)));
|
close xLIST(pxList, len+1, idx, end, cons(end, cons(pxNewListItem, cells_iternext_to_endprev)), cons(portMAX_DELAY, cons(val, vals_iternext_to_endprev)));
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* close xLIST_ITEM(iternext, ?iternextval, _, pxNewListItem, pxList);
|
close xLIST_ITEM(iternext, ?iternextval, _, pxNewListItem, pxList);
|
||||||
* if (pxIterator == endprev)
|
if (pxIterator == endprev)
|
||||||
* {
|
{
|
||||||
* if (iterprev == end)
|
if (iterprev == end)
|
||||||
* {
|
{
|
||||||
* close DLS(end, pxNewListItem, pxIterator, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
close DLS(end, pxNewListItem, pxIterator, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(_, iternext, pxIterator, iterprev, ?cells1, ?vals1, _);
|
assert DLS(_, iternext, pxIterator, iterprev, ?cells1, ?vals1, _);
|
||||||
* close DLS(end, pxNewListItem, pxIterator, iterprev, cons(end, cells1), cons(portMAX_DELAY, vals1), pxList);
|
close DLS(end, pxNewListItem, pxIterator, iterprev, cons(end, cells1), cons(portMAX_DELAY, vals1), pxList);
|
||||||
* }
|
}
|
||||||
* int i = index_of(pxIterator, cells);
|
int i = index_of(pxIterator, cells);
|
||||||
* assert DLS(end, pxNewListItem, pxIterator, iterprev, take(i, cells), take(i, vals), pxList);
|
assert DLS(end, pxNewListItem, pxIterator, iterprev, take(i, cells), take(i, vals), pxList);
|
||||||
* close DLS(pxIterator, iterprev, pxNewListItem, pxIterator, drop(i, cells), drop(i, vals), pxList);
|
close DLS(pxIterator, iterprev, pxNewListItem, pxIterator, drop(i, cells), drop(i, vals), pxList);
|
||||||
* close DLS(pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
close DLS(pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
||||||
* join(end, pxNewListItem, pxIterator, iterprev, take(i, cells), take(i, vals),
|
join(end, pxNewListItem, pxIterator, iterprev, take(i, cells), take(i, vals),
|
||||||
* pxIterator, iterprev, pxNewListItem, pxIterator, drop(i, cells), drop(i, vals));
|
pxIterator, iterprev, pxNewListItem, pxIterator, drop(i, cells), drop(i, vals));
|
||||||
* join(end, pxNewListItem, pxNewListItem, pxIterator, cells, vals,
|
join(end, pxNewListItem, pxNewListItem, pxIterator, cells, vals,
|
||||||
* pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
pxNewListItem, pxIterator, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
||||||
* remove_append(pxNewListItem, cells, singleton(pxNewListItem));
|
remove_append(pxNewListItem, cells, singleton(pxNewListItem));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* int i = index_of(pxIterator, cells);
|
int i = index_of(pxIterator, cells);
|
||||||
* if (iternext == endprev)
|
if (iternext == endprev)
|
||||||
* {
|
{
|
||||||
* close DLS(iternext, pxNewListItem, end, endprev, singleton(iternext), singleton(iternextval), pxList);
|
close DLS(iternext, pxNewListItem, end, endprev, singleton(iternext), singleton(iternextval), pxList);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(_, iternext, end, endprev, ?cells0, ?vals0, pxList);
|
assert DLS(_, iternext, end, endprev, ?cells0, ?vals0, pxList);
|
||||||
* dls_star_item(end, iterprev, iternext);
|
dls_star_item(end, iterprev, iternext);
|
||||||
* close DLS(iternext, pxNewListItem, end, endprev, tail(drop(i, cells)), tail(drop(i, vals)), pxList);
|
close DLS(iternext, pxNewListItem, end, endprev, tail(drop(i, cells)), tail(drop(i, vals)), pxList);
|
||||||
* }
|
}
|
||||||
* drop_drop(1, i, cells);
|
drop_drop(1, i, cells);
|
||||||
* drop_drop(1, i, vals);
|
drop_drop(1, i, vals);
|
||||||
* assert DLS(iternext, pxNewListItem, end, endprev, drop(i+1, cells), drop(i+1, vals), pxList);
|
assert DLS(iternext, pxNewListItem, end, endprev, drop(i+1, cells), drop(i+1, vals), pxList);
|
||||||
* assert DLS(end, endprev, pxIterator, iterprev, take(i, cells), take(i, vals), pxList);
|
assert DLS(end, endprev, pxIterator, iterprev, take(i, cells), take(i, vals), pxList);
|
||||||
* dls_star_item(iternext, endprev, pxNewListItem);
|
dls_star_item(iternext, endprev, pxNewListItem);
|
||||||
* dls_last_mem(iternext, pxNewListItem, end, endprev, drop(i+1, cells));
|
dls_last_mem(iternext, pxNewListItem, end, endprev, drop(i+1, cells));
|
||||||
* close DLS(pxNewListItem, pxIterator, end, endprev, cons(pxNewListItem, drop(i+1, cells)), cons(val, drop(i+1, vals)), pxList);
|
close DLS(pxNewListItem, pxIterator, end, endprev, cons(pxNewListItem, drop(i+1, cells)), cons(val, drop(i+1, vals)), pxList);
|
||||||
* close DLS(pxIterator, iterprev, end, endprev, cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))), cons(iterval, cons(val, drop(i+1, vals))), pxList);
|
close DLS(pxIterator, iterprev, end, endprev, cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))), cons(iterval, cons(val, drop(i+1, vals))), pxList);
|
||||||
* join(end, endprev, pxIterator, iterprev, take(i, cells), take(i, vals),
|
join(end, endprev, pxIterator, iterprev, take(i, cells), take(i, vals),
|
||||||
* pxIterator, iterprev, end, endprev, cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))), cons(iterval, cons(val, drop(i+1, vals))));
|
pxIterator, iterprev, end, endprev, cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))), cons(iterval, cons(val, drop(i+1, vals))));
|
||||||
* list<struct xLIST_ITEM * >new_cells = append(take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))));
|
list<struct xLIST_ITEM * >new_cells = append(take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))));
|
||||||
* list<TickType_t >new_vals = append(take(i, vals), cons(iterval, cons(val, drop(i+1, vals))));
|
list<TickType_t >new_vals = append(take(i, vals), cons(iterval, cons(val, drop(i+1, vals))));
|
||||||
* head_append(take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))));
|
head_append(take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))));
|
||||||
* take_head(take(i, cells));
|
take_head(take(i, cells));
|
||||||
* take_take(1, i, cells);
|
take_take(1, i, cells);
|
||||||
* assert( end == head(new_cells) );
|
assert( end == head(new_cells) );
|
||||||
* head_append(take(i, vals), cons(iterval, cons(val, drop(i+1, vals))));
|
head_append(take(i, vals), cons(iterval, cons(val, drop(i+1, vals))));
|
||||||
* take_head(take(i, vals));
|
take_head(take(i, vals));
|
||||||
* take_take(1, i, vals);
|
take_take(1, i, vals);
|
||||||
* assert( portMAX_DELAY == head(new_vals) );
|
assert( portMAX_DELAY == head(new_vals) );
|
||||||
* append_take_drop_n(cells, index_of(pxIterator, cells));
|
append_take_drop_n(cells, index_of(pxIterator, cells));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells)))), append(take(i, vals), cons(iterval, cons(val, drop(i+1, vals)))));
|
close xLIST(pxList, len+1, idx, end, append(take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells)))), append(take(i, vals), cons(iterval, cons(val, drop(i+1, vals)))));
|
||||||
* mem_take_false(pxNewListItem, i, cells);
|
mem_take_false(pxNewListItem, i, cells);
|
||||||
* remove_append(pxNewListItem, take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))));
|
remove_append(pxNewListItem, take(i, cells), cons(pxIterator, cons(pxNewListItem, drop(i+1, cells))));
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* }@*/
|
}@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,97 +24,96 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/list.h"
|
#include "proof/list.h"
|
||||||
|
|
||||||
void vListInsertEnd( List_t * const pxList,
|
void vListInsertEnd( List_t * const pxList,
|
||||||
ListItem_t * const pxNewListItem )
|
ListItem_t * const pxNewListItem )
|
||||||
|
|
||||||
/*@requires xLIST(pxList, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
/*@requires xLIST(pxList, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
||||||
* xLIST_ITEM(pxNewListItem, ?val, _, _, _);@*/
|
xLIST_ITEM(pxNewListItem, ?val, _, _, _);@*/
|
||||||
|
|
||||||
/*@ensures xLIST(pxList, len+1, idx, end, ?new_cells, ?new_vals) &*&
|
/*@ensures xLIST(pxList, len+1, idx, end, ?new_cells, ?new_vals) &*&
|
||||||
* idx == end
|
idx == end
|
||||||
* ? (new_cells == append(cells, singleton(pxNewListItem)) &*&
|
? (new_cells == append(cells, singleton(pxNewListItem)) &*&
|
||||||
* new_vals == append(vals, singleton(val)))
|
new_vals == append(vals, singleton(val)))
|
||||||
* : (new_cells == append(take(index_of(idx, cells), cells), append(singleton(pxNewListItem), drop(index_of(idx, cells), cells))) &*&
|
: (new_cells == append(take(index_of(idx, cells), cells), append(singleton(pxNewListItem), drop(index_of(idx, cells), cells))) &*&
|
||||||
* new_vals == append(take(index_of(idx, cells), vals), append(singleton(val), drop(index_of(idx, cells), vals))));@*/
|
new_vals == append(take(index_of(idx, cells), vals), append(singleton(val), drop(index_of(idx, cells), vals))));@*/
|
||||||
{
|
{
|
||||||
/*@xLIST_star_item(pxList, pxNewListItem);@*/
|
/*@xLIST_star_item(pxList, pxNewListItem);@*/
|
||||||
/*@assert mem(pxNewListItem, cells) == false;@*/
|
/*@assert mem(pxNewListItem, cells) == false;@*/
|
||||||
/*@open xLIST(pxList, len, idx, end, cells, vals);@*/
|
/*@open xLIST(pxList, len, idx, end, cells, vals);@*/
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
ListItem_t * pxIndex = pxList->pxIndex;
|
ListItem_t * pxIndex = pxList->pxIndex;
|
||||||
#else
|
#else
|
||||||
ListItem_t * const pxIndex = pxList->pxIndex;
|
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||||
|
|
||||||
/* Only effective when configASSERT() is also defined, these tests may catch
|
/* Only effective when configASSERT() is also defined, these tests may catch
|
||||||
* the list data structures being overwritten in memory. They will not catch
|
* the list data structures being overwritten in memory. They will not catch
|
||||||
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
* data errors caused by incorrect configuration or use of FreeRTOS. */
|
||||||
listTEST_LIST_INTEGRITY( pxList );
|
listTEST_LIST_INTEGRITY( pxList );
|
||||||
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*@open xLIST_ITEM(pxNewListItem, _, _, _, _);@*/
|
/*@open xLIST_ITEM(pxNewListItem, _, _, _, _);@*/
|
||||||
/*@assert DLS(end, ?endprev, end, _, cells, vals, pxList);@*/
|
/*@assert DLS(end, ?endprev, end, _, cells, vals, pxList);@*/
|
||||||
/*@dls_first_mem(end, endprev, end, endprev, cells);@*/
|
/*@dls_first_mem(end, endprev, end, endprev, cells);@*/
|
||||||
/*@dls_last_mem(end, endprev, end, endprev, cells);@*/
|
/*@dls_last_mem(end, endprev, end, endprev, cells);@*/
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (end == idx)
|
if (end == idx)
|
||||||
* {
|
{
|
||||||
* open DLS(end, endprev, end, endprev, cells, vals, pxList);
|
open DLS(end, endprev, end, endprev, cells, vals, pxList);
|
||||||
* open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, pxList);
|
open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, pxList);
|
||||||
* if (end == endprev)
|
if (end == endprev)
|
||||||
* {
|
{
|
||||||
* // Case A (singleton): idx==end==endprev
|
// Case A (singleton): idx==end==endprev
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(endnext, end, end, endprev, tail(cells), tail(vals), pxList);
|
assert DLS(endnext, end, end, endprev, tail(cells), tail(vals), pxList);
|
||||||
* if (endnext == endprev)
|
if (endnext == endprev)
|
||||||
* {
|
{
|
||||||
* // Case B (two): idx==end and endnext==endprev
|
// Case B (two): idx==end and endnext==endprev
|
||||||
* open DLS(endnext, end, end, endnext, _, _, _);
|
open DLS(endnext, end, end, endnext, _, _, _);
|
||||||
* open xLIST_ITEM(endnext, _, _, _, _);
|
open xLIST_ITEM(endnext, _, _, _, _);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* // Case C: idx==end and DLS:endnext...endprev
|
// Case C: idx==end and DLS:endnext...endprev
|
||||||
* split(endnext, end, end, endprev, tail(cells), tail(vals), endprev, index_of(endprev, tail(cells)));
|
split(endnext, end, end, endprev, tail(cells), tail(vals), endprev, index_of(endprev, tail(cells)));
|
||||||
* open DLS(endprev, _, _, _, _, _, _);
|
open DLS(endprev, _, _, _, _, _, _);
|
||||||
* open xLIST_ITEM(endprev, _, _, _, _);
|
open xLIST_ITEM(endprev, _, _, _, _);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* int i = index_of(idx, cells);
|
int i = index_of(idx, cells);
|
||||||
* split(end, endprev, end, endprev, cells, vals, idx, i);
|
split(end, endprev, end, endprev, cells, vals, idx, i);
|
||||||
* assert DLS(end, endprev, idx, ?idxprev, take(i, cells), take(i, vals), pxList);
|
assert DLS(end, endprev, idx, ?idxprev, take(i, cells), take(i, vals), pxList);
|
||||||
* assert DLS(idx, idxprev, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
assert DLS(idx, idxprev, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
||||||
* open DLS(idx, idxprev, end, endprev, _, _, _);
|
open DLS(idx, idxprev, end, endprev, _, _, _);
|
||||||
* open xLIST_ITEM(idx, _, _, _, _);
|
open xLIST_ITEM(idx, _, _, _, _);
|
||||||
* if (end == idxprev)
|
if (end == idxprev)
|
||||||
* {
|
{
|
||||||
* // Case D: end==idxprev and DLS:idx...endprev
|
// Case D: end==idxprev and DLS:idx...endprev
|
||||||
* take_take(1, i, vals);
|
take_take(1, i, vals);
|
||||||
* take_head(vals);
|
take_head(vals);
|
||||||
* open DLS(end, endprev, idx, idxprev, take(i, cells), take(i, vals), pxList);
|
open DLS(end, endprev, idx, idxprev, take(i, cells), take(i, vals), pxList);
|
||||||
* open xLIST_ITEM(end, portMAX_DELAY, _, _, _);
|
open xLIST_ITEM(end, portMAX_DELAY, _, _, _);
|
||||||
* assert length(take(i, cells)) == 1;
|
assert length(take(i, cells)) == 1;
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* // Case E: DLS:end...idxprev and DLS:idx...endprev
|
// Case E: DLS:end...idxprev and DLS:idx...endprev
|
||||||
* dls_last_mem(end, endprev, idx, idxprev, take(i, cells));
|
dls_last_mem(end, endprev, idx, idxprev, take(i, cells));
|
||||||
* split(end, endprev, idx, idxprev, take(i, cells), take(i, vals), idxprev, index_of(idxprev, take(i, cells)));
|
split(end, endprev, idx, idxprev, take(i, cells), take(i, vals), idxprev, index_of(idxprev, take(i, cells)));
|
||||||
* open DLS(idxprev, _, _, idxprev, _, _, _);
|
open DLS(idxprev, _, _, idxprev, _, _, _);
|
||||||
* length_take(i, cells);
|
length_take(i, cells);
|
||||||
* drop_take_singleton(i, vals);
|
drop_take_singleton(i, vals);
|
||||||
* open xLIST_ITEM(idxprev, nth(i-1, vals), _, _, _);
|
open xLIST_ITEM(idxprev, nth(i-1, vals), _, _, _);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
/* Insert a new list item into pxList, but rather than sort the list,
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
* makes the new list item the last item to be removed by a call to
|
* makes the new list item the last item to be removed by a call to
|
||||||
|
@ -134,111 +133,110 @@ void vListInsertEnd( List_t * const pxList,
|
||||||
( pxList->uxNumberOfItems )++;
|
( pxList->uxNumberOfItems )++;
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (end == idx)
|
if (end == idx)
|
||||||
* {
|
{
|
||||||
* close xLIST_ITEM(pxNewListItem, val, end, endprev, pxList);
|
close xLIST_ITEM(pxNewListItem, val, end, endprev, pxList);
|
||||||
* close DLS(pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
close DLS(pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val), pxList);
|
||||||
* close xLIST_ITEM(end, portMAX_DELAY, ?endnext, pxNewListItem, pxList);
|
close xLIST_ITEM(end, portMAX_DELAY, ?endnext, pxNewListItem, pxList);
|
||||||
* if (end == endprev)
|
if (end == endprev)
|
||||||
* {
|
{
|
||||||
* // Case A (singleton): idx==end==endprev
|
// Case A (singleton): idx==end==endprev
|
||||||
* close DLS(end, pxNewListItem, endnext, end, cells, vals, pxList);
|
close DLS(end, pxNewListItem, endnext, end, cells, vals, pxList);
|
||||||
* join(end, pxNewListItem, endnext, end, cells, vals,
|
join(end, pxNewListItem, endnext, end, cells, vals,
|
||||||
* pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* close xLIST_ITEM(endprev, ?endprevval, pxNewListItem, ?endprevprev, _);
|
close xLIST_ITEM(endprev, ?endprevval, pxNewListItem, ?endprevprev, _);
|
||||||
* if (endnext == endprev)
|
if (endnext == endprev)
|
||||||
* {
|
{
|
||||||
* // Case B (two): idx==end and endnext==endprev
|
// Case B (two): idx==end and endnext==endprev
|
||||||
* close DLS(endprev, end, pxNewListItem, endprev, singleton(endprev), singleton(endprevval), pxList);
|
close DLS(endprev, end, pxNewListItem, endprev, singleton(endprev), singleton(endprevval), pxList);
|
||||||
* close DLS(end, pxNewListItem, pxNewListItem, endprev, cells, vals, pxList);
|
close DLS(end, pxNewListItem, pxNewListItem, endprev, cells, vals, pxList);
|
||||||
* join(end, pxNewListItem, pxNewListItem, endprev, cells, vals,
|
join(end, pxNewListItem, pxNewListItem, endprev, cells, vals,
|
||||||
* pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* // Case C: idx==end and DLS:endnext...endprev
|
// Case C: idx==end and DLS:endnext...endprev
|
||||||
* close DLS(endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval), pxList);
|
close DLS(endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval), pxList);
|
||||||
* assert DLS(endnext, end, endprev, endprevprev, ?cells_endnext_to_endprevprev, ?vals_endnext_to_endprevprev, pxList);
|
assert DLS(endnext, end, endprev, endprevprev, ?cells_endnext_to_endprevprev, ?vals_endnext_to_endprevprev, pxList);
|
||||||
* join(endnext, end, endprev, endprevprev, cells_endnext_to_endprevprev, vals_endnext_to_endprevprev,
|
join(endnext, end, endprev, endprevprev, cells_endnext_to_endprevprev, vals_endnext_to_endprevprev,
|
||||||
* endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval));
|
endprev, endprevprev, pxNewListItem, endprev, singleton(endprev), singleton(endprevval));
|
||||||
* close DLS(end, pxNewListItem, pxNewListItem, endprev, cells, vals, pxList);
|
close DLS(end, pxNewListItem, pxNewListItem, endprev, cells, vals, pxList);
|
||||||
* join(end, pxNewListItem, pxNewListItem, endprev, cells, vals,
|
join(end, pxNewListItem, pxNewListItem, endprev, cells, vals,
|
||||||
* pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
pxNewListItem, endprev, end, pxNewListItem, singleton(pxNewListItem), singleton(val));
|
||||||
* close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
close xLIST(pxList, len+1, idx, end, append(cells, singleton(pxNewListItem)), append(vals, singleton(val)));
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* // Case D: end==idxprev and DLS:idx...endprev
|
// Case D: end==idxprev and DLS:idx...endprev
|
||||||
* // Case E: DLS:end...idxprev and DLS:idx...endprev
|
// Case E: DLS:end...idxprev and DLS:idx...endprev
|
||||||
* int i = index_of(idx, cells);
|
int i = index_of(idx, cells);
|
||||||
* close xLIST_ITEM(pxNewListItem, val, idx, ?idxprev, pxList);
|
close xLIST_ITEM(pxNewListItem, val, idx, ?idxprev, pxList);
|
||||||
* close xLIST_ITEM(idx, ?idxval, ?idxnext, pxNewListItem, pxList);
|
close xLIST_ITEM(idx, ?idxval, ?idxnext, pxNewListItem, pxList);
|
||||||
* nth_drop2(vals, i);
|
nth_drop2(vals, i);
|
||||||
* assert idxval == nth(i, vals);
|
assert idxval == nth(i, vals);
|
||||||
* close xLIST_ITEM(idxprev, ?idxprevval, pxNewListItem, ?idxprevprev, pxList);
|
close xLIST_ITEM(idxprev, ?idxprevval, pxNewListItem, ?idxprevprev, pxList);
|
||||||
*
|
|
||||||
* if (end == idxprev)
|
if (end == idxprev)
|
||||||
* {
|
{
|
||||||
* close DLS(end, endprev, pxNewListItem, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
close DLS(end, endprev, pxNewListItem, end, singleton(end), singleton(portMAX_DELAY), pxList);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* length_take(i, cells);
|
length_take(i, cells);
|
||||||
* take_take(i-1, i, vals);
|
take_take(i-1, i, vals);
|
||||||
* take_singleton(i-1, vals);
|
take_singleton(i-1, vals);
|
||||||
* take_singleton(i, vals);
|
take_singleton(i, vals);
|
||||||
* assert DLS(end, endprev, idxprev, idxprevprev, ?cells_end_to_idxprevprev, take(i-1, vals), pxList);
|
assert DLS(end, endprev, idxprev, idxprevprev, ?cells_end_to_idxprevprev, take(i-1, vals), pxList);
|
||||||
* close DLS(idxprev, idxprevprev, pxNewListItem, idxprev, singleton(idxprev), singleton(idxprevval), pxList);
|
close DLS(idxprev, idxprevprev, pxNewListItem, idxprev, singleton(idxprev), singleton(idxprevval), pxList);
|
||||||
* join(end, endprev, idxprev, idxprevprev, cells_end_to_idxprevprev, take(i-1, vals),
|
join(end, endprev, idxprev, idxprevprev, cells_end_to_idxprevprev, take(i-1, vals),
|
||||||
* idxprev, idxprevprev, pxNewListItem, idxprev, singleton(idxprev), singleton(idxprevval));
|
idxprev, idxprevprev, pxNewListItem, idxprev, singleton(idxprev), singleton(idxprevval));
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* if (idx == endprev)
|
if (idx == endprev)
|
||||||
* {
|
{
|
||||||
* close DLS(idx, pxNewListItem, end, idx, singleton(idx), singleton(idxval), pxList);
|
close DLS(idx, pxNewListItem, end, idx, singleton(idx), singleton(idxval), pxList);
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* assert DLS(end, endprev, pxNewListItem, idxprev, ?cells_end_to_idxprev, ?vals_end_to_idxprev, pxList);
|
assert DLS(end, endprev, pxNewListItem, idxprev, ?cells_end_to_idxprev, ?vals_end_to_idxprev, pxList);
|
||||||
* close DLS(idx, pxNewListItem, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
close DLS(idx, pxNewListItem, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
||||||
* }
|
}
|
||||||
*
|
|
||||||
* assert DLS(end, endprev, pxNewListItem, idxprev, take(i, cells), take(i, vals), pxList);
|
assert DLS(end, endprev, pxNewListItem, idxprev, take(i, cells), take(i, vals), pxList);
|
||||||
* assert DLS(idx, pxNewListItem, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
assert DLS(idx, pxNewListItem, end, endprev, drop(i, cells), drop(i, vals), pxList);
|
||||||
* assert xLIST_ITEM(pxNewListItem, val, idx, idxprev, pxList);
|
assert xLIST_ITEM(pxNewListItem, val, idx, idxprev, pxList);
|
||||||
* dls_star_item(idx, endprev, pxNewListItem);
|
dls_star_item(idx, endprev, pxNewListItem);
|
||||||
* close DLS(pxNewListItem, idxprev, end, endprev, cons(pxNewListItem, drop(i, cells)), cons(val, drop(i, vals)), pxList);
|
close DLS(pxNewListItem, idxprev, end, endprev, cons(pxNewListItem, drop(i, cells)), cons(val, drop(i, vals)), pxList);
|
||||||
* join(end, endprev, pxNewListItem, idxprev, take(i, cells), take(i, vals),
|
join(end, endprev, pxNewListItem, idxprev, take(i, cells), take(i, vals),
|
||||||
* pxNewListItem, idxprev, end, endprev, cons(pxNewListItem, drop(i, cells)), cons(val, drop(i, vals)));
|
pxNewListItem, idxprev, end, endprev, cons(pxNewListItem, drop(i, cells)), cons(val, drop(i, vals)));
|
||||||
* assert DLS(end, endprev, end, endprev, ?cells_new, ?vals_new, pxList);
|
assert DLS(end, endprev, end, endprev, ?cells_new, ?vals_new, pxList);
|
||||||
* assert cells_new == append(take(i, cells), append(singleton(pxNewListItem), drop(i, cells)));
|
assert cells_new == append(take(i, cells), append(singleton(pxNewListItem), drop(i, cells)));
|
||||||
* assert vals_new == append(take(i, vals) , append(singleton(val), drop(i, vals)));
|
assert vals_new == append(take(i, vals) , append(singleton(val), drop(i, vals)));
|
||||||
* head_append(take(i, cells), append(singleton(pxNewListItem), drop(i, cells)));
|
head_append(take(i, cells), append(singleton(pxNewListItem), drop(i, cells)));
|
||||||
* take_take(1, i, cells);
|
take_take(1, i, cells);
|
||||||
* head_append(take(i, vals), append(singleton(val), drop(i, vals)));
|
head_append(take(i, vals), append(singleton(val), drop(i, vals)));
|
||||||
* take_take(1, i, vals);
|
take_take(1, i, vals);
|
||||||
* close xLIST(pxList, len+1, idx, end, cells_new, vals_new);
|
close xLIST(pxList, len+1, idx, end, cells_new, vals_new);
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void client_example1( List_t * const l,
|
void client_example1( List_t * const l, ListItem_t * const pxNewListItem )
|
||||||
ListItem_t * const pxNewListItem )
|
|
||||||
|
|
||||||
/*@requires
|
/*@requires
|
||||||
* xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
|
||||||
* xLIST_ITEM(pxNewListItem, ?val, _, _, _) &*&
|
xLIST_ITEM(pxNewListItem, ?val, _, _, _) &*&
|
||||||
* idx == end;@*/
|
idx == end;@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* xLIST(l, len + 1, idx, end, _, append(vals, singleton(val)));@*/
|
xLIST(l, len + 1, idx, end, _, append(vals, singleton(val)));@*/
|
||||||
{
|
{
|
||||||
vListInsertEnd( l, pxNewListItem );
|
vListInsertEnd(l, pxNewListItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
/* Simplifying assumption: we do not verify queue initialisation in a
|
/* Simplifying assumption: we do not verify queue initialisation in a
|
||||||
|
@ -37,37 +39,35 @@
|
||||||
/* The following intermediate queue predicates summarise states used by queue
|
/* The following intermediate queue predicates summarise states used by queue
|
||||||
* initialization but not used elsewhere so we confine them to these proofs
|
* initialization but not used elsewhere so we confine them to these proofs
|
||||||
* locally. */
|
* locally. */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* predicate queue_init1(QueueHandle_t q;) =
|
predicate queue_init1(QueueHandle_t q;) =
|
||||||
* QUEUE_SHAPE(q, _, _, _, _) &*&
|
QUEUE_SHAPE(q, _, _, _, _) &*&
|
||||||
* queuelists(q)
|
queuelists(q)
|
||||||
* ;
|
;
|
||||||
*
|
|
||||||
* predicate queue_init2(QueueHandle_t q, int8_t *Storage, size_t N, size_t M;) =
|
predicate queue_init2(QueueHandle_t q, int8_t *Storage, size_t N, size_t M;) =
|
||||||
* QUEUE_SHAPE(q, Storage, N, M, _) &*&
|
QUEUE_SHAPE(q, Storage, N, M, _) &*&
|
||||||
* queuelists(q) &*&
|
queuelists(q) &*&
|
||||||
* 0 < N &*&
|
0 < N &*&
|
||||||
* chars(Storage, (N*M), _) &*&
|
chars(Storage, (N*M), _) &*&
|
||||||
* malloc_block(Storage, N*M) &*&
|
malloc_block(Storage, N*M) &*&
|
||||||
* Storage + N * M <= (int8_t *)UINTPTR_MAX &*&
|
Storage + N * M <= (int8_t *)UINTPTR_MAX &*&
|
||||||
* true
|
true
|
||||||
* ;
|
;
|
||||||
* @*/
|
@*/
|
||||||
|
|
||||||
BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
|
BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
|
||||||
BaseType_t xNewQueue )
|
BaseType_t xNewQueue )
|
||||||
/*@requires queue_init2(xQueue, ?Storage, ?N, ?M);@*/
|
/*@requires queue_init2(xQueue, ?Storage, ?N, ?M);@*/
|
||||||
|
|
||||||
/*@ensures 0 == M
|
/*@ensures 0 == M
|
||||||
* ? freertos_mutex(xQueue, Storage, N, 0)
|
? freertos_mutex(xQueue, Storage, N, 0)
|
||||||
* : queue(xQueue, Storage, N, M, 0, (N-1), 0, false, nil) &*& queuelists(xQueue);@*/
|
: queue(xQueue, Storage, N, M, 0, (N-1), 0, false, nil) &*& queuelists(xQueue);@*/
|
||||||
{
|
{
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
Queue_t * pxQueue = xQueue;
|
Queue_t * pxQueue = xQueue;
|
||||||
#else
|
#else
|
||||||
Queue_t * const pxQueue = xQueue;
|
Queue_t * const pxQueue = xQueue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
|
|
||||||
|
@ -127,20 +127,18 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
|
||||||
Queue_t * pxNewQueue )
|
Queue_t * pxNewQueue )
|
||||||
|
|
||||||
/*@requires queue_init1(pxNewQueue) &*&
|
/*@requires queue_init1(pxNewQueue) &*&
|
||||||
* 0 < uxQueueLength &*& 0 < uxItemSize &*&
|
0 < uxQueueLength &*& 0 < uxItemSize &*&
|
||||||
* malloc_block(pucQueueStorage, uxQueueLength * uxItemSize) &*&
|
malloc_block(pucQueueStorage, uxQueueLength * uxItemSize) &*&
|
||||||
* pucQueueStorage + uxQueueLength * uxItemSize <= (uint8_t *)UINTPTR_MAX &*&
|
pucQueueStorage + uxQueueLength * uxItemSize <= (uint8_t *)UINTPTR_MAX &*&
|
||||||
* uchars(pucQueueStorage, uxQueueLength * uxItemSize,_);@*/
|
uchars(pucQueueStorage, uxQueueLength * uxItemSize,_);@*/
|
||||||
|
|
||||||
/*@ensures queue(pxNewQueue, ((int8_t *)(void *)pucQueueStorage), uxQueueLength, uxItemSize, 0, (uxQueueLength-1), 0, false, nil) &*&
|
/*@ensures queue(pxNewQueue, ((int8_t *)(void *)pucQueueStorage), uxQueueLength, uxItemSize, 0, (uxQueueLength-1), 0, false, nil) &*&
|
||||||
* queuelists(pxNewQueue);@*/
|
queuelists(pxNewQueue);@*/
|
||||||
{
|
{
|
||||||
#ifndef VERIFAST /*< void cast of unused var */
|
#ifndef VERIFAST /*< void cast of unused var */
|
||||||
|
/* Remove compiler warnings about unused parameters should
|
||||||
/* Remove compiler warnings about unused parameters should
|
* configUSE_TRACE_FACILITY not be set to 1. */
|
||||||
* configUSE_TRACE_FACILITY not be set to 1. */
|
( void ) ucQueueType;
|
||||||
( void ) ucQueueType;
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
if( uxItemSize == ( UBaseType_t ) 0 )
|
if( uxItemSize == ( UBaseType_t ) 0 )
|
||||||
{
|
{
|
||||||
|
@ -148,20 +146,20 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
|
||||||
* be set to NULL because NULL is used as a key to say the queue is used as
|
* be set to NULL because NULL is used as a key to say the queue is used as
|
||||||
* a mutex. Therefore just set pcHead to point to the queue as a benign
|
* a mutex. Therefore just set pcHead to point to the queue as a benign
|
||||||
* value that is known to be within the memory map. */
|
* value that is known to be within the memory map. */
|
||||||
#ifdef VERIFAST /*< stricter casting */
|
#ifdef VERIFAST /*< stricter casting */
|
||||||
pxNewQueue->pcHead = ( int8_t * ) ( void * ) pxNewQueue;
|
pxNewQueue->pcHead = ( int8_t * ) ( void * ) pxNewQueue;
|
||||||
#else
|
#else
|
||||||
pxNewQueue->pcHead = ( int8_t * ) pxNewQueue;
|
pxNewQueue->pcHead = ( int8_t * ) pxNewQueue;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Set the head to the start of the queue storage area. */
|
/* Set the head to the start of the queue storage area. */
|
||||||
#ifdef VERIFAST /*< stricter casting */
|
#ifdef VERIFAST /*< stricter casting */
|
||||||
pxNewQueue->pcHead = ( int8_t * ) ( void * ) pucQueueStorage;
|
pxNewQueue->pcHead = ( int8_t * ) ( void * ) pucQueueStorage;
|
||||||
#else
|
#else
|
||||||
pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage;
|
pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise the queue members as described where the queue type is
|
/* Initialise the queue members as described where the queue type is
|
||||||
|
@ -169,11 +167,11 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
|
||||||
pxNewQueue->uxLength = uxQueueLength;
|
pxNewQueue->uxLength = uxQueueLength;
|
||||||
pxNewQueue->uxItemSize = uxItemSize;
|
pxNewQueue->uxItemSize = uxItemSize;
|
||||||
/*@close queue_init2(pxNewQueue, _, uxQueueLength, uxItemSize);@*/
|
/*@close queue_init2(pxNewQueue, _, uxQueueLength, uxItemSize);@*/
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
xQueueGenericReset( pxNewQueue, pdTRUE );
|
xQueueGenericReset( pxNewQueue, pdTRUE );
|
||||||
#else
|
#else
|
||||||
( void ) xQueueGenericReset( pxNewQueue, pdTRUE );
|
( void ) xQueueGenericReset( pxNewQueue, pdTRUE );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||||
{
|
{
|
||||||
|
@ -190,93 +188,100 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength,
|
||||||
traceQUEUE_CREATE( pxNewQueue );
|
traceQUEUE_CREATE( pxNewQueue );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SIZE_MAX ( ( size_t ) -1 )
|
||||||
|
|
||||||
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength,
|
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength,
|
||||||
const UBaseType_t uxItemSize,
|
const UBaseType_t uxItemSize,
|
||||||
const uint8_t ucQueueType )
|
const uint8_t ucQueueType )
|
||||||
|
/*@requires 0 < uxQueueLength &*&
|
||||||
/*@requires 0 < uxQueueLength &*&
|
0 < uxItemSize &*&
|
||||||
* 0 < uxItemSize &*&
|
0 < uxQueueLength * uxItemSize &*&
|
||||||
* 0 < uxQueueLength * uxItemSize &*&
|
uxQueueLength * uxItemSize <= UINT_MAX;@*/
|
||||||
* uxQueueLength * uxItemSize <= UINT_MAX;@*/
|
/*@ensures result == NULL
|
||||||
|
? true
|
||||||
/*@ensures result == NULL
|
: queue(result, _, uxQueueLength, uxItemSize, 0, (uxQueueLength-1), 0, false, nil) &*&
|
||||||
* ? true
|
queuelists(result) &*&
|
||||||
* : queue(result, _, uxQueueLength, uxItemSize, 0, (uxQueueLength-1), 0, false, nil) &*&
|
result->irqMask |-> _ &*&
|
||||||
* queuelists(result) &*&
|
result->schedulerSuspend |-> _ &*&
|
||||||
* result->irqMask |-> _ &*&
|
result->locked |-> _;@*/
|
||||||
* result->schedulerSuspend |-> _ &*&
|
|
||||||
* result->locked |-> _;@*/
|
|
||||||
{
|
|
||||||
Queue_t * pxNewQueue;
|
|
||||||
size_t xQueueSizeInBytes;
|
|
||||||
uint8_t * pucQueueStorage;
|
|
||||||
|
|
||||||
configASSERT( uxQueueLength > ( UBaseType_t ) 0 );
|
|
||||||
|
|
||||||
/* Allocate enough space to hold the maximum number of items that
|
|
||||||
* can be in the queue at any time. It is valid for uxItemSize to be
|
|
||||||
* zero in the case the queue is used as a semaphore. */
|
|
||||||
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
|
||||||
|
|
||||||
/* Check for multiplication overflow. */
|
|
||||||
configASSERT( ( uxItemSize == 0 ) || ( uxQueueLength == ( xQueueSizeInBytes / uxItemSize ) ) );
|
|
||||||
|
|
||||||
/* Check for addition overflow. */
|
|
||||||
configASSERT( ( sizeof( Queue_t ) + xQueueSizeInBytes ) > xQueueSizeInBytes );
|
|
||||||
|
|
||||||
#ifdef VERIFAST /*< ***model single malloc of struct and buffer*** */
|
|
||||||
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) );
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Allocate the queue and storage area. Justification for MISRA
|
|
||||||
* deviation as follows: pvPortMalloc() always ensures returned memory
|
|
||||||
* blocks are aligned per the requirements of the MCU stack. In this case
|
|
||||||
* pvPortMalloc() must return a pointer that is guaranteed to meet the
|
|
||||||
* alignment requirements of the Queue_t structure - which in this case
|
|
||||||
* is an int8_t *. Therefore, whenever the stack alignment requirements
|
|
||||||
* are greater than or equal to the pointer to char requirements the cast
|
|
||||||
* is safe. In other cases alignment requirements are not strict (one or
|
|
||||||
* two bytes). */
|
|
||||||
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( pxNewQueue != NULL )
|
|
||||||
{
|
{
|
||||||
#ifdef VERIFAST /*< ***model single malloc of struct and buffer*** */
|
#ifdef VERIFAST /*< ***model static initialization*** */
|
||||||
pucQueueStorage = ( uint8_t * ) pvPortMalloc( xQueueSizeInBytes );
|
Queue_t * pxNewQueue = NULL;
|
||||||
|
#else
|
||||||
|
Queue_t * pxNewQueue;
|
||||||
|
#endif
|
||||||
|
size_t xQueueSizeInBytes;
|
||||||
|
uint8_t * pucQueueStorage;
|
||||||
|
|
||||||
if( pucQueueStorage == NULL )
|
if( ( uxQueueLength > ( UBaseType_t ) 0 ) &&
|
||||||
{
|
/* Check for multiplication overflow. */
|
||||||
vPortFree( pxNewQueue );
|
( ( SIZE_MAX / uxQueueLength ) >= uxItemSize ) &&
|
||||||
return NULL;
|
/* Check for addition overflow. */
|
||||||
}
|
( ( SIZE_MAX - sizeof( Queue_t ) ) >= ( uxQueueLength * uxItemSize ) ) )
|
||||||
|
|
||||||
/*@malloc_block_limits(pucQueueStorage);@*/
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Jump past the queue structure to find the location of the queue
|
|
||||||
* storage area. */
|
|
||||||
pucQueueStorage = ( uint8_t * ) pxNewQueue;
|
|
||||||
pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */
|
|
||||||
#endif /* ifdef VERIFAST */
|
|
||||||
|
|
||||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
|
||||||
{
|
{
|
||||||
/* Queues can be created either statically or dynamically, so
|
/* Allocate enough space to hold the maximum number of items that
|
||||||
* note this task was created dynamically in case it is later
|
* can be in the queue at any time. It is valid for uxItemSize to be
|
||||||
* deleted. */
|
* zero in the case the queue is used as a semaphore. */
|
||||||
pxNewQueue->ucStaticallyAllocated = pdFALSE;
|
xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
|
||||||
|
|
||||||
|
#ifdef VERIFAST /*< ***model single malloc of struct and buffer*** */
|
||||||
|
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) );
|
||||||
|
#else
|
||||||
|
/* Allocate the queue and storage area. Justification for MISRA
|
||||||
|
* deviation as follows: pvPortMalloc() always ensures returned memory
|
||||||
|
* blocks are aligned per the requirements of the MCU stack. In this case
|
||||||
|
* pvPortMalloc() must return a pointer that is guaranteed to meet the
|
||||||
|
* alignment requirements of the Queue_t structure - which in this case
|
||||||
|
* is an int8_t *. Therefore, whenever the stack alignment requirements
|
||||||
|
* are greater than or equal to the pointer to char requirements the cast
|
||||||
|
* is safe. In other cases alignment requirements are not strict (one or
|
||||||
|
* two bytes). */
|
||||||
|
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( pxNewQueue != NULL )
|
||||||
|
{
|
||||||
|
#ifdef VERIFAST /*< ***model single malloc of struct and buffer*** */
|
||||||
|
pucQueueStorage = ( uint8_t * ) pvPortMalloc( xQueueSizeInBytes );
|
||||||
|
|
||||||
|
if( pucQueueStorage == NULL )
|
||||||
|
{
|
||||||
|
vPortFree( pxNewQueue );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@malloc_block_limits(pucQueueStorage);@*/
|
||||||
|
#else
|
||||||
|
/* Jump past the queue structure to find the location of the queue
|
||||||
|
* storage area. */
|
||||||
|
pucQueueStorage = ( uint8_t * ) pxNewQueue;
|
||||||
|
pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
|
||||||
|
{
|
||||||
|
/* Queues can be created either statically or dynamically, so
|
||||||
|
* note this task was created dynamically in case it is later
|
||||||
|
* deleted. */
|
||||||
|
pxNewQueue->ucStaticallyAllocated = pdFALSE;
|
||||||
|
}
|
||||||
|
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
||||||
|
|
||||||
|
prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceQUEUE_CREATE_FAILED( ucQueueType );
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configASSERT( pxNewQueue );
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
|
|
||||||
|
|
||||||
prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue );
|
return pxNewQueue;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
traceQUEUE_CREATE_FAILED( ucQueueType );
|
|
||||||
mtCOVERAGE_TEST_MARKER();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxNewQueue;
|
/* *INDENT-ON* */
|
||||||
}
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,14 +24,15 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
static void prvCopyDataFromQueue( Queue_t * const pxQueue,
|
static void prvCopyDataFromQueue( Queue_t * const pxQueue,
|
||||||
void * const pvBuffer )
|
void * const pvBuffer )
|
||||||
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*& 0 < K &*& chars(pvBuffer, M, _);@*/
|
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*& 0 < K &*& chars(pvBuffer, M, _);@*/
|
||||||
|
|
||||||
/*@ensures queue_after_prvCopyDataFromQueue(pxQueue, Storage, N, M, W, (R+1)%N, K, is_locked, abs) &*&
|
/*@ensures queue_after_prvCopyDataFromQueue(pxQueue, Storage, N, M, W, (R+1)%N, K, is_locked, abs) &*&
|
||||||
* chars(pvBuffer, M, head(abs));@*/
|
chars(pvBuffer, M, head(abs));@*/
|
||||||
{
|
{
|
||||||
if( pxQueue->uxItemSize != ( UBaseType_t ) 0 )
|
if( pxQueue->uxItemSize != ( UBaseType_t ) 0 )
|
||||||
{
|
{
|
||||||
|
@ -47,48 +48,44 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*@{
|
/*@{
|
||||||
* div_lt(R+1, N, M); // now we know R+1 < N
|
div_lt(R+1, N, M); // now we know R+1 < N
|
||||||
* mod_lt(R+1, N); // so, R+1 == (R+1)%N
|
mod_lt(R+1, N); // so, R+1 == (R+1)%N
|
||||||
* note(pxQueue->u.xQueue.pcReadFrom == Storage + ((R + 1) * M));
|
note(pxQueue->u.xQueue.pcReadFrom == Storage + ((R + 1) * M));
|
||||||
* note( Storage + ((R + 1) * M) == Storage + (((R + 1) % N) * M));
|
note( Storage + ((R + 1) * M) == Storage + (((R + 1) % N) * M));
|
||||||
* }@*/
|
}@*/
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@mod_plus(R+1, K, N);@*/
|
/*@mod_plus(R+1, K, N);@*/
|
||||||
/*@mod_mod(R+1, N);@*/
|
/*@mod_mod(R+1, N);@*/
|
||||||
/*@split_element(Storage, N, M, (R+1)%N);@*/
|
/*@split_element(Storage, N, M, (R+1)%N);@*/
|
||||||
|
|
||||||
/*@assert
|
/*@assert
|
||||||
* buffer(Storage, (R+1)%N, M, ?prefix) &*&
|
buffer(Storage, (R+1)%N, M, ?prefix) &*&
|
||||||
* chars(Storage + ((R+1)%N) * M, M, ?element) &*&
|
chars(Storage + ((R+1)%N) * M, M, ?element) &*&
|
||||||
* buffer(Storage + ((R+1)%N + 1) * M, (N-1-(R+1)%N), M, ?suffix);@*/
|
buffer(Storage + ((R+1)%N + 1) * M, (N-1-(R+1)%N), M, ?suffix);@*/
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize );
|
memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize );
|
||||||
#else
|
#else
|
||||||
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */
|
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*@{
|
/*@{
|
||||||
* combine_list_no_change(prefix, element, suffix, (R+1)%N, contents);
|
combine_list_no_change(prefix, element, suffix, (R+1)%N, contents);
|
||||||
* join_element(Storage, N, M, (R+1)%N);
|
join_element(Storage, N, M, (R+1)%N);
|
||||||
* length_take(K, contents);
|
length_take(K, contents);
|
||||||
* take_length_eq(K, rotate_left((R+1)%N, contents), abs);
|
take_length_eq(K, rotate_left((R+1)%N, contents), abs);
|
||||||
* deq_value_lemma(K, (R+1)%N, contents, abs);
|
deq_value_lemma(K, (R+1)%N, contents, abs);
|
||||||
* }@*/
|
}@*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void caller_reinstates_queue_predicate( Queue_t * const pxQueue,
|
void caller_reinstates_queue_predicate( Queue_t * const pxQueue,
|
||||||
void * const pvBuffer )
|
void * const pvBuffer )
|
||||||
|
|
||||||
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* 0 < K &*&
|
0 < K &*&
|
||||||
* chars(pvBuffer, M, _);@*/
|
chars(pvBuffer, M, _);@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* queue(pxQueue, Storage, N, M, W, (R+1)%N, K-1, is_locked, tail(abs)) &*&
|
queue(pxQueue, Storage, N, M, W, (R+1)%N, K-1, is_locked, tail(abs)) &*&
|
||||||
* chars(pvBuffer, M, head(abs));@*/
|
chars(pvBuffer, M, head(abs));@*/
|
||||||
{
|
{
|
||||||
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
||||||
/*@open queue_after_prvCopyDataFromQueue(pxQueue, Storage, N, M, W, (R+1)%N, K, is_locked, abs);@*/
|
/*@open queue_after_prvCopyDataFromQueue(pxQueue, Storage, N, M, W, (R+1)%N, K, is_locked, abs);@*/
|
||||||
|
@ -96,3 +93,5 @@ void caller_reinstates_queue_predicate( Queue_t * const pxQueue,
|
||||||
pxQueue->uxMessagesWaiting = pxQueue->uxMessagesWaiting - 1;
|
pxQueue->uxMessagesWaiting = pxQueue->uxMessagesWaiting - 1;
|
||||||
/*@deq_lemma(K, (R+1)%N, contents, abs, head(abs));@*/
|
/*@deq_lemma(K, (R+1)%N, contents, abs, head(abs));@*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,27 +24,27 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
||||||
const void * pvItemToQueue,
|
const void * pvItemToQueue,
|
||||||
const BaseType_t xPosition )
|
const BaseType_t xPosition )
|
||||||
|
|
||||||
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
/*@requires queue(pxQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* (K < N || xPosition == queueOVERWRITE) &*&
|
(K < N || xPosition == queueOVERWRITE) &*&
|
||||||
* chars(pvItemToQueue, M, ?x) &*&
|
chars(pvItemToQueue, M, ?x) &*&
|
||||||
* (xPosition == queueSEND_TO_BACK || xPosition == queueSEND_TO_FRONT || (xPosition == queueOVERWRITE && N == 1));@*/
|
(xPosition == queueSEND_TO_BACK || xPosition == queueSEND_TO_FRONT || (xPosition == queueOVERWRITE && N == 1));@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* (xPosition == queueSEND_TO_BACK
|
(xPosition == queueSEND_TO_BACK
|
||||||
* ? queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)))
|
? queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)))
|
||||||
* : (xPosition == queueSEND_TO_FRONT
|
: (xPosition == queueSEND_TO_FRONT
|
||||||
* ? (R == 0
|
? (R == 0
|
||||||
* ? queue(pxQueue, Storage, N, M, W, (N-1), (K+1), is_locked, cons(x, abs))
|
? queue(pxQueue, Storage, N, M, W, (N-1), (K+1), is_locked, cons(x, abs))
|
||||||
* : queue(pxQueue, Storage, N, M, W, (R-1), (K+1), is_locked, cons(x, abs)))
|
: queue(pxQueue, Storage, N, M, W, (R-1), (K+1), is_locked, cons(x, abs)))
|
||||||
* : xPosition == queueOVERWRITE &*& queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x)))
|
: xPosition == queueOVERWRITE &*& queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x)))
|
||||||
* ) &*&
|
) &*&
|
||||||
* chars(pvItemToQueue, M, x);@*/
|
chars(pvItemToQueue, M, x);@*/
|
||||||
{
|
{
|
||||||
BaseType_t xReturn = pdFALSE;
|
BaseType_t xReturn = pdFALSE;
|
||||||
UBaseType_t uxMessagesWaiting;
|
UBaseType_t uxMessagesWaiting;
|
||||||
|
@ -76,29 +76,27 @@ static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
||||||
}
|
}
|
||||||
else if( xPosition == queueSEND_TO_BACK )
|
else if( xPosition == queueSEND_TO_BACK )
|
||||||
{
|
{
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
|
/* Now we focus the proof on the logical element of the buffer that
|
||||||
/* Now we focus the proof on the logical element of the buffer that
|
* will be updated using the following lemma to split the buffer into 3
|
||||||
* will be updated using the following lemma to split the buffer into 3
|
* parts: a prefix, the element we want to update, and the suffix. This
|
||||||
* parts: a prefix, the element we want to update, and the suffix. This
|
* enables the subsequent memcpy to verify. */
|
||||||
* enables the subsequent memcpy to verify. */
|
/*@split_element(Storage, N, M, W);@*/
|
||||||
/*@split_element(Storage, N, M, W);@*/
|
/*@assert
|
||||||
|
buffer(Storage, W, M, ?prefix) &*&
|
||||||
/*@assert
|
chars(Storage + W * M, M, _) &*&
|
||||||
* buffer(Storage, W, M, ?prefix) &*&
|
buffer(Storage + (W + 1) * M, (N-1-W), M, ?suffix);@*/
|
||||||
* chars(Storage + W * M, M, _) &*&
|
memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize );
|
||||||
* buffer(Storage + (W + 1) * M, (N-1-W), M, ?suffix);@*/
|
/* After the update we stitch the buffer back together */
|
||||||
memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize );
|
/*@join_element(Storage, N, M, W);@*/
|
||||||
/* After the update we stitch the buffer back together */
|
/*@combine_list_update(prefix, x, suffix, W, contents);@*/
|
||||||
/*@join_element(Storage, N, M, W);@*/
|
#else
|
||||||
/*@combine_list_update(prefix, x, suffix, W, contents);@*/
|
( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */
|
||||||
#else
|
#endif
|
||||||
( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */
|
|
||||||
#endif /* ifdef VERIFAST */
|
|
||||||
/*@mul_mono_l(W, N-1, M);@*/
|
/*@mul_mono_l(W, N-1, M);@*/
|
||||||
pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */
|
pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */
|
||||||
|
|
||||||
if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
|
if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
|
||||||
{
|
{
|
||||||
/*@div_leq(N, W+1, M);@*/ /* now we know W == N-1 so (W+1)%N == 0 */
|
/*@div_leq(N, W+1, M);@*/ /* now we know W == N-1 so (W+1)%N == 0 */
|
||||||
pxQueue->pcWriteTo = pxQueue->pcHead;
|
pxQueue->pcWriteTo = pxQueue->pcHead;
|
||||||
|
@ -106,29 +104,28 @@ static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*@{
|
/*@{
|
||||||
* div_lt(W+1, N, M); // now we know W+1 < N
|
div_lt(W+1, N, M); // now we know W+1 < N
|
||||||
* mod_lt(W+1, N); // so, W+1 == (W+1)%N
|
mod_lt(W+1, N); // so, W+1 == (W+1)%N
|
||||||
* note(pxQueue->pcWriteTo == Storage + ((W + 1) * M));
|
note(pxQueue->pcWriteTo == Storage + ((W + 1) * M));
|
||||||
* note( Storage + ((W + 1) * M) == Storage + (((W + 1) % N) * M));
|
note( Storage + ((W + 1) * M) == Storage + (((W + 1) % N) * M));
|
||||||
* }@*/
|
}@*/
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@split_element(Storage, N, M, R);@*/
|
/*@split_element(Storage, N, M, R);@*/
|
||||||
|
/*@assert
|
||||||
/*@assert
|
buffer(Storage, R, M, ?prefix) &*&
|
||||||
* buffer(Storage, R, M, ?prefix) &*&
|
chars(Storage + R * M, M, _) &*&
|
||||||
* chars(Storage + R * M, M, _) &*&
|
buffer(Storage + (R + 1) * M, (N-1-R), M, ?suffix);@*/
|
||||||
* buffer(Storage + (R + 1) * M, (N-1-R), M, ?suffix);@*/
|
memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize );
|
||||||
memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize );
|
/*@join_element(Storage, N, M, R);@*/
|
||||||
/*@join_element(Storage, N, M, R);@*/
|
/*@combine_list_update(prefix, x, suffix, R, contents);@*/
|
||||||
/*@combine_list_update(prefix, x, suffix, R, contents);@*/
|
#else
|
||||||
#else
|
( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */
|
||||||
( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */
|
#endif
|
||||||
#endif
|
|
||||||
pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize;
|
pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize;
|
||||||
|
|
||||||
if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
|
if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
|
||||||
|
@ -146,12 +143,12 @@ static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (R == 0)
|
if (R == 0)
|
||||||
* {
|
{
|
||||||
* mod_plus(N, (K+1), N); mod_same(N); mod_mod(K+1, N);
|
mod_plus(N, (K+1), N); mod_same(N); mod_mod(K+1, N);
|
||||||
* assert W == ((N-1) + 1 + (K+1)) % N;
|
assert W == ((N-1) + 1 + (K+1)) % N;
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
if( xPosition == queueOVERWRITE )
|
if( xPosition == queueOVERWRITE )
|
||||||
{
|
{
|
||||||
if( uxMessagesWaiting > ( UBaseType_t ) 0 )
|
if( uxMessagesWaiting > ( UBaseType_t ) 0 )
|
||||||
|
@ -176,20 +173,22 @@ static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue,
|
||||||
pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1;
|
pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1;
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (xPosition == queueSEND_TO_BACK)
|
if (xPosition == queueSEND_TO_BACK)
|
||||||
* {
|
{
|
||||||
* enq_lemma(K, (R+1)%N, contents, abs, x);
|
enq_lemma(K, (R+1)%N, contents, abs, x);
|
||||||
* mod_plus_one(W, R + 1 + K, N);
|
mod_plus_one(W, R + 1 + K, N);
|
||||||
* mod_plus_distr(R+1, K, N);
|
mod_plus_distr(R+1, K, N);
|
||||||
* }
|
}
|
||||||
* else if (xPosition == queueSEND_TO_FRONT)
|
else if (xPosition == queueSEND_TO_FRONT)
|
||||||
* {
|
{
|
||||||
* front_enq_lemma(K, R, contents, abs, x);
|
front_enq_lemma(K, R, contents, abs, x);
|
||||||
* if (0 < R)
|
if (0 < R)
|
||||||
* {
|
{
|
||||||
* mod_lt(R, N);
|
mod_lt(R, N);
|
||||||
* }
|
}
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#define taskENTER_CRITICAL() setInterruptMask( pxQueue )
|
#define taskENTER_CRITICAL() setInterruptMask( pxQueue )
|
||||||
#define taskEXIT_CRITICAL() clearInterruptMask( pxQueue )
|
#define taskEXIT_CRITICAL() clearInterruptMask( pxQueue )
|
||||||
|
@ -51,3 +53,5 @@ static BaseType_t prvIsQueueEmpty( const Queue_t * pxQueue )
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#define taskENTER_CRITICAL() setInterruptMask( pxQueue )
|
#define taskENTER_CRITICAL() setInterruptMask( pxQueue )
|
||||||
#define taskEXIT_CRITICAL() clearInterruptMask( pxQueue )
|
#define taskEXIT_CRITICAL() clearInterruptMask( pxQueue )
|
||||||
|
@ -51,3 +53,5 @@ static BaseType_t prvIsQueueFull( const Queue_t * pxQueue )
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
/* In this case we cannot wrap the macro in a function call to give a function
|
/* In this case we cannot wrap the macro in a function call to give a function
|
||||||
|
@ -46,12 +48,11 @@
|
||||||
void wrapper_prvLockQueue( QueueHandle_t xQueue )
|
void wrapper_prvLockQueue( QueueHandle_t xQueue )
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
||||||
* [1/2]queuelock(xQueue);@*/
|
[1/2]queuelock(xQueue);@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]xQueue->locked |-> ?m &*&
|
[1/2]xQueue->locked |-> ?m &*&
|
||||||
* mutex_held(m, queue_locked_invariant(xQueue), currentThread, 1/2) &*&
|
mutex_held(m, queue_locked_invariant(xQueue), currentThread, 1/2) &*&
|
||||||
* queue_locked_invariant(xQueue)();@*/
|
queue_locked_invariant(xQueue)();@*/
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
/*@open queue(xQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
/*@open queue(xQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
||||||
|
@ -68,7 +69,9 @@ void wrapper_prvLockQueue( QueueHandle_t xQueue )
|
||||||
}
|
}
|
||||||
/*@close queue(xQueue, Storage, N, M, W, R, K, true, abs);@*/
|
/*@close queue(xQueue, Storage, N, M, W, R, K, true, abs);@*/
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
#ifdef VERIFAST /*< ghost action */
|
#ifdef VERIFAST /*< ghost action */
|
||||||
mutex_acquire( xQueue->locked );
|
mutex_acquire( xQueue->locked );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#define taskENTER_CRITICAL() setInterruptMask( pxQueue )
|
#define taskENTER_CRITICAL() setInterruptMask( pxQueue )
|
||||||
#define taskEXIT_CRITICAL() clearInterruptMask( pxQueue )
|
#define taskEXIT_CRITICAL() clearInterruptMask( pxQueue )
|
||||||
|
@ -32,14 +34,12 @@
|
||||||
* decrementing `cTxLock` and `cRxLock`. */
|
* decrementing `cTxLock` and `cRxLock`. */
|
||||||
|
|
||||||
static void prvUnlockQueue( Queue_t * const pxQueue )
|
static void prvUnlockQueue( Queue_t * const pxQueue )
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(pxQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
/*@requires [1/2]queuehandle(pxQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
||||||
* [1/2]pxQueue->locked |-> ?m &*&
|
[1/2]pxQueue->locked |-> ?m &*&
|
||||||
* mutex_held(m, queue_locked_invariant(pxQueue), currentThread, 1/2) &*&
|
mutex_held(m, queue_locked_invariant(pxQueue), currentThread, 1/2) &*&
|
||||||
* queue_locked_invariant(pxQueue)();@*/
|
queue_locked_invariant(pxQueue)();@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(pxQueue, N, M, is_isr) &*&
|
/*@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. */
|
||||||
|
|
||||||
|
@ -127,12 +127,12 @@ static void prvUnlockQueue( Queue_t * const pxQueue )
|
||||||
|
|
||||||
pxQueue->cTxLock = queueUNLOCKED;
|
pxQueue->cTxLock = queueUNLOCKED;
|
||||||
}
|
}
|
||||||
#ifndef VERIFAST /*< ***merge cTxLock and cRxLock critical regions*** */
|
#ifndef VERIFAST /*< ***merge cTxLock and cRxLock critical regions*** */
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
/* Do the same for the Rx lock. */
|
/* Do the same for the Rx lock. */
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int8_t cRxLock = pxQueue->cRxLock;
|
int8_t cRxLock = pxQueue->cRxLock;
|
||||||
|
|
||||||
|
@ -162,7 +162,9 @@ static void prvUnlockQueue( Queue_t * const pxQueue )
|
||||||
}
|
}
|
||||||
/*@close queue(pxQueue, Storage, N, M, W, R, K, false, abs);@*/
|
/*@close queue(pxQueue, Storage, N, M, W, R, K, false, abs);@*/
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
#ifdef VERIFAST /*< ghost action */
|
#ifdef VERIFAST /*< ghost action */
|
||||||
mutex_release( pxQueue->locked );
|
mutex_release( pxQueue->locked );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
/* It may seem that the read of `pxQueue->uxMessagesWaiting` is required to be
|
/* It may seem that the read of `pxQueue->uxMessagesWaiting` is required to be
|
||||||
|
@ -41,11 +43,11 @@ UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue )
|
||||||
{
|
{
|
||||||
UBaseType_t uxReturn;
|
UBaseType_t uxReturn;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
Queue_t * pxQueue = xQueue;
|
Queue_t * pxQueue = xQueue;
|
||||||
#else
|
#else
|
||||||
Queue_t * const pxQueue = xQueue;
|
Queue_t * const pxQueue = xQueue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
uxReturn = pxQueue->uxMessagesWaiting;
|
uxReturn = pxQueue->uxMessagesWaiting;
|
||||||
|
@ -71,3 +73,5 @@ UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue )
|
||||||
|
|
||||||
return uxReturn;
|
return uxReturn;
|
||||||
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
|
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue )
|
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue )
|
||||||
|
@ -32,11 +34,11 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue )
|
||||||
{
|
{
|
||||||
UBaseType_t uxReturn;
|
UBaseType_t uxReturn;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
Queue_t * pxQueue = xQueue;
|
Queue_t * pxQueue = xQueue;
|
||||||
#else
|
#else
|
||||||
Queue_t * const pxQueue = xQueue;
|
Queue_t * const pxQueue = xQueue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
|
|
||||||
|
@ -51,3 +53,5 @@ UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue )
|
||||||
|
|
||||||
return uxReturn;
|
return uxReturn;
|
||||||
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
|
} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,24 +24,25 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||||
|
|
||||||
void vQueueDelete( QueueHandle_t xQueue )
|
void vQueueDelete( QueueHandle_t xQueue )
|
||||||
|
|
||||||
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs) &*&
|
||||||
* queuelists(xQueue) &*&
|
queuelists(xQueue) &*&
|
||||||
* xQueue->irqMask |-> _ &*&
|
xQueue->irqMask |-> _ &*&
|
||||||
* xQueue->schedulerSuspend |-> _ &*&
|
xQueue->schedulerSuspend |-> _ &*&
|
||||||
* xQueue->locked |-> _;@*/
|
xQueue->locked |-> _;@*/
|
||||||
/*@ensures true;@*/
|
/*@ensures true;@*/
|
||||||
{
|
{
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
Queue_t * pxQueue = xQueue;
|
Queue_t * pxQueue = xQueue;
|
||||||
#else
|
#else
|
||||||
Queue_t * const pxQueue = xQueue;
|
Queue_t * const pxQueue = xQueue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
traceQUEUE_DELETE( pxQueue );
|
traceQUEUE_DELETE( pxQueue );
|
||||||
|
@ -57,10 +58,10 @@ void vQueueDelete( QueueHandle_t xQueue )
|
||||||
/* The queue can only have been allocated dynamically - free it
|
/* The queue can only have been allocated dynamically - free it
|
||||||
* again. */
|
* again. */
|
||||||
vPortFree( pxQueue );
|
vPortFree( pxQueue );
|
||||||
#ifdef VERIFAST /*< leak ghost state on deletion */
|
#ifdef VERIFAST /*< leak ghost state on deletion */
|
||||||
/*@leak buffer(_, _, _, _);@*/
|
/*@leak buffer(_, _, _, _);@*/
|
||||||
/*@leak malloc_block(_, _);@*/
|
/*@leak malloc_block(_, _);@*/
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
#elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
|
||||||
{
|
{
|
||||||
|
@ -83,3 +84,5 @@ void vQueueDelete( QueueHandle_t xQueue )
|
||||||
}
|
}
|
||||||
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#include "proof/queuecontracts.h"
|
#include "proof/queuecontracts.h"
|
||||||
|
|
||||||
|
@ -31,50 +33,45 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
const void * const pvItemToQueue,
|
const void * const pvItemToQueue,
|
||||||
TickType_t xTicksToWait,
|
TickType_t xTicksToWait,
|
||||||
const BaseType_t xCopyPosition )
|
const BaseType_t xCopyPosition )
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* chars(pvItemToQueue, M, ?x) &*&
|
chars(pvItemToQueue, M, ?x) &*&
|
||||||
* (xCopyPosition == queueSEND_TO_BACK || xCopyPosition == queueSEND_TO_FRONT || (xCopyPosition == queueOVERWRITE && N == 1));@*/
|
(xCopyPosition == queueSEND_TO_BACK || xCopyPosition == queueSEND_TO_FRONT || (xCopyPosition == queueOVERWRITE && N == 1));@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* chars(pvItemToQueue, M, x);@*/
|
chars(pvItemToQueue, M, x);@*/
|
||||||
{
|
{
|
||||||
BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired;
|
BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired;
|
||||||
TimeOut_t xTimeOut;
|
TimeOut_t xTimeOut;
|
||||||
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
|
Queue_t * pxQueue = xQueue;
|
||||||
|
#else
|
||||||
|
Queue_t * const pxQueue = xQueue;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
configASSERT( pxQueue );
|
||||||
Queue_t * pxQueue = xQueue;
|
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||||
#else
|
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
||||||
Queue_t * const pxQueue = xQueue;
|
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
|
||||||
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
|
||||||
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
|
||||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
{
|
{
|
||||||
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* ifdef VERIFAST */
|
#endif
|
||||||
|
|
||||||
/*lint -save -e904 This function relaxes the coding standard somewhat to
|
/*lint -save -e904 This function relaxes the coding standard somewhat to
|
||||||
* allow return statements within the function itself. This is done in the
|
* allow return statements within the function itself. This is done in the
|
||||||
* interest of execution time efficiency. */
|
* interest of execution time efficiency. */
|
||||||
for( ; ; )
|
for( ; ; )
|
||||||
|
|
||||||
/*@invariant [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@invariant [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* chars(pvItemToQueue, M, x) &*&
|
chars(pvItemToQueue, M, x) &*&
|
||||||
* u_integer(&xTicksToWait, _) &*&
|
u_integer(&xTicksToWait, _) &*&
|
||||||
* (xCopyPosition == queueSEND_TO_BACK || xCopyPosition == queueSEND_TO_FRONT || (xCopyPosition == queueOVERWRITE && N == 1)) &*&
|
(xCopyPosition == queueSEND_TO_BACK || xCopyPosition == queueSEND_TO_FRONT || (xCopyPosition == queueOVERWRITE && N == 1)) &*&
|
||||||
* xTIME_OUT(&xTimeOut);@*/
|
xTIME_OUT(&xTimeOut);@*/
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/*@assert queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
/*@assert queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
||||||
|
|
||||||
/* Is there room on the queue now? The running task must be the
|
/* Is there room on the queue now? The running task must be the
|
||||||
* highest priority task wanting to access the queue. If the head item
|
* highest priority task wanting to access the queue. If the head item
|
||||||
* in the queue is to be overwritten then it does not matter if the
|
* in the queue is to be overwritten then it does not matter if the
|
||||||
|
@ -182,19 +179,19 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (xCopyPosition == queueSEND_TO_BACK)
|
if (xCopyPosition == queueSEND_TO_BACK)
|
||||||
* {
|
{
|
||||||
* close queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)));
|
close queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)));
|
||||||
* }
|
}
|
||||||
* else if (xCopyPosition == queueSEND_TO_FRONT)
|
else if (xCopyPosition == queueSEND_TO_FRONT)
|
||||||
* {
|
{
|
||||||
* close queue(pxQueue, Storage, N, M, W, (R == 0 ? (N-1) : (R-1)), (K+1), is_locked, cons(x, abs));
|
close queue(pxQueue, Storage, N, M, W, (R == 0 ? (N-1) : (R-1)), (K+1), is_locked, cons(x, abs));
|
||||||
* }
|
}
|
||||||
* else if (xCopyPosition == queueOVERWRITE)
|
else if (xCopyPosition == queueOVERWRITE)
|
||||||
* {
|
{
|
||||||
* close queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x));
|
close queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x));
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
return pdPASS;
|
return pdPASS;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +200,6 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
if( xTicksToWait == ( TickType_t ) 0 )
|
if( xTicksToWait == ( TickType_t ) 0 )
|
||||||
{
|
{
|
||||||
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
||||||
|
|
||||||
/* The queue was full and no block time is specified (or
|
/* The queue was full and no block time is specified (or
|
||||||
* the block time has expired) so leave now. */
|
* the block time has expired) so leave now. */
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
@ -226,7 +222,6 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
@ -248,16 +243,16 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
|
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
|
||||||
|
|
||||||
/* Unlocking the queue means queue events can effect the
|
/* Unlocking the queue means queue events can effect the
|
||||||
* event list. It is possible that interrupts occurring now
|
* event list. It is possible that interrupts occurring now
|
||||||
* remove this task from the event list again - but as the
|
* remove this task from the event list again - but as the
|
||||||
* scheduler is suspended the task will go onto the pending
|
* scheduler is suspended the task will go onto the pending
|
||||||
* ready last instead of the actual ready list. */
|
* ready list instead of the actual ready list. */
|
||||||
/*@close queue_locked_invariant(xQueue)();@*/
|
/*@close queue_locked_invariant(xQueue)();@*/
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
|
|
||||||
/* Resuming the scheduler will move tasks from the pending
|
/* Resuming the scheduler will move tasks from the pending
|
||||||
* ready list into the ready list - so it is feasible that this
|
* ready list into the ready list - so it is feasible that this
|
||||||
* task is already in a ready list before it yields - in which
|
* task is already in the ready list before it yields - in which
|
||||||
* case the yield will not cause a context switch unless there
|
* case the yield will not cause a context switch unless there
|
||||||
* is also a higher priority task in the pending ready list. */
|
* is also a higher priority task in the pending ready list. */
|
||||||
/*@close exists(pxQueue);@*/
|
/*@close exists(pxQueue);@*/
|
||||||
|
@ -270,27 +265,29 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
||||||
{
|
{
|
||||||
/* Try again. */
|
/* Try again. */
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@close exists(pxQueue);@*/
|
/*@close exists(pxQueue);@*/
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
#else
|
#else
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The timeout has expired. */
|
/* The timeout has expired. */
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@close exists(pxQueue);@*/
|
/*@close exists(pxQueue);@*/
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
#else
|
#else
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
traceQUEUE_SEND_FAILED( pxQueue );
|
traceQUEUE_SEND_FAILED( pxQueue );
|
||||||
return errQUEUE_FULL;
|
return errQUEUE_FULL;
|
||||||
}
|
}
|
||||||
} /*lint -restore */
|
} /*lint -restore */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#include "proof/queuecontracts.h"
|
#include "proof/queuecontracts.h"
|
||||||
|
|
||||||
|
@ -31,30 +33,28 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||||
const void * const pvItemToQueue,
|
const void * const pvItemToQueue,
|
||||||
BaseType_t * const pxHigherPriorityTaskWoken,
|
BaseType_t * const pxHigherPriorityTaskWoken,
|
||||||
const BaseType_t xCopyPosition )
|
const BaseType_t xCopyPosition )
|
||||||
|
|
||||||
/*@requires
|
/*@requires
|
||||||
* [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true &*&
|
[1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true &*&
|
||||||
* chars(pvItemToQueue, M, ?x) &*&
|
chars(pvItemToQueue, M, ?x) &*&
|
||||||
* integer(pxHigherPriorityTaskWoken, _) &*&
|
integer(pxHigherPriorityTaskWoken, _) &*&
|
||||||
* (xCopyPosition == queueSEND_TO_BACK || xCopyPosition == queueSEND_TO_FRONT || (xCopyPosition == queueOVERWRITE && N == 1));@*/
|
(xCopyPosition == queueSEND_TO_BACK || xCopyPosition == queueSEND_TO_FRONT || (xCopyPosition == queueOVERWRITE && N == 1));@*/
|
||||||
|
|
||||||
/*@ensures
|
/*@ensures
|
||||||
* [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
[1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* chars(pvItemToQueue, M, x) &*&
|
chars(pvItemToQueue, M, x) &*&
|
||||||
* integer(pxHigherPriorityTaskWoken, _);@*/
|
integer(pxHigherPriorityTaskWoken, _);@*/
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
UBaseType_t uxSavedInterruptStatus;
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
Queue_t * pxQueue = xQueue;
|
Queue_t * pxQueue = xQueue;
|
||||||
#else
|
#else
|
||||||
Queue_t * const pxQueue = xQueue;
|
Queue_t * const pxQueue = xQueue;
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||||
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* RTOS ports that support interrupt nesting have the concept of a maximum
|
/* RTOS ports that support interrupt nesting have the concept of a maximum
|
||||||
* system call (or maximum API call) interrupt priority. Interrupts that are
|
* system call (or maximum API call) interrupt priority. Interrupts that are
|
||||||
|
@ -92,12 +92,12 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||||
* in a task disinheriting a priority and prvCopyDataToQueue() can be
|
* in a task disinheriting a priority and prvCopyDataToQueue() can be
|
||||||
* called here even though the disinherit function does not check if
|
* called here even though the disinherit function does not check if
|
||||||
* the scheduler is suspended before accessing the ready lists. */
|
* the scheduler is suspended before accessing the ready lists. */
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
||||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||||
#else
|
#else
|
||||||
( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||||
#endif
|
#endif
|
||||||
/*@open queue(pxQueue, _, N, M, _, _, _, _, _);@*/
|
/*@open queue(pxQueue, _, N, M, _, _, _, _, _);@*/
|
||||||
|
|
||||||
/* The event list is not altered if the queue is locked. This will
|
/* The event list is not altered if the queue is locked. This will
|
||||||
|
@ -191,9 +191,9 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not used in this path. */
|
/* Not used in this path. */
|
||||||
#ifndef VERIFAST /*< void cast of unused var */
|
#ifndef VERIFAST /*< void cast of unused var */
|
||||||
( void ) uxPreviousMessagesWaiting;
|
( void ) uxPreviousMessagesWaiting;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
}
|
}
|
||||||
|
@ -207,27 +207,26 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||||
}
|
}
|
||||||
|
|
||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
|
|
||||||
/*@
|
/*@
|
||||||
* if (xCopyPosition == queueSEND_TO_BACK)
|
if (xCopyPosition == queueSEND_TO_BACK)
|
||||||
* {
|
{
|
||||||
* close queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)));
|
close queue(pxQueue, Storage, N, M, (W+1)%N, R, (K+1), is_locked, append(abs, singleton(x)));
|
||||||
* }
|
}
|
||||||
* else if (xCopyPosition == queueSEND_TO_FRONT)
|
else if (xCopyPosition == queueSEND_TO_FRONT)
|
||||||
* {
|
{
|
||||||
* if (R == 0)
|
if (R == 0)
|
||||||
* {
|
{
|
||||||
* close queue(pxQueue, Storage, N, M, W, (N-1), (K+1), is_locked, cons(x, abs));
|
close queue(pxQueue, Storage, N, M, W, (N-1), (K+1), is_locked, cons(x, abs));
|
||||||
* }
|
}
|
||||||
* else
|
else
|
||||||
* {
|
{
|
||||||
* close queue(pxQueue, Storage, N, M, W, (R-1), (K+1), is_locked, cons(x, abs));
|
close queue(pxQueue, Storage, N, M, W, (R-1), (K+1), is_locked, cons(x, abs));
|
||||||
* }
|
}
|
||||||
* } else if (xCopyPosition == queueOVERWRITE)
|
} else if (xCopyPosition == queueOVERWRITE)
|
||||||
* {
|
{
|
||||||
* close queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x));
|
close queue(pxQueue, Storage, N, M, W, R, 1, is_locked, singleton(x));
|
||||||
* }
|
}
|
||||||
* @*/
|
@*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -240,3 +239,5 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,21 +24,22 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue )
|
BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue )
|
||||||
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
||||||
|
|
||||||
/*@ensures queue(xQueue, Storage, N, M, W, R, K, is_locked, abs) &*&
|
/*@ensures queue(xQueue, Storage, N, M, W, R, K, is_locked, abs) &*&
|
||||||
* result == ((K == 0) ? pdTRUE : pdFALSE);@*/
|
result == ((K == 0) ? pdTRUE : pdFALSE);@*/
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
Queue_t * pxQueue = xQueue;
|
Queue_t * pxQueue = xQueue;
|
||||||
#else
|
#else
|
||||||
Queue_t * const pxQueue = xQueue;
|
Queue_t * const pxQueue = xQueue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
|
|
||||||
|
@ -53,3 +54,5 @@ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue )
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
|
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,21 +24,22 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
|
|
||||||
BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
|
BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
|
||||||
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
/*@requires queue(xQueue, ?Storage, ?N, ?M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
||||||
|
|
||||||
/*@ensures queue(xQueue, Storage, N, M, W, R, K, is_locked, abs) &*&
|
/*@ensures queue(xQueue, Storage, N, M, W, R, K, is_locked, abs) &*&
|
||||||
* result == ((K == N) ? pdTRUE : pdFALSE);@*/
|
result == ((K == N) ? pdTRUE : pdFALSE);@*/
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
Queue_t * pxQueue = xQueue;
|
Queue_t * pxQueue = xQueue;
|
||||||
#else
|
#else
|
||||||
Queue_t * const pxQueue = xQueue;
|
Queue_t * const pxQueue = xQueue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
configASSERT( pxQueue );
|
||||||
|
|
||||||
|
@ -53,3 +54,5 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
|
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,55 +24,53 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#include "proof/queuecontracts.h"
|
#include "proof/queuecontracts.h"
|
||||||
|
|
||||||
BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||||
void * const pvBuffer,
|
void * const pvBuffer,
|
||||||
TickType_t xTicksToWait )
|
TickType_t xTicksToWait )
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* chars(pvBuffer, M, ?x);@*/
|
chars(pvBuffer, M, ?x);@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* (result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x));@*/
|
(result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x));@*/
|
||||||
{
|
{
|
||||||
BaseType_t xEntryTimeSet = pdFALSE;
|
BaseType_t xEntryTimeSet = pdFALSE;
|
||||||
TimeOut_t xTimeOut;
|
TimeOut_t xTimeOut;
|
||||||
int8_t * pcOriginalReadPosition;
|
int8_t * pcOriginalReadPosition;
|
||||||
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
|
Queue_t * pxQueue = xQueue;
|
||||||
|
#else
|
||||||
|
Queue_t * const pxQueue = xQueue;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
/* Check the pointer is not NULL. */
|
||||||
Queue_t * pxQueue = xQueue;
|
configASSERT( ( pxQueue ) );
|
||||||
#else
|
|
||||||
Queue_t * const pxQueue = xQueue;
|
|
||||||
|
|
||||||
/* Check the pointer is not NULL. */
|
/* The buffer into which data is received can only be NULL if the data size
|
||||||
configASSERT( ( pxQueue ) );
|
* is zero (so no data is copied into the buffer. */
|
||||||
|
configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||||
|
|
||||||
/* The buffer into which data is received can only be NULL if the data size
|
/* Cannot block if the scheduler is suspended. */
|
||||||
* is zero (so no data is copied into the buffer. */
|
|
||||||
configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
|
||||||
|
|
||||||
/* Cannot block if the scheduler is suspended. */
|
|
||||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
{
|
{
|
||||||
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* ifdef VERIFAST */
|
#endif
|
||||||
|
|
||||||
/*lint -save -e904 This function relaxes the coding standard somewhat to
|
/*lint -save -e904 This function relaxes the coding standard somewhat to
|
||||||
* allow return statements within the function itself. This is done in the
|
* allow return statements within the function itself. This is done in the
|
||||||
* interest of execution time efficiency. */
|
* interest of execution time efficiency. */
|
||||||
for( ; ; )
|
for( ; ; )
|
||||||
|
|
||||||
/*@invariant [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@invariant [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* chars(pvBuffer, M, x) &*&
|
chars(pvBuffer, M, x) &*&
|
||||||
* u_integer(&xTicksToWait, _) &*&
|
u_integer(&xTicksToWait, _) &*&
|
||||||
* xTIME_OUT(&xTimeOut);@*/
|
xTIME_OUT(&xTimeOut);@*/
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
/*@assert queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
/*@assert queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
||||||
|
@ -148,7 +146,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
/* Interrupts and other tasks can send to and receive from the queue
|
/* Interrupts and other tasks can send to and receive from the queue
|
||||||
* now the critical section has been exited. */
|
* now that the critical section has been exited. */
|
||||||
|
|
||||||
/*@close exists<QueueHandle_t>(pxQueue);@*/
|
/*@close exists<QueueHandle_t>(pxQueue);@*/
|
||||||
vTaskSuspendAll();
|
vTaskSuspendAll();
|
||||||
|
@ -182,12 +180,12 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||||
/* There is data in the queue now, so don't enter the blocked
|
/* There is data in the queue now, so don't enter the blocked
|
||||||
* state, instead return to try and obtain the data. */
|
* state, instead return to try and obtain the data. */
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@close exists<QueueHandle_t>(pxQueue);@*/
|
/*@close exists<QueueHandle_t>(pxQueue);@*/
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
#else
|
#else
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -195,12 +193,12 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||||
/* The timeout has expired. If there is still no data in the queue
|
/* The timeout has expired. If there is still no data in the queue
|
||||||
* exit, otherwise go back and try to read the data again. */
|
* exit, otherwise go back and try to read the data again. */
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@close exists<QueueHandle_t>(pxQueue);@*/
|
/*@close exists<QueueHandle_t>(pxQueue);@*/
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
#else
|
#else
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
|
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -214,3 +212,5 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
||||||
}
|
}
|
||||||
} /*lint -restore */
|
} /*lint -restore */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,31 +24,30 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#include "proof/queuecontracts.h"
|
#include "proof/queuecontracts.h"
|
||||||
|
|
||||||
BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue,
|
BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue,
|
||||||
void * const pvBuffer )
|
void * const pvBuffer )
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true &*&
|
||||||
* chars(pvBuffer, M, ?x);@*/
|
chars(pvBuffer, M, ?x);@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* (result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x));@*/
|
(result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x));@*/
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
UBaseType_t uxSavedInterruptStatus;
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
int8_t * pcOriginalReadPosition;
|
int8_t * pcOriginalReadPosition;
|
||||||
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
|
Queue_t * pxQueue = xQueue;
|
||||||
|
#else
|
||||||
|
Queue_t * const pxQueue = xQueue;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
configASSERT( pxQueue );
|
||||||
Queue_t * pxQueue = xQueue;
|
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||||
#else
|
configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */
|
||||||
Queue_t * const pxQueue = xQueue;
|
#endif
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
|
||||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
|
||||||
configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* RTOS ports that support interrupt nesting have the concept of a maximum
|
/* RTOS ports that support interrupt nesting have the concept of a maximum
|
||||||
* system call (or maximum API call) interrupt priority. Interrupts that are
|
* system call (or maximum API call) interrupt priority. Interrupts that are
|
||||||
|
@ -95,3 +94,5 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue,
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -24,54 +24,52 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#include "proof/queuecontracts.h"
|
#include "proof/queuecontracts.h"
|
||||||
|
|
||||||
BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
||||||
void * const pvBuffer,
|
void * const pvBuffer,
|
||||||
TickType_t xTicksToWait )
|
TickType_t xTicksToWait )
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == false &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* chars(pvBuffer, M, ?x);@*/
|
chars(pvBuffer, M, ?x);@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* (result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x));@*/
|
(result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x));@*/
|
||||||
{
|
{
|
||||||
BaseType_t xEntryTimeSet = pdFALSE;
|
BaseType_t xEntryTimeSet = pdFALSE;
|
||||||
TimeOut_t xTimeOut;
|
TimeOut_t xTimeOut;
|
||||||
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
|
Queue_t * pxQueue = xQueue;
|
||||||
|
#else
|
||||||
|
Queue_t * const pxQueue = xQueue;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
/* Check the pointer is not NULL. */
|
||||||
Queue_t * pxQueue = xQueue;
|
configASSERT( ( pxQueue ) );
|
||||||
#else
|
|
||||||
Queue_t * const pxQueue = xQueue;
|
|
||||||
|
|
||||||
/* Check the pointer is not NULL. */
|
/* The buffer into which data is received can only be NULL if the data size
|
||||||
configASSERT( ( pxQueue ) );
|
* is zero (so no data is copied into the buffer). */
|
||||||
|
configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||||
|
|
||||||
/* The buffer into which data is received can only be NULL if the data size
|
/* Cannot block if the scheduler is suspended. */
|
||||||
* is zero (so no data is copied into the buffer). */
|
|
||||||
configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
|
||||||
|
|
||||||
/* Cannot block if the scheduler is suspended. */
|
|
||||||
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
{
|
{
|
||||||
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* ifdef VERIFAST */
|
#endif
|
||||||
|
|
||||||
/*lint -save -e904 This function relaxes the coding standard somewhat to
|
/*lint -save -e904 This function relaxes the coding standard somewhat to
|
||||||
* allow return statements within the function itself. This is done in the
|
* allow return statements within the function itself. This is done in the
|
||||||
* interest of execution time efficiency. */
|
* interest of execution time efficiency. */
|
||||||
for( ; ; )
|
for( ; ; )
|
||||||
|
|
||||||
/*@invariant [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@invariant [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* [1/2]queuesuspend(xQueue) &*&
|
[1/2]queuesuspend(xQueue) &*&
|
||||||
* chars(pvBuffer, M, x) &*&
|
chars(pvBuffer, M, x) &*&
|
||||||
* u_integer(&xTicksToWait, _) &*&
|
u_integer(&xTicksToWait, _) &*&
|
||||||
* xTIME_OUT(&xTimeOut);@*/
|
xTIME_OUT(&xTimeOut);@*/
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
/*@assert queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
/*@assert queue(pxQueue, ?Storage, N, M, ?W, ?R, ?K, ?is_locked, ?abs);@*/
|
||||||
|
@ -90,10 +88,9 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
||||||
pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;
|
pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1;
|
||||||
|
|
||||||
/*@assert
|
/*@assert
|
||||||
* pxQueue->pcHead |-> ?buffer &*&
|
pxQueue->pcHead |-> ?buffer &*&
|
||||||
* buffer(buffer, N, M, ?contents);@*/
|
buffer(buffer, N, M, ?contents);@*/
|
||||||
/*@deq_lemma(K, (R+1)%N, contents, abs, head(abs));@*/
|
/*@deq_lemma(K, (R+1)%N, contents, abs, head(abs));@*/
|
||||||
|
|
||||||
/* There is now space in the queue, were any tasks waiting to
|
/* There is now space in the queue, were any tasks waiting to
|
||||||
* post to the queue? If so, unblock the highest priority waiting
|
* post to the queue? If so, unblock the highest priority waiting
|
||||||
* task. */
|
* task. */
|
||||||
|
@ -123,7 +120,6 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
||||||
if( xTicksToWait == ( TickType_t ) 0 )
|
if( xTicksToWait == ( TickType_t ) 0 )
|
||||||
{
|
{
|
||||||
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
/*@close queue(pxQueue, Storage, N, M, W, R, K, is_locked, abs);@*/
|
||||||
|
|
||||||
/* The queue was empty and no block time is specified (or
|
/* The queue was empty and no block time is specified (or
|
||||||
* the block time has expired) so leave now. */
|
* the block time has expired) so leave now. */
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
@ -182,12 +178,12 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
||||||
/* The queue contains data again. Loop back to try and read the
|
/* The queue contains data again. Loop back to try and read the
|
||||||
* data. */
|
* data. */
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@close exists(pxQueue);@*/
|
/*@close exists(pxQueue);@*/
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
#else
|
#else
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -195,12 +191,12 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
||||||
/* Timed out. If there is no data in the queue exit, otherwise loop
|
/* Timed out. If there is no data in the queue exit, otherwise loop
|
||||||
* back and attempt to read the data. */
|
* back and attempt to read the data. */
|
||||||
prvUnlockQueue( pxQueue );
|
prvUnlockQueue( pxQueue );
|
||||||
#ifdef VERIFAST /*< void cast of unused return value */
|
#ifdef VERIFAST /*< void cast of unused return value */
|
||||||
/*@close exists(pxQueue);@*/
|
/*@close exists(pxQueue);@*/
|
||||||
xTaskResumeAll();
|
xTaskResumeAll();
|
||||||
#else
|
#else
|
||||||
( void ) xTaskResumeAll();
|
( void ) xTaskResumeAll();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
|
if( prvIsQueueEmpty( pxQueue ) != pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -214,3 +210,5 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
||||||
}
|
}
|
||||||
} /*lint -restore */
|
} /*lint -restore */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* FreeRTOS V202112.00
|
* FreeRTOS V202112.00
|
||||||
* Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,32 +24,31 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
|
||||||
#include "proof/queue.h"
|
#include "proof/queue.h"
|
||||||
#include "proof/queuecontracts.h"
|
#include "proof/queuecontracts.h"
|
||||||
|
|
||||||
BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
|
BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
|
||||||
void * const pvBuffer,
|
void * const pvBuffer,
|
||||||
BaseType_t * const pxHigherPriorityTaskWoken )
|
BaseType_t * const pxHigherPriorityTaskWoken )
|
||||||
|
|
||||||
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true &*&
|
/*@requires [1/2]queuehandle(xQueue, ?N, ?M, ?is_isr) &*& is_isr == true &*&
|
||||||
* chars(pvBuffer, M, ?x) &*&
|
chars(pvBuffer, M, ?x) &*&
|
||||||
* pxHigherPriorityTaskWoken == NULL ? true : integer(pxHigherPriorityTaskWoken, _);@*/
|
pxHigherPriorityTaskWoken == NULL ? true : integer(pxHigherPriorityTaskWoken, _);@*/
|
||||||
|
|
||||||
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
/*@ensures [1/2]queuehandle(xQueue, N, M, is_isr) &*&
|
||||||
* (result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x)) &*&
|
(result == pdPASS ? chars(pvBuffer, M, _) : chars(pvBuffer, M, x)) &*&
|
||||||
* (pxHigherPriorityTaskWoken == NULL ? true : integer(pxHigherPriorityTaskWoken, _));@*/
|
(pxHigherPriorityTaskWoken == NULL ? true : integer(pxHigherPriorityTaskWoken, _));@*/
|
||||||
{
|
{
|
||||||
BaseType_t xReturn;
|
BaseType_t xReturn;
|
||||||
UBaseType_t uxSavedInterruptStatus;
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
|
#ifdef VERIFAST /*< const pointer declaration */
|
||||||
|
Queue_t * pxQueue = xQueue;
|
||||||
|
#else
|
||||||
|
Queue_t * const pxQueue = xQueue;
|
||||||
|
|
||||||
#ifdef VERIFAST /*< const pointer declaration */
|
configASSERT( pxQueue );
|
||||||
Queue_t * pxQueue = xQueue;
|
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||||
#else
|
#endif
|
||||||
Queue_t * const pxQueue = xQueue;
|
|
||||||
|
|
||||||
configASSERT( pxQueue );
|
|
||||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* RTOS ports that support interrupt nesting have the concept of a maximum
|
/* RTOS ports that support interrupt nesting have the concept of a maximum
|
||||||
* system call (or maximum API call) interrupt priority. Interrupts that are
|
* system call (or maximum API call) interrupt priority. Interrupts that are
|
||||||
|
@ -141,3 +140,5 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue