summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/rtems/src/taskmode.c4
-rw-r--r--cpukit/score/include/rtems/score/assert.h9
-rw-r--r--cpukit/score/include/rtems/score/isr.h4
-rw-r--r--cpukit/score/include/rtems/score/isrlevel.h20
-rw-r--r--cpukit/score/include/rtems/score/thread.h4
-rw-r--r--cpukit/score/include/rtems/score/threaddispatch.h4
-rw-r--r--cpukit/score/src/smp.c2
-rw-r--r--cpukit/score/src/threaddispatch.c4
-rw-r--r--cpukit/score/src/threaddispatchdisablelevel.c34
-rw-r--r--testsuites/sptests/sp37/init.c14
-rw-r--r--testsuites/tmtests/tm26/task1.c110
-rw-r--r--testsuites/tmtests/tm27/task1.c4
12 files changed, 165 insertions, 48 deletions
diff --git a/cpukit/rtems/src/taskmode.c b/cpukit/rtems/src/taskmode.c
index 606366b25f..8650ccc250 100644
--- a/cpukit/rtems/src/taskmode.c
+++ b/cpukit/rtems/src/taskmode.c
@@ -39,7 +39,7 @@ static void _RTEMS_Tasks_Dispatch_if_necessary(
#if defined( RTEMS_SMP )
ISR_Level level;
- _ISR_Disable( level );
+ _ISR_Disable_without_giant( level );
#endif
if ( !_Thread_Is_heir( executing ) && executing->is_preemptible ) {
@@ -48,7 +48,7 @@ static void _RTEMS_Tasks_Dispatch_if_necessary(
}
#if defined( RTEMS_SMP )
- _ISR_Enable( level );
+ _ISR_Enable_without_giant( level );
#endif
if ( dispatch_necessary ) {
diff --git a/cpukit/score/include/rtems/score/assert.h b/cpukit/score/include/rtems/score/assert.h
index 174676e0e3..4856eae8b4 100644
--- a/cpukit/score/include/rtems/score/assert.h
+++ b/cpukit/score/include/rtems/score/assert.h
@@ -50,6 +50,15 @@ extern "C" {
#define _Assert_Thread_dispatching_repressed() ( ( void ) 0 )
#endif
+/**
+ * @brief Asserts that current thread of execution owns the giant lock.
+ */
+#if defined( RTEMS_DEBUG ) && defined( RTEMS_SMP )
+ void _Assert_Owner_of_giant( void );
+#else
+ #define _Assert_Owner_of_giant() ( ( void ) 0 )
+#endif
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/cpukit/score/include/rtems/score/isr.h b/cpukit/score/include/rtems/score/isr.h
index 4d4a5f3c49..fa0052fdcb 100644
--- a/cpukit/score/include/rtems/score/isr.h
+++ b/cpukit/score/include/rtems/score/isr.h
@@ -163,13 +163,13 @@ RTEMS_INLINE_ROUTINE uint32_t _ISR_Get_nest_level( void )
#if defined( RTEMS_SMP )
ISR_Level level;
- _ISR_Disable( level );
+ _ISR_Disable_without_giant( level );
#endif
isr_nest_level = _ISR_Nest_level;
#if defined( RTEMS_SMP )
- _ISR_Enable( level );
+ _ISR_Enable_without_giant( level );
#endif
return isr_nest_level;
diff --git a/cpukit/score/include/rtems/score/isrlevel.h b/cpukit/score/include/rtems/score/isrlevel.h
index 35d3d037cc..3da67fd189 100644
--- a/cpukit/score/include/rtems/score/isrlevel.h
+++ b/cpukit/score/include/rtems/score/isrlevel.h
@@ -20,6 +20,7 @@
#define _RTEMS_SCORE_ISR_LEVEL_h
#include <rtems/score/cpu.h>
+#include <rtems/score/assert.h>
#ifdef __cplusplus
extern "C" {
@@ -57,6 +58,7 @@ typedef uint32_t ISR_Level;
#define _ISR_Disable( _level ) \
do { \
_CPU_ISR_Disable( _level ); \
+ _Assert_Owner_of_giant(); \
RTEMS_COMPILER_MEMORY_BARRIER(); \
} while (0)
@@ -74,6 +76,7 @@ typedef uint32_t ISR_Level;
#define _ISR_Enable( _level ) \
do { \
RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _Assert_Owner_of_giant(); \
_CPU_ISR_Enable( _level ); \
} while (0)
@@ -99,6 +102,7 @@ typedef uint32_t ISR_Level;
#define _ISR_Flash( _level ) \
do { \
RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _Assert_Owner_of_giant(); \
_CPU_ISR_Flash( _level ); \
RTEMS_COMPILER_MEMORY_BARRIER(); \
} while (0)
@@ -132,6 +136,22 @@ typedef uint32_t ISR_Level;
RTEMS_COMPILER_MEMORY_BARRIER(); \
} while (0)
+#if defined( RTEMS_SMP )
+
+#define _ISR_Disable_without_giant( _level ) \
+ do { \
+ _CPU_ISR_Disable( _level ); \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ } while (0)
+
+#define _ISR_Enable_without_giant( _level ) \
+ do { \
+ RTEMS_COMPILER_MEMORY_BARRIER(); \
+ _CPU_ISR_Enable( _level ); \
+ } while (0)
+
+#endif /* defined( RTEMS_SMP ) */
+
/**@}*/
#ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 77f1d7a2d2..33b5244ac7 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -495,13 +495,13 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get_executing( void )
#if defined( RTEMS_SMP )
ISR_Level level;
- _ISR_Disable( level );
+ _ISR_Disable_without_giant( level );
#endif
executing = _Thread_Executing;
#if defined( RTEMS_SMP )
- _ISR_Enable( level );
+ _ISR_Enable_without_giant( level );
#endif
return executing;
diff --git a/cpukit/score/include/rtems/score/threaddispatch.h b/cpukit/score/include/rtems/score/threaddispatch.h
index 9cd12873fb..2211662696 100644
--- a/cpukit/score/include/rtems/score/threaddispatch.h
+++ b/cpukit/score/include/rtems/score/threaddispatch.h
@@ -54,13 +54,13 @@ RTEMS_INLINE_ROUTINE bool _Thread_Dispatch_is_enabled(void)
#if defined(RTEMS_SMP)
ISR_Level level;
- _ISR_Disable( level );
+ _ISR_Disable_without_giant( level );
#endif
enabled = _Thread_Dispatch_disable_level == 0;
#if defined(RTEMS_SMP)
- _ISR_Enable( level );
+ _ISR_Enable_without_giant( level );
#endif
return enabled;
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c
index 6020b94c46..2f8a488474 100644
--- a/cpukit/score/src/smp.c
+++ b/cpukit/score/src/smp.c
@@ -75,7 +75,7 @@ void rtems_smp_process_interrupt( void )
#endif
if ( ( message & RTEMS_BSP_SMP_SHUTDOWN ) != 0 ) {
- _ISR_Disable( level );
+ _ISR_Disable_without_giant( level );
_Thread_Dispatch_set_disable_level( 0 );
diff --git a/cpukit/score/src/threaddispatch.c b/cpukit/score/src/threaddispatch.c
index 3b5fb429cf..0c8298f15f 100644
--- a/cpukit/score/src/threaddispatch.c
+++ b/cpukit/score/src/threaddispatch.c
@@ -35,7 +35,7 @@ void _Thread_Dispatch( void )
ISR_Level level;
#if defined( RTEMS_SMP )
- _ISR_Disable( level );
+ _ISR_Disable_without_giant( level );
#endif
per_cpu = _Per_CPU_Get();
@@ -43,7 +43,7 @@ void _Thread_Dispatch( void )
per_cpu->thread_dispatch_disable_level = 1;
#if defined( RTEMS_SMP )
- _ISR_Enable( level );
+ _ISR_Enable_without_giant( level );
#endif
/*
diff --git a/cpukit/score/src/threaddispatchdisablelevel.c b/cpukit/score/src/threaddispatchdisablelevel.c
index 30755349b2..a3dec9998c 100644
--- a/cpukit/score/src/threaddispatchdisablelevel.c
+++ b/cpukit/score/src/threaddispatchdisablelevel.c
@@ -17,6 +17,7 @@
#include <rtems/score/threaddispatch.h>
#include <rtems/score/assert.h>
+#include <rtems/score/sysstate.h>
#define NO_OWNER_CPU 0xffffffffU
@@ -63,7 +64,7 @@ uint32_t _Thread_Dispatch_increment_disable_level( void )
uint32_t disable_level;
Per_CPU_Control *self_cpu;
- _ISR_Disable( isr_level );
+ _ISR_Disable_without_giant( isr_level );
/*
* We must obtain the processor ID after interrupts are disabled to prevent
@@ -78,7 +79,7 @@ uint32_t _Thread_Dispatch_increment_disable_level( void )
++disable_level;
self_cpu->thread_dispatch_disable_level = disable_level;
- _ISR_Enable( isr_level );
+ _ISR_Enable_without_giant( isr_level );
return disable_level;
}
@@ -89,7 +90,7 @@ uint32_t _Thread_Dispatch_decrement_disable_level( void )
uint32_t disable_level;
Per_CPU_Control *self_cpu;
- _ISR_Disable( isr_level );
+ _ISR_Disable_without_giant( isr_level );
self_cpu = _Per_CPU_Get();
disable_level = self_cpu->thread_dispatch_disable_level;
@@ -97,8 +98,9 @@ uint32_t _Thread_Dispatch_decrement_disable_level( void )
self_cpu->thread_dispatch_disable_level = disable_level;
_Giant_Do_release();
+ _Assert( disable_level != 0 || _Giant.owner_cpu == NO_OWNER_CPU );
- _ISR_Enable( isr_level );
+ _ISR_Enable_without_giant( isr_level );
return disable_level;
}
@@ -118,9 +120,9 @@ uint32_t _Thread_Dispatch_set_disable_level(uint32_t value)
ISR_Level isr_level;
uint32_t disable_level;
- _ISR_Disable( isr_level );
+ _ISR_Disable_without_giant( isr_level );
disable_level = _Thread_Dispatch_disable_level;
- _ISR_Enable( isr_level );
+ _ISR_Enable_without_giant( isr_level );
/*
* If we need the dispatch level to go higher
@@ -147,18 +149,30 @@ void _Giant_Acquire( void )
{
ISR_Level isr_level;
- _ISR_Disable( isr_level );
+ _ISR_Disable_without_giant( isr_level );
_Assert( _Thread_Dispatch_disable_level != 0 );
_Giant_Do_acquire( _SMP_Get_current_processor() );
- _ISR_Enable( isr_level );
+ _ISR_Enable_without_giant( isr_level );
}
void _Giant_Release( void )
{
ISR_Level isr_level;
- _ISR_Disable( isr_level );
+ _ISR_Disable_without_giant( isr_level );
_Assert( _Thread_Dispatch_disable_level != 0 );
_Giant_Do_release();
- _ISR_Enable( isr_level );
+ _ISR_Enable_without_giant( isr_level );
}
+
+#if defined( RTEMS_DEBUG )
+void _Assert_Owner_of_giant( void )
+{
+ Giant_Control *giant = &_Giant;
+
+ _Assert(
+ giant->owner_cpu == _SMP_Get_current_processor()
+ || !_System_state_Is_up( _System_state_Get() )
+ );
+}
+#endif
diff --git a/testsuites/sptests/sp37/init.c b/testsuites/sptests/sp37/init.c
index efb92b82a2..b6ab157589 100644
--- a/testsuites/sptests/sp37/init.c
+++ b/testsuites/sptests/sp37/init.c
@@ -229,13 +229,19 @@ void test_interrupt_inline(void)
}
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();
puts( "interrupt level mode (use inline)" );
level_mode_body = rtems_interrupt_level_body( level );
@@ -463,16 +469,24 @@ rtems_task Init(
}
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 );
diff --git a/testsuites/tmtests/tm26/task1.c b/testsuites/tmtests/tm26/task1.c
index fbe0d2f9e9..5a51f4c209 100644
--- a/testsuites/tmtests/tm26/task1.c
+++ b/testsuites/tmtests/tm26/task1.c
@@ -21,6 +21,10 @@
#include <rtems/rtems/semimpl.h>
+#if defined( RTEMS_SMP ) && defined( RTEMS_DEBUG )
+ #define PREVENT_SMP_ASSERT_FAILURES
+#endif
+
/* TEST DATA */
rtems_id Semaphore_id;
@@ -84,56 +88,56 @@ void complete_test( void );
static void set_thread_dispatch_necessary( bool dispatch_necessary )
{
-#if defined( RTEMS_SMP )
- rtems_interrupt_level level;
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ ISR_Level level;
- rtems_interrupt_disable( level );
+ _ISR_Disable_without_giant( level );
#endif
_Thread_Dispatch_necessary = dispatch_necessary;
-#if defined( RTEMS_SMP )
- rtems_interrupt_enable( level );
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _ISR_Enable_without_giant( level );
#endif
}
static void set_thread_heir( Thread_Control *thread )
{
-#if defined( RTEMS_SMP )
- rtems_interrupt_level level;
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ ISR_Level level;
- rtems_interrupt_disable( level );
+ _ISR_Disable_without_giant( level );
#endif
_Thread_Heir = thread;
-#if defined( RTEMS_SMP )
- rtems_interrupt_enable( level );
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _ISR_Enable_without_giant( level );
#endif
}
static void set_thread_executing( Thread_Control *thread )
{
-#if defined( RTEMS_SMP )
- rtems_interrupt_level level;
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ ISR_Level level;
- rtems_interrupt_disable( level );
+ _ISR_Disable_without_giant( level );
#endif
_Thread_Executing = thread;
-#if defined( RTEMS_SMP )
- rtems_interrupt_enable( level );
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _ISR_Enable_without_giant( level );
#endif
}
static void thread_disable_dispatch( void )
{
-#if defined( RTEMS_SMP )
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
Per_CPU_Control *self_cpu;
- rtems_interrupt_level level;
+ ISR_Level level;
- rtems_interrupt_disable( level );
+ _ISR_Disable_without_giant( level );
( void ) level;
self_cpu = _Per_CPU_Get();
@@ -145,6 +149,58 @@ static void thread_disable_dispatch( void )
#endif
}
+static void thread_set_state( Thread_Control *thread, States_Control state )
+{
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Disable_dispatch();
+#endif
+
+ _Thread_Set_state( thread, state );
+
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Unnest_dispatch();
+#endif
+}
+
+static void thread_resume( Thread_Control *thread )
+{
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Disable_dispatch();
+#endif
+
+ _Thread_Resume( thread );
+
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Unnest_dispatch();
+#endif
+}
+
+static void thread_unblock( Thread_Control *thread )
+{
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Disable_dispatch();
+#endif
+
+ _Thread_Unblock( thread );
+
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Unnest_dispatch();
+#endif
+}
+
+static void thread_ready( Thread_Control *thread )
+{
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Disable_dispatch();
+#endif
+
+ _Thread_Ready( thread );
+
+#if defined( PREVENT_SMP_ASSERT_FAILURES )
+ _Thread_Unnest_dispatch();
+#endif
+}
+
rtems_task null_task(
rtems_task_argument argument
)
@@ -273,6 +329,8 @@ rtems_task High_task(
{
rtems_interrupt_level level;
+ _Thread_Disable_dispatch();
+
benchmark_timer_initialize();
rtems_interrupt_disable( level );
isr_disable_time = benchmark_timer_read();
@@ -285,6 +343,8 @@ rtems_task High_task(
rtems_interrupt_enable( level );
isr_enable_time = benchmark_timer_read();
+ _Thread_Enable_dispatch();
+
benchmark_timer_initialize();
_Thread_Disable_dispatch();
thread_disable_dispatch_time = benchmark_timer_read();
@@ -294,7 +354,7 @@ rtems_task High_task(
thread_enable_dispatch_time = benchmark_timer_read();
benchmark_timer_initialize();
- _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED );
+ thread_set_state( _Thread_Get_executing(), STATES_SUSPENDED );
thread_set_state_time = benchmark_timer_read();
set_thread_dispatch_necessary( true );
@@ -311,7 +371,7 @@ rtems_task Middle_task(
thread_dispatch_no_fp_time = benchmark_timer_read();
- _Thread_Set_state( _Thread_Get_executing(), STATES_SUSPENDED );
+ thread_set_state( _Thread_Get_executing(), STATES_SUSPENDED );
Middle_tcb = _Thread_Get_executing();
@@ -478,19 +538,19 @@ void complete_test( void )
rtems_id task_id;
benchmark_timer_initialize();
- _Thread_Resume( Middle_tcb );
+ thread_resume( Middle_tcb );
thread_resume_time = benchmark_timer_read();
- _Thread_Set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
+ thread_set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
benchmark_timer_initialize();
- _Thread_Unblock( Middle_tcb );
+ thread_unblock( Middle_tcb );
thread_unblock_time = benchmark_timer_read();
- _Thread_Set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
+ thread_set_state( Middle_tcb, STATES_WAITING_FOR_MESSAGE );
benchmark_timer_initialize();
- _Thread_Ready( Middle_tcb );
+ thread_ready( Middle_tcb );
thread_ready_time = benchmark_timer_read();
benchmark_timer_initialize();
diff --git a/testsuites/tmtests/tm27/task1.c b/testsuites/tmtests/tm27/task1.c
index fac889c1f3..7b6726d119 100644
--- a/testsuites/tmtests/tm27/task1.c
+++ b/testsuites/tmtests/tm27/task1.c
@@ -184,7 +184,7 @@ rtems_task Task_1(
_Thread_Dispatch_set_disable_level( 0 );
#if defined(RTEMS_SMP)
- rtems_interrupt_disable(level);
+ _ISR_Disable_without_giant(level);
#endif
ready_queues = (Chain_Control *) _Scheduler.information;
@@ -194,7 +194,7 @@ rtems_task Task_1(
_Thread_Dispatch_necessary = 1;
#if defined(RTEMS_SMP)
- rtems_interrupt_enable(level);
+ _ISR_Enable_without_giant(level);
#endif
Interrupt_occurred = 0;