Back to home page

LXR

 
 

    


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

0001 /*
0002  * Copyright (c) 2014 Daniel Ramirez. (javamonn@gmail.com)
0003  *
0004  * This file's license is 2-clause BSD as in this distribution's LICENSE file.
0005  */
0006 
0007 #include <timesys.h>
0008 #include <rtems/btimer.h>
0009 
0010 const char rtems_test_name[] = "RHDEADLOCKBRK";
0011 
0012 #define BENCHMARKS 20000
0013 
0014 rtems_task Task01( rtems_task_argument ignored );
0015 rtems_task Task02( rtems_task_argument ignored );
0016 rtems_task Task03( rtems_task_argument ignored );
0017 rtems_task Init( rtems_task_argument ignored );
0018 
0019 rtems_id           Task_id[3];
0020 rtems_name         Task_name[3];
0021 rtems_id           sem_id;
0022 rtems_name         sem_name;
0023 rtems_status_code  status;
0024 
0025 uint32_t count;
0026 uint32_t telapsed;
0027 uint32_t tswitch_overhead;
0028 uint32_t tobtain_overhead;
0029 uint32_t sem_exe;
0030 
0031 rtems_task Init( rtems_task_argument ignored )
0032 {
0033   rtems_attribute      sem_attr;
0034   rtems_task_priority  pri;
0035   rtems_mode           prev_mode;
0036 
0037   Print_Warning();
0038 
0039   TEST_BEGIN();
0040 
0041   sem_attr = RTEMS_INHERIT_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY;
0042 
0043   sem_name = rtems_build_name( 'S','0',' ',' ' );
0044   status = rtems_semaphore_create(
0045     sem_name,
0046     1,
0047     sem_attr,
0048     0,
0049     &sem_id
0050   );
0051   directive_failed( status, "rtems_semaphore_create of S0" );
0052 
0053   Task_name[0] = rtems_build_name( 'T','A','0','1' );
0054   status = rtems_task_create(
0055     Task_name[0],
0056     26,  /* High priority task */
0057     RTEMS_MINIMUM_STACK_SIZE,
0058     RTEMS_DEFAULT_MODES,
0059     RTEMS_DEFAULT_ATTRIBUTES,
0060     &Task_id[0]
0061   );
0062   directive_failed( status, "rtems_task_create of TA01" );
0063 
0064   Task_name[1] = rtems_build_name( 'T','A','0','2' );
0065   status = rtems_task_create(
0066     Task_name[1],
0067     28,  /* Mid priority task */
0068     RTEMS_MINIMUM_STACK_SIZE,
0069     RTEMS_DEFAULT_MODES,
0070     RTEMS_DEFAULT_ATTRIBUTES,
0071     &Task_id[1]
0072   );
0073   directive_failed( status, "rtems_task_create of TA02" );
0074 
0075   Task_name[2] = rtems_build_name( 'T','A','0','3' );
0076   status = rtems_task_create(
0077     Task_name[2],
0078     30,  /* Low priority task */
0079     RTEMS_MINIMUM_STACK_SIZE,
0080     RTEMS_DEFAULT_MODES,
0081     RTEMS_DEFAULT_ATTRIBUTES,
0082     &Task_id[2]
0083   );
0084   directive_failed( status, "rtems_task_create of TA03" );
0085 
0086   /* find overhead of obtaining semaphore */
0087   benchmark_timer_initialize();
0088   rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 );
0089   tobtain_overhead = benchmark_timer_read();
0090   rtems_semaphore_release( sem_id );
0091 
0092   rtems_task_mode( RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, &prev_mode );
0093   /* Lower own priority so tasks can start up and run */
0094   rtems_task_set_priority( RTEMS_SELF, 40, &pri );
0095 
0096   /* Get time of benchmark with no semaphores involved, i.e. find overhead */
0097   sem_exe = 0;
0098   status = rtems_task_start( Task_id[2], Task03, 0 );
0099   directive_failed( status, "rtems_task_start of TA03" );
0100 
0101   /* Get time of benchmark with semaphores */
0102   sem_exe = 1;
0103   status = rtems_task_restart( Task_id[2], 0 );
0104   directive_failed( status, "rtems_task_start of TA03" );
0105 
0106   /* Should never reach here */
0107   rtems_test_assert( false );
0108 }
0109 
0110 rtems_task Task01( rtems_task_argument ignored )
0111 {
0112   /* All tasks have had time to start up once TA01 is running */
0113 
0114   /* Benchmark code */
0115   benchmark_timer_initialize();
0116   for ( count = 0; count < BENCHMARKS; count++ ) {
0117     if ( sem_exe == 1 ) {
0118       /* Block on call */
0119       rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 );
0120     }
0121 
0122     if ( sem_exe == 1 ) {
0123       /* Release semaphore immediately after obtaining it */
0124       rtems_semaphore_release( sem_id );
0125     }
0126 
0127     /* Suspend self, go to TA02 */
0128     rtems_task_suspend( RTEMS_SELF );
0129   }
0130   telapsed = benchmark_timer_read();
0131 
0132   /* Check which run this was */
0133   if (sem_exe == 0) {
0134     tswitch_overhead = telapsed;
0135     rtems_task_suspend( Task_id[1] );
0136     rtems_task_suspend( Task_id[2] );
0137     rtems_task_suspend( RTEMS_SELF );
0138   } else {
0139     put_time(
0140        "Rhealstone: Deadlock Break",
0141        telapsed,
0142        BENCHMARKS,              /* Total number of times deadlock broken*/
0143        tswitch_overhead,        /* Overhead of loop and task switches */
0144        tobtain_overhead
0145     );
0146     TEST_END();
0147     rtems_test_exit( 0 );
0148   }
0149 
0150 }
0151 
0152 rtems_task Task02( rtems_task_argument ignored )
0153 {
0154   /* Start up TA01, get preempted */
0155   if ( sem_exe == 1) {
0156     status = rtems_task_restart( Task_id[0], 0);
0157     directive_failed( status, "rtems_task_start of TA01");
0158   } else {
0159     status = rtems_task_start( Task_id[0], Task01, 0);
0160     directive_failed( status, "rtems_task_start of TA01");
0161   }
0162 
0163   /* Benchmark code */
0164   for ( ; count < BENCHMARKS ; ) {
0165     /* Suspend self, go to TA01 */
0166     rtems_task_suspend( RTEMS_SELF );
0167 
0168     /* Wake up TA01, get preempted */
0169     rtems_task_resume( Task_id[0] );
0170   }
0171 }
0172 
0173 rtems_task Task03( rtems_task_argument ignored )
0174 {
0175   if (sem_exe == 1) {
0176     /* Low priority task holds mutex */
0177     rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 );
0178   }
0179 
0180   /* Start up TA02, get preempted */
0181   if ( sem_exe == 1) {
0182     status = rtems_task_restart( Task_id[1], 0);
0183     directive_failed( status, "rtems_task_start of TA02");
0184   } else {
0185     status = rtems_task_start( Task_id[1], Task02, 0);
0186     directive_failed( status, "rtems_task_start of TA02");
0187   }
0188 
0189   /* Benchmark code */
0190   for ( ; count < BENCHMARKS ; ) {
0191     if ( sem_exe == 1 ) {
0192       /* Preempted by TA01 upon release */
0193       rtems_semaphore_release( sem_id );
0194     }
0195 
0196     if ( sem_exe == 1 ) {
0197       /* Prepare for next Benchmark */
0198       rtems_semaphore_obtain( sem_id, RTEMS_WAIT, 0 );
0199     }
0200     /* Wake up TA02, get preempted */
0201     rtems_task_resume( Task_id[1] );
0202   }
0203 }
0204 
0205 /* configuration information */
0206 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0207 #define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER
0208 
0209 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0210 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0211 #define CONFIGURE_MAXIMUM_TASKS 4
0212 
0213 #define CONFIGURE_INIT
0214 #include <rtems/confdefs.h>