source: rtems/testsuites/sptests/sp42/init.c @ b679b492

Last change on this file since b679b492 was b679b492, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 23, 2016 at 7:09:55 AM

sptests/sp42: Relax priority requirements

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*
2 *  Exercise thread queue enqueue and dequeue priority
3 *
4 *  COPYRIGHT (c) 1989-2009.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.org/license/LICENSE.
10 */
11
12#ifdef HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16#include <stdio.h>
17#include <stdlib.h>
18
19#include <bsp.h>
20
21#include "tmacros.h"
22
23const char rtems_test_name[] = "SP 42";
24
25#define MAX_TASKS 20
26
27/*
28 * Carefully chosen to exercise threadq enqueue/dequeue priority logic.
29 * Somewhat randomly sorted to ensure than if discipline is FIFO, run-time
30 * behavior won't be the same when released.
31 */
32static const rtems_task_priority Priorities_High[MAX_TASKS] = {
33  37, 37, 37, 37,       /* backward - more 2-n */
34  2, 2, 2, 2,           /* forward - multiple are on 2-n chain */
35  4, 3,                 /* forward - search forward arbitrary */
36  3, 3, 3, 3,           /* forward - more 2-n */
37  38, 37,               /* backward - search backward arbitrary */
38  34, 34, 34, 34,       /* backward - multple on 2-n chain */
39};
40
41static const rtems_task_priority Priorities_Low[MAX_TASKS] = {
42  13, 13, 13, 13,       /* backward - more 2-n */
43  2, 2, 2, 2,           /* forward - multiple are on 2-n chain */
44  4, 3,                 /* forward - search forward arbitrary */
45  3, 3, 3, 3,           /* forward - more 2-n */
46  14, 13,               /* backward - search backward arbitrary */
47  12, 12, 12, 12,       /* backward - multple on 2-n chain */
48};
49
50static const int Obtain_order[2][MAX_TASKS] = {
51  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 },
52  { 4, 5, 6, 7, 9, 10, 11, 12, 13, 8, 16, 17, 18, 19, 0, 1, 2, 3, 15, 14 }
53};
54
55static const rtems_task_priority *Priorities;
56
57static rtems_id   Semaphore;
58static rtems_id   Master;
59static rtems_id   Task_id[ MAX_TASKS ];
60static rtems_name Task_name[ MAX_TASKS ];
61
62static rtems_task_argument Obtain_counter;
63
64static enum {
65 FIFO,
66 PRIORITY
67} Variant;
68
69static rtems_task Locker_task(
70  rtems_task_argument task_index
71)
72{
73  rtems_id            tid;
74  rtems_status_code   status;
75  rtems_task_argument my_obtain_counter;
76
77  status = rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &tid );
78  directive_failed( status, "rtems_task_ident" );
79
80  rtems_test_assert( task_index == task_number( tid ) - 1 );
81
82  status = rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 0 );
83  directive_failed( status, "rtems_semaphore_obtain" );
84
85  put_name( Task_name[ task_index ], FALSE );
86  puts( " - unblocked - OK" );
87
88  status = rtems_task_wake_after( 10 );
89  directive_failed( status, "rtems_task_wake_after" );
90
91  my_obtain_counter = Obtain_counter;
92  rtems_test_assert( task_index == Obtain_order[ Variant ][ Obtain_counter ] );
93  ++Obtain_counter;
94
95  status = rtems_semaphore_release( Semaphore );
96  directive_failed( status, "rtems_semaphore_release" );
97
98  if ( my_obtain_counter == MAX_TASKS - 1 ) {
99    status = rtems_event_transient_send( Master );
100    directive_failed( status, "rtems_event_transient_send" );
101  }
102
103  (void) rtems_task_delete( RTEMS_SELF );
104}
105
106static void do_test(
107  rtems_attribute attr,
108  bool            extract  /* TRUE if extract, not release */
109)
110{
111  rtems_status_code   status;
112  rtems_task_argument i;
113
114  Variant = ( ( attr & RTEMS_PRIORITY ) != 0 ? PRIORITY : FIFO );
115  Obtain_counter = 0;
116
117  status = rtems_semaphore_create(
118    rtems_build_name( 'S', 'E', 'M', '0' ),  /* name = SEM0 */
119    0,                                       /* locked */
120    RTEMS_BINARY_SEMAPHORE | attr,           /* mutex w/desired discipline */
121    0,                                       /* IGNORED */
122    &Semaphore
123  );
124  directive_failed( status, "rtems_semaphore_create" );
125
126  for (i = 0 ; i < MAX_TASKS ; i++ ) {
127    Task_name[ i ] = rtems_build_name(
128       'T',
129       'A',
130       '0' + (char)(i/10),
131       '0' + (char)(i%10)
132    );
133
134    status = rtems_task_create(
135      Task_name[ i ],
136      Priorities[ i ],
137      RTEMS_MINIMUM_STACK_SIZE,
138      RTEMS_DEFAULT_MODES,
139      RTEMS_DEFAULT_ATTRIBUTES,
140      &Task_id[ i ]
141    );
142    directive_failed( status, "rtems_task_create" );
143
144    status = rtems_task_start( Task_id[ i ], Locker_task, i );
145    directive_failed( status, "rtems_task_start" );
146  }
147
148  if ( extract ) {
149    for (i = 0 ; i< MAX_TASKS ; i++ ) {
150      status = rtems_task_delete( Task_id[ i ]  );
151      directive_failed( status, "rtems_task_delete" );
152    }
153  }
154
155  /* do the initial release */
156  status = rtems_semaphore_release( Semaphore );
157  directive_failed( status, "rtems_semaphore_release" );
158
159  if ( !extract ) {
160    status = rtems_event_transient_receive( RTEMS_WAIT, RTEMS_NO_TIMEOUT );
161    directive_failed( status, "rtems_event_transient_receive" );
162  }
163
164  /* now delete the semaphore since no one is waiting and it is unlocked */
165  status = rtems_semaphore_delete( Semaphore );
166  directive_failed( status, "rtems_semaphore_delete" );
167}
168
169static rtems_task Init(
170  rtems_task_argument argument
171)
172{
173  rtems_task_priority prio;
174  rtems_status_code status;
175
176  TEST_BEGIN();
177
178  Master = rtems_task_self();
179
180  if (RTEMS_MAXIMUM_PRIORITY >= 255)
181    Priorities = Priorities_High;
182  else if (RTEMS_MAXIMUM_PRIORITY >= 15)
183    Priorities = Priorities_Low;
184  else {
185    puts( "Test needs at least 16 configured priority levels" );
186    rtems_test_exit( 0 );
187  }
188
189  prio = RTEMS_MAXIMUM_PRIORITY - 1;
190  status = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
191  directive_failed( status, "rtems_task_set_priority" );
192
193  if ( sizeof(Priorities_Low) / sizeof(rtems_task_priority) != MAX_TASKS ) {
194    puts( "Priorities_Low table does not have right number of entries" );
195    rtems_test_exit( 0 );
196  }
197
198  if ( sizeof(Priorities_High) / sizeof(rtems_task_priority) != MAX_TASKS ) {
199    puts( "Priorities_High table does not have right number of entries" );
200    rtems_test_exit( 0 );
201  }
202
203  puts( "Exercising blocking discipline w/extract in FIFO order " );
204  do_test( RTEMS_FIFO, TRUE );
205
206  puts( "Exercising blocking discipline w/unblock in FIFO order" );
207  do_test( RTEMS_FIFO, FALSE );
208
209  rtems_test_pause_and_screen_number( 2 );
210
211  puts( "Exercising blocking discipline w/extract in priority order " );
212  do_test( RTEMS_PRIORITY, TRUE );
213
214  puts( "Exercising blocking discipline w/unblock in priority order" );
215  do_test( RTEMS_PRIORITY, FALSE );
216
217  TEST_END();
218  rtems_test_exit(0);
219}
220
221/**************** START OF CONFIGURATION INFORMATION ****************/
222
223#define CONFIGURE_INIT
224
225#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
226#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
227
228#define CONFIGURE_MAXIMUM_TASKS             MAX_TASKS+1
229#define CONFIGURE_MAXIMUM_SEMAPHORES        1
230
231#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
232
233#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
234
235#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
236
237#include <rtems/confdefs.h>
238
239/****************  END OF CONFIGURATION INFORMATION  ****************/
240
Note: See TracBrowser for help on using the repository browser.