forked from Imagelibrary/rtems
score: Fix thread restart extensions context
Run the thread restart extensions in the context of the restarted thread. Run them with thread dispatching enabled.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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 *,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user