source: rtems/testsuites/sptests/sp43/init.c @ 6c2b8a4b

5
Last change on this file since 6c2b8a4b was 6c2b8a4b, checked in by Sebastian Huber <sebastian.huber@…>, on 11/29/17 at 05:23:27

score: Use self-contained API mutex

Use a self-contained recursive mutex for API_Mutex_Control. The API
mutexes are protected against asynchronous thread cancellation.

Add dedicated mutexes for libatomic and TOD.

Close #2629.
Close #2630.

  • Property mode set to 100644
File size: 15.7 KB
Line 
1/*
2 *  Exercise Object Manager Services
3 *
4 *  COPYRIGHT (c) 1989-2011.
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#define CONFIGURE_INIT
17#include "system.h"
18
19#include <rtems/score/objectimpl.h>
20
21const char rtems_test_name[] = "SP 43";
22
23/* These functions have both macro and function incarnations */
24#undef rtems_build_id
25extern rtems_id rtems_build_id(int api,int class,int node,int index);
26#undef rtems_build_name
27extern rtems_name rtems_build_name(char C1,char C2,char C3,char C4);
28#undef rtems_object_id_api_maximum
29extern int rtems_object_id_api_maximum(void);
30#undef rtems_object_id_api_minimum
31extern int rtems_object_id_api_minimum(void);
32#undef rtems_object_id_get_api
33extern int rtems_object_id_get_api(rtems_id id);
34#undef rtems_object_id_get_class
35extern int rtems_object_id_get_class(rtems_id id);
36#undef rtems_object_id_get_index
37extern int rtems_object_id_get_index(rtems_id id);
38#undef rtems_object_id_get_node
39extern int rtems_object_id_get_node(rtems_id id);
40
41void print_class_info(
42  int                                 api,
43  int                                 class,
44  rtems_object_api_class_information *info
45);
46
47void change_name(
48  rtems_id    id,
49  const char *newName,
50  bool        printable
51);
52
53rtems_id         main_task;
54rtems_name       main_name;
55
56void print_class_info(
57  int                                 api,
58  int                                 class,
59  rtems_object_api_class_information *info
60)
61{
62  printf(
63    "%s API %s Information\n"
64    "    minimum id  : 0x%08" PRIxrtems_id
65      " maximum id: 0x%08" PRIxrtems_id "\n"
66    "    maximum     :    %7" PRIu32 " available : %" PRIu32 "\n"
67    "    auto_extend : %s\n",
68    rtems_object_get_api_name(api),
69    rtems_object_get_api_class_name(api, class),
70    info->minimum_id,
71    info->maximum_id,
72    info->maximum,
73    info->unallocated,
74    ((info->auto_extend) ? "yes" : "no")
75  );
76}
77
78void change_name(
79  rtems_id    id,
80  const char *newName,
81  bool        printable
82)
83{
84  rtems_status_code    sc;
85  char                 name[ 5 ];
86  char                *ptr;
87  const char          *c;
88
89  printf( "rtems_object_set_name - change name of init task to " );
90  if ( printable )
91    printf( "(%s)\n", newName );
92  else {
93    printf( "(" );
94    for (c=newName ; *c ; ) {
95       if (isprint((unsigned char)*c)) printf( "%c", *c );
96       else                            printf( "0x%02x", *c );
97       c++;
98       if ( *c )
99         printf( "-" );
100    }
101    printf( ")\n" );
102  }
103
104  sc = rtems_object_set_name( id, newName );
105  directive_failed( sc, "rtems_object_set_name" );
106
107  sc = rtems_object_get_classic_name( id, &main_name );
108  directive_failed( sc, "rtems_object_get_classic_name" );
109  put_name( main_name, FALSE );
110  puts( " - name returned by rtems_object_get_classic_name" );
111
112  ptr = rtems_object_get_name( id, 5, name );
113  rtems_test_assert(ptr != NULL);
114  printf( "rtems_object_get_name returned (%s) for init task\n", ptr );
115}
116
117rtems_task Init(
118  rtems_task_argument argument
119)
120{
121  rtems_status_code                   sc;
122  rtems_id                            tmpId;
123  rtems_name                          tmpName;
124  char                                name[5];
125  char                               *ptr;
126  const char                          newName[5] = "New1";
127  char                                tmpNameString[5];
128  int                                 part;
129  rtems_object_api_class_information  info;
130
131  TEST_BEGIN();
132
133  printf( "RTEMS Version: %s\n", rtems_get_version_string() );
134
135  main_task = rtems_task_self();
136
137  puts( "rtems_object_get_classic_name - INVALID_ADDRESS" );
138  sc = rtems_object_get_classic_name( main_task, NULL );
139  fatal_directive_status(
140    sc,
141    RTEMS_INVALID_ADDRESS,
142    "rtems_object_get_classic_name #1"
143  );
144
145  puts( "rtems_object_get_classic_name - INVALID_ID (bad index)" );
146  sc = rtems_object_get_classic_name( main_task + 5, &main_name );
147  fatal_directive_status(
148    sc,
149    RTEMS_INVALID_ID,
150    "rtems_object_get_classic_name #2"
151  );
152
153  puts( "rtems_object_get_classic_name - INVALID_ID (unallocated index)" );
154  sc = rtems_object_get_classic_name( main_task + 1, &main_name );
155  fatal_directive_status(
156    sc,
157    RTEMS_INVALID_ID,
158    "rtems_object_get_classic_name #4"
159  );
160
161  puts( "rtems_object_get_classic_name - INVALID_ID (bad API)" );
162  tmpId = rtems_build_id( 0xff, OBJECTS_RTEMS_TASKS, 1, 1 ),
163  sc = rtems_object_get_classic_name( tmpId, &main_name );
164  fatal_directive_status(
165    sc,
166    RTEMS_INVALID_ID,
167    "rtems_object_get_classic_name #5"
168  );
169
170  sc = rtems_object_get_classic_name( main_task, &main_name );
171  directive_failed( sc, "rtems_object_get_classic_name" );
172  put_name( main_name, FALSE );
173  puts( " - name returned by rtems_object_get_classic_name for Init task id" );
174
175  sc = rtems_object_get_classic_name( RTEMS_SELF, &main_name );
176  directive_failed( sc, "rtems_object_get_classic_name" );
177  put_name( main_name, FALSE );
178  puts( " - name returned by rtems_object_get_classic_name for RTEMS_SELF" );
179
180  tmpName = rtems_build_name( 'T', 'E', 'M', 'P' );
181  put_name( tmpName, FALSE );
182  puts( " - rtems_build_name for TEMP" );
183
184
185  /*
186   * rtems_object_get_name - cases
187   */
188  puts( "rtems_object_get_name - bad id for class with instances" );
189  ptr = rtems_object_get_name( main_task + 5, 5, name );
190  rtems_test_assert(ptr == NULL);
191
192  puts( "rtems_object_get_name - bad id for class without instances" );
193  ptr = rtems_object_get_name(
194    rtems_build_id( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_BARRIERS, 1, 1 ),
195    5,
196    name
197  );
198  rtems_test_assert(ptr == NULL);
199
200  puts( "rtems_object_get_name - bad length" );
201  ptr = rtems_object_get_name( main_task, 0, name );
202  rtems_test_assert(ptr == NULL);
203
204  puts( "rtems_object_get_name - bad pointer" );
205  ptr = rtems_object_get_name( main_task, 5, NULL );
206  rtems_test_assert(ptr == NULL);
207
208  ptr = rtems_object_get_name( main_task, 5, name );
209  rtems_test_assert(ptr != NULL);
210  printf( "rtems_object_get_name returned (%s) for init task id\n", ptr );
211
212  ptr = rtems_object_get_name( RTEMS_SELF, 5, name );
213  rtems_test_assert(ptr != NULL);
214  printf( "rtems_object_get_name returned (%s) for RTEMS_SELF\n", ptr );
215
216  /*
217   * rtems_object_set_name - errors
218   */
219
220  puts( "rtems_object_set_name - INVALID_ADDRESS" );
221  sc = rtems_object_set_name( tmpId, NULL );
222  fatal_directive_status(
223    sc,
224    RTEMS_INVALID_ADDRESS,
225    "rtems_object_set_name INVALID_ADDRESS"
226  );
227
228  puts( "rtems_object_set_name - INVALID_ID (bad API)" );
229  tmpId = rtems_build_id( 0xff, OBJECTS_RTEMS_TASKS, 1, 1 ),
230  sc = rtems_object_set_name( tmpId, newName );
231  fatal_directive_status(
232    sc,
233    RTEMS_INVALID_ID,
234    "rtems_object_set_name #1"
235  );
236
237  puts( "rtems_object_set_name - INVALID_ID (bad index)" );
238  sc = rtems_object_set_name( main_task + 10, newName );
239  fatal_directive_status(
240    sc,
241    RTEMS_INVALID_ID,
242    "rtems_object_set_name #2"
243  );
244
245  /*
246   * rtems_object_set_name - change name of init task in various ways.
247   *
248   * This is strange but pushes the SuperCore code to do different things.
249   */
250
251  change_name( main_task,  "New1", TRUE );
252  change_name( main_task, "Ne1", TRUE );
253  change_name( main_task, "N1", TRUE );
254  change_name( main_task, "N", TRUE );
255  change_name( main_task, "", TRUE );
256  tmpNameString[0] = 'N';
257  tmpNameString[1] = 0x07;
258  tmpNameString[2] = 0x09;
259  tmpNameString[3] = '1';
260  tmpNameString[4] = '\0';
261  change_name( main_task, tmpNameString, FALSE );
262
263  /*
264   * Change object name using SELF ID
265   */
266
267  change_name( RTEMS_SELF,  "SELF", TRUE );
268
269  ptr = rtems_object_get_name( main_task, 5, name );
270  rtems_test_assert(ptr != NULL);
271  printf( "rtems_object_get_name returned (%s) for init task id\n", ptr );
272
273
274  /*
275   * Exercise id build and extraction routines
276   */
277
278  puts( "rtems_build_id - build an id to match init task" );
279  tmpId = rtems_build_id( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS, 1, 1 );
280  rtems_test_assert( tmpId == main_task );
281
282  puts( "rtems_object_id_get_api - OK" );
283  part = rtems_object_id_get_api( main_task );
284  rtems_test_assert( part == OBJECTS_CLASSIC_API );
285
286  puts( "rtems_object_id_get_class - OK" );
287  part = rtems_object_id_get_class( main_task );
288  rtems_test_assert( part == OBJECTS_RTEMS_TASKS );
289
290  puts( "rtems_object_id_get_node - OK" );
291  part = rtems_object_id_get_node( main_task );
292  rtems_test_assert( part == 1 );
293
294  puts( "rtems_object_id_get_index - OK" );
295  part = rtems_object_id_get_index( main_task );
296  rtems_test_assert( part == 1 );
297
298  /*
299   * Start another screen and do the API/Class min/max routines
300   */
301  rtems_test_pause();
302
303  printf( "rtems_object_id_api_minimum returned %d\n",
304          rtems_object_id_api_minimum() );
305  printf( "rtems_object_id_api_maximum returned %d\n",
306          rtems_object_id_api_maximum() );
307
308  printf( "rtems_object_api_minimum_class(0) returned %d\n",
309          rtems_object_api_minimum_class(0) );
310  printf( "rtems_object_api_maximum_class(0) returned %d\n",
311          rtems_object_api_maximum_class(0) );
312
313  printf( "rtems_object_api_minimum_class(0) returned %d\n",
314          rtems_object_api_minimum_class(0) );
315  printf( "rtems_object_api_maximum_class(0) returned %d\n",
316          rtems_object_api_maximum_class(0) );
317  printf( "rtems_object_api_minimum_class(255) returned %d\n",
318          rtems_object_api_minimum_class(255) );
319  printf( "rtems_object_api_maximum_class(255) returned %d\n",
320          rtems_object_api_maximum_class(255) );
321
322  printf( "rtems_object_api_minimum_class(OBJECTS_INTERNAL_API) returned %d\n",
323          rtems_object_api_minimum_class(OBJECTS_INTERNAL_API) );
324  printf( "rtems_object_api_maximum_class(OBJECTS_INTERNAL_API) returned %d\n",
325          rtems_object_api_maximum_class(OBJECTS_INTERNAL_API) );
326
327  printf( "rtems_object_api_minimum_class(OBJECTS_CLASSIC_API) returned %d\n",
328          rtems_object_api_minimum_class(OBJECTS_CLASSIC_API) );
329  printf( "rtems_object_api_maximum_class(OBJECTS_CLASSIC_API) returned %d\n",
330          rtems_object_api_maximum_class(OBJECTS_CLASSIC_API) );
331
332  /*
333   *  Another screen break for the API and class name tests
334   */
335  rtems_test_pause();
336
337  printf( "rtems_object_get_api_name(0) = %s\n", rtems_object_get_api_name(0) );
338  printf( "rtems_object_get_api_name(255) = %s\n",
339    rtems_object_get_api_name(255));
340
341  printf( "rtems_object_get_api_name(INTERNAL_API) = %s\n",
342     rtems_object_get_api_name(OBJECTS_INTERNAL_API) );
343  printf( "rtems_object_get_api_name(CLASSIC_API) = %s\n",
344     rtems_object_get_api_name(OBJECTS_CLASSIC_API) );
345
346  printf( "rtems_object_get_api_class_name(0, RTEMS_TASKS) = %s\n",
347    rtems_object_get_api_class_name( 0, OBJECTS_RTEMS_TASKS ) );
348  printf( "rtems_object_get_api_class_name(CLASSIC_API, 0) = %s\n",
349    rtems_object_get_api_class_name( OBJECTS_CLASSIC_API, 0 ) );
350  printf("rtems_object_get_api_class_name(INTERNAL_API, THREADS) = %s\n",
351    rtems_object_get_api_class_name(
352       OBJECTS_INTERNAL_API, OBJECTS_INTERNAL_THREADS));
353  printf("rtems_object_get_api_class_name(CLASSIC_API, RTEMS_BARRIERS) = %s\n",
354    rtems_object_get_api_class_name(
355       OBJECTS_CLASSIC_API, OBJECTS_RTEMS_BARRIERS));
356
357  /*
358   *  Another screen break for the information
359   */
360
361  rtems_test_pause();
362
363  puts( "rtems_object_get_class_information - INVALID_ADDRESS" );
364  sc = rtems_object_get_class_information(
365             OBJECTS_INTERNAL_API, OBJECTS_INTERNAL_THREADS, NULL );
366  fatal_directive_status(
367    sc,
368    RTEMS_INVALID_ADDRESS,
369    "rtems_object_get_class_information"
370  );
371
372  puts( "rtems_object_get_class_information - INVALID_NUMBER (bad API)" );
373  sc =
374    rtems_object_get_class_information(0, OBJECTS_INTERNAL_THREADS, &info);
375  fatal_directive_status(
376    sc,
377    RTEMS_INVALID_NUMBER,
378    "rtems_object_get_class_information (API)"
379  );
380
381  puts( "rtems_object_get_class_information - INVALID_NUMBER (api=0xff)" );
382  sc = rtems_object_get_class_information( 0xff, 1, &info );
383  fatal_directive_status(
384    sc,
385    RTEMS_INVALID_NUMBER,
386    "rtems_object_get_class_information (api=0xff)"
387  );
388
389  puts( "rtems_object_get_class_information - INVALID_NUMBER (class=0)" );
390  sc = rtems_object_get_class_information(
391    OBJECTS_INTERNAL_API, 0, &info );
392  fatal_directive_status(
393    sc,
394    RTEMS_INVALID_NUMBER,
395    "rtems_object_get_class_information (class=0)"
396  );
397
398  puts(
399    "rtems_object_get_class_information - INVALID_NUMBER (class too high)" );
400  sc = rtems_object_get_class_information(
401    OBJECTS_INTERNAL_API, 0xff, &info);
402  fatal_directive_status(
403    sc,
404    RTEMS_INVALID_NUMBER,
405    "rtems_object_get_class_information (class #2)"
406  );
407
408  puts( "rtems_object_get_class_information - Classic Tasks - OK" );
409  sc = rtems_object_get_class_information(
410             OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS, &info );
411  directive_failed( sc, "rtems_object_get_class_information" );
412  print_class_info( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS, &info );
413
414  puts( "rtems_object_get_class_information - Classic Timers - OK" );
415  sc = rtems_timer_create(0, NULL);
416  fatal_directive_status(
417    sc,
418    RTEMS_INVALID_NAME,
419    "rtems_timer_create"
420  );
421  sc = rtems_object_get_class_information(
422             OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TIMERS, &info );
423  directive_failed( sc, "rtems_object_get_class_information" );
424  print_class_info( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TIMERS, &info );
425
426  /*
427   *  Ugly hack to force a weird error.
428   *
429   *  The weird case is that we need to look up a thread Id where the
430   *  thread classes' object information table pointer is NULL.  Probably
431   *  impossible to really hit until registration is completely dynamically
432   *  configurable.
433   */
434  {
435    rtems_task_priority              old_priority;
436    void                            *tmp;
437    int                              class;
438    int                              api;
439
440    class = OBJECTS_INTERNAL_API;
441    api   = OBJECTS_INTERNAL_THREADS;
442
443    puts( "rtems_task_set_priority - use valid Idle thread id" );
444    sc = rtems_task_set_priority(
445      rtems_build_id( class, api, 1, 1 ),
446      RTEMS_CURRENT_PRIORITY,
447      &old_priority
448    );
449    directive_failed( sc, "rtems_task_set_priority" );
450
451    /* destroy internal API thread class pointer */
452    puts( "rtems_task_set_priority - clobber internal thread class info" );
453    tmp = _Objects_Information_table[ api ][ class ];
454    _Objects_Information_table[ api ][ class ] = NULL;
455
456    puts( "rtems_task_set_priority - use valid Idle thread id again" );
457    sc = rtems_task_set_priority(
458      rtems_build_id( class, api, 1, 1 ),
459      RTEMS_CURRENT_PRIORITY,
460      &old_priority
461    );
462    fatal_directive_status( sc, RTEMS_INVALID_ID, "rtems_task_set_priority" );
463
464    puts( "rtems_task_set_priority - use valid Idle thread id again" );
465    sc = rtems_task_set_priority(
466      rtems_build_id( class, api, 1, 1 ),
467      RTEMS_CURRENT_PRIORITY,
468      &old_priority
469    );
470    fatal_directive_status( sc, RTEMS_INVALID_ID, "rtems_task_set_priority" );
471
472    /* restore pointer */
473    puts( "rtems_task_set_priority - restore internal thread class info" );
474    _Objects_Information_table[ api ][ class ] = tmp;
475  }
476
477  /*
478   *  Bad Id on an object which disables interrupts as part of translating
479   *  the Id into an object pointer.  Semaphore is the only object that
480   *  needs this. This is a "good" Id in that is it in range, but bad in
481   *  that it has not been allocated so the local_table pointer is NULL.
482   */
483  puts( "rtems_semaphore_obtain - good but uncreated ID - INVALID_ID - OK" );
484  sc = rtems_semaphore_obtain(
485    rtems_build_id(
486      OBJECTS_CLASSIC_API,
487      OBJECTS_RTEMS_SEMAPHORES,
488      1,
489      rtems_configuration_get_maximum_semaphores()
490    ),
491    RTEMS_DEFAULT_OPTIONS,
492    0
493  );
494  fatal_directive_status( sc, RTEMS_INVALID_ID, "rtems_semaphore_obtain" );
495
496  TEST_END();
497  rtems_test_exit( 0 );
498}
Note: See TracBrowser for help on using the repository browser.