<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>change log for rtems (2011-08-22)</title>
</head>
<body text='#000000' bgcolor='#ffffff'>
<a name='cs1'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
<font color='#bb2222'><strong>jennifer</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2011-08-22 Jennifer Averett <Jennifer.Averett@OARcorp.com>
PR 1876
* score/Makefile.am, score/include/rtems/score/isr.h, score/src/isr.c,
score/src/smp.c, score/src/smplock.c, score/src/threaddispatch.c,
score/src/threaddispatchdisablelevel.c: Add smp isr support.
* score/src/isrsmp.c: New file.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/ChangeLog.diff?r1=text&tr1=1.2907&r2=text&tr2=1.2908&diff_format=h">M</a></td><td width='1%'>1.2908</td><td width='100%'>cpukit/ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/Makefile.am.diff?r1=text&tr1=1.106&r2=text&tr2=1.107&diff_format=h">M</a></td><td width='1%'>1.107</td><td width='100%'>cpukit/score/Makefile.am</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/include/rtems/score/isr.h.diff?r1=text&tr1=1.37&r2=text&tr2=1.38&diff_format=h">M</a></td><td width='1%'>1.38</td><td width='100%'>cpukit/score/include/rtems/score/isr.h</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/src/isr.c.diff?r1=text&tr1=1.21&r2=text&tr2=1.22&diff_format=h">M</a></td><td width='1%'>1.22</td><td width='100%'>cpukit/score/src/isr.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/src/isrsmp.c?rev=1.1&content-type=text/vnd.viewcvs-markup">A</a></td><td width='1%'><font color="#000088">1.1</font></td><td width='100%'><font color="#000088">cpukit/score/src/isrsmp.c</font></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/src/smp.c.diff?r1=text&tr1=1.8&r2=text&tr2=1.9&diff_format=h">M</a></td><td width='1%'>1.9</td><td width='100%'>cpukit/score/src/smp.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/src/smplock.c.diff?r1=text&tr1=1.3&r2=text&tr2=1.4&diff_format=h">M</a></td><td width='1%'>1.4</td><td width='100%'>cpukit/score/src/smplock.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/src/threaddispatch.c.diff?r1=text&tr1=1.25&r2=text&tr2=1.26&diff_format=h">M</a></td><td width='1%'>1.26</td><td width='100%'>cpukit/score/src/threaddispatch.c</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/score/src/threaddispatchdisablelevel.c.diff?r1=text&tr1=1.1&r2=text&tr2=1.2&diff_format=h">M</a></td><td width='1%'>1.2</td><td width='100%'>cpukit/score/src/threaddispatchdisablelevel.c</td></tr>
</table>
<pre>
<font color='#006600'>diff -u rtems/cpukit/ChangeLog:1.2907 rtems/cpukit/ChangeLog:1.2908
--- rtems/cpukit/ChangeLog:1.2907 Sun Aug 21 15:07:10 2011
+++ rtems/cpukit/ChangeLog Mon Aug 22 13:26:06 2011
</font><font color='#997700'>@@ -1,3 +1,11 @@
</font><font color='#000088'>+2011-08-22 Jennifer Averett <Jennifer.Averett@OARcorp.com>
+
+ PR 1876
+ * score/Makefile.am, score/include/rtems/score/isr.h, score/src/isr.c,
+ score/src/smp.c, score/src/smplock.c, score/src/threaddispatch.c,
+ score/src/threaddispatchdisablelevel.c: Add smp isr support.
+ * score/src/isrsmp.c: New file.
+
</font> 2011-08-21 Petr Benes <benesp16@fel.cvut.cz>
PR 1886/cpukit
<font color='#006600'>diff -u rtems/cpukit/score/Makefile.am:1.106 rtems/cpukit/score/Makefile.am:1.107
--- rtems/cpukit/score/Makefile.am:1.106 Fri Jul 15 09:36:36 2011
+++ rtems/cpukit/score/Makefile.am Mon Aug 22 13:26:07 2011
</font><font color='#997700'>@@ -133,7 +133,7 @@
</font> endif
if HAS_SMP
<font color='#880000'>-libscore_a_SOURCES += src/smp.c src/smplock.c \
</font><font color='#000088'>+libscore_a_SOURCES += src/isrsmp.c src/smp.c src/smplock.c \
</font> src/schedulersimplesmpblock.c src/schedulersimplesmpschedule.c \
src/schedulersimplesmpunblock.c src/schedulersimplesmptick.c<span style="background-color: #FF0000"> </span>
endif
<font color='#006600'>diff -u rtems/cpukit/score/include/rtems/score/isr.h:1.37 rtems/cpukit/score/include/rtems/score/isr.h:1.38
--- rtems/cpukit/score/include/rtems/score/isr.h:1.37 Mon Aug 1 14:21:47 2011
+++ rtems/cpukit/score/include/rtems/score/isr.h Mon Aug 22 13:26:07 2011
</font><font color='#997700'>@@ -90,7 +90,7 @@
</font> void _ISR_Handler_initialization ( void );
/**
<font color='#880000'>- * @brief Disable Interrupts
</font><font color='#000088'>+ * @brief Disable Interrupts on This Core
</font> *
* This routine disables all interrupts so that a critical section
* of code can be executing without being interrupted.
<font color='#997700'>@@ -98,30 +98,30 @@
</font> * @return The argument @a _level will contain the previous interrupt
* mask level.
*/
<font color='#880000'>-#define _ISR_Disable( _level ) \
</font><font color='#000088'>+#define _ISR_Disable_on_this_core( _level ) \
</font> do { \
_CPU_ISR_Disable( _level ); \
RTEMS_COMPILER_MEMORY_BARRIER(); \
} while (0)
/**
<font color='#880000'>- * @brief Enable Interrupts
</font><font color='#000088'>+ * @brief Enable Interrupts on This Core
</font> *
* This routine enables interrupts to the previous interrupt mask
* LEVEL. It is used at the end of a critical section of code to
* enable interrupts so they can be processed again.
*
* @param[in] level contains the interrupt level mask level
<font color='#880000'>- * previously returned by @ref _ISR_Disable_on_core.
</font><font color='#000088'>+ * previously returned by @ref _ISR_Disable_on_this_core.
</font> */
<font color='#880000'>-#define _ISR_Enable( _level ) \
</font><font color='#000088'>+#define _ISR_Enable_on_this_core( _level ) \
</font> do { \
RTEMS_COMPILER_MEMORY_BARRIER(); \
_CPU_ISR_Enable( _level ); \
} while (0)
/**
<font color='#880000'>- * @brief Temporarily Enable Interrupts
</font><font color='#000088'>+ * @brief Temporarily Enable Interrupts on This Core
</font> *
* This routine temporarily enables interrupts to the previous
* interrupt mask level and then disables all interrupts so that
<font color='#997700'>@@ -137,15 +137,139 @@
</font> * properly protects itself.
*
* @param[in] level contains the interrupt level mask level
<font color='#880000'>- * previously returned by @ref _ISR_Disable_on_core.
</font><font color='#000088'>+ * previously returned by @ref _ISR_Disable_on_this_core.
</font> */
<font color='#880000'>-#define _ISR_Flash( _level ) \
</font><font color='#000088'>+#define _ISR_Flash_on_this_core( _level ) \
</font> do { \
RTEMS_COMPILER_MEMORY_BARRIER(); \
_CPU_ISR_Flash( _level ); \
RTEMS_COMPILER_MEMORY_BARRIER(); \
} while (0)
<font color='#000088'>+#if defined(RTEMS_SMP)
+
+/**
+ * @brief Initialize SMP Interrupt Critical Section Support
+ *
+ * This method initializes the variables required by the SMP implementation
+ * of interrupt critical section management.
+ */
+void _ISR_SMP_Initialize(void);
+
+/**
+ * @brief Enter Interrupt Critical Section on SMP System
+ *
+ * This method is used to enter an interrupt critical section that
+ * is honored across all cores in an SMP system.
+ *
+ * @return This method returns the previous interrupt mask level.
+ */
+ISR_Level _ISR_SMP_Disable(void);
+
+/**
+ * @brief Exit Interrupt Critical Section on SMP System
+ *
+ * This method is used to exit an interrupt critical section that
+ * is honored across all cores in an SMP system.
+ *
+ * @param[in] level contains the interrupt level mask level
+ * previously returned by @ref _ISR_SMP_Disable.
+ */
+void _ISR_SMP_Enable(ISR_Level level);
+
+/**
+ * @brief Temporarily Exit Interrupt Critical Section on SMP System
+ *
+ * This method is used to temporarily exit an interrupt critical section
+ * that is honored across all cores in an SMP system.
+ *
+ * @param[in] level contains the interrupt level mask level
+ * previously returned by @ref _ISR_SMP_Disable.
+ */
+void _ISR_SMP_Flash(ISR_Level level);
+
+/**
+ * @brief Enter SMP interrupt code
+ *
+ * This method is used to enter the SMP interrupt section.
+ *
+ * @return This method returns the isr level.
+ */
+int _ISR_SMP_Enter(void);
+
+/**
+ * @brief Exit SMP interrupt code
+ *
+ * This method is used to exit the SMP interrupt.
+ *
+ * @return This method returns 0 on a simple return and returns 1 on a
+ * dispatching return.
+ */
+int _ISR_SMP_Exit(void);
+
+#endif
+
+/**
+ * @brief Enter Interrupt Disable Critical Section
+ *
+ * This routine enters an interrupt disable critical section. When
+ * in an SMP configuration, this involves obtaining a spinlock to ensure
+ * that only one core is inside an interrupt disable critical section.
+ * When on a single core system, this only involves disabling local
+ * CPU interrupts.
+ *
+ * @return The argument @a _level will contain the previous interrupt
+ * mask level.
+ */
+#if defined(RTEMS_SMP)
+ #define _ISR_Disable( _level ) \
+ _level = _ISR_SMP_Disable();
+#else
+ #define _ISR_Disable( _level ) \
+ _ISR_Disable_on_this_core( _level );
+#endif
+<span style="background-color: #FF0000"> </span>
+/**
+ * @brief Exits Interrupt Disable Critical Section
+ *
+ * This routine exits an interrupt disable critical section. When
+ * in an SMP configuration, this involves releasing a spinlock.
+ * When on a single core system, this only involves disabling local
+ * CPU interrupts.
+ *
+ * @return The argument @a _level will contain the previous interrupt
+ * mask level.
+ */
+#if defined(RTEMS_SMP)
+ #define _ISR_Enable( _level ) \
+ _ISR_SMP_Enable( _level );
+#else
+ #define _ISR_Enable( _level ) \
+ _ISR_Enable_on_this_core( _level );
+#endif
+
+/**
+ * @brief Temporarily Exit Interrupt Disable Critical Section
+ *
+ * This routine is used to temporarily enable interrupts
+ * during a long critical section. It is used in long sections of
+ * critical code when a point is reached at which interrupts can
+ * be temporarily enabled. Deciding where to flash interrupts
+ * in a long critical section is often difficult and the point
+ * must be selected with care to ensure that the critical section
+ * properly protects itself.
+ *
+ * @return The argument @a _level will contain the previous interrupt
+ * mask level.
+ */
+#if defined(RTEMS_SMP)
+ #define _ISR_Flash( _level ) \
+ _ISR_SMP_Flash( _level );
+#else
+ #define _ISR_Flash( _level ) \
+ _ISR_Flash_on_this_core( _level );
+#endif
+
</font> /**
* @brief Install Interrupt Handler Vector
*
<font color='#997700'>@@ -201,7 +325,7 @@
</font> * ensure that the necessary thread scheduling operations are
* performed when the outermost interrupt service routine exits.
*
<font color='#880000'>- * @note Implemented in assembly language.
</font><font color='#000088'>+ * @note Typically implemented in assembly language.
</font> */
void _ISR_Handler( void );
<font color='#006600'>diff -u rtems/cpukit/score/src/isr.c:1.21 rtems/cpukit/score/src/isr.c:1.22
--- rtems/cpukit/score/src/isr.c:1.21 Tue Feb 1 14:22:08 2011
+++ rtems/cpukit/score/src/isr.c Mon Aug 22 13:26:07 2011
</font><font color='#997700'>@@ -80,4 +80,7 @@
</font> _CPU_Install_interrupt_stack();
#endif
<font color='#000088'>+#if defined(RTEMS_SMP)
+ _ISR_SMP_Initialize();
+#endif
</font> }
<font color='#006600'>diff -u /dev/null rtems/cpukit/score/src/isrsmp.c:1.1
--- /dev/null Mon Aug 22 14:10:39 2011
+++ rtems/cpukit/score/src/isrsmp.c Mon Aug 22 13:26:07 2011
</font><font color='#997700'>@@ -0,0 +1,104 @@
</font><font color='#000088'>+/*
+ * ISR Enable/Disable for SMP Configurations
+ *
+ * COPYRIGHT (c) 1989-2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/smp.h>
+
+void _ISR_SMP_Initialize(void)
+{
+}
+
+ISR_Level _ISR_SMP_Disable(void)
+{
+ ISR_Level level;
+
+ _ISR_Disable_on_this_core( level );
+ return level;
+}
+
+void _ISR_SMP_Enable(ISR_Level level)
+{
+ _ISR_Enable_on_this_core( level );
+}
+
+void _ISR_SMP_Flash(ISR_Level level)
+{
+ ISR_Level ignored;
+
+ _ISR_SMP_Enable( level );
+ ignored = _ISR_SMP_Disable();
+}
+
+int _ISR_SMP_Enter(void)
+{
+ uint32_t isr_nest_level;
+ ISR_Level level;
+
+ _ISR_Disable_on_this_core( level );
+
+ isr_nest_level = _ISR_Nest_level++;
+
+ _Thread_Disable_dispatch();
+
+ return isr_nest_level;
+}
+
+/*
+ * Return values:
+ * 0 - simple return
+ * 1 - dispatching return
+ */
+int _ISR_SMP_Exit(void)
+{
+ ISR_Level level;
+ int retval;
+
+ retval = 0;
+
+ _ISR_Disable_on_this_core( level );
+
+ _ISR_Nest_level--;
+
+ if ( _ISR_Nest_level == 0 ) {
+ if ( _Thread_Dispatch_necessary ) {
+ if ( _Thread_Dispatch_get_disable_level() == 1 ) {
+ retval = 1;
+ }
+ }<span style="background-color: #FF0000"> </span>
+ }
+
+ /*
+ * SPARC has special support to avoid some nasty recursive type behaviour.
+ * When dispatching in a thread and we want to return to it then it needs
+ * to finish.
+ */
+ #if defined(__sparc__)
+ if ( _CPU_ISR_Dispatch_disable )
+ retval = 0;
+ #endif
+
+ _ISR_Enable_on_this_core( level );
+
+ _Thread_Dispatch_decrement_disable_level();
+
+ if ( retval == 0 )
+ _SMP_Request_other_cores_to_dispatch();
+
+ return retval;
+}
</font>
<font color='#006600'>diff -u rtems/cpukit/score/src/smp.c:1.8 rtems/cpukit/score/src/smp.c:1.9
--- rtems/cpukit/score/src/smp.c:1.8 Thu Jun 16 08:19:39 2011
+++ rtems/cpukit/score/src/smp.c Mon Aug 22 13:26:08 2011
</font><font color='#997700'>@@ -18,10 +18,6 @@
</font> #include <rtems/score/smp.h>
#include <rtems/score/thread.h>
<font color='#880000'>-#if defined(RTEMS_SMP)
- #define RTEMS_DEBUG
-#endif
-
</font> #if defined(RTEMS_DEBUG)
#include <rtems/bspIo.h>
#endif
<font color='#997700'>@@ -32,6 +28,9 @@
</font> void rtems_smp_run_first_task(int cpu)
{
Thread_Control *heir;
<font color='#000088'>+ ISR_Level level;
+
+ _ISR_Disable_on_this_core( level );
</font>
/*
* The Scheduler will have selected the heir thread for each CPU core.
<font color='#997700'>@@ -50,16 +49,14 @@
</font> */
void rtems_smp_secondary_cpu_initialize(void)
{
<font color='#880000'>- int cpu;
</font><font color='#000088'>+ int cpu;
+ ISR_Level level;
</font>
cpu = bsp_smp_processor_id();
<font color='#000088'>+ _ISR_Disable_on_this_core( level );
</font> bsp_smp_secondary_cpu_initialize(cpu);
<font color='#880000'>- #if defined(RTEMS_DEBUG)
- printk( "Made it to %d -- ", cpu );
- #endif
-
</font> /*
* Inform the primary CPU that this secondary CPU is initialized
* and ready to dispatch to the first thread it is supposed to
<font color='#997700'>@@ -67,20 +64,31 @@
</font> */
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_INITIALIZED;
<font color='#000088'>+ #if defined(RTEMS_DEBUG)
+ printk( "Made it to %d -- ", cpu );
+ #endif
+
</font> /*
* With this secondary core out of reset, we can wait for the
* request to switch to the first task.
<font color='#880000'>- *
- * XXX When SMP ISR code is complete, do we want interrupts on
- * XXX or off at this point?
</font> */
<font color='#880000'>- _ISR_Set_level( 0 );
</font> while(1) {
<font color='#000088'>+ uint32_t message;
+
</font> bsp_smp_wait_for(
(volatile unsigned int *)&_Per_CPU_Information[cpu].message,
RTEMS_BSP_SMP_FIRST_TASK,
10000
);
<font color='#000088'>+
+ level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
+ message = _Per_CPU_Information[cpu].message;
+ if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
+ _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
+ _ISR_Set_level( 0 );
+ }
+<span style="background-color: #FF0000"> </span>
+ _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
</font> }
}
<font color='#997700'>@@ -119,33 +127,25 @@
</font> #endif
if ( message & RTEMS_BSP_SMP_FIRST_TASK ) {
<font color='#880000'>- /*
- * XXX Thread dispatch disable level at this point will have to be
- * XXX revisited when Interrupts on SMP is addressed.
- */
- _Thread_Dispatch_disable_level--; /* undo ISR code */
</font> _Per_CPU_Information[cpu].isr_nest_level = 0;
_Per_CPU_Information[cpu].message &= ~message;
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP;
_SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
<font color='#880000'>- _Thread_Disable_dispatch();
</font><font color='#000088'>+
</font> rtems_smp_run_first_task(cpu);
/* does not return */
}
if ( message & RTEMS_BSP_SMP_SHUTDOWN ) {
<font color='#880000'>- /*
- * XXX Thread dispatch disable level at this point will have to be
- * XXX revisited when Interrupts on SMP is addressed.
- */
</font> _Per_CPU_Information[cpu].message &= ~message;
<font color='#880000'>- _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
</font>
<font color='#880000'>- _Thread_Dispatch_disable_level--; /* undo ISR code */
</font> _Per_CPU_Information[cpu].isr_nest_level = 0;
_Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_SHUTDOWN;
<font color='#880000'>- _ISR_Disable( level );
</font><font color='#000088'>+ _SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
+
+ _Thread_Enable_dispatch(); /* undo ISR code */
+ _ISR_Disable_on_this_core( level );
</font> while(1)
;
/* does not continue past here */
<font color='#997700'>@@ -155,10 +155,6 @@
</font> #if defined(RTEMS_DEBUG)
printk( "switch needed\n" );
#endif
<font color='#880000'>- /*
- * XXX Thread dispatch disable level at this point will have to be
- * XXX revisited when Interrupts on SMP is addressed.
- */
</font> _Per_CPU_Information[cpu].message &= ~message;
_SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
}
<font color='#997700'>@@ -174,6 +170,11 @@
</font> {
ISR_Level level;
<font color='#000088'>+ #if defined(RTEMS_DEBUG)
+ if ( message & RTEMS_BSP_SMP_SIGNAL_TO_SELF )
+ printk( "Send 0x%x to %d\n", message, cpu );
+ #endif
+
</font> level = _SMP_lock_spinlock_simple_Obtain( &_Per_CPU_Information[cpu].lock );
_Per_CPU_Information[cpu].message |= message;
_SMP_lock_spinlock_simple_Release( &_Per_CPU_Information[cpu].lock, level );
<font color='#997700'>@@ -210,15 +211,9 @@
</font> {
int cpu;
<font color='#000088'>+ _Per_CPU_Information[cpu].state = RTEMS_BSP_SMP_CPU_UP;<span style="background-color: #FF0000"> </span>
</font> for (cpu=1 ; cpu < _SMP_Processor_count ; cpu++ ) {
_SMP_Send_message( cpu, RTEMS_BSP_SMP_FIRST_TASK );
<font color='#880000'>- while (_Per_CPU_Information[cpu].state != RTEMS_BSP_SMP_CPU_UP ) {
- bsp_smp_wait_for(
- (volatile unsigned int *)&_Per_CPU_Information[cpu].state,
- RTEMS_BSP_SMP_CPU_UP,
- 10000
- );
- }
</font> }
}
<font color='#997700'>@@ -243,11 +238,6 @@
</font> if ( !_Per_CPU_Information[i].dispatch_necessary )
continue;
_SMP_Send_message( i, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
<font color='#880000'>- bsp_smp_wait_for(
- (volatile unsigned int *)&_Per_CPU_Information[i].message,
- 0,
- 10000
- );
</font> }
}
<font color='#997700'>@@ -256,28 +246,32 @@
</font> */
void _SMP_Request_other_cores_to_shutdown(void)
{
<font color='#880000'>- bool allDown;
- int ncpus;
- int cpu;
</font><font color='#000088'>+ bool allDown;
+ int ncpus;
+ int n;
+ int cpu;
</font>
<font color='#000088'>+ cpu = bsp_smp_processor_id();
</font> ncpus = _SMP_Processor_count;
_SMP_Broadcast_message( RTEMS_BSP_SMP_SHUTDOWN );
allDown = true;
<font color='#880000'>- for (cpu=1 ; cpu<ncpus ; cpu++ ) {
</font><font color='#000088'>+ for (n=0 ; n<ncpus ; n++ ) {
+ if ( n == cpu )<span style="background-color: #FF0000"> </span>
+ continue;
</font> bsp_smp_wait_for(
<font color='#880000'>- (unsigned int *)&_Per_CPU_Information[cpu].state,
</font><font color='#000088'>+ (unsigned int *)&_Per_CPU_Information[n].state,
</font> RTEMS_BSP_SMP_CPU_SHUTDOWN,
10000
);
<font color='#880000'>- if ( _Per_CPU_Information[cpu].state != RTEMS_BSP_SMP_CPU_SHUTDOWN )
</font><font color='#000088'>+ if ( _Per_CPU_Information[n].state != RTEMS_BSP_SMP_CPU_SHUTDOWN )
</font> allDown = false;
}
if ( !allDown )
<font color='#880000'>- printk( "All CPUs not successfully shutdown -- timed out\n" );
</font><font color='#000088'>+ printk( "not all down -- timed out\n" );
</font> #if defined(RTEMS_DEBUG)
<font color='#880000'>- else<span style="background-color: #FF0000"> </span>
</font><font color='#000088'>+ else
</font> printk( "All CPUs shutdown successfully\n" );
#endif
}
<font color='#006600'>diff -u rtems/cpukit/score/src/smplock.c:1.3 rtems/cpukit/score/src/smplock.c:1.4
--- rtems/cpukit/score/src/smplock.c:1.3 Mon May 23 21:44:58 2011
+++ rtems/cpukit/score/src/smplock.c Mon Aug 22 13:26:08 2011
</font><font color='#997700'>@@ -16,11 +16,62 @@
</font> #include <rtems/system.h>
#include <rtems/score/smplock.h>
#include <rtems/score/smp.h>
<font color='#000088'>+#include <rtems/score/isr.h>
</font>
<font color='#880000'>-#if defined (RTEMS_DEBUG)
</font><font color='#000088'>+/*
+ * Some debug stuff that is being left in, but disabled. This will keep<span style="background-color: #FF0000"> </span>
+ * a log of lock/unlock sequences that can be printed out when the<span style="background-color: #FF0000"> </span>
+ * lockcount appears to have gotten off track.
+ */
+/* #define SMPLOCK_DEBUG */
+#if defined (SMPLOCK_DEBUG)
+ #include <rtems/score/thread.h>
</font> #include <rtems/bspIo.h>
<font color='#000088'>+ #include <rtems/score/percpu.h>
+ #if (0)
+ #define ENABLE_ONESHOT_DEBUG_LOGGING
+ #else
+ #define ENABLE_LOOPED_DEBUG_LOGGING
+ #endif
+ #define ENABLE_DEBUG_LOGGING<span style="background-color: #FF0000"> </span>
</font> #endif
<font color='#000088'>+/*
+ * Prototypes and structures used in the debug lock/unlock error log.
+ */
+#if defined(ENABLE_DEBUG_LOGGING)
+ typedef struct {
+ char action;
+ char lock;
+ char cpu;
+ char count;
+ uint32_t nest_level;
+ void *ret1;
+ void *ret2;
+ void *ret3;
+ void *ret4;
+ } debug_spinlog_t;
+
+ extern void start(void);
+ extern void _fini(void);
+
+ #define DEBUG_SPINLOG_MAX 1024
+ debug_spinlog_t DEBUG_SPINLOG[DEBUG_SPINLOG_MAX];
+ int DEBUG_SPINLOG_INDEX = 0;
+
+ static void debug_logit(
+ char act,
+ SMP_lock_spinlock_nested_Control *lock
+ );
+ static void debug_dump_log(void);
+#else
+ #define debug_logit( _act, _lock )
+ #define debug_dump_log()
+#endif
+
+/*
+ * SMP spinlock simple methods
+ */
</font> void _SMP_lock_spinlock_simple_Initialize(
SMP_lock_spinlock_simple_Control *lock
)
<font color='#997700'>@@ -32,14 +83,16 @@
</font> SMP_lock_spinlock_simple_Control *lock
)
{
<font color='#880000'>- ISR_Level level;
</font><font color='#000088'>+ ISR_Level level = 0;
</font> uint32_t value = 1;
uint32_t previous;
/* Note: Disable provides an implicit memory barrier. */
<font color='#880000'>- _ISR_Disable( level );
</font><font color='#000088'>+ _ISR_Disable_on_this_core( level );
</font> do {
<font color='#000088'>+ RTEMS_COMPILER_MEMORY_BARRIER();
</font> SMP_CPU_SWAP( lock, value, previous );
<font color='#000088'>+ RTEMS_COMPILER_MEMORY_BARRIER();
</font> } while (previous == 1);
return level;
<font color='#997700'>@@ -51,15 +104,53 @@
</font> )
{
*lock = 0;
<font color='#880000'>- _ISR_Enable( level );
</font><font color='#000088'>+ _ISR_Enable_on_this_core( level );
</font> }
<font color='#000088'>+/*
+ * SMP spinlock nested methods.
+ */
</font> void _SMP_lock_spinlock_nested_Initialize(
SMP_lock_spinlock_nested_Control *lock
)
{
lock->count = 0;
<font color='#880000'>- lock->cpu_id = 0;
</font><font color='#000088'>+ lock->cpu_id = -1;
+}
+
+void _SMP_lock_spinlock_nested_Release(
+ SMP_lock_spinlock_nested_Control *lock,
+ ISR_Level level
+)
+{
+ #if defined (RTEMS_DEBUG) || defined(SMPLOCK_DEBUG)
+ if ( lock->count == 0 ) {
+ printk(
+ "\ncpu %d lock %d Releasing spinlock when count is already "
+ "zero (%p from %p,%p)?!?!\n",
+ bsp_smp_processor_id(),<span style="background-color: #FF0000"> </span>
+ lock->cpu_id,
+ lock,
+ __builtin_return_address(0),
+ __builtin_return_address(1)
+ );
+ debug_dump_log();
+ return;
+ }
+ #endif
+
+ /* assume we actually have it */
+ if (lock->count == 1) {
+ lock->cpu_id = -1;
+ debug_logit( 'U', lock );
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ lock->count = 0;
+ } else {
+ debug_logit( 'u', lock );
+ lock->count--;
+ }
+
+ _ISR_Enable_on_this_core( level );<span style="background-color: #FF0000"> </span>
</font> }
ISR_Level _SMP_lock_spinlock_nested_Obtain(
<font color='#997700'>@@ -72,36 +163,121 @@
</font> int cpu_id;
/* Note: Disable provides an implicit memory barrier. */
<font color='#880000'>- _ISR_Disable( level );
</font><font color='#000088'>+ _ISR_Disable_on_this_core( level );<span style="background-color: #FF0000"> </span>
</font>
cpu_id = bsp_smp_processor_id();
<font color='#880000'>- /* Deal with nested calls from one cpu */
- if ( (lock->count > 0) && (cpu_id == lock->cpu_id) ) {
- lock->count++;
- return level;
</font><font color='#000088'>+ /*
+ * Attempt to obtain the lock. If we do not get it immediately, then
+ * do a single "monitor" iteration. This should allow the loop to back
+ * off the bus a bit and allow the other core to finish sooner.
+ */
+ while (1) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ SMP_CPU_SWAP( &lock->count, value, previous );
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ if ( previous == 0 ) {
+ /* was not locked */
+ break;
+ }
+
+ /* Deal with nested calls from one cpu */
+ if (cpu_id == lock->cpu_id) {
+ lock->count++;
+ debug_logit( 'l', lock );
+ return level;
+ }
</font> }
<font color='#880000'>- do {
- SMP_CPU_SWAP( lock, value, previous );
- } while (previous == 1);
-
- lock->count++;
</font> lock->cpu_id = cpu_id;
<font color='#000088'>+ debug_logit( 'L', lock );
</font>
return level;
}
<font color='#880000'>-void _SMP_lock_spinlock_nested_Release(
- SMP_lock_spinlock_nested_Control *lock,
- ISR_Level level
-)
-{
-#if defined(RTEMS_DEBUG)
- if ( lock->count == 0 )
- printk ("Releasing spinlock when count is already zero?!?!\n");
</font><font color='#000088'>+/*
+ * Debug log for debugging nested lock/unlock problems.
+ */
+#if defined(ENABLE_DEBUG_LOGGING)
+ static void debug_logit(
+ char act,
+ SMP_lock_spinlock_nested_Control *lock
+ )
+ {<span style="background-color: #FF0000"> </span>
+ debug_debug_spinlog_t *sp;
+ if ( DEBUG_SPINLOG_INDEX == DEBUG_SPINLOG_MAX )
+ #if defined (ENABLE_LOOPED_DEBUG_LOGGING)
+ DEBUG_SPINLOG_INDEX = 0;
+ #else
+ return;
+ #endif
+
+ sp = &DEBUG_SPINLOG[ DEBUG_SPINLOG_INDEX++ ];
+ sp->action = act;
+
+ #if 0
+ if ( lock == &_ISR_SMP_Lock )
+ sp->lock = 'I';
+ else<span style="background-color: #FF0000"> </span>
+ #endif
+ if ( lock == &_Thread_Dispatch_disable_level_lock )
+ sp->lock = 'D';
+ sp->cpu = bsp_smp_processor_id() + '0';
+ sp->count = lock->count;
+ #if 0
+ if ( sp->lock == 'I' ) {
+ if ( _Thread_Dispatch_smp_spin_lock.id == 0 )
+ printk( "not nested %p from %p %p %p %p\n", sp,
+ __builtin_return_address(0), __builtin_return_address(1),
+ __builtin_return_address(2), __builtin_return_address(3)<span style="background-color: #FF0000"> </span>
+ );
+ }
+ #endif
+ sp->nest_level = _ISR_Nest_level;<span style="background-color: #FF0000"> </span>
+ sp->ret1 = 0;
+ sp->ret2 = 0;
+ sp->ret3 = 0;
+ sp->ret4 = 0;
+ sp->ret1 = __builtin_return_address(0);
+ if ( sp->ret1 >= start && sp->ret1 <= _fini ) {
+ sp->ret2 = __builtin_return_address(1);
+ if ( sp->ret2 >= start && sp->ret2 <= _fini ) {
+ sp->ret3 = __builtin_return_address(2);
+ if ( sp->ret3 >= start && sp->ret3 <= _fini ) {
+ sp->ret4 = __builtin_return_address(3);
+ }
+ }
+ }
+ }
+<span style="background-color: #FF0000"> </span>
+ static void debug_dump_log(void)
+ {<span style="background-color: #FF0000"> </span>
+ debug_debug_spinlog_t *sp;
+ int index;
+ bool done =false;
+<span style="background-color: #FF0000"> </span>
+ #if defined (ENABLE_ONESHOT_DEBUG_LOGGING)
+ index = 0;
+ #else
+ if (DEBUG_SPINLOG_INDEX >= DEBUG_SPINLOG_MAX)
+ index = 0;
+ else
+ index = DEBUG_SPINLOG_INDEX;
+ #endif
+
+
+ do {
+ sp = &DEBUG_SPINLOG[ index ];
+ printk("%d) act %c lock %c cpu %c count=%d nest %d (%p, %p, %p, %p)\n",
+ index, sp->action, sp->lock, sp->cpu, sp->count, sp->nest_level,<span style="background-color: #FF0000"> </span>
+ sp->ret1, sp->ret2, sp->ret3, sp->ret4
+ );
+
+ index++;
+ if (index == DEBUG_SPINLOG_INDEX)
+ break;
+ if (index >= DEBUG_SPINLOG_MAX)
+ index = 0;
+ } while (1);
+ }
</font> #endif
<font color='#880000'>- lock->count--;
-
- _ISR_Enable( level );
-}
</font>
<font color='#006600'>diff -u rtems/cpukit/score/src/threaddispatch.c:1.25 rtems/cpukit/score/src/threaddispatch.c:1.26
--- rtems/cpukit/score/src/threaddispatch.c:1.25 Thu May 26 13:07:07 2011
+++ rtems/cpukit/score/src/threaddispatch.c Mon Aug 22 13:26:08 2011
</font><font color='#997700'>@@ -169,9 +169,10 @@
</font> }
post_switch:
<font color='#880000'>- _Thread_Dispatch_set_disable_level( 0 );
</font>
_ISR_Enable( level );
<font color='#000088'>+ _Thread_Unnest_dispatch();
+<span style="background-color: #FF0000"> </span>
</font> _API_extensions_Run_postswitch();
}
<font color='#006600'>diff -u rtems/cpukit/score/src/threaddispatchdisablelevel.c:1.1 rtems/cpukit/score/src/threaddispatchdisablelevel.c:1.2
--- rtems/cpukit/score/src/threaddispatchdisablelevel.c:1.1 Mon May 23 08:30:15 2011
+++ rtems/cpukit/score/src/threaddispatchdisablelevel.c Mon Aug 22 13:26:08 2011
</font><font color='#997700'>@@ -66,8 +66,7 @@
</font> _Thread_Dispatch_disable_level++;
level = _Thread_Dispatch_disable_level;
<font color='#880000'>- _ISR_Enable(isr_level);<span style="background-color: #FF0000"> </span>
-
</font><font color='#000088'>+ _ISR_Enable_on_this_core(isr_level);
</font> return level;
}
<font color='#997700'>@@ -79,8 +78,7 @@
</font> /* First we must disable ISRs in order to protect
* accesses to the dispatch disable level.
*/
<font color='#880000'>-
- _ISR_Disable( isr_level );
</font><font color='#000088'>+ _ISR_Disable_on_this_core( isr_level );
</font>
_Thread_Dispatch_disable_level--;
level = _Thread_Dispatch_disable_level;
</pre>
<p> </p>
<p>--<br />
<small>Generated by <a href="http://www.codewiz.org/projects/index.html#loginfo">Deluxe Loginfo</a> 2.122 by Bernardo Innocenti <bernie@develer.com></small></p>
</body>
</html>