From cdf30f0550432648ac005e3f71814b7f708a4ce3 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 19 Jun 2015 14:57:44 +0200 Subject: 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. --- testsuites/libtests/heapwalk/init.c | 4 +- testsuites/samples/Makefile.am | 3 + testsuites/samples/configure.ac | 2 + testsuites/sptests/sp37/init.c | 158 +++++++++++++++++++----------------- testsuites/sptests/sp40/init.c | 6 +- testsuites/tmtests/tm26/task1.c | 9 +- 6 files changed, 101 insertions(+), 81 deletions(-) (limited to 'testsuites') diff --git a/testsuites/libtests/heapwalk/init.c b/testsuites/libtests/heapwalk/init.c index 80073e8f50..3bd6c91ce4 100644 --- a/testsuites/libtests/heapwalk/init.c +++ b/testsuites/libtests/heapwalk/init.c @@ -94,12 +94,12 @@ static void test_system_not_up(void) puts( "start with a system state != SYSTEM_STATE_UP" ); - rtems_interrupt_disable( level ); + rtems_interrupt_local_disable( level ); System_state_Codes state = _System_state_Get(); _System_state_Set( SYSTEM_STATE_TERMINATED ); test_call_heap_walk( true ); _System_state_Set( state ); - rtems_interrupt_enable( level ); + rtems_interrupt_local_enable( level ); } static void test_check_control(void) diff --git a/testsuites/samples/Makefile.am b/testsuites/samples/Makefile.am index 08455d3742..374617b7e4 100644 --- a/testsuites/samples/Makefile.am +++ b/testsuites/samples/Makefile.am @@ -18,8 +18,11 @@ endif if NETTESTS ## loopback tests a network loopback interface _SUBDIRS += loopback +if HAS_SMP +else _SUBDIRS += pppd endif +endif include $(top_srcdir)/../automake/test-subdirs.am include $(top_srcdir)/../automake/local.am diff --git a/testsuites/samples/configure.ac b/testsuites/samples/configure.ac index e6f12d032f..91a36612df 100644 --- a/testsuites/samples/configure.ac +++ b/testsuites/samples/configure.ac @@ -26,6 +26,7 @@ RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP) RTEMS_CHECK_CPUOPTS([RTEMS_MULTIPROCESSING]) RTEMS_CHECK_CXX(RTEMS_BSP) RTEMS_CHECK_CPUOPTS([RTEMS_NETWORKING]) +RTEMS_CHECK_CPUOPTS([RTEMS_SMP]) CXXTESTS=$HAS_CPLUSPLUS AS_IF([test $HAS_CPLUSPLUS = yes],[ @@ -52,6 +53,7 @@ AS_IF([test $HAS_CPLUSPLUS = yes],[ AM_CONDITIONAL([CXXTESTS],[test $CXXTESTS = "yes"]) AM_CONDITIONAL(NETTESTS,test "$rtems_cv_RTEMS_NETWORKING" = "yes") AM_CONDITIONAL(MPTESTS,test "$rtems_cv_RTEMS_MULTIPROCESSING" = "yes") +AM_CONDITIONAL(HAS_SMP,test "$rtems_cv_RTEMS_SMP" = "yes") # FIXME: We should get rid of this. It's a cludge. AC_CHECK_SIZEOF([time_t]) diff --git a/testsuites/sptests/sp37/init.c b/testsuites/sptests/sp37/init.c index 0846491700..1dd434f52c 100644 --- a/testsuites/sptests/sp37/init.c +++ b/testsuites/sptests/sp37/init.c @@ -243,8 +243,7 @@ static void test_clock_tick_functions( void ) rtems_interrupt_level level; Watchdog_Interval saved_ticks; - _Thread_Disable_dispatch(); - rtems_interrupt_disable( level ); + rtems_interrupt_local_disable( level ); saved_ticks = _Watchdog_Ticks_since_boot; @@ -287,16 +286,19 @@ static void test_clock_tick_functions( void ) _Watchdog_Ticks_since_boot = saved_ticks; - rtems_interrupt_enable( level ); - _Thread_Enable_dispatch(); + rtems_interrupt_local_enable( level ); } void test_interrupt_inline(void) { rtems_interrupt_level level; + rtems_interrupt_level level_1; rtems_mode level_mode_body; rtems_mode level_mode_macro; bool in_isr; + uint32_t isr_level_0; + uint32_t isr_level_1; + uint32_t isr_level_2; puts( "interrupt is in progress (use body)" ); in_isr = rtems_interrupt_is_in_progress(); @@ -305,20 +307,33 @@ void test_interrupt_inline(void) rtems_test_exit( 0 ); } +#if !defined(RTEMS_SMP) puts( "interrupt disable (use inline)" ); - _Thread_Disable_dispatch(); rtems_interrupt_disable( level ); - _Thread_Enable_dispatch(); puts( "interrupt flash (use inline)" ); - _Thread_Disable_dispatch(); rtems_interrupt_flash( level ); - _Thread_Enable_dispatch(); puts( "interrupt enable (use inline)" ); - _Thread_Disable_dispatch(); rtems_interrupt_enable( level ); - _Thread_Enable_dispatch(); +#endif /* RTEMS_SMP */ + + isr_level_0 = _ISR_Get_level(); + rtems_test_assert( isr_level_0 == 0 ); + + rtems_interrupt_local_disable( level ); + isr_level_1 = _ISR_Get_level(); + rtems_test_assert( isr_level_1 != isr_level_0 ); + + rtems_interrupt_local_disable( level_1 ); + isr_level_2 = _ISR_Get_level(); + rtems_test_assert( isr_level_2 == isr_level_1 ); + + rtems_interrupt_local_enable( level_1 ); + rtems_test_assert( _ISR_Get_level() == isr_level_1 ); + + rtems_interrupt_local_enable( level ); + rtems_test_assert( _ISR_Get_level() == isr_level_0 ); puts( "interrupt level mode (use inline)" ); level_mode_body = rtems_interrupt_level_body( level ); @@ -329,6 +344,7 @@ void test_interrupt_inline(void) } volatile int isr_in_progress_body; + volatile int isr_in_progress_inline; void check_isr_in_progress_inline(void) @@ -336,25 +352,6 @@ void check_isr_in_progress_inline(void) isr_in_progress_inline = rtems_interrupt_is_in_progress() ? 1 : 2; } -#undef rtems_interrupt_disable -extern rtems_interrupt_level rtems_interrupt_disable(void); -#undef rtems_interrupt_enable -extern void rtems_interrupt_enable(rtems_interrupt_level previous_level); -#undef rtems_interrupt_flash -extern void rtems_interrupt_flash(rtems_interrupt_level previous_level); -#undef rtems_interrupt_is_in_progress -extern bool rtems_interrupt_is_in_progress(void); - -rtems_timer_service_routine test_isr_in_progress( - rtems_id timer, - void *arg -) -{ - check_isr_in_progress_inline(); - - isr_in_progress_body = rtems_interrupt_is_in_progress() ? 1 : 2; -} - void check_isr_worked( char *s, int result @@ -429,16 +426,70 @@ rtems_timer_service_routine test_unblock_task( directive_failed( status, "rtems_task_resume" ); } +#undef rtems_interrupt_disable +extern rtems_interrupt_level rtems_interrupt_disable(void); +#undef rtems_interrupt_enable +extern void rtems_interrupt_enable(rtems_interrupt_level previous_level); +#undef rtems_interrupt_flash +extern void rtems_interrupt_flash(rtems_interrupt_level previous_level); +#undef rtems_interrupt_is_in_progress +extern bool rtems_interrupt_is_in_progress(void); + +static void test_interrupt_body(void) +{ +#if !defined(RTEMS_SMP) + rtems_interrupt_level level; + rtems_mode level_mode_body; + rtems_mode level_mode_macro; + bool in_isr; + + puts( "interrupt disable (use body)" ); + level = rtems_interrupt_disable(); + + puts( "interrupt disable (use body)" ); + level = rtems_interrupt_disable(); + + puts( "interrupt flash (use body)" ); + rtems_interrupt_flash( level ); + + puts( "interrupt enable (use body)" ); + rtems_interrupt_enable( level ); + + puts( "interrupt level mode (use body)" ); + level_mode_body = rtems_interrupt_level_body( level ); + level_mode_macro = RTEMS_INTERRUPT_LEVEL(level); + if ( level_mode_macro == level_mode_body ) { + puts("test seems to work"); + } + + /* + * Test interrupt bodies + */ + puts( "interrupt is in progress (use body)" ); + in_isr = rtems_interrupt_is_in_progress(); + if ( in_isr ) { + puts( "interrupt reported to be is in progress (body)" ); + rtems_test_exit( 0 ); + } +#endif /* RTEMS_SMP */ +} + +rtems_timer_service_routine test_isr_in_progress( + rtems_id timer, + void *arg +) +{ + check_isr_in_progress_inline(); + + isr_in_progress_body = rtems_interrupt_is_in_progress() ? 1 : 2; +} + rtems_task Init( rtems_task_argument argument ) { rtems_time_of_day time; rtems_status_code status; - rtems_interrupt_level level; - rtems_mode level_mode_body; - rtems_mode level_mode_macro; - bool in_isr; rtems_id timer; int i; @@ -523,47 +574,8 @@ rtems_task Init( break; } - /* - * Test interrupt inline versions - */ test_interrupt_inline(); - - /* - * Test interrupt bodies - */ - puts( "interrupt is in progress (use body)" ); - in_isr = rtems_interrupt_is_in_progress(); - if ( in_isr ) { - puts( "interrupt reported to be is in progress (body)" ); - rtems_test_exit( 0 ); - } - - puts( "interrupt disable (use body)" ); - _Thread_Disable_dispatch(); - level = rtems_interrupt_disable(); - _Thread_Enable_dispatch(); - - puts( "interrupt disable (use body)" ); - _Thread_Disable_dispatch(); - level = rtems_interrupt_disable(); - _Thread_Enable_dispatch(); - - puts( "interrupt flash (use body)" ); - _Thread_Disable_dispatch(); - rtems_interrupt_flash( level ); - _Thread_Enable_dispatch(); - - puts( "interrupt enable (use body)" ); - _Thread_Disable_dispatch(); - rtems_interrupt_enable( level ); - _Thread_Enable_dispatch(); - - puts( "interrupt level mode (use body)" ); - level_mode_body = rtems_interrupt_level_body( level ); - level_mode_macro = RTEMS_INTERRUPT_LEVEL(level); - if ( level_mode_macro == level_mode_body ) { - puts("test seems to work"); - } + test_interrupt_body(); /* * Test ISR in progress from actual ISR diff --git a/testsuites/sptests/sp40/init.c b/testsuites/sptests/sp40/init.c index 5b0ad7d98c..d3b547bbbe 100644 --- a/testsuites/sptests/sp40/init.c +++ b/testsuites/sptests/sp40/init.c @@ -42,16 +42,14 @@ static rtems_driver_address_table test_driver = { #define test_interrupt_context_enter( level ) \ do { \ - _Thread_Disable_dispatch(); \ - rtems_interrupt_disable( level ); \ + rtems_interrupt_local_disable( level ); \ ++_ISR_Nest_level; \ } while (0) #define test_interrupt_context_leave( level ) \ do { \ --_ISR_Nest_level; \ - rtems_interrupt_enable( level ); \ - _Thread_Enable_dispatch(); \ + rtems_interrupt_local_enable( level ); \ } while (0) rtems_task Init( diff --git a/testsuites/tmtests/tm26/task1.c b/testsuites/tmtests/tm26/task1.c index ee662184c5..5b19c3d3b6 100644 --- a/testsuites/tmtests/tm26/task1.c +++ b/testsuites/tmtests/tm26/task1.c @@ -341,15 +341,20 @@ rtems_task High_task( _Thread_Disable_dispatch(); benchmark_timer_initialize(); - rtems_interrupt_disable( level ); + rtems_interrupt_local_disable( level ); isr_disable_time = benchmark_timer_read(); benchmark_timer_initialize(); +#if defined(RTEMS_SMP) + rtems_interrupt_local_enable( level ); + rtems_interrupt_local_disable( level ); +#else rtems_interrupt_flash( level ); +#endif isr_flash_time = benchmark_timer_read(); benchmark_timer_initialize(); - rtems_interrupt_enable( level ); + rtems_interrupt_local_enable( level ); isr_enable_time = benchmark_timer_read(); _Thread_Enable_dispatch(); -- cgit v1.2.3