source: rtems/testsuites/sptests/spchain/init.c @ 0c286e3

5
Last change on this file since 0c286e3 was 0c286e3, checked in by Sebastian Huber <sebastian.huber@…>, on 10/25/17 at 14:00:17

score: _Chain_Insert_ordered_unprotected()

Change the chain order relation to use a directly specified left hand
side value. This is similar to _RBTree_Insert_inline() and helps the
compiler to better optimize the code.

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