source: rtems/testsuites/sptests/spwatchdog/init.c @ a48b7c44

Last change on this file since a48b7c44 was a48b7c44, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 20, 2015 at 8:47:12 PM

score: Fix watchdog removal

Under certain conditions a new watchdog was inserted with a wrong and
very large delta interval due to an incomplete iterator update.

Bug was introduced by 1ccbd052910ed16131c74b0d5595c8a94066942d.

Close #2501.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*  Init
2 *
3 *  This routine is the XXX.
4 *
5 *  Input parameters:
6 *    argument - task argument
7 *
8 *  Output parameters:  NONE
9 *
10 *  COPYRIGHT (c) 2008.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#define CONFIGURE_INIT
23#include "system.h"
24
25#include <rtems/score/watchdogimpl.h>
26
27const char rtems_test_name[] = "SPWATCHDOG";
28
29static void test_watchdog_routine( Objects_Id id, void *arg )
30{
31  (void) id;
32  (void) arg;
33
34  rtems_test_assert( 0 );
35}
36
37static void init_watchdogs(
38  Watchdog_Header *header,
39  Watchdog_Control watchdogs[4]
40)
41{
42  Watchdog_Control *a = &watchdogs[0];
43  Watchdog_Control *b = &watchdogs[1];
44  Watchdog_Control *c = &watchdogs[2];
45  Watchdog_Control *d = &watchdogs[3];
46
47  _Watchdog_Header_initialize( header );
48  rtems_test_assert( _Watchdog_Is_empty( header ) );
49  rtems_test_assert( _Chain_Is_empty( &header->Iterators ) );
50
51  _Watchdog_Preinitialize( c );
52  c->initial = 6;
53  _Watchdog_Insert( header, c );
54  rtems_test_assert( c->delta_interval == 6 );
55
56  rtems_test_assert( !_Watchdog_Is_empty( header ) );
57  rtems_test_assert( _Chain_Is_empty( &header->Iterators ) );
58
59  _Watchdog_Preinitialize( a );
60  a->initial = 2;
61  _Watchdog_Insert( header, a );
62  rtems_test_assert( a->delta_interval == 2 );
63  rtems_test_assert( c->delta_interval == 4 );
64
65  _Watchdog_Preinitialize( b );
66  b->initial = 4;
67  _Watchdog_Insert( header, b );
68  rtems_test_assert( a->delta_interval == 2 );
69  rtems_test_assert( b->delta_interval == 2 );
70  rtems_test_assert( c->delta_interval == 2 );
71
72  _Watchdog_Preinitialize( d );
73}
74
75static void destroy_watchdogs(
76  Watchdog_Header *header
77)
78{
79  _ISR_lock_Destroy( &header->Lock );
80}
81
82static void add_iterator(
83  Watchdog_Header *header,
84  Watchdog_Iterator *i,
85  Watchdog_Control *w
86)
87{
88  _Chain_Append_unprotected( &header->Iterators, &i->Node );
89  i->delta_interval = 2;
90  i->current = &w->Node;
91}
92
93static void test_watchdog_insert_and_remove( void )
94{
95  Watchdog_Header header;
96  Watchdog_Control watchdogs[4];
97  Watchdog_Control *a = &watchdogs[0];
98  Watchdog_Control *b = &watchdogs[1];
99  Watchdog_Control *c = &watchdogs[2];
100  Watchdog_Control *d = &watchdogs[3];
101  Watchdog_Iterator i;
102
103  init_watchdogs( &header, watchdogs );
104  add_iterator( &header, &i, c );
105
106  /* Remove next watchdog of iterator */
107  _Watchdog_Remove( &header, c );
108  rtems_test_assert( i.delta_interval == 4 );
109  rtems_test_assert( i.current == &b->Node );
110
111  /* Remove watchdog before the current watchdog of iterator */
112  _Watchdog_Remove( &header, a );
113  rtems_test_assert( i.delta_interval == 6 );
114  rtems_test_assert( i.current == &b->Node );
115
116  /* Remove current (= last) watchdog of iterator */
117  _Watchdog_Remove( &header, b );
118  rtems_test_assert( i.delta_interval == 6 );
119  rtems_test_assert( i.current == _Chain_Head( &header.Watchdogs ) );
120
121  /* Insert first watchdog */
122  a->initial = 1;
123  _Watchdog_Insert( &header, a );
124  rtems_test_assert( i.delta_interval == 6 );
125  rtems_test_assert( i.current == _Chain_Head( &header.Watchdogs ) );
126
127  destroy_watchdogs( &header );
128  init_watchdogs( &header, watchdogs );
129  add_iterator( &header, &i, b );
130
131  /* Insert right before current watchdog of iterator */
132  d->initial = 3;
133  _Watchdog_Insert( &header, d );
134  rtems_test_assert( i.delta_interval == 1 );
135  rtems_test_assert( i.current == &b->Node );
136
137  destroy_watchdogs( &header );
138  init_watchdogs( &header, watchdogs );
139  add_iterator( &header, &i, b );
140
141  /* Insert right after current watchdog of iterator */
142  d->initial = 5;
143  _Watchdog_Insert( &header, d );
144  rtems_test_assert( i.delta_interval == 2 );
145  rtems_test_assert( i.current == &b->Node );
146
147  destroy_watchdogs( &header );
148}
149
150static void init_watchdogs_remove_second_and_insert_first(
151  Watchdog_Header *header,
152  Watchdog_Control watchdogs[3]
153)
154{
155  Watchdog_Control *a = &watchdogs[0];
156  Watchdog_Control *b = &watchdogs[1];
157  Watchdog_Control *c = &watchdogs[2];
158
159  _Watchdog_Preinitialize( a );
160  _Watchdog_Preinitialize( b );
161  _Watchdog_Preinitialize( c );
162
163  _Watchdog_Header_initialize( header );
164
165  a->initial = 6;
166  _Watchdog_Insert( header, a );
167  rtems_test_assert( a->delta_interval == 6 );
168
169  b->initial = 8;
170  _Watchdog_Insert( header, b );
171  rtems_test_assert( a->delta_interval == 6 );
172  rtems_test_assert( b->delta_interval == 2 );
173}
174
175static void test_watchdog_remove_second_and_insert_first( void )
176{
177  Watchdog_Header header;
178  Watchdog_Control watchdogs[3];
179  Watchdog_Control *a = &watchdogs[0];
180  Watchdog_Control *b = &watchdogs[1];
181  Watchdog_Control *c = &watchdogs[2];
182  Watchdog_Iterator i;
183
184  init_watchdogs_remove_second_and_insert_first( &header, watchdogs );
185  add_iterator( &header, &i, b );
186
187  _Watchdog_Remove( &header, b );
188  rtems_test_assert( i.delta_interval == 8 );
189  rtems_test_assert( i.current == &a->Node );
190
191  c->initial = 4;
192  _Watchdog_Insert( &header, c );
193  rtems_test_assert( a->delta_interval == 2 );
194  rtems_test_assert( c->delta_interval == 4 );
195  rtems_test_assert( i.delta_interval == 4 );
196  rtems_test_assert( i.current == &a->Node );
197
198  destroy_watchdogs( &header );
199}
200
201static void test_watchdog_static_init( void )
202{
203  #if defined(RTEMS_USE_16_BIT_OBJECT)
204    #define JUNK_ID 0x1234
205  #else
206    #define JUNK_ID 0x12345678
207  #endif
208
209  static Watchdog_Control a = WATCHDOG_INITIALIZER(
210    test_watchdog_routine,
211    JUNK_ID,
212    (void *) 0xdeadbeef
213  );
214  Watchdog_Control b;
215
216  memset( &b, 0, sizeof( b ) );
217  _Watchdog_Initialize(
218    &b,
219    test_watchdog_routine,
220    JUNK_ID,
221    (void *) 0xdeadbeef
222  );
223
224  rtems_test_assert( memcmp( &a, &b, sizeof( a ) ) == 0 );
225}
226
227rtems_task Init(
228  rtems_task_argument argument
229)
230{
231  rtems_time_of_day  time;
232  rtems_status_code  status;
233
234  TEST_BEGIN();
235
236  test_watchdog_static_init();
237  test_watchdog_insert_and_remove();
238  test_watchdog_remove_second_and_insert_first();
239
240  build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
241
242  status = rtems_clock_set( &time );
243  directive_failed( status, "rtems_clock_set" );
244
245  Task_name[ 1 ]  = rtems_build_name( 'T', 'A', '1', ' ' );
246  Timer_name[ 1 ] = rtems_build_name( 'T', 'M', '1', ' ' );
247
248  status = rtems_task_create(
249    Task_name[ 1 ],
250    1,
251    RTEMS_MINIMUM_STACK_SIZE * 2,
252    RTEMS_DEFAULT_MODES,
253    RTEMS_DEFAULT_ATTRIBUTES,
254    &Task_id[ 1 ]
255  );
256  directive_failed( status, "rtems_task_create of TA1" );
257
258  status = rtems_task_start( Task_id[ 1 ], Task_1, 0 );
259  directive_failed( status, "rtems_task_start of TA1" );
260
261  puts( "INIT - rtems_timer_create - creating timer 1" );
262  status = rtems_timer_create( Timer_name[ 1 ], &Timer_id[ 1 ] );
263  directive_failed( status, "rtems_timer_create" );
264
265  printf( "INIT - timer 1 has id (0x%" PRIxrtems_id ")\n", Timer_id[ 1 ] );
266
267  status = rtems_task_delete( RTEMS_SELF );
268  directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
269
270
271  rtems_test_exit( 0 );
272}
Note: See TracBrowser for help on using the repository browser.