summaryrefslogblamecommitdiffstats
path: root/testsuites/sptests/sp34/changepri.c
blob: 20d4ba4037a1cbef7e668471b4534817b681d4b4 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                                                      

                                                           
                                         

   



                    




                                                                      
                              





                                                                      

                      



                    

                                   

                                       
                                                  

                                             



                                                                  
                            

                         
                                                      

                                  
                                                             
     
                  


                       
 
                               
                                                     
       
                                                 
        
                                                          
                                                                 
                                       















                                                 
                                                      





                                                                              
         
                                                                
                                                      
        

        






                                                                              
         
                                                                
                                                       
        

        
 
                    







                                                                           
                             
                        
 
               




                                                                            

                              



                                                             
 




                                                                   
                                                                       




                                                                               
 
                                                                          




                              








                                                                  


                                                                        














                                                               
             
                     



                               
                                                         
                                                
 

                                                                 

                                        

                                                               



                                      


                           
/*
 *  Test program to demonstrate reordering of threads on thread queues
 *  when their priority changes.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <bsp.h>
#include <stdio.h>

/********************************************************************/
/* define this to use the RTEMS 4.5 scheme for object names */
/* #define TEST_ON_RTEMS_45 */

/* define this to print the Id of the calling task */
/* #define TEST_ON_TASK_ID */

/********************************************************************/

#define CONFIGURE_INIT

#include <bsp.h>
#include <stdio.h>
#include "tmacros.h"

#include <rtems/score/threadimpl.h>

const char rtems_test_name[] = "SP 34";

rtems_task BlockingTasks(rtems_task_argument arg);
rtems_task Init(rtems_task_argument ignored);
const char *CallerName(void);

/*
 *  CallerName -- print the calling tasks name or id as configured
 */
const char *CallerName(void)
{
  static char buffer[32];
  Thread_Control *executing = _Thread_Get_executing();
#if defined(TEST_PRINT_TASK_ID)
  sprintf( buffer, "0x%08x -- %d",
      rtems_task_self(), _Thread_Get_priority( executing ) );
#else
  volatile union {
    uint32_t u;
    unsigned char c[4];
  } TempName;

  #if defined(TEST_ON_RTEMS_45)
    TempName.u = *(uint32_t *)executing->Object.name;
  #else
    TempName.u = executing->Object.name.name_u32;
  #endif
    sprintf( buffer, "%c%c%c%c -- %" PRIdPriority_Control,
      TempName.c[0], TempName.c[1], TempName.c[2], TempName.c[3],
      _Thread_Get_priority( executing )
  );
#endif
  return buffer;
}

#define NUMBER_OF_BLOCKING_TASKS 5

/* RTEMS ids of blocking threads */
rtems_id  Blockers[NUMBER_OF_BLOCKING_TASKS];

/* Semaphore they are all blocked on */
rtems_id  Semaphore;

rtems_task BlockingTasks(rtems_task_argument arg)
{
  rtems_status_code   status;
  rtems_task_priority pri = (rtems_task_priority) arg;
  rtems_task_priority opri;
  rtems_task_priority npri;

  status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &opri);
  directive_failed( status, "rtems_task_set_priority" );

  printf(
    "semaphore_obtain -- BlockingTask %" PRIdrtems_task_priority
      " @ pri=%" PRIdrtems_task_priority ") blocks\n",
    pri,
    opri
  );
  status = rtems_semaphore_obtain(Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
  directive_failed( status, "rtems_semaphore_obtain" );

  /* priority should have changed while blocked */
  status = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &npri);
  directive_failed( status, "rtems_task_set_priority" );

  printf(
    "semaphore_obtain -- BlockingTask %" PRIdrtems_task_priority
      " @ pri=%" PRIdrtems_task_priority ") returns\n",
    pri,
    npri
  );

  rtems_task_exit();
}

/*************************************************************************/
/**********************        INITIALIZATION        *********************/
/*************************************************************************/

rtems_task Init(rtems_task_argument ignored)
{
  rtems_status_code   status;
  int                 i;

  TEST_BEGIN();

  /* Create synchronisation semaphore for LocalHwIsr -> Test Tasks */
  status = rtems_semaphore_create(
    rtems_build_name ('S', 'E', 'M', '1'),           /* name */
    0,                                               /* initial count = 0 */
    RTEMS_LOCAL              |
    RTEMS_COUNTING_SEMAPHORE |
    RTEMS_PRIORITY,
    0,
    &Semaphore);                                    /* *id */
  directive_failed( status, "rtems_semaphore_create" );

  /* Create and start all tasks in the test */

  for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
    status = rtems_task_create(
      rtems_build_name('B','L','K','0'+i),               /* Name */
      (rtems_task_priority) 2+i,                         /* Priority */
      RTEMS_MINIMUM_STACK_SIZE*2,                        /* Stack size (8KB) */
      RTEMS_DEFAULT_MODES | RTEMS_NO_ASR,                /* Mode */
      RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT,   /* Attributes */
      &Blockers[i]);                                     /* Assigned ID */
    directive_failed( status, "rtems_task_create (BLKn)" );

    printf( "Blockers[%d] Id = 0x%08" PRIxrtems_id "\n", i, Blockers[i] );
    status = rtems_task_start(
      Blockers[i],
      BlockingTasks,
      (rtems_task_argument)i
    );
    directive_failed( status, "rtems_task_start (BLKn)" );
  }

  status = rtems_task_wake_after( 100 );
  directive_failed( status, "rtems_task_wake_after" );

  puts( "rtems_task_set_priority -- invert priorities of tasks" );
  for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
    rtems_task_priority opri;
    rtems_task_priority npri;

    npri = (rtems_task_priority) (2 + NUMBER_OF_BLOCKING_TASKS - i - 1);

    status = rtems_task_set_priority(Blockers[i], npri, &opri);
    directive_failed( status, "rtems_task_set_priority" );
  }

  for (i = 0; i < NUMBER_OF_BLOCKING_TASKS; i++) {
    puts( "rtems_semaphore_release -- OK" );
    status = rtems_semaphore_release(Semaphore);
    directive_failed( status, "rtems_semaphore_release" );

    status = rtems_task_wake_after( 100 );
    directive_failed( status, "rtems_task_wake_after" );
  }

  /* exit the test */
  TEST_END();
  rtems_test_exit(0);
}

/* configuration information */

#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER

#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION

#define CONFIGURE_RTEMS_INIT_TASKS_TABLE

#define CONFIGURE_EXTRA_TASK_STACKS \
          (RTEMS_MINIMUM_STACK_SIZE * NUMBER_OF_BLOCKING_TASKS)

#define CONFIGURE_MAXIMUM_TASKS 6
#define CONFIGURE_MAXIMUM_SEMAPHORES 1

#include <rtems/confdefs.h>

/* end of file */