[PATCH 11/17] score: Fix thread restart extensions context

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Mar 25 12:49:15 UTC 2014


Run the thread restart extensions in the context of the restarted
thread.  Run them with thread dispatching enabled.
---
 cpukit/posix/src/pthread.c                 |   11 +++-
 cpukit/score/include/rtems/score/userext.h |    9 ++-
 cpukit/score/src/threadrestart.c           |    4 +-
 testsuites/psxtests/psxcleanup01/init.c    |   87 +++++++++++++++++++++++++++-
 4 files changed, 101 insertions(+), 10 deletions(-)

diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c
index d2e6373..0416e28 100644
--- a/cpukit/posix/src/pthread.c
+++ b/cpukit/posix/src/pthread.c
@@ -255,6 +255,15 @@ static bool _POSIX_Threads_Create_extension(
   return true;
 }
 
+static void _POSIX_Threads_Restart_extension(
+  Thread_Control *executing,
+  Thread_Control *restarted
+)
+{
+  (void) executing;
+  _POSIX_Threads_cancel_run( restarted );
+}
+
 /*
  *  _POSIX_Threads_Delete_extension
  *
@@ -336,7 +345,7 @@ User_extensions_Control _POSIX_Threads_User_extensions = {
   { { NULL, NULL }, NULL },
   { _POSIX_Threads_Create_extension,          /* create */
     NULL,                                     /* start */
-    NULL,                                     /* restart */
+    _POSIX_Threads_Restart_extension,         /* restart */
     _POSIX_Threads_Delete_extension,          /* delete */
     NULL,                                     /* switch */
     NULL,                                     /* begin */
diff --git a/cpukit/score/include/rtems/score/userext.h b/cpukit/score/include/rtems/score/userext.h
index 98145f0..91e7f97 100644
--- a/cpukit/score/include/rtems/score/userext.h
+++ b/cpukit/score/include/rtems/score/userext.h
@@ -119,11 +119,12 @@ typedef void( *User_extensions_thread_start_extension )(
  * which restarted the thread.  The second parameter points to the restarted
  * thread.
  *
- * It is invoked after the environment of the thread has been loaded and the
- * thread has been made ready.
+ * It is invoked in the context of the restarted thread right before the
+ * execution context is restarted.  The executing and restarted arguments are
+ * equal.  The thread stack reflects the previous execution context.
  *
- * Thread dispatching is disabled.  The executing thread is not the holder of
- * the allocator mutex.
+ * Thread dispatching is enabled.  The thread is not the holder of the
+ * allocator mutex.
  */
 typedef void( *User_extensions_thread_restart_extension )(
   Thread_Control *,
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index d01a229..a0416b8 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -33,6 +33,8 @@ void _Thread_Life_action_handler(
   (void) action;
   _Thread_Action_release_and_ISR_enable( cpu, level );
 
+  _User_extensions_Thread_restart( the_thread );
+
   _Thread_Disable_dispatch();
 
   _Thread_Load_environment( executing );
@@ -83,8 +85,6 @@ bool _Thread_Restart(
 
     _Thread_Request_life_change( the_thread );
 
-    _User_extensions_Thread_restart( the_thread );
-
     return true;
   }
 
diff --git a/testsuites/psxtests/psxcleanup01/init.c b/testsuites/psxtests/psxcleanup01/init.c
index 502f90b..d29a891 100644
--- a/testsuites/psxtests/psxcleanup01/init.c
+++ b/testsuites/psxtests/psxcleanup01/init.c
@@ -19,12 +19,89 @@ const char rtems_test_name[] = "PSXCLEANUP 1";
 
 /* forward declarations to avoid warnings */
 void *POSIX_Init(void *argument);
-void cleaner(void *arg);
 
-void cleaner(void *arg)
+static rtems_id main_task_id;
+
+static rtems_id restart_task_id;
+
+static volatile rtems_task_argument restart_cleanup_arg;
+
+static void wake_up_main(void)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_send(main_task_id);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void wait_for_restart_task(void)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void restart_cleanup(void *arg)
+{
+  rtems_test_assert(restart_task_id == rtems_task_self());
+
+  restart_cleanup_arg = (rtems_task_argument) arg;
+
+  wake_up_main();
+}
+
+static void restart_task(rtems_task_argument arg)
+{
+  pthread_cleanup_push(restart_cleanup, (void *) arg);
+
+  wake_up_main();
+
+  rtems_test_assert(0);
+
+  pthread_cleanup_pop(0);
+}
+
+static void test_restart_with_cleanup(void)
+{
+  rtems_status_code sc;
+  rtems_id id;
+  rtems_task_priority prio = 1;
+
+  main_task_id = rtems_task_self();
+
+  sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_create(
+    rtems_build_name('R', 'E', 'S', 'T'),
+    2,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  restart_task_id = id;
+
+  sc = rtems_task_start(id, restart_task, 1);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  wait_for_restart_task();
+
+  sc = rtems_task_restart(id, 2);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  wait_for_restart_task();
+
+  rtems_test_assert(restart_cleanup_arg == 1);
+}
+
+static void cleaner(void *arg)
 {
   puts( "clean was not supposed to run" );
-  rtems_test_exit(0);
+  rtems_test_assert(0);
 }
 
 void *POSIX_Init(
@@ -33,6 +110,8 @@ void *POSIX_Init(
 {
   TEST_BEGIN();
 
+  test_restart_with_cleanup();
+
   puts( "Init - pthread_cleanup_push - a routine we will not execute" );
   pthread_cleanup_push(cleaner, NULL);
 
@@ -53,6 +132,8 @@ void *POSIX_Init(
 
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
+#define CONFIGURE_MAXIMUM_TASKS 1
+
 #define CONFIGURE_MAXIMUM_POSIX_THREADS 1
 
 #define CONFIGURE_INIT
-- 
1.7.7




More information about the devel mailing list