From 5f66ac86dd1dc7bf0eb570ac5919a0a8334e5d4c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 20 Jul 2020 14:00:31 +0200 Subject: spintrcritical08: Use T_interrupt_test() --- testsuites/sptests/Makefile.am | 4 +- testsuites/sptests/spintrcritical08/init.c | 206 +++++++++++++-------- .../sptests/spintrcritical08/spintrcritical08.scn | 30 ++- 3 files changed, 157 insertions(+), 83 deletions(-) (limited to 'testsuites') diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am index bbfabbaa36..4e3a3f0009 100644 --- a/testsuites/sptests/Makefile.am +++ b/testsuites/sptests/Makefile.am @@ -1240,9 +1240,7 @@ if TEST_spintrcritical08 sp_tests += spintrcritical08 sp_screens += spintrcritical08/spintrcritical08.scn sp_docs += spintrcritical08/spintrcritical08.doc -spintrcritical08_SOURCES = spintrcritical08/init.c \ - spintrcritical_support/intrcritical.c \ - spintrcritical_support/intrcritical.h +spintrcritical08_SOURCES = spintrcritical08/init.c spintrcritical08_CPPFLAGS = $(AM_CPPFLAGS) \ $(TEST_FLAGS_spintrcritical08) $(support_includes) \ -I$(top_srcdir)/spintrcritical_support diff --git a/testsuites/sptests/spintrcritical08/init.c b/testsuites/sptests/spintrcritical08/init.c index aab5701ed4..60ba585a8c 100644 --- a/testsuites/sptests/spintrcritical08/init.c +++ b/testsuites/sptests/spintrcritical08/init.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * * COPYRIGHT (c) 1989-2012. * On-Line Applications Research Corporation (OAR). * @@ -11,111 +13,168 @@ #include "config.h" #endif -#include -#include +#include + +#include +#include + #include #include const char rtems_test_name[] = "SPINTRCRITICAL 8"; -/* forward declarations to avoid warnings */ -rtems_task Init(rtems_task_argument argument); - -static rtems_id Period; - -static volatile bool case_hit = false; - -static Thread_Control *thread; +typedef struct { + rtems_id period; + Thread_Control *thread; +} test_context; -static rtems_rate_monotonic_period_states getState(void) +static rtems_rate_monotonic_period_states getState(test_context *ctx) { Rate_monotonic_Control *the_period; ISR_lock_Context lock_context; - the_period = _Rate_monotonic_Get( Period, &lock_context ); - rtems_test_assert( the_period != NULL ); + the_period = _Rate_monotonic_Get( ctx->period, &lock_context ); + T_quiet_assert_not_null( the_period ); _ISR_lock_ISR_enable( &lock_context ); return the_period->state; } -static rtems_timer_service_routine test_release_from_isr( - rtems_id timer, - void *arg -) +static T_interrupt_test_state interrupt( void *arg ) { - Per_CPU_Control *cpu = _Per_CPU_Get(); - Watchdog_Header *header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; - Watchdog_Control *watchdog = (Watchdog_Control *) header->first; - - if ( - watchdog != NULL - && watchdog->expire == cpu->Watchdog.ticks - && watchdog->routine == _Rate_monotonic_Timeout - ) { - Thread_Wait_flags flags = _Thread_Wait_flags_get( thread ); - - _Watchdog_Per_CPU_remove_ticks( watchdog ); - - rtems_test_assert( getState() == RATE_MONOTONIC_ACTIVE ); - - (*watchdog->routine)( watchdog ); - - if ( flags == RATE_MONOTONIC_INTEND_TO_BLOCK ) { - rtems_test_assert( - _Thread_Wait_flags_get( thread ) == RATE_MONOTONIC_READY_AGAIN - ); - rtems_test_assert( getState() == RATE_MONOTONIC_ACTIVE ); - case_hit = true; - } + test_context *ctx; + Per_CPU_Control *cpu_self; + Watchdog_Header *header; + Watchdog_Control *watchdog; + T_interrupt_test_state state; + Thread_Wait_flags flags; + ISR_Level level; + rtems_rate_monotonic_period_states previous_period_state; + + state = T_interrupt_test_get_state(); + + if ( state != T_INTERRUPT_TEST_ACTION ) { + return T_INTERRUPT_TEST_CONTINUE; } + + ctx = arg; + cpu_self = _Per_CPU_Get(); + header = &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; + watchdog = (Watchdog_Control *) header->first; + T_quiet_assert_not_null( watchdog ); + T_quiet_eq_u64( watchdog->expire, cpu_self->Watchdog.ticks ); + T_quiet_eq_ptr( watchdog->routine, _Rate_monotonic_Timeout ); + + flags = _Thread_Wait_flags_get( ctx->thread ); + + _ISR_Local_disable( level ); + _Watchdog_Per_CPU_remove( watchdog, cpu_self, header ); + _ISR_Local_enable( level ); + + previous_period_state = getState( ctx ); + ( *watchdog->routine )( watchdog ); + + if ( flags == RATE_MONOTONIC_INTEND_TO_BLOCK ) { + T_quiet_eq_int( previous_period_state, RATE_MONOTONIC_ACTIVE ); + T_quiet_eq_int( getState( ctx ), RATE_MONOTONIC_ACTIVE ); + state = T_INTERRUPT_TEST_DONE; + } else if ( flags == THREAD_WAIT_FLAGS_INITIAL ) { + T_quiet_true( + previous_period_state == RATE_MONOTONIC_ACTIVE + || previous_period_state == RATE_MONOTONIC_EXPIRED + ); + state = T_INTERRUPT_TEST_EARLY; + } else { + T_quiet_eq_int( flags, RATE_MONOTONIC_BLOCKED ); + T_quiet_true( + previous_period_state == RATE_MONOTONIC_ACTIVE + || previous_period_state == RATE_MONOTONIC_EXPIRED + ); + state = T_INTERRUPT_TEST_LATE; + } + + return state; } -static bool test_body( void *arg ) +static void prepare( void *arg ) { - rtems_status_code sc; - - (void) arg; + test_context *ctx; + rtems_status_code sc; + ISR_Level level; + bool success; + + ctx = arg; + + do { + sc = rtems_rate_monotonic_cancel( ctx->period ); + T_quiet_rsc_success( sc ); + + sc = rtems_rate_monotonic_period( ctx->period, 1 ); + T_quiet_rsc_success( sc ); + + /* + * Depending on the time to the next clock tick and the CPU time available + * to a simulator, we may get sporadic RTEMS_TIMEOUT here. In the next + * round we are synchronized with the clock tick. + */ + sc = rtems_rate_monotonic_period( ctx->period, 1 ); + } while ( sc != RTEMS_SUCCESSFUL ); + + _ISR_Local_disable( level ); + success = _Thread_Wait_flags_try_change_release( + ctx->thread, + RATE_MONOTONIC_READY_AGAIN, + THREAD_WAIT_FLAGS_INITIAL + ); + _ISR_Local_enable( level ); + T_quiet_true( success ); +} - sc = rtems_rate_monotonic_cancel( Period ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); +static void action( void *arg ) +{ + test_context *ctx; + rtems_status_code sc; - sc = rtems_rate_monotonic_period( Period, 1 ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL ); + ctx = arg; - sc = rtems_rate_monotonic_period( Period, 1 ); - rtems_test_assert( sc == RTEMS_SUCCESSFUL || sc == RTEMS_TIMEOUT ); + sc = rtems_rate_monotonic_period( ctx->period, 1 ); + T_quiet_true( sc == RTEMS_SUCCESSFUL || sc == RTEMS_TIMEOUT ); - return case_hit; + T_interrupt_test_busy_wait_for_interrupt(); } -rtems_task Init( - rtems_task_argument ignored -) -{ - rtems_status_code sc; - - TEST_BEGIN(); +static const T_interrupt_test_config config = { + .prepare = prepare, + .action = action, + .interrupt = interrupt, + .max_iteration_count = 10000 +}; - puts( "Init - Trying to generate period ending while blocking" ); +T_TEST_CASE( RateMonotonicPeriodInterrupt ) +{ + test_context ctx; + rtems_status_code sc; + T_interrupt_test_state state; - thread = _Thread_Get_executing(); + memset( &ctx, 0 , sizeof( ctx ) ); + ctx.thread = _Thread_Get_executing(); - puts( "Init - rtems_rate_monotonic_create - OK" ); sc = rtems_rate_monotonic_create( rtems_build_name( 'P', 'E', 'R', '1' ), - &Period + &ctx.period ); - directive_failed( sc, "rtems_rate_monotonic_create" ); + T_rsc_success( sc ); - interrupt_critical_section_test( test_body, NULL, test_release_from_isr ); + state = T_interrupt_test( &config, &ctx ); + T_eq_int( state, T_INTERRUPT_TEST_DONE ); - if ( case_hit ) { - puts( "Init - It appears the case has been hit" ); - TEST_END(); - } else - puts( "Init - Case not hit - ran too long" ); - rtems_test_exit(0); + sc = rtems_rate_monotonic_delete( ctx.period ); + T_rsc_success( sc ); +} + +static rtems_task Init( rtems_task_argument argument ) +{ + rtems_test_run( argument, TEST_STATE ); } /* configuration information */ @@ -123,10 +182,9 @@ rtems_task Init( #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER -#define CONFIGURE_MAXIMUM_TASKS 2 -#define CONFIGURE_MAXIMUM_TIMERS 1 +#define CONFIGURE_MAXIMUM_TASKS 1 #define CONFIGURE_MAXIMUM_PERIODS 1 -#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1 + #define CONFIGURE_MICROSECONDS_PER_TICK 1000 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION diff --git a/testsuites/sptests/spintrcritical08/spintrcritical08.scn b/testsuites/sptests/spintrcritical08/spintrcritical08.scn index 86aa7fad54..c9791a9e42 100644 --- a/testsuites/sptests/spintrcritical08/spintrcritical08.scn +++ b/testsuites/sptests/spintrcritical08/spintrcritical08.scn @@ -1,6 +1,24 @@ -*** TEST INTERRUPT CRITICAL SECTION 08 *** -Init - Trying to generate period ending while blocking -Init - rtems_rate_monotonic_create - OK -Support - rtems_timer_create - creating timer 1 -Init - It appears the case has been hit -*** END OF TEST INTERRUPT CRITICAL SECTION 08 *** +*** BEGIN OF TEST SPINTRCRITICAL 8 *** +*** TEST VERSION: 6.0.0.929e49a54ab4d2d18c9fb8d03610614f63e25b8d +*** TEST STATE: EXPECTED_PASS +*** TEST BUILD: RTEMS_DEBUG RTEMS_POSIX_API RTEMS_SMP +*** TEST TOOLS: 10.0.1 20200406 (RTEMS 6, RSB bec88a6dd856892c3e66e4598252ea07d7a0d762, Newlib ece49e4) +A:SPINTRCRITICAL 8 +S:Platform:RTEMS +S:Compiler:10.0.1 20200406 (RTEMS 6, RSB bec88a6dd856892c3e66e4598252ea07d7a0d762, Newlib ece49e4) +S:Version:6.0.0.929e49a54ab4d2d18c9fb8d03610614f63e25b8d +S:BSP:realview_pbx_a9_qemu +S:RTEMS_DEBUG:1 +S:RTEMS_MULTIPROCESSING:0 +S:RTEMS_POSIX_API:1 +S:RTEMS_PROFILING:0 +S:RTEMS_SMP:1 +B:RateMonotonicPeriodInterrupt +P:0:0:UI1:init.c:156 +P:1:0:UI1:init.c:159 +P:2:0:UI1:init.c:162 +E:RateMonotonicPeriodInterrupt:N:3:F:0:D:0.057652 +Z:SPINTRCRITICAL 8:C:1:N:3:F:0:D:0.058758 +Y:ReportHash:SHA256:381af5dc18c561d18b7b3ead593defa1aef4835f918df9edee7fe1ded0e089da + +*** END OF TEST SPINTRCRITICAL 8 *** -- cgit v1.2.3