mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-10-15 09:17:44 -04:00
Add VeriFast kernel queue proofs (#117)
This commit is contained in:
parent
d5fedeaa96
commit
529c481c39
31 changed files with 3702 additions and 1 deletions
3
FreeRTOS/Test/VeriFast/scripts/annotation_overhead.sh
Executable file
3
FreeRTOS/Test/VeriFast/scripts/annotation_overhead.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
NO_COVERAGE=1 EXTRA_VERIFAST_ARGS=-stats make list queue | grep overhead: | sort | uniq
|
20
FreeRTOS/Test/VeriFast/scripts/callgraph.md
Normal file
20
FreeRTOS/Test/VeriFast/scripts/callgraph.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Generate callgraph
|
||||
|
||||
## Requirements
|
||||
|
||||
- python3
|
||||
- pycparser
|
||||
- graphviz/dot
|
||||
- [inconsolata](https://fonts.google.com/specimen/Inconsolata)
|
||||
|
||||
## Instructions
|
||||
|
||||
```
|
||||
cd scripts
|
||||
git clone https://github.com/eliben/pycparser.git #< you need this for pycparser's libc headers even if pycparser is installed
|
||||
mkdir fake_include
|
||||
touch fake_include/threading.h
|
||||
gcc -E -I pycparser/utils/fake_libc_include/ -I ../include/ -I fake_include/ ../queue/*.c > out.pp
|
||||
./callgraph.py > out.dot
|
||||
dot -Nfontname=inconsolata -Tpng -o callgraph.png out.dot
|
||||
```
|
83
FreeRTOS/Test/VeriFast/scripts/callgraph.py
Executable file
83
FreeRTOS/Test/VeriFast/scripts/callgraph.py
Executable file
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import print_function
|
||||
from pycparser import c_parser, c_ast, parse_file
|
||||
import sys
|
||||
|
||||
ignore_callee = set(['mutex_acquire', 'mutex_release'])
|
||||
ignore_caller = set(['caller_reinstates_queue_predicate'])
|
||||
proven = [
|
||||
'prvCopyDataFromQueue',
|
||||
'prvCopyDataToQueue',
|
||||
'prvInitialiseNewQueue',
|
||||
'prvIsQueueEmpty',
|
||||
'prvIsQueueFull',
|
||||
'prvLockQueue',
|
||||
'prvUnlockQueue',
|
||||
'uxQueueMessagesWaiting',
|
||||
'uxQueueSpacesAvailable',
|
||||
'vQueueDelete',
|
||||
'xQueueGenericCreate',
|
||||
'xQueueGenericReset',
|
||||
'xQueueGenericSend',
|
||||
'xQueueGenericSendFromISR',
|
||||
'xQueueIsQueueEmptyFromISR',
|
||||
'xQueueIsQueueFullFromISR',
|
||||
'xQueuePeek',
|
||||
'xQueuePeekFromISR',
|
||||
'xQueueReceive',
|
||||
'xQueueReceiveFromISR',
|
||||
]
|
||||
|
||||
modeled = [
|
||||
'setInterruptMask',
|
||||
'clearInterruptMask',
|
||||
'setInterruptMaskFromISR',
|
||||
'clearInterruptMaskFromISR',
|
||||
'vTaskSuspendAll',
|
||||
'xTaskResumeAll',
|
||||
]
|
||||
|
||||
CALLMAP = set()
|
||||
|
||||
|
||||
class FuncCallVisitor(c_ast.NodeVisitor):
|
||||
def __init__(self, caller):
|
||||
self.caller = caller
|
||||
|
||||
def visit_FuncCall(self, node):
|
||||
callee = node.name.name
|
||||
if callee not in ignore_callee:
|
||||
CALLMAP.add((node.name.name, self.caller))
|
||||
|
||||
|
||||
class FuncDefVisitor(c_ast.NodeVisitor):
|
||||
def visit_FuncDef(self, node):
|
||||
caller = node.decl.name
|
||||
if caller in ignore_caller:
|
||||
return
|
||||
if caller.startswith('wrapper_'):
|
||||
caller = caller[8:]
|
||||
v = FuncCallVisitor(caller)
|
||||
v.visit(node)
|
||||
|
||||
|
||||
def show_func_calls(filename):
|
||||
ast = parse_file(filename, use_cpp=False)
|
||||
v = FuncDefVisitor()
|
||||
v.visit(ast)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
filename = 'out.pp'
|
||||
show_func_calls(filename)
|
||||
print('digraph G {')
|
||||
print(' rankdir=LR;')
|
||||
print(' node [style = filled, colorscheme = set13;];')
|
||||
for f in proven:
|
||||
print(' %s [fillcolor = 3];' % f)
|
||||
for f in modeled:
|
||||
print(' %s [fillcolor = 2];' % f)
|
||||
for (callee, caller) in CALLMAP:
|
||||
print(' %s -> %s;' % (callee, caller))
|
||||
print('}')
|
40
FreeRTOS/Test/VeriFast/scripts/diff_files.md
Normal file
40
FreeRTOS/Test/VeriFast/scripts/diff_files.md
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Generate diffs between FreeRTOS source and proofs
|
||||
|
||||
## Requirements
|
||||
|
||||
- python3
|
||||
- ctags 5.8
|
||||
- diff 3.4+
|
||||
- [diff2html](https://diff2html.xyz/)
|
||||
|
||||
## Instructions
|
||||
|
||||
The following will extract per-function files from the original FreeRTOS source
|
||||
implementation and the proof directory.
|
||||
|
||||
|
||||
```
|
||||
cd scripts
|
||||
./generate_diff_files.sh
|
||||
# will extract to ./FreeRTOS-Kernel/generated and ./queue/generated
|
||||
```
|
||||
|
||||
Then use `diff` for a side-by-side comparison. Note that the `--color=always`
|
||||
flag needs v3.4+:
|
||||
|
||||
```
|
||||
diff --color=always --width=$COLUMNS --suppress-common-lines --side-by-side FreeRTOS-Kernel/generated queue/generated | less -r
|
||||
```
|
||||
|
||||
Or generate a html report using `diff2html`:
|
||||
|
||||
```
|
||||
diff -u FreeRTOS-Kernel/generated queue/generated | diff2html -i stdin
|
||||
```
|
||||
|
||||
The expectation is that the proofs make minimal changes to the original source
|
||||
implementation in the form of:
|
||||
|
||||
- VeriFast annotations `/*@...@*/` and `//*...`
|
||||
- Additional comments explaining the proof `/*...*/`
|
||||
- Flagged changes within `#if[n]def VERIFAST`
|
47
FreeRTOS/Test/VeriFast/scripts/generate_diff_files.sh
Executable file
47
FreeRTOS/Test/VeriFast/scripts/generate_diff_files.sh
Executable file
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash -eu
|
||||
|
||||
FUNCS=(
|
||||
prvCopyDataFromQueue
|
||||
prvCopyDataToQueue
|
||||
prvInitialiseNewQueue
|
||||
prvIsQueueEmpty
|
||||
prvIsQueueFull
|
||||
prvUnlockQueue
|
||||
uxQueueMessagesWaiting
|
||||
uxQueueSpacesAvailable
|
||||
vQueueDelete
|
||||
xQueueGenericCreate
|
||||
xQueueGenericReset
|
||||
xQueueGenericSend
|
||||
xQueueGenericSendFromISR
|
||||
xQueueIsQueueEmptyFromISR
|
||||
xQueueIsQueueFullFromISR
|
||||
xQueuePeek
|
||||
xQueuePeekFromISR
|
||||
xQueueReceive
|
||||
xQueueReceiveFromISR
|
||||
)
|
||||
|
||||
if [ ! -d "FreeRTOS-Kernel" ]; then
|
||||
git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git
|
||||
fi
|
||||
pushd FreeRTOS-Kernel > /dev/null
|
||||
rm -rf tags generated
|
||||
ctags --excmd=number queue.c
|
||||
mkdir generated
|
||||
for f in ${FUNCS[@]}; do
|
||||
../extract.py tags $f > generated/$f.c
|
||||
done
|
||||
popd > /dev/null
|
||||
echo "created: FreeRTOS-Kernel/generated"
|
||||
|
||||
ln -fs ../queue .
|
||||
pushd queue > /dev/null
|
||||
rm -rf tags generated
|
||||
ctags --excmd=number *.c
|
||||
mkdir generated
|
||||
for f in ${FUNCS[@]}; do
|
||||
../scripts/extract.py tags $f > generated/$f.c
|
||||
done
|
||||
popd > /dev/null
|
||||
echo "created: queue/generated"
|
Loading…
Add table
Add a link
Reference in a new issue