source: rtems/testsuites/sptests/spchain/init.c @ 059529e

Last change on this file since 059529e was 059529e, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 21, 2016 at 8:15:02 AM

score: Add debug support to chains

This helps to detect

  • double insert, append, prepend errors, and
  • get from empty chain errors.
  • Property mode set to 100644
File size: 15.2 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2012.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include <tmacros.h>
15#include <rtems/chain.h>
16
17const char rtems_test_name[] = "SPCHAIN";
18
19static void update_registry_and_extract(
20  Chain_Iterator_registry *reg,
21  Chain_Node *n
22)
23{
24  _Chain_Iterator_registry_update( reg, n );
25  _Chain_Extract_unprotected( n );
26}
27
28static Chain_Iterator_registry static_reg =
29  CHAIN_ITERATOR_REGISTRY_INITIALIZER( static_reg );
30
31static void test_chain_iterator( void )
32{
33  Chain_Control chain;
34  Chain_Iterator_registry reg;
35  Chain_Iterator fit;
36  Chain_Iterator bit;
37  Chain_Node a;
38  Chain_Node b;
39  Chain_Node c;
40
41  puts( "INIT - Verify Chain_Iterator" );
42
43  rtems_test_assert( _Chain_Is_empty( &static_reg.Iterators ));
44
45  _Chain_Initialize_empty( &chain );
46  _Chain_Initialize_node( &a );
47  _Chain_Initialize_node( &b );
48  _Chain_Initialize_node( &c );
49  _Chain_Iterator_registry_initialize( &reg );
50  _Chain_Iterator_initialize( &chain, &reg, &fit, CHAIN_ITERATOR_FORWARD );
51  _Chain_Iterator_initialize( &chain, &reg, &bit, CHAIN_ITERATOR_BACKWARD );
52
53  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
54  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));
55
56  _Chain_Iterator_set_position( &fit, _Chain_Head( &chain ) );
57  _Chain_Iterator_set_position( &bit, _Chain_Tail( &chain ) );
58  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
59  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));
60
61  _Chain_Append_unprotected( &chain, &a );
62  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
63  rtems_test_assert( _Chain_Iterator_next( &bit ) == &a );
64
65  _Chain_Append_unprotected( &chain, &b );
66  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
67  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );
68
69  _Chain_Append_unprotected( &chain, &c );
70  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
71  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
72
73  update_registry_and_extract( &reg, &b );
74  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
75  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
76
77  _Chain_Insert_unprotected( &a, &b );
78  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
79  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
80
81  update_registry_and_extract( &reg, &c );
82  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
83  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );
84
85  _Chain_Append_unprotected( &chain, &c );
86  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
87  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
88
89  update_registry_and_extract( &reg, &a );
90  rtems_test_assert( _Chain_Iterator_next( &fit ) == &b );
91  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
92
93  _Chain_Prepend_unprotected( &chain, &a );
94  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
95  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
96
97  update_registry_and_extract( &reg, &a );
98  rtems_test_assert( _Chain_Iterator_next( &fit ) == &b );
99  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
100
101  update_registry_and_extract( &reg, &b );
102  rtems_test_assert( _Chain_Iterator_next( &fit ) == &c );
103  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
104
105  update_registry_and_extract( &reg, &c );
106  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
107  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));
108
109  _Chain_Append_unprotected( &chain, &a );
110  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
111  rtems_test_assert( _Chain_Iterator_next( &bit ) == &a );
112
113  _Chain_Append_unprotected( &chain, &b );
114  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
115  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );
116
117  _Chain_Append_unprotected( &chain, &c );
118  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
119  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );
120
121  update_registry_and_extract( &reg, &c );
122  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
123  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );
124
125  update_registry_and_extract( &reg, &b );
126  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
127  rtems_test_assert( _Chain_Iterator_next( &bit ) == &a );
128
129  update_registry_and_extract( &reg, &a );
130  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
131  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));
132
133  rtems_test_assert( !_Chain_Is_empty( &reg.Iterators ));
134  _Chain_Iterator_destroy( &fit );
135  rtems_test_assert( !_Chain_Is_empty( &reg.Iterators ));
136  _Chain_Iterator_destroy( &bit );
137  rtems_test_assert( _Chain_Is_empty( &reg.Iterators ));
138}
139
140/* forward declarations to avoid warnings */
141rtems_task Init(rtems_task_argument argument);
142
143#define EVENT RTEMS_EVENT_13
144#define TIMEOUT 1
145
146typedef struct {
147  rtems_chain_node Node;
148  int              id;
149} test_node;
150
151static rtems_chain_control one_node_chain;
152
153static rtems_chain_node node_of_one_node_chain =
154  RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( &one_node_chain );
155
156static rtems_chain_control one_node_chain =
157  RTEMS_CHAIN_INITIALIZER_ONE_NODE( &node_of_one_node_chain );
158
159static void test_chain_control_initializer(void)
160{
161  rtems_chain_control chain = RTEMS_CHAIN_INITIALIZER_EMPTY( chain );
162
163  puts( "INIT - Verify rtems_chain_control initializer" );
164
165  rtems_test_assert( rtems_chain_is_empty( &chain ) );
166
167  rtems_test_assert( rtems_chain_has_only_one_node( &one_node_chain ) );
168  rtems_test_assert(
169    rtems_chain_immutable_first( &one_node_chain ) == &node_of_one_node_chain
170  );
171  rtems_test_assert(
172    rtems_chain_immutable_last( &one_node_chain ) == &node_of_one_node_chain
173  );
174  rtems_test_assert(
175    rtems_chain_immutable_head( &one_node_chain )
176      == rtems_chain_immutable_previous( &node_of_one_node_chain )
177  );
178  rtems_test_assert(
179    rtems_chain_immutable_tail( &one_node_chain )
180      == rtems_chain_immutable_next( &node_of_one_node_chain )
181  );
182}
183
184static void test_chain_control_layout(void)
185{
186  Chain_Control chain;
187
188  puts( "INIT - Verify rtems_chain_control layout" );
189
190  rtems_test_assert(
191    sizeof(Chain_Control)
192      == sizeof(Chain_Node) + sizeof(Chain_Node *)
193  );
194  rtems_test_assert(
195    sizeof(Chain_Control)
196      == 3 * sizeof(Chain_Node *)
197  );
198  rtems_test_assert(
199    _Chain_Previous( _Chain_Head( &chain ) )
200      == _Chain_Next( _Chain_Tail( &chain ) )
201  );
202
203#if !defined( RTEMS_SMP )
204  rtems_test_assert(
205    sizeof(Chain_Control)
206      == sizeof(rtems_chain_control)
207  );
208#endif
209}
210
211static void test_chain_get_with_wait(void)
212{
213  rtems_status_code sc = RTEMS_SUCCESSFUL;
214  rtems_chain_control chain;
215  rtems_chain_node *p = (rtems_chain_node *) 1;
216
217  puts( "INIT - Verify rtems_chain_get_with_wait" );
218  rtems_chain_initialize_empty( &chain );
219  sc = rtems_chain_get_with_wait( &chain, EVENT, TIMEOUT, &p );
220  rtems_test_assert( sc == RTEMS_TIMEOUT );
221  rtems_test_assert( p == NULL );
222}
223
224static void test_chain_first_and_last(void)
225{
226  rtems_chain_control   chain;
227  rtems_chain_node      node1, node2;
228  rtems_chain_node     *cnode;
229
230  rtems_chain_initialize_empty( &chain );
231  rtems_chain_initialize_node( &node1 );
232  rtems_chain_initialize_node( &node2 );
233  rtems_chain_append( &chain, &node1 );
234  rtems_chain_insert( &node1, &node2 );
235
236  puts( "INIT - Verify rtems_chain_is_first" );
237  cnode = rtems_chain_first(&chain); 
238  rtems_test_assert( rtems_chain_is_first( cnode ) );
239
240  puts( "INIT - Verify rtems_chain_is_last" );
241  cnode = rtems_chain_last(&chain);
242  rtems_test_assert( rtems_chain_is_last( cnode ) );
243
244  cnode = rtems_chain_get_first_unprotected( &chain );
245  rtems_test_assert( cnode == &node1 );
246  cnode = rtems_chain_first( &chain );
247  rtems_test_assert( cnode == &node2 );
248  cnode = rtems_chain_last( &chain );
249  rtems_test_assert( cnode == &node2 );
250}
251
252static void test_chain_with_notification(void)
253{
254  rtems_status_code sc = RTEMS_SUCCESSFUL;
255  rtems_chain_control chain;
256  rtems_chain_node a;
257  rtems_chain_node b;
258  rtems_chain_node *p = (rtems_chain_node *) 1;
259  rtems_event_set out = 0;
260
261  puts( "INIT - Verify rtems_chain_append_with_notification" );
262  rtems_chain_initialize_empty( &chain );
263  rtems_chain_initialize_node( &a );
264  sc = rtems_chain_append_with_notification(
265    &chain,
266    &a,
267    rtems_task_self(),
268    EVENT
269  );
270  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
271  sc = rtems_chain_get_with_wait( &chain, EVENT, TIMEOUT, &p );
272  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
273  rtems_test_assert( p == &a );
274
275  rtems_chain_initialize_empty( &chain );
276  rtems_chain_initialize_node( &a );
277  rtems_chain_initialize_node( &b );
278
279  rtems_chain_append( &chain, &b );
280  sc = rtems_chain_append_with_notification(
281    &chain,
282    &a,
283    rtems_task_self(),
284    EVENT
285  );
286  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
287  rtems_test_assert( p == &a );
288
289  puts( "INIT - Verify rtems_chain_prepend_with_notification" );
290  rtems_chain_initialize_empty( &chain );
291  rtems_chain_initialize_node( &a );
292  rtems_chain_initialize_node( &b );
293  sc = rtems_chain_prepend_with_notification(
294    &chain,
295    &a,
296    rtems_task_self(),
297    EVENT
298  );
299  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
300  sc = rtems_chain_get_with_wait( &chain, EVENT, TIMEOUT, &p );
301  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
302  rtems_test_assert( p == &a );
303
304  rtems_chain_prepend( &chain, &b );
305  sc = rtems_chain_prepend_with_notification(
306    &chain,
307    &a,
308    rtems_task_self(),
309    EVENT
310  );
311  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
312  rtems_test_assert( p == &a );
313
314  puts( "INIT - Verify rtems_chain_get_with_notification" );
315  rtems_chain_initialize_empty( &chain );
316  rtems_chain_initialize_node( &a );
317  rtems_chain_initialize_node( &b );
318
319  rtems_chain_append( &chain, &b );
320  rtems_chain_append( &chain, &a );
321
322  sc = rtems_chain_get_with_notification(&chain, rtems_task_self(), EVENT, &p);
323  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
324  rtems_test_assert( p == &b );
325
326  sc = rtems_chain_get_with_notification(&chain, rtems_task_self(), EVENT, &p);
327  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
328  rtems_test_assert( p == &a );
329  sc = rtems_event_receive(
330    EVENT,
331    RTEMS_EVENT_ALL | RTEMS_WAIT,
332    TIMEOUT,
333    &out
334  );
335  rtems_test_assert( sc == RTEMS_SUCCESSFUL );
336  rtems_test_assert( out == EVENT );
337}
338
339static void test_chain_with_empty_check(void)
340{
341  rtems_chain_control chain;
342  rtems_chain_node a;
343  rtems_chain_node b;
344  rtems_chain_node c;
345  rtems_chain_node *p;
346  bool empty;
347
348  puts( "INIT - Verify rtems_chain_append_with_empty_check" );
349  rtems_chain_initialize_empty( &chain );
350  rtems_chain_initialize_node( &a );
351  rtems_chain_initialize_node( &b );
352  empty = rtems_chain_append_with_empty_check( &chain, &a );
353  rtems_test_assert( empty );
354  empty = rtems_chain_append_with_empty_check( &chain, &b );
355  rtems_test_assert( !empty );
356
357  puts( "INIT - Verify rtems_chain_prepend_with_empty_check" );
358  rtems_chain_initialize_empty( &chain );
359  rtems_chain_initialize_node( &a );
360  rtems_chain_initialize_node( &b );
361  rtems_chain_initialize_node( &c );
362  empty = rtems_chain_prepend_with_empty_check( &chain, &a );
363  rtems_test_assert( empty );
364  empty = rtems_chain_prepend_with_empty_check( &chain, &b );
365  rtems_test_assert( !empty );
366  empty = rtems_chain_prepend_with_empty_check( &chain, &c );
367  rtems_test_assert( !empty );
368
369  puts( "INIT - Verify rtems_chain_get_with_empty_check" );
370  rtems_chain_initialize_empty( &chain );
371  rtems_chain_initialize_node( &a );
372  rtems_chain_initialize_node( &b );
373  empty = rtems_chain_get_with_empty_check( &chain, &p );
374  rtems_test_assert( empty );
375
376  rtems_chain_append( &chain, &a );
377  rtems_chain_append( &chain, &b );
378  empty = rtems_chain_get_with_empty_check( &chain, &p );
379  rtems_test_assert( !empty );
380  rtems_test_assert( p == &a );
381  empty = rtems_chain_get_with_empty_check( &chain, &p );
382  rtems_test_assert( empty );
383  rtems_test_assert( p == &b );
384}
385
386static void test_chain_node_count(void)
387{
388  rtems_chain_control chain;
389  rtems_chain_node nodes[3];
390  size_t count;
391  size_t i;
392
393  puts( "INIT - Verify rtems_chain_node_count_unprotected" );
394
395  rtems_chain_initialize_empty( &chain );
396  count = rtems_chain_node_count_unprotected( &chain );
397  rtems_test_assert( count == 0 );
398
399  for (i = 0; i < RTEMS_ARRAY_SIZE( nodes ); ++i) {
400    rtems_chain_initialize_node( &nodes[ i ] );
401    rtems_chain_append_unprotected( &chain, &nodes[i] );
402    count = rtems_chain_node_count_unprotected( &chain );
403    rtems_test_assert( count == i + 1 );
404  }
405}
406
407static bool test_order( const Chain_Node *left, const Chain_Node *right )
408{
409  return left < right;
410}
411
412static void test_chain_insert_ordered( void )
413{
414  Chain_Control chain = CHAIN_INITIALIZER_EMPTY(chain);
415  Chain_Node nodes[5];
416  const Chain_Node *tail;
417  const Chain_Node *node;
418  size_t n = RTEMS_ARRAY_SIZE( nodes );
419  size_t i;
420
421  puts( "INIT - Verify _Chain_Insert_ordered_unprotected" );
422
423  for ( i = 0; i < n; ++i ) {
424    _Chain_Initialize_node( &nodes[ i ] );
425  }
426
427  _Chain_Insert_ordered_unprotected( &chain, &nodes[4], test_order );
428  _Chain_Insert_ordered_unprotected( &chain, &nodes[2], test_order );
429  _Chain_Insert_ordered_unprotected( &chain, &nodes[0], test_order );
430  _Chain_Insert_ordered_unprotected( &chain, &nodes[3], test_order );
431  _Chain_Insert_ordered_unprotected( &chain, &nodes[1], test_order );
432
433  tail = _Chain_Immutable_tail( &chain );
434  node = _Chain_Immutable_first( &chain );
435  i = 0;
436  while ( node != tail && i < n ) {
437    rtems_test_assert( node == &nodes[ i ] );
438    ++i;
439    node = _Chain_Immutable_next( node );
440  }
441
442  rtems_test_assert( i == n );
443}
444
445rtems_task Init(
446  rtems_task_argument ignored
447)
448{
449  rtems_chain_control  chain1;
450  rtems_chain_node    *p;
451  test_node            node1, node2;
452  int                  id;
453
454  TEST_BEGIN();
455
456  puts( "Init - Initialize chain empty" );
457  rtems_chain_initialize_empty( &chain1 );
458  rtems_chain_initialize_node( &node1.Node );
459  rtems_chain_initialize_node( &node2.Node );
460
461  /* verify that the chain append and insert work */
462  puts( "INIT - Verify rtems_chain_insert" );
463  node1.id = 1;
464  node2.id = 2;
465  rtems_chain_append( &chain1, &node1.Node );
466  rtems_chain_insert( &node1.Node, &node2.Node );
467
468  for ( p = rtems_chain_first(&chain1), id = 1 ;
469        !rtems_chain_is_tail(&chain1, p) ;
470        p = p->next , id++ ) {
471     test_node *t = (test_node *)p;
472     if ( id > 2 ) {
473       puts( "INIT - TOO MANY NODES ON CHAIN" );
474       rtems_test_exit(0);
475     }
476     if ( t->id != id ) {
477       puts( "INIT - ERROR ON CHAIN ID MISMATCH" );
478       rtems_test_exit(0);
479     }
480  }
481
482  test_chain_first_and_last();
483  test_chain_with_empty_check();
484  test_chain_with_notification();
485  test_chain_get_with_wait();
486  test_chain_control_layout();
487  test_chain_control_initializer();
488  test_chain_node_count();
489  test_chain_insert_ordered();
490  test_chain_iterator();
491
492  TEST_END();
493  rtems_test_exit(0);
494}
495
496/* configuration information */
497
498#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
499#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
500
501#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
502
503#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
504#define CONFIGURE_MAXIMUM_TASKS 1
505
506#define CONFIGURE_INIT
507#include <rtems/confdefs.h>
508
509/* global variables */
Note: See TracBrowser for help on using the repository browser.