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  *  @brief Test for Bodies of Macros
0005  *
0006  *  Interrupt Disable/Enable Tests
0007  *  Clock Tick from task level
0008  */
0009 
0010 /*
0011  *  COPYRIGHT (c) 1989-2012.
0012  *  On-Line Applications Research Corporation (OAR).
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039 
0040 #define CONFIGURE_INIT
0041 #include "system.h"
0042 
0043 #include <rtems/sysinit.h>
0044 
0045 const char rtems_test_name[] = "SP 37";
0046 
0047 /* prototypes */
0048 void test_interrupt_inline(void);
0049 void check_isr_in_progress_inline(void);
0050 rtems_task blocked_task(rtems_task_argument argument);
0051 rtems_timer_service_routine test_unblock_task(
0052   rtems_id  timer,
0053   void     *arg
0054 );
0055 rtems_timer_service_routine test_unblock_task(
0056   rtems_id  timer,
0057   void     *arg
0058 );
0059 void check_isr_worked(
0060   char *s,
0061   int   result
0062 );
0063 rtems_timer_service_routine test_isr_in_progress(
0064   rtems_id  timer,
0065   void     *arg
0066 );
0067 
0068 /* test bodies */
0069 
0070 #define TEST_ISR_EVENT RTEMS_EVENT_0
0071 
0072 static uint32_t boot_isr_level;
0073 
0074 static void set_boot_isr_level( void )
0075 {
0076   boot_isr_level = _ISR_Get_level();
0077 }
0078 
0079 RTEMS_SYSINIT_ITEM(
0080   set_boot_isr_level,
0081   RTEMS_SYSINIT_DEVICE_DRIVERS,
0082   RTEMS_SYSINIT_ORDER_MIDDLE
0083 );
0084 
0085 typedef struct {
0086   ISR_Level actual_level;
0087   rtems_id master_task_id;
0088 } test_isr_level_context;
0089 
0090 static void isr_level_check_task( rtems_task_argument arg )
0091 {
0092   test_isr_level_context *ctx = (test_isr_level_context *) arg;
0093   rtems_status_code sc;
0094 
0095   ctx->actual_level = _ISR_Get_level();
0096 
0097   sc = rtems_event_send( ctx->master_task_id,  TEST_ISR_EVENT );
0098   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0099 
0100   ( void ) rtems_task_suspend( RTEMS_SELF );
0101   rtems_test_assert( 0 );
0102 }
0103 
0104 static void test_isr_level_for_new_threads( ISR_Level last_proper_level )
0105 {
0106   ISR_Level mask = CPU_MODES_INTERRUPT_MASK;
0107   ISR_Level current;
0108   test_isr_level_context ctx = {
0109     .master_task_id = rtems_task_self()
0110   };
0111 
0112   for ( current = 0 ; current <= mask ; ++current ) {
0113     rtems_mode initial_modes;
0114     rtems_id id;
0115     rtems_status_code sc;
0116     rtems_event_set events;
0117 
0118     initial_modes = RTEMS_INTERRUPT_LEVEL(current);
0119 
0120 #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
0121     if ( initial_modes != 0 ) {
0122       break;
0123     }
0124 #endif
0125 
0126     ctx.actual_level = 0xffffffff;
0127 
0128     sc = rtems_task_create(
0129       rtems_build_name('I', 'S', 'R', 'L'),
0130       RTEMS_MINIMUM_PRIORITY,
0131       RTEMS_MINIMUM_STACK_SIZE,
0132       initial_modes,
0133       RTEMS_DEFAULT_ATTRIBUTES,
0134       &id
0135     );
0136     rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0137 
0138     sc = rtems_task_start(
0139       id,
0140       isr_level_check_task,
0141       (rtems_task_argument) &ctx
0142     );
0143     rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0144 
0145     sc = rtems_event_receive(
0146       TEST_ISR_EVENT,
0147       RTEMS_EVENT_ALL | RTEMS_WAIT,
0148       RTEMS_NO_TIMEOUT,
0149       &events
0150     );
0151     rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0152     rtems_test_assert( events == TEST_ISR_EVENT );
0153 
0154     if ( current <= last_proper_level ) {
0155       rtems_test_assert( ctx.actual_level == current );
0156     } else {
0157       rtems_test_assert( ctx.actual_level == last_proper_level );
0158     }
0159 
0160     sc = rtems_task_delete( id ) ;
0161     rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0162   }
0163 }
0164 
0165 static void test_isr_level( void )
0166 {
0167   ISR_Level mask = CPU_MODES_INTERRUPT_MASK;
0168   ISR_Level normal = _ISR_Get_level();
0169   ISR_Level current = 0;
0170   ISR_Level last_proper_level;
0171 
0172   /* Interrupts shall be disabled during system initialization */
0173   rtems_test_assert( boot_isr_level != 0 );
0174 
0175   _ISR_Set_level( current );
0176   rtems_test_assert( _ISR_Get_level() == current );
0177 
0178   for ( current = current + 1 ; current <= mask ; ++current ) {
0179     ISR_Level actual;
0180 
0181     _ISR_Set_level( current );
0182 
0183     actual = _ISR_Get_level();
0184     rtems_test_assert( actual == current || actual == ( current - 1 ) );
0185 
0186     if ( _ISR_Get_level() != current ) {
0187       break;
0188     }
0189   }
0190 
0191   last_proper_level = current - 1;
0192 
0193   for ( current = current + 1 ; current <= mask ; ++current ) {
0194     _ISR_Set_level( current );
0195     rtems_test_assert( _ISR_Get_level() == current );
0196   }
0197 
0198   _ISR_Set_level( normal );
0199 
0200   /*
0201    * Now test that the ISR level specified for _Thread_Initialize() propagates
0202    * properly to the thread.
0203    */
0204   test_isr_level_for_new_threads( last_proper_level );
0205 }
0206 
0207 static void test_isr_locks( void )
0208 {
0209   static const char name[] = "test";
0210   ISR_Level normal_interrupt_level = _ISR_Get_level();
0211 #if ISR_LOCK_NEEDS_OBJECT
0212   ISR_lock_Control initialized = ISR_LOCK_INITIALIZER( name );
0213   ISR_lock_Control zero_initialized;
0214   union {
0215     ISR_lock_Control lock;
0216     uint8_t bytes[ sizeof( ISR_lock_Control ) ];
0217   } container;
0218   size_t i;
0219   const uint8_t *bytes;
0220 #endif
0221   ISR_lock_Context lock_context;
0222   ISR_Level interrupt_level;
0223 
0224 #if ISR_LOCK_NEEDS_OBJECT
0225   memset( &container, 0xff, sizeof( container ) );
0226 #endif
0227 
0228   _ISR_lock_Initialize( &container.lock, name );
0229 
0230 #if ISR_LOCK_NEEDS_OBJECT
0231   bytes = (const uint8_t *) &initialized;
0232 
0233   for ( i = 0; i < sizeof( container ); ++i ) {
0234     if ( container.bytes[ i ] != 0xff ) {
0235       rtems_test_assert( container.bytes[ i ] == bytes[ i ] );
0236     }
0237   }
0238 
0239   memset( &zero_initialized, 0, sizeof( zero_initialized ) );
0240   _ISR_lock_Set_name( &zero_initialized, name );
0241   bytes = (const uint8_t *) &zero_initialized;
0242 
0243   for ( i = 0; i < sizeof( container ); ++i ) {
0244     if ( container.bytes[ i ] != 0xff ) {
0245       rtems_test_assert( container.bytes[ i ] == bytes[ i ] );
0246     }
0247   }
0248 #endif
0249 
0250   _ISR_lock_ISR_disable_and_acquire( &container.lock, &lock_context );
0251   rtems_test_assert( normal_interrupt_level != _ISR_Get_level() );
0252   _ISR_lock_Release_and_ISR_enable( &container.lock, &lock_context );
0253 
0254   rtems_test_assert( normal_interrupt_level == _ISR_Get_level() );
0255 
0256   _ISR_lock_ISR_disable( &lock_context );
0257   rtems_test_assert( normal_interrupt_level != _ISR_Get_level() );
0258   _ISR_lock_ISR_enable( &lock_context );
0259 
0260   rtems_test_assert( normal_interrupt_level == _ISR_Get_level() );
0261 
0262 #if defined(RTEMS_DEBUG)
0263   _ISR_lock_ISR_disable( &lock_context );
0264 #endif
0265   interrupt_level = _ISR_Get_level();
0266   _ISR_lock_Acquire( &container.lock, &lock_context );
0267   rtems_test_assert( interrupt_level == _ISR_Get_level() );
0268 #if !defined(RTEMS_DEBUG)
0269   rtems_test_assert( normal_interrupt_level == _ISR_Get_level() );
0270 #endif
0271   _ISR_lock_Release( &container.lock, &lock_context );
0272   rtems_test_assert( interrupt_level == _ISR_Get_level() );
0273 #if defined(RTEMS_DEBUG)
0274   _ISR_lock_ISR_enable( &lock_context );
0275 #endif
0276 
0277   rtems_test_assert( normal_interrupt_level == _ISR_Get_level() );
0278 
0279   _ISR_lock_Destroy( &container.lock );
0280   _ISR_lock_Destroy( &initialized );
0281 }
0282 
0283 static rtems_mode get_interrupt_level( void )
0284 {
0285   rtems_status_code sc;
0286   rtems_mode mode;
0287 
0288   sc = rtems_task_mode( RTEMS_CURRENT_MODE, RTEMS_CURRENT_MODE, &mode );
0289   rtems_test_assert( sc == RTEMS_SUCCESSFUL );
0290 
0291   return mode & RTEMS_INTERRUPT_MASK;
0292 }
0293 
0294 static void test_interrupt_locks( void )
0295 {
0296   rtems_mode normal_interrupt_level = get_interrupt_level();
0297   rtems_interrupt_lock initialized = RTEMS_INTERRUPT_LOCK_INITIALIZER("test");
0298   union {
0299     rtems_interrupt_lock lock;
0300     uint8_t bytes[ sizeof( rtems_interrupt_lock ) ];
0301   } container = {0};
0302   rtems_interrupt_lock_context lock_context;
0303   size_t i;
0304   const uint8_t *initialized_bytes;
0305 
0306   rtems_interrupt_lock_initialize( &container.lock, "test" );
0307   initialized_bytes = (const uint8_t *) &initialized;
0308 
0309   for ( i = 0; i < sizeof( container ); ++i ) {
0310     if ( container.bytes[ i ] != 0xff ) {
0311       rtems_test_assert( container.bytes[ i ] == initialized_bytes[ i] );
0312     }
0313   }
0314 
0315   rtems_interrupt_lock_acquire( &container.lock, &lock_context );
0316   rtems_test_assert( normal_interrupt_level != get_interrupt_level() );
0317   rtems_interrupt_lock_release( &container.lock, &lock_context );
0318 
0319   rtems_test_assert( normal_interrupt_level == get_interrupt_level() );
0320 
0321   rtems_interrupt_lock_acquire_isr( &container.lock, &lock_context );
0322   rtems_test_assert( normal_interrupt_level == get_interrupt_level() );
0323   rtems_interrupt_lock_release_isr( &container.lock, &lock_context );
0324 
0325   rtems_test_assert( normal_interrupt_level == get_interrupt_level() );
0326 
0327   rtems_interrupt_lock_destroy( &container.lock );
0328   rtems_interrupt_lock_destroy( &initialized );
0329 }
0330 
0331 static void test_clock_tick_functions( void )
0332 {
0333   rtems_interrupt_level level;
0334   Watchdog_Interval saved_ticks;
0335 
0336   rtems_interrupt_local_disable( level );
0337 
0338   saved_ticks = _Watchdog_Ticks_since_boot;
0339 
0340   _Watchdog_Ticks_since_boot = 0xdeadbeef;
0341   rtems_test_assert( rtems_clock_get_ticks_since_boot() == 0xdeadbeef );
0342 
0343   rtems_test_assert( rtems_clock_tick_later( 0 ) == 0xdeadbeef );
0344   rtems_test_assert( rtems_clock_tick_later( 0x8160311e ) == 0x600df00d );
0345 
0346   _Watchdog_Ticks_since_boot = 0;
0347   rtems_test_assert( rtems_clock_tick_later_usec( 0 ) == 1 );
0348   rtems_test_assert( rtems_clock_tick_later_usec( 1 ) == 2 );
0349   rtems_test_assert( rtems_clock_tick_later_usec( US_PER_TICK ) == 2 );
0350   rtems_test_assert( rtems_clock_tick_later_usec( US_PER_TICK + 1 ) == 3 );
0351 
0352   _Watchdog_Ticks_since_boot = 0;
0353   rtems_test_assert( !rtems_clock_tick_before( 0xffffffff ) );
0354   rtems_test_assert( !rtems_clock_tick_before( 0 ) );
0355   rtems_test_assert( rtems_clock_tick_before( 1 ) );
0356 
0357   _Watchdog_Ticks_since_boot = 1;
0358   rtems_test_assert( !rtems_clock_tick_before( 0 ) );
0359   rtems_test_assert( !rtems_clock_tick_before( 1 ) );
0360   rtems_test_assert( rtems_clock_tick_before( 2 ) );
0361 
0362   _Watchdog_Ticks_since_boot = 0x7fffffff;
0363   rtems_test_assert( !rtems_clock_tick_before( 0x7ffffffe ) );
0364   rtems_test_assert( !rtems_clock_tick_before( 0x7fffffff ) );
0365   rtems_test_assert( rtems_clock_tick_before( 0x80000000 ) );
0366 
0367   _Watchdog_Ticks_since_boot = 0x80000000;
0368   rtems_test_assert( !rtems_clock_tick_before( 0x7fffffff ) );
0369   rtems_test_assert( !rtems_clock_tick_before( 0x80000000 ) );
0370   rtems_test_assert( rtems_clock_tick_before( 0x80000001 ) );
0371 
0372   _Watchdog_Ticks_since_boot = 0xffffffff;
0373   rtems_test_assert( !rtems_clock_tick_before( 0xfffffffe ) );
0374   rtems_test_assert( !rtems_clock_tick_before( 0xffffffff ) );
0375   rtems_test_assert( rtems_clock_tick_before( 0 ) );
0376 
0377   _Watchdog_Ticks_since_boot = saved_ticks;
0378 
0379   rtems_interrupt_local_enable( level );
0380 }
0381 
0382 void test_interrupt_inline(void)
0383 {
0384   rtems_interrupt_level level;
0385   rtems_interrupt_level level_1;
0386   rtems_mode            level_mode_body;
0387   rtems_mode            level_mode_macro;
0388   bool                  in_isr;
0389   uint32_t              isr_level_0;
0390   uint32_t              isr_level_1;
0391   uint32_t              isr_level_2;
0392 
0393   puts( "interrupt is in progress (use body)" );
0394   in_isr = rtems_interrupt_is_in_progress();
0395   if ( in_isr ) {
0396     puts( "interrupt reported to be is in progress (body)" );
0397     rtems_test_exit( 0 );
0398   }
0399 
0400 #if !defined(RTEMS_SMP)
0401   puts( "interrupt disable (use inline)" );
0402   rtems_interrupt_disable( level );
0403 
0404   puts( "interrupt flash (use inline)" );
0405   rtems_interrupt_flash( level );
0406 
0407   puts( "interrupt enable (use inline)" );
0408   rtems_interrupt_enable( level );
0409 #endif /* RTEMS_SMP */
0410 
0411   isr_level_0 = _ISR_Get_level();
0412   rtems_test_assert( isr_level_0 == 0 );
0413 
0414   rtems_interrupt_local_disable( level );
0415   isr_level_1 = _ISR_Get_level();
0416   rtems_test_assert( isr_level_1 != isr_level_0 );
0417   rtems_test_assert( _ISR_Is_enabled( level ) );
0418 
0419   rtems_interrupt_local_disable( level_1 );
0420   isr_level_2 = _ISR_Get_level();
0421   rtems_test_assert( isr_level_2 == isr_level_1 );
0422   rtems_test_assert( !_ISR_Is_enabled( level_1 ) );
0423 
0424   rtems_interrupt_local_enable( level_1 );
0425   rtems_test_assert( _ISR_Get_level() == isr_level_1 );
0426 
0427   rtems_interrupt_local_enable( level );
0428   rtems_test_assert( _ISR_Get_level() == isr_level_0 );
0429 
0430   puts( "interrupt level mode (use inline)" );
0431   level_mode_body = rtems_interrupt_level_body( level );
0432   level_mode_macro = RTEMS_INTERRUPT_LEVEL(level);
0433   if ( level_mode_macro == level_mode_body ) {
0434     puts( "test case working.." );
0435   }
0436 }
0437 
0438 volatile int isr_in_progress_body;
0439 
0440 volatile int isr_in_progress_inline;
0441 
0442 void check_isr_in_progress_inline(void)
0443 {
0444   isr_in_progress_inline = rtems_interrupt_is_in_progress() ? 1 : 2;
0445 }
0446 
0447 void check_isr_worked(
0448   char *s,
0449   int   result
0450 )
0451 {
0452   switch (result) {
0453     case 0:
0454       printf( "isr_in_progress(%s) timer did not fire\n", s );
0455       rtems_test_exit(0);
0456       break;
0457     case 1:
0458       printf( "isr_in_progress(%s) from ISR -- OK\n", s );
0459       break;
0460     default:
0461       printf( "isr_in_progress(%s) from ISR -- returned bad value\n", s);
0462       rtems_test_exit(0);
0463       break;
0464   }
0465 }
0466 
0467 volatile int blocked_task_status;
0468 rtems_id     blocked_task_id;
0469 
0470 rtems_task blocked_task(
0471   rtems_task_argument argument
0472 )
0473 {
0474   rtems_status_code     status;
0475 
0476   puts( "Blocking task... suspending self" );
0477   blocked_task_status = 1;
0478   status = rtems_task_suspend( RTEMS_SELF );
0479   directive_failed( status, "rtems_task_suspend" );
0480 
0481   blocked_task_status = 3;
0482   rtems_task_exit();
0483 }
0484 
0485 /*
0486  *  Timer Service Routine
0487  *
0488  *  If we are in an ISR, then this is a normal clock tick.
0489  *  If we are not, then it is the test case.
0490  */
0491 rtems_timer_service_routine test_unblock_task(
0492   rtems_id  timer,
0493   void     *arg
0494 )
0495 {
0496   bool               in_isr;
0497   rtems_status_code  status;
0498   Per_CPU_Control   *cpu_self;
0499 
0500   in_isr = rtems_interrupt_is_in_progress();
0501   status = rtems_task_is_suspended( blocked_task_id );
0502   if ( in_isr ) {
0503     status = rtems_timer_fire_after( timer, 1, test_unblock_task, NULL );
0504     directive_failed( status, "timer_fire_after failed" );
0505     return;
0506   }
0507 
0508   if ( (status != RTEMS_ALREADY_SUSPENDED) ) {
0509     status = rtems_timer_fire_after( timer, 1, test_unblock_task, NULL );
0510     directive_failed( status, "timer_fire_after failed" );
0511     return;
0512   }
0513 
0514   blocked_task_status = 2;
0515   cpu_self = _Thread_Dispatch_disable();
0516   status = rtems_task_resume( blocked_task_id );
0517   _Thread_Dispatch_enable( cpu_self );
0518   directive_failed( status, "rtems_task_resume" );
0519 }
0520 
0521 #undef rtems_interrupt_disable
0522 extern rtems_interrupt_level rtems_interrupt_disable(void);
0523 #undef rtems_interrupt_enable
0524 extern void rtems_interrupt_enable(rtems_interrupt_level previous_level);
0525 #undef rtems_interrupt_flash
0526 extern void rtems_interrupt_flash(rtems_interrupt_level previous_level);
0527 #undef rtems_interrupt_is_in_progress
0528 extern bool rtems_interrupt_is_in_progress(void);
0529 
0530 static void test_interrupt_body(void)
0531 {
0532 #if !defined(RTEMS_SMP)
0533   rtems_interrupt_level level_0;
0534   rtems_interrupt_level level_1;
0535   rtems_mode            level_mode_body;
0536   rtems_mode            level_mode_macro;
0537   bool                  in_isr;
0538 
0539   puts( "interrupt disable (use body)" );
0540   level_0 = rtems_interrupt_disable();
0541 
0542   puts( "interrupt disable (use body)" );
0543   level_1 = rtems_interrupt_disable();
0544 
0545   puts( "interrupt flash (use body)" );
0546   rtems_interrupt_flash( level_1 );
0547 
0548   puts( "interrupt enable (use body)" );
0549   rtems_interrupt_enable( level_1 );
0550 
0551   puts( "interrupt level mode (use body)" );
0552   level_mode_body = rtems_interrupt_level_body( level_0 );
0553   level_mode_macro = RTEMS_INTERRUPT_LEVEL( level_0 );
0554   if ( level_mode_macro == level_mode_body ) {
0555     puts("test seems to work");
0556   }
0557 
0558   /*
0559    *  Test interrupt bodies
0560    */
0561   puts( "interrupt is in progress (use body)" );
0562   in_isr = rtems_interrupt_is_in_progress();
0563 
0564   puts( "interrupt enable (use body)" );
0565   rtems_interrupt_enable( level_0 );
0566 
0567   if ( in_isr ) {
0568     puts( "interrupt reported to be is in progress (body)" );
0569     rtems_test_exit( 0 );
0570   }
0571 #endif /* RTEMS_SMP */
0572 }
0573 
0574 rtems_timer_service_routine test_isr_in_progress(
0575   rtems_id  timer,
0576   void     *arg
0577 )
0578 {
0579   check_isr_in_progress_inline();
0580 
0581   isr_in_progress_body = rtems_interrupt_is_in_progress() ? 1 : 2;
0582 }
0583 
0584 rtems_task Init(
0585   rtems_task_argument argument
0586 )
0587 {
0588   rtems_time_of_day     time;
0589   rtems_status_code     status;
0590   rtems_id              timer;
0591   int                   i;
0592 
0593   TEST_BEGIN();
0594 
0595   test_isr_level();
0596   test_isr_locks();
0597   test_interrupt_locks();
0598 
0599   build_time( &time, 12, 31, 1988, 9, 0, 0, 0 );
0600   status = rtems_clock_set( &time );
0601   directive_failed( status, "rtems_clock_set" );
0602 
0603   /*
0604    *  Timer used in multiple ways
0605    */
0606   status = rtems_timer_create( 1, &timer );
0607   directive_failed( status, "rtems_timer_create" );
0608 
0609   /*
0610    *  Test clock tick from outside ISR
0611    */
0612   status = rtems_clock_tick();
0613   directive_failed( status, "rtems_clock_tick" );
0614   puts( "clock_tick from task level" );
0615 
0616   test_clock_tick_functions();
0617 
0618   /*
0619    *  Now do a dispatch directly out of a clock tick that is
0620    *  called from a task.  We need to create a task that will
0621    *  block so we have one to unblock.  Then we schedule a TSR
0622    *  to run in the clock tick but it has to be careful to
0623    *  make sure it is not called from an ISR and that the
0624    *  dispatching critical section is managed properly to
0625    *  make the dispatch happen.
0626    */
0627 
0628   blocked_task_status = -1;
0629 
0630   status = rtems_task_create(
0631     rtems_build_name( 'T', 'A', '1', ' ' ),
0632     1,
0633     RTEMS_MINIMUM_STACK_SIZE,
0634     RTEMS_DEFAULT_MODES,
0635     RTEMS_DEFAULT_ATTRIBUTES,
0636     &blocked_task_id
0637   );
0638   directive_failed( status, "rtems_task_create" );
0639 
0640   status = rtems_task_start( blocked_task_id, blocked_task, 0 );
0641   directive_failed( status, "rtems_task_start" );
0642 
0643   status = rtems_task_wake_after( 10 );
0644   directive_failed( status, "rtems_task_wake_after" );
0645 
0646   status = rtems_timer_fire_after( timer, 1, test_unblock_task, NULL );
0647   directive_failed( status, "timer_fire_after failed" );
0648 
0649   /* we expect to be preempted from this call */
0650   for ( i=0 ; i<100 && blocked_task_status != 3 ; i++ ) {
0651     status = rtems_clock_tick();
0652     directive_failed( status, "rtems_clock_tick" );
0653   }
0654   switch ( blocked_task_status ) {
0655      case -1:
0656        puts(
0657          "clock_tick with task preempt -- task blocked, timer did not fire"
0658        );
0659        rtems_test_exit(0);
0660        break;
0661      case 1:
0662        puts( "clock_tick with task preempt -- timer fired case 1" );
0663        rtems_test_exit(0);
0664        break;
0665      case 2:
0666        puts( "clock_tick with task preempt -- timer fired case 2" );
0667        rtems_test_exit(0);
0668        break;
0669      case 3:
0670        puts( "clock_tick from task level with preempt -- OK" );
0671        break;
0672   }
0673 
0674   test_interrupt_inline();
0675   test_interrupt_body();
0676 
0677   /*
0678    * Test ISR in progress from actual ISR
0679    */
0680   status = rtems_timer_fire_after( timer, 10, test_isr_in_progress, NULL );
0681   directive_failed( status, "timer_fire_after failed" );
0682 
0683   status = rtems_task_wake_after( 11 );
0684   directive_failed( status, "wake_after failed" );
0685 
0686   check_isr_worked( "inline", isr_in_progress_inline );
0687 
0688   check_isr_worked( "body", isr_in_progress_body );
0689 
0690   TEST_END();
0691   rtems_test_exit( 0 );
0692 }