summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-17 10:12:14 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-31 08:29:43 +0200
commit5c731a83485ce3e7a6b6556e7a38b92d10a98cd6 (patch)
treebee44daeabdb237541a911283651f43c91b1c049 /cpukit/score
parentscore: Delete post-switch API extensions (diff)
downloadrtems-5c731a83485ce3e7a6b6556e7a38b92d10a98cd6.tar.bz2
score: Use thread action for thread restart
The thread restart is now supported on SMP. New test smptests/smpthreadlife01.
Diffstat (limited to 'cpukit/score')
-rw-r--r--cpukit/score/include/rtems/score/objectimpl.h17
-rw-r--r--cpukit/score/include/rtems/score/thread.h5
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h37
-rw-r--r--cpukit/score/src/threadinitialize.c5
-rw-r--r--cpukit/score/src/threadrestart.c50
5 files changed, 78 insertions, 36 deletions
diff --git a/cpukit/score/include/rtems/score/objectimpl.h b/cpukit/score/include/rtems/score/objectimpl.h
index 3764c664fd..119f11d829 100644
--- a/cpukit/score/include/rtems/score/objectimpl.h
+++ b/cpukit/score/include/rtems/score/objectimpl.h
@@ -880,23 +880,6 @@ RTEMS_INLINE_ROUTINE void _Objects_Put_without_thread_dispatch(
}
/**
- * @brief Puts back an object obtained with _Objects_Get().
- *
- * The thread dispatch disable level will remain unchanged.
- *
- * On SMP configurations the Giant lock will be released.
- */
-RTEMS_INLINE_ROUTINE void _Objects_Put_and_keep_thread_dispatch_disabled(
- Objects_Control *the_object
-)
-{
- (void) the_object;
-#if defined(RTEMS_SMP)
- _Giant_Release();
-#endif
-}
-
-/**
* @brief Puts back an object obtained with _Objects_Get_isr_disable().
*/
RTEMS_INLINE_ROUTINE void _Objects_Put_for_get_isr_disable(
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index e5a1a55acd..d853aa035a 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -396,6 +396,10 @@ typedef struct {
Chain_Control Chain;
} Thread_Action_control;
+typedef struct {
+ Thread_Action Action;
+} Thread_Life_control;
+
/**
* This structure defines the Thread Control Block (TCB).
*/
@@ -543,6 +547,7 @@ struct Thread_Control_struct {
*/
Chain_Control Key_Chain;
+ Thread_Life_control Life;
};
#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index bbaa10a2f0..b8647276a5 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -219,6 +219,13 @@ void _Thread_Reset(
Thread_Entry_numeric_type numeric_argument
);
+void _Thread_Life_action_handler(
+ Thread_Control *executing,
+ Thread_Action *action,
+ Per_CPU_Control *cpu,
+ ISR_Level level
+);
+
/**
* @brief Frees all memory associated with the specified thread.
*
@@ -501,21 +508,23 @@ RTEMS_INLINE_ROUTINE void _Thread_Unblock (
* to that of its initial state.
*/
-RTEMS_INLINE_ROUTINE void _Thread_Restart_self( void )
+RTEMS_INLINE_ROUTINE void _Thread_Restart_self( Thread_Control *executing )
{
#if defined(RTEMS_SMP)
ISR_Level level;
+ _Giant_Release();
+
_Per_CPU_ISR_disable_and_acquire( _Per_CPU_Get(), level );
( void ) level;
#endif
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
- if ( _Thread_Executing->fp_context != NULL )
- _Context_Restore_fp( &_Thread_Executing->fp_context );
+ if ( executing->fp_context != NULL )
+ _Context_Restore_fp( &executing->fp_context );
#endif
- _CPU_Context_Restart_self( &_Thread_Executing->Registers );
+ _CPU_Context_Restart_self( &executing->Registers );
}
/**
@@ -603,6 +612,26 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
return (Thread_Control *) _Objects_Allocate( &_Thread_Internal_information );
}
+RTEMS_INLINE_ROUTINE void _Thread_Request_dispatch_if_executing(
+ Thread_Control *thread
+)
+{
+#if defined(RTEMS_SMP)
+ if ( thread->is_executing ) {
+ const Per_CPU_Control *cpu_of_executing = _Per_CPU_Get();
+ Per_CPU_Control *cpu_of_thread = _Thread_Get_CPU( thread );
+
+ cpu_of_thread->dispatch_necessary = true;
+
+ if ( cpu_of_executing != cpu_of_thread ) {
+ _Per_CPU_Send_interrupt( cpu_of_thread );
+ }
+ }
+#else
+ (void) thread;
+#endif
+}
+
RTEMS_INLINE_ROUTINE void _Thread_Signal_notification( Thread_Control *thread )
{
if ( _ISR_Is_in_progress() && _Thread_Is_executing( thread ) ) {
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 315156e52a..c851320936 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -240,6 +240,11 @@ bool _Thread_Initialize(
_Thread_Action_control_initialize( &the_thread->Post_switch_actions );
+ _Thread_Action_initialize(
+ &the_thread->Life.Action,
+ _Thread_Life_action_handler
+ );
+
/*
* Open the object
*/
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index b9a7dd56ae..d982f720e7 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -20,32 +20,52 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/userextimpl.h>
-#include <rtems/config.h>
-bool _Thread_Restart(
+void _Thread_Life_action_handler(
+ Thread_Control *executing,
+ Thread_Action *action,
+ Per_CPU_Control *cpu,
+ ISR_Level level
+)
+{
+ (void) action;
+ _Thread_Action_release_and_ISR_enable( cpu, level );
+
+ _Thread_Disable_dispatch();
+
+ _Thread_Load_environment( executing );
+ _Thread_Restart_self( executing );
+}
+
+static void _Thread_Request_life_change(
Thread_Control *the_thread,
void *pointer_argument,
Thread_Entry_numeric_type numeric_argument
)
{
-#if defined( RTEMS_SMP )
- if (
- rtems_configuration_is_smp_enabled()
- && !_Thread_Is_executing( the_thread )
- ) {
- return false;
- }
-#endif
+ _Thread_Set_transient( the_thread );
- if ( !_States_Is_dormant( the_thread->current_state ) ) {
+ _Thread_Reset( the_thread, pointer_argument, numeric_argument );
- _Thread_Set_transient( the_thread );
+ _Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
- _Thread_Reset( the_thread, pointer_argument, numeric_argument );
+ _Thread_Ready( the_thread );
- _Thread_Load_environment( the_thread );
+ _Thread_Request_dispatch_if_executing( the_thread );
+}
- _Thread_Ready( the_thread );
+bool _Thread_Restart(
+ Thread_Control *the_thread,
+ void *pointer_argument,
+ Thread_Entry_numeric_type numeric_argument
+)
+{
+ if ( !_States_Is_dormant( the_thread->current_state ) ) {
+ _Thread_Request_life_change(
+ the_thread,
+ pointer_argument,
+ numeric_argument
+ );
_User_extensions_Thread_restart( the_thread );