summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-23 16:15:50 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-30 11:16:28 +0200
commitbf30999cc697325eda3afd1833b78a7e64255fc4 (patch)
treebc365daf0a3c0e6fe7c72cfe33c7603f7da54351 /cpukit/score/src
parentsapi: SMP support for chains (diff)
downloadrtems-bf30999cc697325eda3afd1833b78a7e64255fc4.tar.bz2
smp: Add and use _Assert_Owner_of_giant()
Add and use _ISR_Disable_without_giant() and _ISR_Enable_without_giant() if RTEMS_SMP is defined. On single processor systems the ISR disable/enable was the big hammer which ensured system-wide mutual exclusion. On SMP configurations this no longer works since other processors do not care about disabled interrupts on this processor and continue to execute freely. On SMP in addition to ISR disable/enable an SMP lock must be used. Currently we have only the Giant lock so we can check easily that ISR disable/enable is used only in the right context.
Diffstat (limited to 'cpukit/score/src')
-rw-r--r--cpukit/score/src/smp.c2
-rw-r--r--cpukit/score/src/threaddispatch.c4
-rw-r--r--cpukit/score/src/threaddispatchdisablelevel.c34
3 files changed, 27 insertions, 13 deletions
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