summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus/Test/CBMC/include/queue_init.h
blob: f05d18830e1cd526e9d1d30adb65b64de37457e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "FreeRTOS.h"
#include "queue.h"
#include "queue_datastructure.h"

#ifndef CBMC_OBJECT_BITS
#define CBMC_OBJECT_BITS 7
#endif

#ifndef CBMC_OBJECT_MAX_SIZE
#define CBMC_OBJECT_MAX_SIZE (UINT32_MAX>>(CBMC_OBJECT_BITS+1))
#endif

/* Using prvCopyDataToQueue together with prvNotifyQueueSetContainer
   leads to a problem space explosion. Therefore, we use this stub
   and a sepearted proof on prvCopyDataToQueue to deal with it.
   As prvNotifyQueueSetContainer is disabled if configUSE_QUEUE_SETS != 1,
   in other cases the original implementation should be used. */
#if( configUSE_QUEUE_SETS == 1 )
	BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition )
	{
		if(pxQueue->uxItemSize > ( UBaseType_t ) 0)
		{
			__CPROVER_assert(__CPROVER_r_ok(pvItemToQueue, ( size_t ) pxQueue->uxItemSize), "pvItemToQueue region must be readable");
			if(xPosition == queueSEND_TO_BACK){
				__CPROVER_assert(__CPROVER_w_ok(( void * ) pxQueue->pcWriteTo, ( size_t ) pxQueue->uxItemSize), "pxQueue->pcWriteTo region must be writable");
			}else{
				__CPROVER_assert(__CPROVER_w_ok(( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize), "pxQueue->u.xQueue.pcReadFrom region must be writable");
			}
			return pdFALSE;
		}else
		{
			return nondet_BaseType_t();
		}
	}
#endif

/* xQueueCreateSet is compiled out if configUSE_QUEUE_SETS != 1.*/
#if( configUSE_QUEUE_SETS == 1 )
	QueueSetHandle_t xUnconstrainedQueueSet()
	{
		UBaseType_t uxEventQueueLength = 2;
		QueueSetHandle_t xSet = xQueueCreateSet(uxEventQueueLength);
		if( xSet )
		{
			xSet->cTxLock = nondet_int8_t();
			xSet->cRxLock = nondet_int8_t();
			xSet->uxMessagesWaiting = nondet_UBaseType_t();
			xSet->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
			/* This is an invariant checked with a couple of asserts in the code base.
			   If it is false from the beginning, the CBMC proofs are not able to succeed*/
			__CPROVER_assume(xSet->uxMessagesWaiting < xSet->uxLength);
			xSet->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
		}
		return xSet;
	}
#endif

/* Create a mostly unconstrained Queue but bound the max item size.
   This is required for performance reasons in CBMC at the moment. */
QueueHandle_t xUnconstrainedQueueBoundedItemSize( UBaseType_t uxItemSizeBound ) {
	UBaseType_t uxQueueLength;
	UBaseType_t uxItemSize;
	uint8_t ucQueueType;
	__CPROVER_assume(uxQueueLength > 0);
	__CPROVER_assume(uxItemSize < uxItemSizeBound);

	// QueueGenericCreate method does not check for multiplication overflow
	size_t uxQueueStorageSize;
	__CPROVER_assume(uxQueueStorageSize < CBMC_OBJECT_MAX_SIZE);
	__CPROVER_assume(uxItemSize < uxQueueStorageSize/uxQueueLength);

	QueueHandle_t xQueue =
		xQueueGenericCreate(uxQueueLength, uxItemSize, ucQueueType);
	if(xQueue){
		xQueue->cTxLock = nondet_int8_t();
		xQueue->cRxLock = nondet_int8_t();
		xQueue->uxMessagesWaiting = nondet_UBaseType_t();
		/* This is an invariant checked with a couple of asserts in the code base.
		   If it is false from the beginning, the CBMC proofs are not able to succeed*/
		__CPROVER_assume(xQueue->uxMessagesWaiting < xQueue->uxLength);
		xQueue->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
		xQueue->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
		#if( configUSE_QUEUE_SETS == 1)
			xQueueAddToSet(xQueue, xUnconstrainedQueueSet());
		#endif
	}
	return xQueue;
}

/* Create a mostly unconstrained Queue */
QueueHandle_t xUnconstrainedQueue( void ) {
	UBaseType_t uxQueueLength;
	UBaseType_t uxItemSize;
	uint8_t ucQueueType;

	__CPROVER_assume(uxQueueLength > 0);

	// QueueGenericCreate method does not check for multiplication overflow
	size_t uxQueueStorageSize;
	__CPROVER_assume(uxQueueStorageSize < CBMC_OBJECT_MAX_SIZE);
	__CPROVER_assume(uxItemSize < uxQueueStorageSize/uxQueueLength);

	QueueHandle_t xQueue =
		xQueueGenericCreate(uxQueueLength, uxItemSize, ucQueueType);

	if(xQueue){
		xQueue->cTxLock = nondet_int8_t();
		xQueue->cRxLock = nondet_int8_t();
		xQueue->uxMessagesWaiting = nondet_UBaseType_t();
		/* This is an invariant checked with a couple of asserts in the code base.
		   If it is false from the beginning, the CBMC proofs are not able to succeed*/
		__CPROVER_assume(xQueue->uxMessagesWaiting < xQueue->uxLength);
		xQueue->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
		xQueue->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
		#if( configUSE_QUEUE_SETS == 1)
			xQueueAddToSet(xQueue, xUnconstrainedQueueSet());
		#endif
	}
	return xQueue;
}

/* Create a mostly unconstrained Mutex */
QueueHandle_t xUnconstrainedMutex( void ) {
	uint8_t ucQueueType;
	QueueHandle_t xQueue =
		xQueueCreateMutex(ucQueueType);
	if(xQueue){
		xQueue->cTxLock = nondet_int8_t();
		xQueue->cRxLock = nondet_int8_t();
		xQueue->uxMessagesWaiting = nondet_UBaseType_t();
		/* This is an invariant checked with a couple of asserts in the code base.
		   If it is false from the beginning, the CBMC proofs are not able to succeed*/
		__CPROVER_assume(xQueue->uxMessagesWaiting < xQueue->uxLength);
		xQueue->xTasksWaitingToReceive.uxNumberOfItems = nondet_UBaseType_t();
		xQueue->xTasksWaitingToSend.uxNumberOfItems = nondet_UBaseType_t();
		#if( configUSE_QUEUE_SETS == 1)
			xQueueAddToSet(xQueue, xUnconstrainedQueueSet());
		#endif
	}
	return xQueue;
}