Back to home page

LXR

 
 

    


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

0001 /*
0002  *  Test program to demonstrate reordering of threads on thread queues
0003  *  when their priority changes.
0004  *
0005  *  The license and distribution terms for this file may be
0006  *  found in the file LICENSE in this distribution or at
0007  *  http://www.rtems.org/license/LICENSE.
0008  */
0009 
0010 #ifdef HAVE_CONFIG_H
0011 #include "config.h"
0012 #endif
0013 
0014 #include <bsp.h>
0015 #include <stdio.h>
0016 
0017 /********************************************************************/
0018 /* define this to use the RTEMS 4.5 scheme for object names */
0019 /* #define TEST_ON_RTEMS_45 */
0020 
0021 /* define this to print the Id of the calling task */
0022 /* #define TEST_ON_TASK_ID */
0023 
0024 /********************************************************************/
0025 
0026 #define CONFIGURE_INIT
0027 
0028 #include <bsp.h>
0029 #include <stdio.h>
0030 #include "tmacros.h"
0031 
0032 #include <rtems/score/threadimpl.h>
0033 
0034 const char rtems_test_name[] = "SP 34";
0035 
0036 rtems_task BlockingTasks(rtems_task_argument arg);
0037 rtems_task Init(rtems_task_argument ignored);
0038 const char *CallerName(void);
0039 
0040 /*
0041  *  CallerName -- print the calling tasks name or id as configured
0042  */
0043 const char *CallerName(void)
0044 {
0045   static char buffer[32];
0046   Thread_Control *executing = _Thread_Get_executing();
0047 #if defined(TEST_PRINT_TASK_ID)
0048   sprintf( buffer, "0x%08x -- %d",
0049       rtems_task_self(), _Thread_Get_priority( executing ) );
0050 #else
0051   volatile union {
0052     uint32_t u;
0053     unsigned char c[4];
0054   } TempName;
0055 
0056   #if defined(TEST_ON_RTEMS_45)
0057     TempName.u = *(uint32_t *)executing->Object.name;
0058   #else
0059     TempName.u = executing->Object.name.name_u32;
0060   #endif
0061     sprintf( buffer, "%c%c%c%c -- %" PRIdPriority_Control,
0062       TempName.c[0], TempName.c[1], TempName.c[2], TempName.c[3],
0063       _Thread_Get_priority( executing )
0064   );
0065 #endif
0066   return buffer;
0067 }
0068 
0069 #define NUMBER_OF_BLOCKING_TASKS 5
0070 
0071 /* RTEMS ids of blocking threads */
0072 rtems_id  Blockers[NUMBER_OF_BLOCKING_TASKS];
0073 
0074 /* Semaphore they are all blocked on */
0075 rtems_id  Semaphore;
0076 
0077 rtems_task BlockingTasks(rtems_task_argument arg)
0078 {
0079   rtems_status_code   status;
0080   rtems_task_priority pri = (rtems_task_priority) arg;
0081   rtems_task_priority opri;
0082   rtems_task_priority npri;
0083 
0084   status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &opri);
0085   directive_failed( status, "rtems_task_set_priority" );
0086 
0087   printf(
0088     "semaphore_obtain -- BlockingTask %" PRIdrtems_task_priority
0089       " @ pri=%" PRIdrtems_task_priority ") blocks\n",
0090     pri,
0091     opri
0092   );
0093   status = rtems_semaphore_obtain(Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0094   directive_failed( status, "rtems_semaphore_obtain" );
0095 
0096   /* priority should have changed while blocked */
0097   status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &npri);
0098   directive_failed( status, "rtems_task_set_priority" );
0099 
0100   printf(
0101     "semaphore_obtain -- BlockingTask %" PRIdrtems_task_priority
0102       " @ pri=%" PRIdrtems_task_priority ") returns\n",
0103     pri,
0104     npri
0105   );
0106 
0107   rtems_task_exit();
0108 }
0109 
0110 /*************************************************************************/
0111 /**********************        INITIALIZATION        *********************/
0112 /*************************************************************************/
0113 
0114 rtems_task Init(rtems_task_argument ignored)
0115 {
0116   rtems_status_code   status;
0117   int                 i;
0118 
0119   TEST_BEGIN();
0120 
0121   /* Create synchronisation semaphore for LocalHwIsr -> Test Tasks */
0122   status = rtems_semaphore_create(
0123     rtems_build_name ('S', 'E', 'M', '1'),           /* name */
0124     0,                                               /* initial count = 0 */
0125     RTEMS_LOCAL              |
0126     RTEMS_COUNTING_SEMAPHORE |
0127     RTEMS_PRIORITY,
0128     0,
0129     &Semaphore);                                    /* *id */
0130   directive_failed( status, "rtems_semaphore_create" );
0131 
0132   /* Create and start all tasks in the test */
0133 
0134   for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
0135     status = rtems_task_create(
0136       rtems_build_name('B','L','K','0'+i),               /* Name */
0137       (rtems_task_priority) 2+i,                         /* Priority */
0138       RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
0139       RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
0140       RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
0141       &Blockers[i]);                                     /* Assigned ID */
0142     directive_failed( status, "rtems_task_create (BLKn)" );
0143 
0144     printf( "Blockers[%d] Id = 0x%08" PRIxrtems_id "\n", i, Blockers[i] );
0145     status = rtems_task_start(
0146       Blockers[i],
0147       BlockingTasks,
0148       (rtems_task_argument)i
0149     );
0150     directive_failed( status, "rtems_task_start (BLKn)" );
0151   }
0152 
0153   status = rtems_task_wake_after( 100 );
0154   directive_failed( status, "rtems_task_wake_after" );
0155 
0156   puts( "rtems_task_set_priority -- invert priorities of tasks" );
0157   for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
0158     rtems_task_priority opri;
0159     rtems_task_priority npri;
0160 
0161     npri = (rtems_task_priority) (2 + NUMBER_OF_BLOCKING_TASKS - i - 1);
0162 
0163     status = rtems_task_set_priority(Blockers[i], npri, &opri);
0164     directive_failed( status, "rtems_task_set_priority" );
0165   }
0166 
0167   for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
0168     puts( "rtems_semaphore_release -- OK" );
0169     status = rtems_semaphore_release(Semaphore);
0170     directive_failed( status, "rtems_semaphore_release" );
0171 
0172     status = rtems_task_wake_after( 100 );
0173     directive_failed( status, "rtems_task_wake_after" );
0174   }
0175 
0176   /* exit the test */
0177   TEST_END();
0178   rtems_test_exit(0);
0179 }
0180 
0181 /* configuration information */
0182 
0183 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0184 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0185 
0186 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0187 
0188 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0189 
0190 #define CONFIGURE_EXTRA_TASK_STACKS \
0191           (RTEMS_MINIMUM_STACK_SIZE * NUMBER_OF_BLOCKING_TASKS)
0192 
0193 #define CONFIGURE_MAXIMUM_TASKS 6
0194 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0195 
0196 #include <rtems/confdefs.h>
0197 
0198 /* end of file */