From 391ad3ee4ff868c637a4e1c254da96f194be04e4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 17 Mar 2014 15:03:22 +0100 Subject: score: Fix thread restart extensions context 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 d2e637365e..0416e28adf 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 98145f099f..91e7f97bd3 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 d01a229d9f..a0416b802b 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 502f90bc6b..d29a891f54 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 -- cgit v1.2.3