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 thread queue enqueue and dequeue priority
0005  *
0006  *  COPYRIGHT (c) 1989-2009.
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 #include <stdio.h>
0036 #include <stdlib.h>
0037 
0038 #include <bsp.h>
0039 
0040 #include "tmacros.h"
0041 
0042 const char rtems_test_name[] = "SP 42";
0043 
0044 #define MAX_TASKS 20
0045 
0046 /*
0047  * Carefully chosen to exercise threadq enqueue/dequeue priority logic.
0048  * Somewhat randomly sorted to ensure than if discipline is FIFO, run-time
0049  * behavior won't be the same when released.
0050  */
0051 static const rtems_task_priority Priorities_High[MAX_TASKS] = {
0052   37, 37, 37, 37,       /* backward - more 2-n */
0053   2, 2, 2, 2,           /* forward - multiple are on 2-n chain */
0054   4, 3,                 /* forward - search forward arbitrary */
0055   3, 3, 3, 3,           /* forward - more 2-n */
0056   38, 37,               /* backward - search backward arbitrary */
0057   34, 34, 34, 34,       /* backward - multple on 2-n chain */
0058 };
0059 
0060 static const rtems_task_priority Priorities_Low[MAX_TASKS] = {
0061   13, 13, 13, 13,       /* backward - more 2-n */
0062   2, 2, 2, 2,           /* forward - multiple are on 2-n chain */
0063   4, 3,                 /* forward - search forward arbitrary */
0064   3, 3, 3, 3,           /* forward - more 2-n */
0065   14, 13,               /* backward - search backward arbitrary */
0066   12, 12, 12, 12,       /* backward - multple on 2-n chain */
0067 };
0068 
0069 static const int Obtain_order[2][MAX_TASKS] = {
0070   { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 },
0071   { 4, 5, 6, 7, 9, 10, 11, 12, 13, 8, 16, 17, 18, 19, 0, 1, 2, 3, 15, 14 }
0072 };
0073 
0074 static const rtems_task_priority *Priorities;
0075 
0076 static rtems_id   Semaphore;
0077 static rtems_id   Master;
0078 static rtems_id   Task_id[ MAX_TASKS ];
0079 static rtems_name Task_name[ MAX_TASKS ];
0080 
0081 static rtems_task_argument Obtain_counter;
0082 
0083 static enum {
0084  FIFO,
0085  PRIORITY
0086 } Variant;
0087 
0088 static rtems_task Locker_task(
0089   rtems_task_argument task_index
0090 )
0091 {
0092   rtems_id            tid;
0093   rtems_status_code   status;
0094   rtems_task_argument my_obtain_counter;
0095 
0096   status = rtems_task_ident( RTEMS_WHO_AM_I, RTEMS_SEARCH_ALL_NODES, &tid );
0097   directive_failed( status, "rtems_task_ident" );
0098 
0099   rtems_test_assert( task_index == task_number( tid ) - 1 );
0100 
0101   status = rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 0 );
0102   directive_failed( status, "rtems_semaphore_obtain" );
0103 
0104   put_name( Task_name[ task_index ], FALSE );
0105   puts( " - unblocked - OK" );
0106 
0107   status = rtems_task_wake_after( 10 );
0108   directive_failed( status, "rtems_task_wake_after" );
0109 
0110   my_obtain_counter = Obtain_counter;
0111   rtems_test_assert( task_index == Obtain_order[ Variant ][ Obtain_counter ] );
0112   ++Obtain_counter;
0113 
0114   status = rtems_semaphore_release( Semaphore );
0115   directive_failed( status, "rtems_semaphore_release" );
0116 
0117   if ( my_obtain_counter == MAX_TASKS - 1 ) {
0118     status = rtems_event_transient_send( Master );
0119     directive_failed( status, "rtems_event_transient_send" );
0120   }
0121 
0122   rtems_task_exit();
0123 }
0124 
0125 static void do_test(
0126   rtems_attribute attr,
0127   bool            extract  /* TRUE if extract, not release */
0128 )
0129 {
0130   rtems_status_code   status;
0131   rtems_task_argument i;
0132 
0133   Variant = ( ( attr & RTEMS_PRIORITY ) != 0 ? PRIORITY : FIFO );
0134   Obtain_counter = 0;
0135 
0136   status = rtems_semaphore_create(
0137     rtems_build_name( 'S', 'E', 'M', '0' ),  /* name = SEM0 */
0138     0,                                       /* locked */
0139     RTEMS_BINARY_SEMAPHORE | attr,           /* mutex w/desired discipline */
0140     0,                                       /* IGNORED */
0141     &Semaphore
0142   );
0143   directive_failed( status, "rtems_semaphore_create" );
0144 
0145   for (i = 0 ; i < MAX_TASKS ; i++ ) {
0146     Task_name[ i ] = rtems_build_name(
0147        'T',
0148        'A',
0149        '0' + (char)(i/10),
0150        '0' + (char)(i%10)
0151     );
0152 
0153     status = rtems_task_create(
0154       Task_name[ i ],
0155       Priorities[ i ],
0156       RTEMS_MINIMUM_STACK_SIZE,
0157       RTEMS_DEFAULT_MODES,
0158       RTEMS_DEFAULT_ATTRIBUTES,
0159       &Task_id[ i ]
0160     );
0161     directive_failed( status, "rtems_task_create" );
0162 
0163     status = rtems_task_start( Task_id[ i ], Locker_task, i );
0164     directive_failed( status, "rtems_task_start" );
0165   }
0166 
0167   if ( extract ) {
0168     for (i = 0 ; i< MAX_TASKS ; i++ ) {
0169       status = rtems_task_delete( Task_id[ i ]  );
0170       directive_failed( status, "rtems_task_delete" );
0171     }
0172   }
0173 
0174   /* do the initial release */
0175   status = rtems_semaphore_release( Semaphore );
0176   directive_failed( status, "rtems_semaphore_release" );
0177 
0178   if ( !extract ) {
0179     status = rtems_event_transient_receive( RTEMS_WAIT, RTEMS_NO_TIMEOUT );
0180     directive_failed( status, "rtems_event_transient_receive" );
0181   }
0182 
0183   /* now delete the semaphore since no one is waiting and it is unlocked */
0184   status = rtems_semaphore_delete( Semaphore );
0185   directive_failed( status, "rtems_semaphore_delete" );
0186 }
0187 
0188 static rtems_task Init(
0189   rtems_task_argument argument
0190 )
0191 {
0192   rtems_task_priority prio;
0193   rtems_status_code status;
0194 
0195   TEST_BEGIN();
0196 
0197   Master = rtems_task_self();
0198 
0199   if (RTEMS_MAXIMUM_PRIORITY >= 255)
0200     Priorities = Priorities_High;
0201   else if (RTEMS_MAXIMUM_PRIORITY >= 15)
0202     Priorities = Priorities_Low;
0203   else {
0204     puts( "Test needs at least 16 configured priority levels" );
0205     rtems_test_exit( 0 );
0206   }
0207 
0208   prio = RTEMS_MAXIMUM_PRIORITY - 1;
0209   status = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
0210   directive_failed( status, "rtems_task_set_priority" );
0211 
0212   if ( sizeof(Priorities_Low) / sizeof(rtems_task_priority) != MAX_TASKS ) {
0213     puts( "Priorities_Low table does not have right number of entries" );
0214     rtems_test_exit( 0 );
0215   }
0216 
0217   if ( sizeof(Priorities_High) / sizeof(rtems_task_priority) != MAX_TASKS ) {
0218     puts( "Priorities_High table does not have right number of entries" );
0219     rtems_test_exit( 0 );
0220   }
0221 
0222   puts( "Exercising blocking discipline w/extract in FIFO order " );
0223   do_test( RTEMS_FIFO, TRUE );
0224 
0225   puts( "Exercising blocking discipline w/unblock in FIFO order" );
0226   do_test( RTEMS_FIFO, FALSE );
0227 
0228   puts( "Exercising blocking discipline w/extract in priority order " );
0229   do_test( RTEMS_PRIORITY, TRUE );
0230 
0231   puts( "Exercising blocking discipline w/unblock in priority order" );
0232   do_test( RTEMS_PRIORITY, FALSE );
0233 
0234   TEST_END();
0235   rtems_test_exit(0);
0236 }
0237 
0238 /**************** START OF CONFIGURATION INFORMATION ****************/
0239 
0240 #define CONFIGURE_INIT
0241 
0242 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0243 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0244 
0245 #define CONFIGURE_MAXIMUM_TASKS             MAX_TASKS+1
0246 #define CONFIGURE_MAXIMUM_SEMAPHORES        1
0247 
0248 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
0249 
0250 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0251 
0252 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0253 
0254 #include <rtems/confdefs.h>
0255 
0256 /****************  END OF CONFIGURATION INFORMATION  ****************/
0257