From b8a5abf3fafa9df7cc0354c0ada6192c38e78354 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 26 Feb 2015 10:33:36 +0100 Subject: score: Update _Thread_Heir only if necessary Previously, the _Thread_Heir was updated unconditionally in case a new heir was determined. The _Thread_Dispatch_necessary was only updated in case the executing thread was preemptible or an internal thread was unblocked. Change this to update the _Thread_Heir and _Thread_Dispatch_necessary only in case the currently selected heir thread is preemptible or a dispatch is forced. Move the schedule decision into the change priority operation and use the schedule operation only in rtems_task_mode() in case preemption is enabled or an ASR dispatch is necessary. This is a behaviour change. Previously, the RTEMS_NO_PREEMPT also prevented signal delivery in certain cases (not always). Now, signal delivery is no longer influenced by RTEMS_NO_PREEMPT. Since the currently selected heir thread is used to determine if a new heir is chosen, non-preemptible heir threads currently not executing now prevent a new heir. This may have an application impact, see change test tm04. Document this change in sp04. Update #2273. --- testsuites/sptests/sp04/system.h | 1 + testsuites/sptests/sp04/task1.c | 99 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) (limited to 'testsuites/sptests') diff --git a/testsuites/sptests/sp04/system.h b/testsuites/sptests/sp04/system.h index b770ff214a..2181b8c9f0 100644 --- a/testsuites/sptests/sp04/system.h +++ b/testsuites/sptests/sp04/system.h @@ -50,6 +50,7 @@ void Task_switch( #define CONFIGURE_EXTRA_TASK_STACKS (3 * RTEMS_MINIMUM_STACK_SIZE) #define CONFIGURE_MAXIMUM_TASKS 4 +#define CONFIGURE_MAXIMUM_TIMERS 1 #include diff --git a/testsuites/sptests/sp04/task1.c b/testsuites/sptests/sp04/task1.c index 364e09c63e..eac1bf6d51 100644 --- a/testsuites/sptests/sp04/task1.c +++ b/testsuites/sptests/sp04/task1.c @@ -34,6 +34,103 @@ showTaskSwitches (void) } } +static int test_no_preempt_step; + +static rtems_id high_task_id; + +static rtems_id low_task_id; + +static void high_task( rtems_task_argument arg ) +{ + rtems_status_code sc; + + rtems_test_assert( test_no_preempt_step == 2 ); + test_no_preempt_step = 3; + + sc = rtems_event_transient_send( Task_id[ 1 ] ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + rtems_task_suspend(RTEMS_SELF); + rtems_test_assert(0); +} + +static void low_task( rtems_task_argument arg ) +{ + rtems_test_assert( test_no_preempt_step == 1 ); + test_no_preempt_step = 2; + + rtems_task_suspend(RTEMS_SELF); + rtems_test_assert(0); +} + +static void no_preempt_timer( rtems_id id, void *arg ) +{ + rtems_status_code sc; + + rtems_test_assert( test_no_preempt_step == 0 ); + test_no_preempt_step = 1; + + sc = rtems_task_start( low_task_id, low_task, 0 ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_task_start( high_task_id, high_task, 0 ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); +} + +static void test_no_preempt( void ) +{ + rtems_status_code sc; + rtems_id id; + + rtems_test_assert( test_no_preempt_step == 0 ); + + sc = rtems_task_delete( Task_id[ 2 ] ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_task_delete( Task_id[ 3 ] ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_task_create( + rtems_build_name( 'H', 'I', 'G', 'H' ), + 1, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &high_task_id + ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_task_create( + rtems_build_name( 'L', 'O', 'W', ' ' ), + 2, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_NO_PREEMPT, + RTEMS_DEFAULT_ATTRIBUTES, + &low_task_id + ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_timer_create( rtems_build_name( 'N', 'O', 'P', 'R' ), &id ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_timer_fire_after( id, 1, no_preempt_timer, NULL ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_event_transient_receive( RTEMS_WAIT, RTEMS_NO_TIMEOUT ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_timer_delete( id ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_task_delete( high_task_id ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + sc = rtems_task_delete( low_task_id ); + rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + + rtems_test_assert( test_no_preempt_step == 3 ); +} + rtems_task Task_1( rtems_task_argument argument ) @@ -117,6 +214,8 @@ rtems_task Task_1( status = rtems_extension_delete( Extension_id[1] ); directive_failed( status, "rtems_extension_delete" ); + test_no_preempt(); + TEST_END(); rtems_test_exit (0); } -- cgit v1.2.3