Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:45

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  Exercise Object Manager Services
0005  *
0006  *  COPYRIGHT (c) 1989-2011.
0007  *  On-Line Applications Research Corporation (OAR).
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034 
0035 #define CONFIGURE_INIT
0036 #include "system.h"
0037 
0038 #include <rtems/score/objectimpl.h>
0039 
0040 const char rtems_test_name[] = "SP 43";
0041 
0042 /* These functions have both macro and function incarnations */
0043 #undef rtems_build_id
0044 #undef rtems_build_name
0045 #undef rtems_object_id_api_maximum
0046 #undef rtems_object_id_api_minimum
0047 #undef rtems_object_id_get_api
0048 #undef rtems_object_id_get_class
0049 #undef rtems_object_id_get_index
0050 #undef rtems_object_id_get_node
0051 
0052 void print_class_info(
0053   int                                 api,
0054   int                                 class,
0055   rtems_object_api_class_information *info
0056 );
0057 
0058 void change_name(
0059   rtems_id    id,
0060   const char *newName,
0061   bool        printable
0062 );
0063 
0064 rtems_id         main_task;
0065 rtems_name       main_name;
0066 
0067 void print_class_info(
0068   int                                 api,
0069   int                                 class,
0070   rtems_object_api_class_information *info
0071 )
0072 {
0073   printf(
0074     "%s API %s Information\n"
0075     "    minimum id  : 0x%08" PRIxrtems_id
0076       " maximum id: 0x%08" PRIxrtems_id "\n"
0077     "    maximum     :    %7" PRIu32 " available : %" PRIu32 "\n"
0078     "    auto_extend : %s\n",
0079     rtems_object_get_api_name(api),
0080     rtems_object_get_api_class_name(api, class),
0081     info->minimum_id,
0082     info->maximum_id,
0083     info->maximum,
0084     info->unallocated,
0085     ((info->auto_extend) ? "yes" : "no")
0086   );
0087 }
0088 
0089 void change_name(
0090   rtems_id    id,
0091   const char *newName,
0092   bool        printable
0093 )
0094 {
0095   rtems_status_code    sc;
0096   char                 name[ 5 ];
0097   char                *ptr;
0098   const char          *c;
0099 
0100   printf( "rtems_object_set_name - change name of init task to " );
0101   if ( printable )
0102     printf( "(%s)\n", newName );
0103   else {
0104     printf( "(" );
0105     for (c=newName ; *c ; ) {
0106        if (isprint((unsigned char)*c)) printf( "%c", *c );
0107        else                            printf( "0x%02x", *c );
0108        c++;
0109        if ( *c )
0110          printf( "-" );
0111     }
0112     printf( ")\n" );
0113   }
0114 
0115   sc = rtems_object_set_name( id, newName );
0116   directive_failed( sc, "rtems_object_set_name" );
0117 
0118   sc = rtems_object_get_classic_name( id, &main_name );
0119   directive_failed( sc, "rtems_object_get_classic_name" );
0120   put_name( main_name, FALSE );
0121   puts( " - name returned by rtems_object_get_classic_name" );
0122 
0123   ptr = rtems_object_get_name( id, 5, name );
0124   rtems_test_assert(ptr != NULL);
0125   printf( "rtems_object_get_name returned (%s) for init task\n", ptr );
0126 }
0127 
0128 rtems_task Init(
0129   rtems_task_argument argument
0130 )
0131 {
0132   rtems_status_code                   sc;
0133   rtems_id                            tmpId;
0134   rtems_name                          tmpName;
0135   char                                name[5];
0136   char                               *ptr;
0137   const char                          newName[5] = "New1";
0138   char                                tmpNameString[5];
0139   int                                 part;
0140   rtems_object_api_class_information  info;
0141 
0142   TEST_BEGIN();
0143 
0144   printf( "RTEMS Version: %s\n", rtems_get_version_string() );
0145   printf( "RTEMS Copyright Notice: %s\n", rtems_get_copyright_notice() );
0146 
0147   main_task = rtems_task_self();
0148 
0149   puts( "rtems_object_get_classic_name - INVALID_ADDRESS" );
0150   sc = rtems_object_get_classic_name( main_task, NULL );
0151   fatal_directive_status(
0152     sc,
0153     RTEMS_INVALID_ADDRESS,
0154     "rtems_object_get_classic_name #1"
0155   );
0156 
0157   puts( "rtems_object_get_classic_name - INVALID_ID (bad index)" );
0158   sc = rtems_object_get_classic_name( main_task + 5, &main_name );
0159   fatal_directive_status(
0160     sc,
0161     RTEMS_INVALID_ID,
0162     "rtems_object_get_classic_name #2"
0163   );
0164 
0165   puts( "rtems_object_get_classic_name - INVALID_ID (unallocated index)" );
0166   sc = rtems_object_get_classic_name( main_task + 1, &main_name );
0167   fatal_directive_status(
0168     sc,
0169     RTEMS_INVALID_ID,
0170     "rtems_object_get_classic_name #4"
0171   );
0172 
0173   puts( "rtems_object_get_classic_name - INVALID_ID (bad API)" );
0174   tmpId = rtems_build_id( 0xff, OBJECTS_RTEMS_TASKS, 1, 1 ),
0175   sc = rtems_object_get_classic_name( tmpId, &main_name );
0176   fatal_directive_status(
0177     sc,
0178     RTEMS_INVALID_ID,
0179     "rtems_object_get_classic_name #5"
0180   );
0181 
0182   sc = rtems_object_get_classic_name( main_task, &main_name );
0183   directive_failed( sc, "rtems_object_get_classic_name" );
0184   put_name( main_name, FALSE );
0185   puts( " - name returned by rtems_object_get_classic_name for Init task id" );
0186 
0187   sc = rtems_object_get_classic_name( RTEMS_SELF, &main_name );
0188   directive_failed( sc, "rtems_object_get_classic_name" );
0189   put_name( main_name, FALSE );
0190   puts( " - name returned by rtems_object_get_classic_name for RTEMS_SELF" );
0191 
0192   tmpName = rtems_build_name( 'T', 'E', 'M', 'P' );
0193   put_name( tmpName, FALSE );
0194   puts( " - rtems_build_name for TEMP" );
0195 
0196 
0197   /*
0198    * rtems_object_get_name - cases
0199    */
0200   puts( "rtems_object_get_name - bad id for class with instances" );
0201   ptr = rtems_object_get_name( main_task + 5, 5, name );
0202   rtems_test_assert(ptr == NULL);
0203 
0204   puts( "rtems_object_get_name - bad id for class without instances" );
0205   ptr = rtems_object_get_name(
0206     rtems_build_id( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_BARRIERS, 1, 1 ),
0207     5,
0208     name
0209   );
0210   rtems_test_assert(ptr == NULL);
0211 
0212   puts( "rtems_object_get_name - bad length" );
0213   ptr = rtems_object_get_name( main_task, 0, name );
0214   rtems_test_assert(ptr == NULL);
0215 
0216   puts( "rtems_object_get_name - bad pointer" );
0217   ptr = rtems_object_get_name( main_task, 5, NULL );
0218   rtems_test_assert(ptr == NULL);
0219 
0220   ptr = rtems_object_get_name( main_task, 5, name );
0221   rtems_test_assert(ptr != NULL);
0222   printf( "rtems_object_get_name returned (%s) for init task id\n", ptr );
0223 
0224   ptr = rtems_object_get_name( RTEMS_SELF, 5, name );
0225   rtems_test_assert(ptr != NULL);
0226   printf( "rtems_object_get_name returned (%s) for RTEMS_SELF\n", ptr );
0227 
0228   /*
0229    * rtems_object_set_name - errors
0230    */
0231 
0232   puts( "rtems_object_set_name - INVALID_ADDRESS" );
0233   sc = rtems_object_set_name( tmpId, NULL );
0234   fatal_directive_status(
0235     sc,
0236     RTEMS_INVALID_ADDRESS,
0237     "rtems_object_set_name INVALID_ADDRESS"
0238   );
0239 
0240   puts( "rtems_object_set_name - INVALID_ID (bad API)" );
0241   tmpId = rtems_build_id( 0xff, OBJECTS_RTEMS_TASKS, 1, 1 ),
0242   sc = rtems_object_set_name( tmpId, newName );
0243   fatal_directive_status(
0244     sc,
0245     RTEMS_INVALID_ID,
0246     "rtems_object_set_name #1"
0247   );
0248 
0249   puts( "rtems_object_set_name - INVALID_ID (bad index)" );
0250   sc = rtems_object_set_name( main_task + 10, newName );
0251   fatal_directive_status(
0252     sc,
0253     RTEMS_INVALID_ID,
0254     "rtems_object_set_name #2"
0255   );
0256 
0257   /*
0258    * rtems_object_set_name - change name of init task in various ways.
0259    *
0260    * This is strange but pushes the SuperCore code to do different things.
0261    */
0262 
0263   change_name( main_task,  "New1", TRUE );
0264   change_name( main_task, "Ne1", TRUE );
0265   change_name( main_task, "N1", TRUE );
0266   change_name( main_task, "N", TRUE );
0267   change_name( main_task, "", TRUE );
0268   tmpNameString[0] = 'N';
0269   tmpNameString[1] = 0x07;
0270   tmpNameString[2] = 0x09;
0271   tmpNameString[3] = '1';
0272   tmpNameString[4] = '\0';
0273   change_name( main_task, tmpNameString, FALSE );
0274 
0275   /*
0276    * Change object name using SELF ID
0277    */
0278 
0279   change_name( RTEMS_SELF,  "SELF", TRUE );
0280 
0281   ptr = rtems_object_get_name( main_task, 5, name );
0282   rtems_test_assert(ptr != NULL);
0283   printf( "rtems_object_get_name returned (%s) for init task id\n", ptr );
0284 
0285 
0286   /*
0287    * Exercise id build and extraction routines
0288    */
0289 
0290   puts( "rtems_build_id - build an id to match init task" );
0291   tmpId = rtems_build_id( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS, 1, 1 );
0292   rtems_test_assert( tmpId == main_task );
0293 
0294   puts( "rtems_object_id_get_api - OK" );
0295   part = rtems_object_id_get_api( main_task );
0296   rtems_test_assert( part == OBJECTS_CLASSIC_API );
0297 
0298   puts( "rtems_object_id_get_class - OK" );
0299   part = rtems_object_id_get_class( main_task );
0300   rtems_test_assert( part == OBJECTS_RTEMS_TASKS );
0301 
0302   puts( "rtems_object_id_get_node - OK" );
0303   part = rtems_object_id_get_node( main_task );
0304   rtems_test_assert( part == 1 );
0305 
0306   puts( "rtems_object_id_get_index - OK" );
0307   part = rtems_object_id_get_index( main_task );
0308   rtems_test_assert( part == 1 );
0309 
0310   /*
0311    * API/Class min/max routines
0312    */
0313 
0314   printf( "rtems_object_id_api_minimum returned %d\n",
0315           rtems_object_id_api_minimum() );
0316   printf( "rtems_object_id_api_maximum returned %d\n",
0317           rtems_object_id_api_maximum() );
0318 
0319   printf( "rtems_object_api_minimum_class(0) returned %d\n",
0320           rtems_object_api_minimum_class(0) );
0321   printf( "rtems_object_api_maximum_class(0) returned %d\n",
0322           rtems_object_api_maximum_class(0) );
0323 
0324   printf( "rtems_object_api_minimum_class(0) returned %d\n",
0325           rtems_object_api_minimum_class(0) );
0326   printf( "rtems_object_api_maximum_class(0) returned %d\n",
0327           rtems_object_api_maximum_class(0) );
0328   printf( "rtems_object_api_minimum_class(255) returned %d\n",
0329           rtems_object_api_minimum_class(255) );
0330   printf( "rtems_object_api_maximum_class(255) returned %d\n",
0331           rtems_object_api_maximum_class(255) );
0332 
0333   printf( "rtems_object_api_minimum_class(OBJECTS_INTERNAL_API) returned %d\n",
0334           rtems_object_api_minimum_class(OBJECTS_INTERNAL_API) );
0335   printf( "rtems_object_api_maximum_class(OBJECTS_INTERNAL_API) returned %d\n",
0336           rtems_object_api_maximum_class(OBJECTS_INTERNAL_API) );
0337 
0338   printf( "rtems_object_api_minimum_class(OBJECTS_CLASSIC_API) returned %d\n",
0339           rtems_object_api_minimum_class(OBJECTS_CLASSIC_API) );
0340   printf( "rtems_object_api_maximum_class(OBJECTS_CLASSIC_API) returned %d\n",
0341           rtems_object_api_maximum_class(OBJECTS_CLASSIC_API) );
0342 
0343   /*
0344    *  API and class name tests
0345    */
0346 
0347   printf( "rtems_object_get_api_name(0) = %s\n", rtems_object_get_api_name(0) );
0348   printf( "rtems_object_get_api_name(255) = %s\n",
0349     rtems_object_get_api_name(255));
0350 
0351   printf( "rtems_object_get_api_name(INTERNAL_API) = %s\n",
0352      rtems_object_get_api_name(OBJECTS_INTERNAL_API) );
0353   printf( "rtems_object_get_api_name(CLASSIC_API) = %s\n",
0354      rtems_object_get_api_name(OBJECTS_CLASSIC_API) );
0355 
0356   printf( "rtems_object_get_api_class_name(0, RTEMS_TASKS) = %s\n",
0357     rtems_object_get_api_class_name( 0, OBJECTS_RTEMS_TASKS ) );
0358   printf( "rtems_object_get_api_class_name(CLASSIC_API, 0) = %s\n",
0359     rtems_object_get_api_class_name( OBJECTS_CLASSIC_API, 0 ) );
0360   printf("rtems_object_get_api_class_name(INTERNAL_API, THREADS) = %s\n",
0361     rtems_object_get_api_class_name(
0362        OBJECTS_INTERNAL_API, OBJECTS_INTERNAL_THREADS));
0363   printf("rtems_object_get_api_class_name(CLASSIC_API, RTEMS_BARRIERS) = %s\n",
0364     rtems_object_get_api_class_name(
0365        OBJECTS_CLASSIC_API, OBJECTS_RTEMS_BARRIERS));
0366 
0367   /*
0368    *  Class information
0369    */
0370 
0371   puts( "rtems_object_get_class_information - INVALID_ADDRESS" );
0372   sc = rtems_object_get_class_information(
0373              OBJECTS_INTERNAL_API, OBJECTS_INTERNAL_THREADS, NULL );
0374   fatal_directive_status(
0375     sc,
0376     RTEMS_INVALID_ADDRESS,
0377     "rtems_object_get_class_information"
0378   );
0379 
0380   puts( "rtems_object_get_class_information - INVALID_NUMBER (bad API)" );
0381   sc =
0382     rtems_object_get_class_information(0, OBJECTS_INTERNAL_THREADS, &info);
0383   fatal_directive_status(
0384     sc,
0385     RTEMS_INVALID_NUMBER,
0386     "rtems_object_get_class_information (API)"
0387   );
0388 
0389   puts( "rtems_object_get_class_information - INVALID_NUMBER (api=0xff)" );
0390   sc = rtems_object_get_class_information( 0xff, 1, &info );
0391   fatal_directive_status(
0392     sc,
0393     RTEMS_INVALID_NUMBER,
0394     "rtems_object_get_class_information (api=0xff)"
0395   );
0396 
0397   puts( "rtems_object_get_class_information - INVALID_NUMBER (class=0)" );
0398   sc = rtems_object_get_class_information(
0399     OBJECTS_INTERNAL_API, 0, &info );
0400   fatal_directive_status(
0401     sc,
0402     RTEMS_INVALID_NUMBER,
0403     "rtems_object_get_class_information (class=0)"
0404   );
0405 
0406   puts(
0407     "rtems_object_get_class_information - INVALID_NUMBER (class too high)" );
0408   sc = rtems_object_get_class_information(
0409     OBJECTS_INTERNAL_API, 0xff, &info);
0410   fatal_directive_status(
0411     sc,
0412     RTEMS_INVALID_NUMBER,
0413     "rtems_object_get_class_information (class #2)"
0414   );
0415 
0416   puts( "rtems_object_get_class_information - Classic Tasks - OK" );
0417   sc = rtems_object_get_class_information(
0418              OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS, &info );
0419   directive_failed( sc, "rtems_object_get_class_information" );
0420   print_class_info( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS, &info );
0421 
0422   puts( "rtems_object_get_class_information - Classic Timers - OK" );
0423   sc = rtems_timer_create(0, NULL);
0424   fatal_directive_status(
0425     sc,
0426     RTEMS_INVALID_NAME,
0427     "rtems_timer_create"
0428   );
0429   sc = rtems_object_get_class_information(
0430              OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TIMERS, &info );
0431   directive_failed( sc, "rtems_object_get_class_information" );
0432   print_class_info( OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TIMERS, &info );
0433 
0434   /*
0435    *  Ugly hack to force a weird error.
0436    *
0437    *  The weird case is that we need to look up a thread Id where the
0438    *  thread classes' object information table pointer is NULL.  Probably
0439    *  impossible to really hit until registration is completely dynamically
0440    *  configurable.
0441    */
0442   {
0443     rtems_task_priority              old_priority;
0444     void                            *tmp;
0445     int                              class;
0446     int                              api;
0447 
0448     class = OBJECTS_INTERNAL_API;
0449     api   = OBJECTS_INTERNAL_THREADS;
0450 
0451     puts( "rtems_task_set_priority - use valid Idle thread id" );
0452     sc = rtems_task_set_priority(
0453       rtems_build_id( class, api, 1, 1 ),
0454       RTEMS_CURRENT_PRIORITY,
0455       &old_priority
0456     );
0457     directive_failed( sc, "rtems_task_set_priority" );
0458 
0459     /* destroy internal API thread class pointer */
0460     puts( "rtems_task_set_priority - clobber internal thread class info" );
0461     tmp = _Objects_Information_table[ api ][ class ];
0462     _Objects_Information_table[ api ][ class ] = NULL;
0463 
0464     puts( "rtems_task_set_priority - use valid Idle thread id again" );
0465     sc = rtems_task_set_priority(
0466       rtems_build_id( class, api, 1, 1 ),
0467       RTEMS_CURRENT_PRIORITY,
0468       &old_priority
0469     );
0470     fatal_directive_status( sc, RTEMS_INVALID_ID, "rtems_task_set_priority" );
0471 
0472     puts( "rtems_task_set_priority - use valid Idle thread id again" );
0473     sc = rtems_task_set_priority(
0474       rtems_build_id( class, api, 1, 1 ),
0475       RTEMS_CURRENT_PRIORITY,
0476       &old_priority
0477     );
0478     fatal_directive_status( sc, RTEMS_INVALID_ID, "rtems_task_set_priority" );
0479 
0480     /* restore pointer */
0481     puts( "rtems_task_set_priority - restore internal thread class info" );
0482     _Objects_Information_table[ api ][ class ] = tmp;
0483   }
0484 
0485   /*
0486    *  Bad Id on an object which disables interrupts as part of translating
0487    *  the Id into an object pointer.  Semaphore is the only object that
0488    *  needs this. This is a "good" Id in that is it in range, but bad in
0489    *  that it has not been allocated so the local_table pointer is NULL.
0490    */
0491   puts( "rtems_semaphore_obtain - good but uncreated ID - INVALID_ID - OK" );
0492   sc = rtems_semaphore_obtain(
0493     rtems_build_id(
0494       OBJECTS_CLASSIC_API,
0495       OBJECTS_RTEMS_SEMAPHORES,
0496       1,
0497       rtems_configuration_get_maximum_semaphores()
0498     ),
0499     RTEMS_DEFAULT_OPTIONS,
0500     0
0501   );
0502   fatal_directive_status( sc, RTEMS_INVALID_ID, "rtems_semaphore_obtain" );
0503 
0504   TEST_END();
0505   rtems_test_exit( 0 );
0506 }