3 * Copyright (C) Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * https://www.FreeRTOS.org
23 * https://github.com/FreeRTOS
27 #include "proof/list.h"
29 UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
32 * exists<struct xLIST * >(?l) &*&
33 * xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
34 * end != pxItemToRemove &*&
35 * mem(pxItemToRemove, cells) == true;@*/
39 * xLIST_ITEM(pxItemToRemove, nth(index_of(pxItemToRemove, cells), vals), _, ?pxItemToRemovePrevious, NULL) &*&
40 * pxItemToRemovePrevious == nth(index_of(pxItemToRemove, cells)-1, cells) &*&
41 * xLIST(l, result, idx == pxItemToRemove ? pxItemToRemovePrevious : idx, end, remove(pxItemToRemove, cells), remove_nth(index_of(pxItemToRemove, cells), vals));@*/
43 /* For brevity we alias x to pxItemToRemove */
44 /*@struct xLIST_ITEM *x = pxItemToRemove;@*/
46 /* Start by establishing that the list must be non-empty since x != end */
47 /*@open xLIST(l, len, idx, end, cells, vals);@*/
48 /*@assert DLS(end, ?endprev, end, _, cells, vals, l);@*/
49 /*@assert vals == cons(portMAX_DELAY, _);@*/
50 /*@dls_not_empty(end, endprev, cells, x);@*/
52 /* We know the xLIST is a DLS: end...endprev
53 * Split this into DLS1:end...xprev and DLS2:x...endprev */
54 /*@int i = index_of(x, cells);@*/
55 /*@split(end, endprev, end, endprev, cells, vals, x, i);@*/
56 /*@list<struct xLIST_ITEM *> ys = take(i, cells);@*/
57 /*@list<struct xLIST_ITEM *> zs = drop(i, cells);@*/
58 /*@list<TickType_t> vs = take(i, vals);@*/
59 /*@list<TickType_t> ws = drop(i, vals);@*/
60 /*@assert length(ys) == length(vs);@*/
61 /*@assert length(zs) == length(ws);@*/
62 /*@assert DLS(end, endprev, x, ?xprev, ys, vs, l);@*/ /*< DLS1 (ys, vs) */
63 /*@assert DLS(x, xprev, end, endprev, zs, ws, l);@*/ /*< DLS2 (zs, ws) */
65 /* Now case split to open DLS1 and DLS2 appropriately */
73 * //DLS1: extract end=prev=next
74 * open DLS(end, endprev, x, xprev, ys, vs, l);
75 * open xLIST_ITEM(end, portMAX_DELAY, x, endprev, l);
77 * open DLS(x, xprev, end, endprev, zs, ws, l);
79 * assert length(ys) == 1;
80 * assert length(zs) == 1;
85 * //DLS1: extract end=prev
86 * open DLS(end, endprev, x, xprev, ys, vs, l);
87 * open xLIST_ITEM(end, portMAX_DELAY, x, endprev, l);
88 * //DLS2: extract next and x
89 * open DLS(x, end, end, endprev, zs, ws, l);
90 * assert DLS(?xnext, x, end, endprev, tail(zs), tail(ws), l);
91 * open DLS(xnext, x, end, endprev, tail(zs), tail(ws), l);
92 * open xLIST_ITEM(xnext, _, _, x, l);
94 * assert length(ys) == 1;
102 * //DLS1: extract end=next and prev
103 * dls_last_mem(end, endprev, x, xprev, ys);
104 * assert mem(xprev, ys) == true;
105 * open DLS(end, endprev, x, xprev, ys, vs, l);
106 * open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, l);
107 * if (endnext == xprev)
109 * open DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
110 * open xLIST_ITEM(xprev, _, x, _, l);
114 * assert DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
115 * int k = index_of(xprev, tail(ys));
116 * dls_last_mem(endnext, end, x, xprev, tail(ys));
117 * split(endnext, end, x, xprev, tail(ys), tail(vs), xprev, k);
118 * open DLS(xprev, _, x, xprev, _, _, l);
119 * open xLIST_ITEM(xprev, _, x, _, l);
122 * open DLS(x, xprev, end, endprev, zs, ws, l);
124 * assert length(zs) == 1;
129 * //DLS1: extract prev
130 * dls_last_mem(end, endprev, x, xprev, ys);
131 * int j = index_of(xprev, ys);
132 * open DLS(end, endprev, x, xprev, ys, vs, l);
133 * open xLIST_ITEM(end, portMAX_DELAY, ?endnext, endprev, l);
134 * if (endnext == xprev)
136 * open DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
137 * assert tail(ys) == singleton(xprev);
138 * open xLIST_ITEM(xprev, _, x, _, l);
142 * assert DLS(endnext, end, x, xprev, tail(ys), tail(vs), l);
143 * int k = index_of(xprev, tail(ys));
144 * dls_last_mem(endnext, end, x, xprev, tail(ys));
145 * split(endnext, end, x, xprev, tail(ys), tail(vs), xprev, k);
146 * open DLS(xprev, _, x, xprev, _, _, l);
147 * open xLIST_ITEM(xprev, _, x, _, l);
149 * //DLS2: extract next and x
150 * open DLS(x, xprev, end, endprev, zs, ws, l);
151 * assert xLIST_ITEM(x, _, ?xnext, _, l);
152 * open DLS(xnext, x, end, endprev, tail(zs), tail(ws), l);
153 * open xLIST_ITEM(xnext, _, _, x, l);
157 /*@drop_nth_index_of(vals, i);@*/
158 /*@open xLIST_ITEM(x, nth(i, vals), ?xnext, xprev, l);@*/
160 /* The list item knows which list it is in. Obtain the list from the list
162 #ifdef VERIFAST /*< const pointer declaration */
163 List_t * pxList = pxItemToRemove->pxContainer;
165 List_t * const pxList = pxItemToRemove->pxContainer;
168 pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
169 pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
171 /* Only used during decision coverage testing. */
172 mtCOVERAGE_TEST_DELAY();
174 /* Make sure the index is left pointing to a valid item. */
175 if( pxList->pxIndex == pxItemToRemove )
177 pxList->pxIndex = pxItemToRemove->pxPrevious;
181 mtCOVERAGE_TEST_MARKER();
184 pxItemToRemove->pxContainer = NULL;
185 ( pxList->uxNumberOfItems )--;
187 return pxList->uxNumberOfItems;
190 * // Reassemble DLS1 and a modified DLS2, which no longer includes x
196 * close xLIST_ITEM(end, portMAX_DELAY, _, _, _);
197 * close DLS(end, end, end, end, singleton(end), singleton(portMAX_DELAY), l);
202 * close xLIST_ITEM(xprev, _, xnext, endprev, l);
203 * close DLS(end, endprev, xnext, xprev, singleton(end), singleton(portMAX_DELAY), l);
204 * close xLIST_ITEM(xnext, _, _, xprev, l);
205 * close DLS(xnext, xprev, end, endprev, tail(zs), tail(ws), l);
206 * join(end, endprev, xnext, xprev, singleton(end), singleton(portMAX_DELAY),
207 * xnext, xprev, end, endprev, tail(zs), tail(ws));
215 * close xLIST_ITEM(end, _, ?endnext, xprev, l);
216 * close xLIST_ITEM(xprev, ?xprev_val, end, _, l);
217 * if (endnext == xprev)
219 * close DLS(xprev, end, end, xprev, singleton(xprev), singleton(xprev_val), l);
220 * close DLS(end, xprev, end, xprev, cons(end, singleton(xprev)), cons(portMAX_DELAY, singleton(xprev_val)), l);
224 * close DLS(xprev, ?xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
225 * assert DLS(endnext, end, xprev, xprevprev, ?cells_endnext_to_xprevprev, ?vals_endnext_to_xprevprev, l);
226 * join(endnext, end, xprev, xprevprev, cells_endnext_to_xprevprev, vals_endnext_to_xprevprev,
227 * xprev, xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val));
228 * close DLS(end, xprev, end, xprev, ys, vs, l);
234 * close xLIST_ITEM(xnext, _, ?xnextnext, xprev, l);
235 * close DLS(xnext, xprev, end, endprev, tail(zs), tail(ws), l);
236 * close xLIST_ITEM(end, _, ?endnext, endprev, l);
237 * close xLIST_ITEM(xprev, ?xprev_val, xnext, _, l);
238 * if (endnext == xprev)
240 * close DLS(xprev, _, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
241 * close DLS(end, endprev, xnext, xprev, ys, vs, l);
242 * join(end, endprev, xnext, xprev, ys, vs,
243 * xnext, xprev, end, endprev, tail(zs), tail(ws));
247 * close DLS(xprev, ?xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val), l);
248 * assert DLS(endnext, end, xprev, xprevprev, ?cells_endnext_to_xprevprev, ?vals_endnext_to_xprevprev, l);
249 * join(endnext, end, xprev, xprevprev, cells_endnext_to_xprevprev, vals_endnext_to_xprevprev,
250 * xprev, xprevprev, xnext, xprev, singleton(xprev), singleton(xprev_val));
251 * close DLS(end, endprev, xnext, xprev, ys, vs, l);
252 * join(end, endprev, xnext, xprev, ys, vs,
253 * xnext, xprev, end, endprev, tail(zs), tail(ws));
258 /*@remove_remove_nth(cells, x);@*/
263 * close xLIST(l, len-1, xprev, end, append(ys, tail(zs)), append(vs, tail(ws)));
267 * idx_remains_in_list(cells, idx, x, i);
268 * close xLIST(l, len-1, idx, end, append(ys, tail(zs)), append(vs, tail(ws)));
271 /*@close xLIST_ITEM(x, nth(i, vals), xnext, xprev, NULL);@*/
274 ListItem_t * client_example( List_t * l )
277 * xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
279 * cells == cons(end, cons(idx, ?cells_tl)) &*&
280 * vals == cons(portMAX_DELAY, cons(42, ?vals_tl));@*/
283 * xLIST(l, len - 1, _, end, cons(end, cells_tl), cons(portMAX_DELAY, vals_tl)) &*&
284 * xLIST_ITEM(result, 42, _, _, NULL);@*/
286 /*@open xLIST(l, len, idx, end, cells, vals);@*/
287 ListItem_t * index = l->pxIndex;
289 /*@close xLIST(l, len, idx, end, cells, vals);@*/
290 /*@close exists(l);@*/
291 uxListRemove( index );
295 void client_example2( List_t * l )
298 * xLIST(l, ?len, ?idx, ?end, ?cells, ?vals) &*&
299 * cells == cons(end, cons(?x1, cons(?x2, ?cells_tl))) &*&
301 * vals == cons(portMAX_DELAY, cons(1, cons(2, ?vals_tl)));@*/
304 * xLIST(l, len-2, end, end, cons(end, cells_tl), cons(portMAX_DELAY, vals_tl)) &*&
305 * xLIST_ITEM(_, 1, _, _, NULL) &*&
306 * xLIST_ITEM(_, 2, _, _, NULL);@*/
308 /*@xLIST_distinct_cells(l);@*/
309 /*@open xLIST(l, len, idx, end, cells, vals);@*/
310 ListItem_t * index = l->pxIndex;
312 /*@close xLIST(l, len, idx, end, cells, vals);@*/
313 /*@close exists(l);@*/
314 uxListRemove( index );
315 /*@open xLIST(l, len-1, x1, end, cons(end, cons(x1, cells_tl)), cons(portMAX_DELAY, cons(1, vals_tl)));@*/
317 /*@close xLIST(l, len-1, x1, end, cons(end, cons(x1, cells_tl)), cons(portMAX_DELAY, cons(1, vals_tl)));@*/
318 /*@close exists(l);@*/
319 uxListRemove( index );