Changeset cdf30f05 in rtems


Ignore:
Timestamp:
Jun 19, 2015, 12:57:44 PM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
df8341a
Parents:
f9090ac
git-author:
Sebastian Huber <sebastian.huber@…> (06/19/15 12:57:44)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/22/15 06:40:26)
Message:

rtems: Add rtems_interrupt_local_disable|enable()

Add rtems_interrupt_local_disable|enable() as suggested by Pavel Pisa to
emphasize that interrupts are only disabled on the current processor.
Do not define the rtems_interrupt_disable|enable|flash() macros and
functions on SMP configurations since they don't ensure system wide
mutual exclusion.

Files:
10 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/shared/bootcard.c

    rf9090ac rcdf30f05  
    7373   */
    7474  (void) bsp_isr_level;
    75   rtems_interrupt_disable( bsp_isr_level );
     75  rtems_interrupt_local_disable( bsp_isr_level );
    7676
    7777  bsp_boot_cmdline = cmdline;
  • cpukit/rtems/include/rtems/rtems/intr.h

    rf9090ac rcdf30f05  
    9090#endif
    9191
     92#if !defined(RTEMS_SMP)
     93
    9294/**
    9395 *  @brief Disable RTEMS Interrupt
    9496 *
    9597 *  @note The interrupt level shall be of type @ref rtems_interrupt_level.
     98 *
     99 *  This macro is only available on uni-processor configurations.  The macro
     100 *  rtems_interrupt_local_disable() is available on all configurations.
    96101 */
    97102#define rtems_interrupt_disable( _isr_cookie ) \
     
    102107 *
    103108 *  @note The interrupt level shall be of type @ref rtems_interrupt_level.
     109 *
     110 *  This macro is only available on uni-processor configurations.  The macro
     111 *  rtems_interrupt_local_enable() is available on all configurations.
    104112 */
    105113#define rtems_interrupt_enable( _isr_cookie ) \
     
    110118 *
    111119 *  @note The interrupt level shall be of type @ref rtems_interrupt_level.
     120 *
     121 *  This macro is only available on uni-processor configurations.  The macro
     122 *  rtems_interrupt_local_disable() and rtems_interrupt_local_enable() is
     123 *  available on all configurations.
    112124 */
    113125#define rtems_interrupt_flash( _isr_cookie ) \
    114126    _ISR_Flash(_isr_cookie)
     127
     128#endif /* RTEMS_SMP */
     129
     130/**
     131 * @brief This macro disables the interrupts on the current processor.
     132 *
     133 * On SMP configurations this will not ensure system wide mutual exclusion.
     134 * Use interrupt locks instead.
     135 *
     136 * @param[in] _isr_cookie The previous interrupt level is returned.  The type
     137 *   of this variable must be rtems_interrupt_level.
     138 *
     139 * @see rtems_interrupt_local_enable().
     140 */
     141#define rtems_interrupt_local_disable( _isr_cookie ) \
     142  _ISR_Disable_without_giant( _isr_cookie )
     143
     144/**
     145 * @brief This macro restores the previous interrupt level on the current
     146 * processor.
     147 *
     148 * @param[in] _isr_cookie The previous interrupt level returned by
     149 *   rtems_interrupt_local_disable().
     150 */
     151#define rtems_interrupt_local_enable( _isr_cookie ) \
     152  _ISR_Enable_without_giant( _isr_cookie )
    115153
    116154/**
  • cpukit/rtems/src/intrbody.c

    rf9090ac rcdf30f05  
    2424#include <rtems/rtems/intr.h>
    2525
     26#if !defined(RTEMS_SMP)
     27
    2628/*
    2729 *  Undefine all of these is normally a macro and we want a real body in
     
    3133#undef rtems_interrupt_enable
    3234#undef rtems_interrupt_flash
    33 #undef rtems_interrupt_is_in_progress
    3435
    3536/*
     
    3940void rtems_interrupt_enable( rtems_interrupt_level previous_level );
    4041void rtems_interrupt_flash( rtems_interrupt_level previous_level );
    41 bool rtems_interrupt_is_in_progress( void );
    4242
    4343/*
     
    6767}
    6868
     69#endif /* RTEMS_SMP */
     70
     71#undef rtems_interrupt_is_in_progress
     72bool rtems_interrupt_is_in_progress( void );
     73
    6974bool rtems_interrupt_is_in_progress( void )
    7075{
  • doc/user/intr.t

    rf9090ac rcdf30f05  
    2222@item @code{@value{DIRPREFIX}interrupt_enable} - Enable Interrupts
    2323@item @code{@value{DIRPREFIX}interrupt_flash} - Flash Interrupt
     24@item @code{@value{DIRPREFIX}interrupt_local_disable} - Disable Interrupts on Current Processor
     25@item @code{@value{DIRPREFIX}interrupt_local_enable} - Enable Interrupts on Current Processor
    2426@item @code{@value{DIRPREFIX}interrupt_lock_initialize} - Initialize an ISR Lock
    2527@item @code{@value{DIRPREFIX}interrupt_lock_acquire} - Acquire an ISR Lock
     
    398400@end ifset
    399401
     402This directive is only available on uni-processor configurations.  The
     403directive @code{@value{DIRPREFIX}interrupt_local_disable} is available on all
     404configurations.
     405
    400406@c
    401407@c
     
    442448This directive will not cause the calling task to be preempted.
    443449
     450This directive is only available on uni-processor configurations.  The
     451directive @code{@value{DIRPREFIX}interrupt_local_enable} is available on all
     452configurations.
    444453
    445454@c
     
    487496This directive will not cause the calling task to be preempted.
    488497
     498This directive is only available on uni-processor configurations.  The
     499directives @code{@value{DIRPREFIX}interrupt_local_disable} and
     500@code{@value{DIRPREFIX}interrupt_local_enable} is available on all
     501configurations.
     502
     503@c
     504@c
     505@c
     506@page
     507@subsection INTERRUPT_LOCAL_DISABLE - Disable Interrupts on Current Processor
     508
     509@cindex disable interrupts
     510
     511@subheading CALLING SEQUENCE:
     512
     513@ifset is-C
     514@findex rtems_interrupt_local_disable
     515@example
     516void rtems_interrupt_local_disable(
     517  rtems_interrupt_level  level
     518);
     519
     520/* this is implemented as a macro and sets level as a side-effect */
     521@end example
     522@end ifset
     523
     524@subheading DIRECTIVE STATUS CODES:
     525
     526NONE
     527
     528@subheading DESCRIPTION:
     529
     530This directive disables all maskable interrupts and returns
     531the previous @code{level}.  A later invocation of the
     532@code{@value{DIRPREFIX}interrupt_local_enable} directive should be used to
     533restore the interrupt level.
     534
     535@subheading NOTES:
     536
     537This directive will not cause the calling task to be preempted.
     538
     539@ifset is-C
     540@b{This directive is implemented as a macro which modifies the @code{level}
     541parameter.}
     542@end ifset
     543
     544On SMP configurations this will not ensure system wide mutual exclusion.  Use
     545interrupt locks instead.
     546
     547@c
     548@c
     549@c
     550@page
     551@subsection INTERRUPT_LOCAL_ENABLE - Enable Interrupts on Current Processor
     552
     553@cindex enable interrupts
     554
     555@subheading CALLING SEQUENCE:
     556
     557@ifset is-C
     558@findex rtems_interrupt_local_enable
     559@example
     560void rtems_interrupt_local_enable(
     561  rtems_interrupt_level  level
     562);
     563@end example
     564@end ifset
     565
     566@subheading DIRECTIVE STATUS CODES:
     567
     568NONE
     569
     570@subheading DESCRIPTION:
     571
     572This directive enables maskable interrupts to the @code{level}
     573which was returned by a previous call to
     574@code{@value{DIRPREFIX}interrupt_local_disable}.
     575Immediately prior to invoking this directive, maskable interrupts should
     576be disabled by a call to @code{@value{DIRPREFIX}interrupt_local_disable}
     577and will be enabled when this directive returns to the caller.
     578
     579@subheading NOTES:
     580
     581This directive will not cause the calling task to be preempted.
     582
    489583@c
    490584@c
  • testsuites/libtests/heapwalk/init.c

    rf9090ac rcdf30f05  
    9595  puts( "start with a system state != SYSTEM_STATE_UP" );
    9696
    97   rtems_interrupt_disable( level );
     97  rtems_interrupt_local_disable( level );
    9898  System_state_Codes state = _System_state_Get();
    9999  _System_state_Set( SYSTEM_STATE_TERMINATED );
    100100  test_call_heap_walk( true );
    101101  _System_state_Set( state );
    102   rtems_interrupt_enable( level );
     102  rtems_interrupt_local_enable( level );
    103103}
    104104
  • testsuites/samples/Makefile.am

    rf9090ac rcdf30f05  
    1919## loopback tests a network loopback interface
    2020_SUBDIRS += loopback
     21if HAS_SMP
     22else
    2123_SUBDIRS += pppd
     24endif
    2225endif
    2326
  • testsuites/samples/configure.ac

    rf9090ac rcdf30f05  
    2727RTEMS_CHECK_CXX(RTEMS_BSP)
    2828RTEMS_CHECK_CPUOPTS([RTEMS_NETWORKING])
     29RTEMS_CHECK_CPUOPTS([RTEMS_SMP])
    2930
    3031CXXTESTS=$HAS_CPLUSPLUS
     
    5354AM_CONDITIONAL(NETTESTS,test "$rtems_cv_RTEMS_NETWORKING" = "yes")
    5455AM_CONDITIONAL(MPTESTS,test "$rtems_cv_RTEMS_MULTIPROCESSING" = "yes")
     56AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes")
    5557
    5658# FIXME: We should get rid of this. It's a cludge.
  • testsuites/sptests/sp37/init.c

    rf9090ac rcdf30f05  
    244244  Watchdog_Interval saved_ticks;
    245245
    246   _Thread_Disable_dispatch();
    247   rtems_interrupt_disable( level );
     246  rtems_interrupt_local_disable( level );
    248247
    249248  saved_ticks = _Watchdog_Ticks_since_boot;
     
    288287  _Watchdog_Ticks_since_boot = saved_ticks;
    289288
    290   rtems_interrupt_enable( level );
    291   _Thread_Enable_dispatch();
     289  rtems_interrupt_local_enable( level );
    292290}
    293291
     
    295293{
    296294  rtems_interrupt_level level;
     295  rtems_interrupt_level level_1;
    297296  rtems_mode            level_mode_body;
    298297  rtems_mode            level_mode_macro;
    299298  bool                  in_isr;
     299  uint32_t              isr_level_0;
     300  uint32_t              isr_level_1;
     301  uint32_t              isr_level_2;
    300302
    301303  puts( "interrupt is in progress (use body)" );
     
    306308  }
    307309
     310#if !defined(RTEMS_SMP)
    308311  puts( "interrupt disable (use inline)" );
    309   _Thread_Disable_dispatch();
    310312  rtems_interrupt_disable( level );
    311   _Thread_Enable_dispatch();
    312313
    313314  puts( "interrupt flash (use inline)" );
    314   _Thread_Disable_dispatch();
    315315  rtems_interrupt_flash( level );
    316   _Thread_Enable_dispatch();
    317316
    318317  puts( "interrupt enable (use inline)" );
    319   _Thread_Disable_dispatch();
    320318  rtems_interrupt_enable( level );
    321   _Thread_Enable_dispatch();
     319#endif /* RTEMS_SMP */
     320
     321  isr_level_0 = _ISR_Get_level();
     322  rtems_test_assert( isr_level_0 == 0 );
     323
     324  rtems_interrupt_local_disable( level );
     325  isr_level_1 = _ISR_Get_level();
     326  rtems_test_assert( isr_level_1 != isr_level_0 );
     327
     328  rtems_interrupt_local_disable( level_1 );
     329  isr_level_2 = _ISR_Get_level();
     330  rtems_test_assert( isr_level_2 == isr_level_1 );
     331
     332  rtems_interrupt_local_enable( level_1 );
     333  rtems_test_assert( _ISR_Get_level() == isr_level_1 );
     334
     335  rtems_interrupt_local_enable( level );
     336  rtems_test_assert( _ISR_Get_level() == isr_level_0 );
    322337
    323338  puts( "interrupt level mode (use inline)" );
     
    330345
    331346volatile int isr_in_progress_body;
     347
    332348volatile int isr_in_progress_inline;
    333349
     
    335351{
    336352  isr_in_progress_inline = rtems_interrupt_is_in_progress() ? 1 : 2;
    337 }
    338 
    339 #undef rtems_interrupt_disable
    340 extern rtems_interrupt_level rtems_interrupt_disable(void);
    341 #undef rtems_interrupt_enable
    342 extern void rtems_interrupt_enable(rtems_interrupt_level previous_level);
    343 #undef rtems_interrupt_flash
    344 extern void rtems_interrupt_flash(rtems_interrupt_level previous_level);
    345 #undef rtems_interrupt_is_in_progress
    346 extern bool rtems_interrupt_is_in_progress(void);
    347 
    348 rtems_timer_service_routine test_isr_in_progress(
    349   rtems_id  timer,
    350   void     *arg
    351 )
    352 {
    353   check_isr_in_progress_inline();
    354 
    355   isr_in_progress_body = rtems_interrupt_is_in_progress() ? 1 : 2;
    356353}
    357354
     
    430427}
    431428
    432 rtems_task Init(
    433   rtems_task_argument argument
    434 )
    435 {
    436   rtems_time_of_day     time;
    437   rtems_status_code     status;
     429#undef rtems_interrupt_disable
     430extern rtems_interrupt_level rtems_interrupt_disable(void);
     431#undef rtems_interrupt_enable
     432extern void rtems_interrupt_enable(rtems_interrupt_level previous_level);
     433#undef rtems_interrupt_flash
     434extern void rtems_interrupt_flash(rtems_interrupt_level previous_level);
     435#undef rtems_interrupt_is_in_progress
     436extern bool rtems_interrupt_is_in_progress(void);
     437
     438static void test_interrupt_body(void)
     439{
     440#if !defined(RTEMS_SMP)
    438441  rtems_interrupt_level level;
    439442  rtems_mode            level_mode_body;
    440443  rtems_mode            level_mode_macro;
    441444  bool                  in_isr;
     445
     446  puts( "interrupt disable (use body)" );
     447  level = rtems_interrupt_disable();
     448
     449  puts( "interrupt disable (use body)" );
     450  level = rtems_interrupt_disable();
     451
     452  puts( "interrupt flash (use body)" );
     453  rtems_interrupt_flash( level );
     454
     455  puts( "interrupt enable (use body)" );
     456  rtems_interrupt_enable( level );
     457
     458  puts( "interrupt level mode (use body)" );
     459  level_mode_body = rtems_interrupt_level_body( level );
     460  level_mode_macro = RTEMS_INTERRUPT_LEVEL(level);
     461  if ( level_mode_macro == level_mode_body ) {
     462    puts("test seems to work");
     463  }
     464
     465  /*
     466   *  Test interrupt bodies
     467   */
     468  puts( "interrupt is in progress (use body)" );
     469  in_isr = rtems_interrupt_is_in_progress();
     470  if ( in_isr ) {
     471    puts( "interrupt reported to be is in progress (body)" );
     472    rtems_test_exit( 0 );
     473  }
     474#endif /* RTEMS_SMP */
     475}
     476
     477rtems_timer_service_routine test_isr_in_progress(
     478  rtems_id  timer,
     479  void     *arg
     480)
     481{
     482  check_isr_in_progress_inline();
     483
     484  isr_in_progress_body = rtems_interrupt_is_in_progress() ? 1 : 2;
     485}
     486
     487rtems_task Init(
     488  rtems_task_argument argument
     489)
     490{
     491  rtems_time_of_day     time;
     492  rtems_status_code     status;
    442493  rtems_id              timer;
    443494  int                   i;
     
    524575  }
    525576
    526   /*
    527    *  Test interrupt inline versions
    528    */
    529577  test_interrupt_inline();
    530 
    531   /*
    532    *  Test interrupt bodies
    533    */
    534   puts( "interrupt is in progress (use body)" );
    535   in_isr = rtems_interrupt_is_in_progress();
    536   if ( in_isr ) {
    537     puts( "interrupt reported to be is in progress (body)" );
    538     rtems_test_exit( 0 );
    539   }
    540 
    541   puts( "interrupt disable (use body)" );
    542   _Thread_Disable_dispatch();
    543   level = rtems_interrupt_disable();
    544   _Thread_Enable_dispatch();
    545 
    546   puts( "interrupt disable (use body)" );
    547   _Thread_Disable_dispatch();
    548   level = rtems_interrupt_disable();
    549   _Thread_Enable_dispatch();
    550 
    551   puts( "interrupt flash (use body)" );
    552   _Thread_Disable_dispatch();
    553   rtems_interrupt_flash( level );
    554   _Thread_Enable_dispatch();
    555 
    556   puts( "interrupt enable (use body)" );
    557   _Thread_Disable_dispatch();
    558   rtems_interrupt_enable( level );
    559   _Thread_Enable_dispatch();
    560 
    561   puts( "interrupt level mode (use body)" );
    562   level_mode_body = rtems_interrupt_level_body( level );
    563   level_mode_macro = RTEMS_INTERRUPT_LEVEL(level);
    564   if ( level_mode_macro == level_mode_body ) {
    565     puts("test seems to work");
    566   }
     578  test_interrupt_body();
    567579
    568580  /*
  • testsuites/sptests/sp40/init.c

    rf9090ac rcdf30f05  
    4343#define test_interrupt_context_enter( level ) \
    4444  do { \
    45     _Thread_Disable_dispatch(); \
    46     rtems_interrupt_disable( level ); \
     45    rtems_interrupt_local_disable( level ); \
    4746    ++_ISR_Nest_level; \
    4847  } while (0)
     
    5150  do { \
    5251    --_ISR_Nest_level; \
    53     rtems_interrupt_enable( level ); \
    54     _Thread_Enable_dispatch(); \
     52    rtems_interrupt_local_enable( level ); \
    5553  } while (0)
    5654
  • testsuites/tmtests/tm26/task1.c

    rf9090ac rcdf30f05  
    342342
    343343  benchmark_timer_initialize();
    344     rtems_interrupt_disable( level );
     344    rtems_interrupt_local_disable( level );
    345345  isr_disable_time = benchmark_timer_read();
    346346
    347347  benchmark_timer_initialize();
     348#if defined(RTEMS_SMP)
     349    rtems_interrupt_local_enable( level );
     350    rtems_interrupt_local_disable( level );
     351#else
    348352    rtems_interrupt_flash( level );
     353#endif
    349354  isr_flash_time = benchmark_timer_read();
    350355
    351356  benchmark_timer_initialize();
    352     rtems_interrupt_enable( level );
     357    rtems_interrupt_local_enable( level );
    353358  isr_enable_time = benchmark_timer_read();
    354359
Note: See TracChangeset for help on using the changeset viewer.