summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testsuites/psxtests/psxintrcritical01/init.c42
-rw-r--r--testsuites/sptests/spintrcritical01/init.c38
-rw-r--r--testsuites/sptests/spintrcritical06/init.c28
-rw-r--r--testsuites/sptests/spintrcritical08/init.c70
-rw-r--r--testsuites/sptests/spintrcritical09/init.c24
-rw-r--r--testsuites/sptests/spintrcritical10/init.c120
-rw-r--r--testsuites/sptests/spintrcritical11/init.c24
-rw-r--r--testsuites/sptests/spintrcritical13/init.c27
-rw-r--r--testsuites/sptests/spintrcritical15/init.c33
-rw-r--r--testsuites/sptests/spintrcritical16/init.c32
-rw-r--r--testsuites/sptests/spintrcritical18/init.c23
-rw-r--r--testsuites/sptests/spintrcritical20/init.c82
-rw-r--r--testsuites/sptests/spintrcritical_support/intrcritical.c230
-rw-r--r--testsuites/sptests/spintrcritical_support/intrcritical.h21
14 files changed, 504 insertions, 290 deletions
diff --git a/testsuites/psxtests/psxintrcritical01/init.c b/testsuites/psxtests/psxintrcritical01/init.c
index 2c4620969f..a6a64bad60 100644
--- a/testsuites/psxtests/psxintrcritical01/init.c
+++ b/testsuites/psxtests/psxintrcritical01/init.c
@@ -19,31 +19,40 @@ const char rtems_test_name[] = "PSXINTRCRITICAL 1";
/* forward declarations to avoid warnings */
rtems_task Init(rtems_task_argument ignored);
-rtems_timer_service_routine test_release_from_isr(rtems_id timer, void *arg);
#define TEST_NAME "01"
#define TEST_STRING "POSIX Timer"
-rtems_id Main_task;
-timer_t Timer;
-struct itimerspec TimerParams;
+static timer_t Timer;
+static struct itimerspec TimerParams;
#define POSIX_TIMER_RELATIVE 0
-rtems_timer_service_routine test_release_from_isr(
+static bool test_body( void *arg )
+{
+ int rv;
+
+ (void) arg;
+
+ rv = timer_settime(Timer, POSIX_TIMER_RELATIVE, &TimerParams, NULL);
+ rtems_test_assert( rv == 0 );
+
+ return false;
+}
+
+static rtems_timer_service_routine test_release_from_isr(
rtems_id timer,
void *arg
)
{
- (void) timer_settime(Timer, POSIX_TIMER_RELATIVE, &TimerParams, NULL);
+ test_body( NULL );
}
rtems_task Init(
rtems_task_argument ignored
)
{
- int sc;
- int resets;
+ int sc;
TEST_BEGIN();
@@ -59,27 +68,13 @@ rtems_task Init(
rtems_test_exit(0);
}
- Main_task = rtems_task_self();
-
/* we don't care if it ever fires */
TimerParams.it_interval.tv_sec = 10;
TimerParams.it_interval.tv_nsec = 0;
TimerParams.it_value.tv_sec = 10;
TimerParams.it_value.tv_nsec = 0;
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- for (resets=0 ; resets<10 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- sc = timer_settime(Timer, POSIX_TIMER_RELATIVE, &TimerParams, NULL);
- if ( sc == -1 ) {
- perror ("Error in timer setting\n");
- rtems_test_exit(0);
- }
-
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
TEST_END();
rtems_test_exit(0);
@@ -93,6 +88,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_POSIX_TIMERS 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/spintrcritical01/init.c b/testsuites/sptests/spintrcritical01/init.c
index 7db5143469..dc36aee4fd 100644
--- a/testsuites/sptests/spintrcritical01/init.c
+++ b/testsuites/sptests/spintrcritical01/init.c
@@ -58,9 +58,8 @@ Thread_blocking_operation_States getState(void);
const char rtems_test_name[] = "SPINTRCRITICAL " TEST_NAME;
-rtems_id Main_task;
rtems_id Semaphore;
-volatile bool case_hit;
+volatile bool case_hit = false;
Thread_blocking_operation_States getState(void)
{
@@ -94,6 +93,21 @@ rtems_timer_service_routine test_release_from_isr(
}
+static bool test_body( void *arg )
+{
+ rtems_status_code status;
+
+ (void) arg;
+
+ status = rtems_semaphore_obtain(
+ Semaphore,
+ RTEMS_DEFAULT_OPTIONS,
+ SEMAPHORE_OBTAIN_TIMEOUT
+ );
+ directive_failed( status, "rtems_semaphore_obtain" );
+
+ return case_hit;
+}
rtems_task Init(
rtems_task_argument ignored
@@ -107,29 +121,14 @@ rtems_task Init(
puts( "Init - Variation is: " TEST_STRING );
status = rtems_semaphore_create(
rtems_build_name( 'S', 'M', '1', ' ' ),
- 1,
+ 0,
SEMAPHORE_ATTRIBUTES,
RTEMS_NO_PRIORITY,
&Semaphore
);
directive_failed( status, "rtems_semaphore_create of SM1" );
- Main_task = rtems_task_self();
-
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- case_hit = false;
-
- while (!case_hit) {
- interrupt_critical_section_test_support_delay();
-
- status = rtems_semaphore_obtain(
- Semaphore,
- RTEMS_DEFAULT_OPTIONS,
- SEMAPHORE_OBTAIN_TIMEOUT
- );
- directive_failed( status, "rtems_semaphore_obtain" );
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
if ( case_hit ) {
puts( "Init - Case hit" );
@@ -148,6 +147,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_MICROSECONDS_PER_TICK 1000
#if defined(PRIORITY_NO_TIMEOUT_REVERSE)
#define CONFIGURE_INIT_TASK_PRIORITY 250
diff --git a/testsuites/sptests/spintrcritical06/init.c b/testsuites/sptests/spintrcritical06/init.c
index 96c2a91be4..8d519226ff 100644
--- a/testsuites/sptests/spintrcritical06/init.c
+++ b/testsuites/sptests/spintrcritical06/init.c
@@ -71,12 +71,24 @@ rtems_task Secondary_task(
rtems_test_assert(0);
}
+static bool test_body( void *arg )
+{
+ (void) arg;
+
+ rtems_semaphore_obtain(
+ Semaphore,
+ RTEMS_DEFAULT_OPTIONS,
+ SEMAPHORE_OBTAIN_TIMEOUT
+ );
+
+ return false;
+}
+
rtems_task Init(
rtems_task_argument ignored
)
{
rtems_status_code status;
- int resets;
TEST_BEGIN();
@@ -105,18 +117,7 @@ rtems_task Init(
status = rtems_task_start( Secondary_task_id, Secondary_task, 0 );
directive_failed( status, "rtems_task_start" );
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- for (resets=0 ; resets< 2 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- status = rtems_semaphore_obtain(
- Semaphore,
- RTEMS_DEFAULT_OPTIONS,
- SEMAPHORE_OBTAIN_TIMEOUT
- );
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
TEST_END();
rtems_test_exit(0);
@@ -130,6 +131,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_INIT_TASK_PRIORITY INIT_PRIORITY
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_PREEMPT
#define CONFIGURE_MICROSECONDS_PER_TICK 2000
diff --git a/testsuites/sptests/spintrcritical08/init.c b/testsuites/sptests/spintrcritical08/init.c
index e286e869fb..7a1353daeb 100644
--- a/testsuites/sptests/spintrcritical08/init.c
+++ b/testsuites/sptests/spintrcritical08/init.c
@@ -13,20 +13,19 @@
#include <tmacros.h>
#include <intrcritical.h>
+#include <rtems/score/watchdogimpl.h>
#include <rtems/rtems/ratemonimpl.h>
const char rtems_test_name[] = "SPINTRCRITICAL 8";
/* forward declarations to avoid warnings */
rtems_task Init(rtems_task_argument argument);
-rtems_timer_service_routine test_release_from_isr(rtems_id timer, void *arg);
-rtems_rate_monotonic_period_states getState(void);
-rtems_id Main_task;
-rtems_id Period;
-volatile bool case_hit;
+static rtems_id Period;
-rtems_rate_monotonic_period_states getState(void)
+static volatile bool case_hit = false;
+
+static rtems_rate_monotonic_period_states getState(void)
{
Objects_Locations location;
Rate_monotonic_Control *period;
@@ -42,13 +41,48 @@ rtems_rate_monotonic_period_states getState(void)
return period->state;
}
-rtems_timer_service_routine test_release_from_isr(
+static rtems_timer_service_routine test_release_from_isr(
rtems_id timer,
void *arg
)
{
- if ( getState() == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING )
- case_hit = true;
+ Chain_Control *chain = &_Watchdog_Ticks_chain;
+
+ if ( !_Chain_Is_empty( chain ) ) {
+ Watchdog_Control *watchdog = _Watchdog_First( chain );
+
+ if (
+ watchdog->delta_interval == 0
+ && watchdog->routine == _Rate_monotonic_Timeout
+ ) {
+ Watchdog_States state = _Watchdog_Remove( watchdog );
+
+ rtems_test_assert( state == WATCHDOG_ACTIVE );
+ (*watchdog->routine)( watchdog->id, watchdog->user_data );
+
+ if ( getState() == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING ) {
+ case_hit = true;
+ }
+ }
+ }
+}
+
+static bool test_body( void *arg )
+{
+ rtems_status_code sc;
+
+ (void) arg;
+
+ sc = rtems_rate_monotonic_cancel( Period );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+ sc = rtems_rate_monotonic_period( Period, 1 );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+ sc = rtems_rate_monotonic_period( Period, 1 );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL || sc == RTEMS_TIMEOUT );
+
+ return case_hit;
}
rtems_task Init(
@@ -56,7 +90,6 @@ rtems_task Init(
)
{
rtems_status_code sc;
- int resets;
TEST_BEGIN();
@@ -69,21 +102,7 @@ rtems_task Init(
);
directive_failed( sc, "rtems_rate_monotonic_create" );
- Main_task = rtems_task_self();
-
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- case_hit = false;
-
- for (resets=0 ; case_hit == false && resets< 2 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- sc = rtems_rate_monotonic_period( Period, 1 );
- if ( sc == RTEMS_TIMEOUT )
- continue;
- directive_failed( sc, "rtems_monotonic_period");
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
if ( case_hit ) {
puts( "Init - It appears the case has been hit" );
@@ -101,6 +120,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_TIMERS 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/spintrcritical09/init.c b/testsuites/sptests/spintrcritical09/init.c
index 90948eccc6..bc942d5f77 100644
--- a/testsuites/sptests/spintrcritical09/init.c
+++ b/testsuites/sptests/spintrcritical09/init.c
@@ -20,7 +20,7 @@
const char rtems_test_name[] = "SPINTRCRITICAL 9";
static rtems_id Semaphore;
-static bool case_hit;
+static bool case_hit = false;
static Thread_blocking_operation_States getState(void)
{
@@ -64,12 +64,20 @@ static rtems_timer_service_routine test_release_from_isr(
}
}
+static bool test_body( void *arg )
+{
+ (void) arg;
+
+ rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 1 );
+
+ return case_hit;
+}
+
static rtems_task Init(
rtems_task_argument ignored
)
{
rtems_status_code sc;
- int resets;
TEST_BEGIN();
@@ -84,16 +92,7 @@ static rtems_task Init(
);
directive_failed( sc, "rtems_semaphore_create of SM1" );
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- case_hit = false;
-
- for (resets=0 ; resets< 2 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- (void) rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 1 );
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
if ( case_hit ) {
puts( "Init - It appears the case has been hit" );
@@ -112,6 +111,7 @@ static rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
diff --git a/testsuites/sptests/spintrcritical10/init.c b/testsuites/sptests/spintrcritical10/init.c
index f3883f7fa6..8959e5c4e3 100644
--- a/testsuites/sptests/spintrcritical10/init.c
+++ b/testsuites/sptests/spintrcritical10/init.c
@@ -86,10 +86,28 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
+static bool test_body_any_satisfy_before_timeout(void *arg)
+{
+ test_context *ctx = arg;
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = DEADBEEF;
+ sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_WAIT, 1, &out);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(out == GREEN);
+
+ out = DEADBEEF;
+ sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, 0, &out);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(out == RED);
+
+ return ctx->hit;
+}
+
static void test_any_satisfy_before_timeout(test_context *ctx)
{
rtems_status_code sc;
- int resets = 0;
puts(
"Init - Trying to generate any satisfied before timeout "
@@ -98,27 +116,14 @@ static void test_any_satisfy_before_timeout(test_context *ctx)
ctx->hit = false;
- interrupt_critical_section_test_support_initialize(NULL);
-
sc = rtems_timer_fire_after(ctx->timer, 1, any_satisfy_before_timeout, ctx);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- while (!ctx->hit && resets < 2) {
- rtems_event_set out;
-
- if (interrupt_critical_section_test_support_delay())
- resets++;
-
- out = DEADBEEF;
- sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_WAIT, 1, &out);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(out == GREEN);
-
- out = DEADBEEF;
- sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, 0, &out);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(out == RED);
- }
+ interrupt_critical_section_test(
+ test_body_any_satisfy_before_timeout,
+ ctx,
+ NULL
+ );
sc = rtems_timer_cancel(ctx->timer);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
@@ -178,10 +183,23 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
+static bool test_body_all_satisfy_before_timeout(void *arg)
+{
+ test_context *ctx = arg;
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = DEADBEEF;
+ sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(out == EVENTS);
+
+ return ctx->hit;
+}
+
static void test_all_satisfy_before_timeout(test_context *ctx)
{
rtems_status_code sc;
- int resets = 0;
puts(
"Init - Trying to generate all satisfied before timeout "
@@ -190,22 +208,14 @@ static void test_all_satisfy_before_timeout(test_context *ctx)
ctx->hit = false;
- interrupt_critical_section_test_support_initialize(NULL);
-
sc = rtems_timer_fire_after(ctx->timer, 1, all_satisfy_before_timeout, ctx);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- while (!ctx->hit && resets < 2) {
- rtems_event_set out;
-
- if (interrupt_critical_section_test_support_delay())
- resets++;
-
- out = DEADBEEF;
- sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(out == EVENTS);
- }
+ interrupt_critical_section_test(
+ test_body_all_satisfy_before_timeout,
+ ctx,
+ NULL
+ );
sc = rtems_timer_cancel(ctx->timer);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
@@ -257,10 +267,28 @@ static void timeout_before_satisfied(rtems_id timer, void *arg)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
+static bool test_body_timeout_before_all_satisfy(void *arg)
+{
+ test_context *ctx = arg;
+ rtems_event_set out;
+ rtems_status_code sc;
+
+ out = DEADBEEF;
+ sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
+ rtems_test_assert(sc == RTEMS_TIMEOUT);
+ rtems_test_assert(out == DEADBEEF);
+
+ out = DEADBEEF;
+ sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_NO_WAIT, 0, &out);
+ rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+ rtems_test_assert(out == EVENTS);
+
+ return ctx->hit;
+}
+
static void test_timeout_before_all_satisfy(test_context *ctx)
{
rtems_status_code sc;
- int resets = 0;
puts(
"Init - Trying to generate timeout before all satisfied "
@@ -269,27 +297,14 @@ static void test_timeout_before_all_satisfy(test_context *ctx)
ctx->hit = false;
- interrupt_critical_section_test_support_initialize(NULL);
-
sc = rtems_timer_fire_after(ctx->timer, 1, timeout_before_satisfied, ctx);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- while (!ctx->hit && resets < 2) {
- rtems_event_set out;
-
- if (interrupt_critical_section_test_support_delay())
- resets++;
-
- out = DEADBEEF;
- sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
- rtems_test_assert(sc == RTEMS_TIMEOUT);
- rtems_test_assert(out == DEADBEEF);
-
- out = DEADBEEF;
- sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_NO_WAIT, 0, &out);
- rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- rtems_test_assert(out == EVENTS);
- }
+ interrupt_critical_section_test(
+ test_body_timeout_before_all_satisfy,
+ ctx,
+ NULL
+ );
sc = rtems_timer_cancel(ctx->timer);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
@@ -326,6 +341,7 @@ static rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_TIMERS 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
diff --git a/testsuites/sptests/spintrcritical11/init.c b/testsuites/sptests/spintrcritical11/init.c
index 0d8987537c..2a3f83a315 100644
--- a/testsuites/sptests/spintrcritical11/init.c
+++ b/testsuites/sptests/spintrcritical11/init.c
@@ -47,13 +47,21 @@ rtems_timer_service_routine test_release_from_isr(
(void) rtems_event_send( Main_task, EVENTS_TO_SEND );
}
+static bool test_body( void *arg )
+{
+ rtems_event_set out;
+
+ (void) arg;
+
+ rtems_event_receive( EVENTS_TO_RECEIVE, RTEMS_EVENT_ANY, 1, &out );
+
+ return false;
+}
+
rtems_task Init(
rtems_task_argument ignored
)
{
- rtems_event_set out;
- int resets;
-
TEST_BEGIN();
puts( "Init - Test may not be able to detect case is hit reliably" );
@@ -62,14 +70,7 @@ rtems_task Init(
Main_task = rtems_task_self();
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- for (resets=0 ; resets< 2 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- (void) rtems_event_receive( EVENTS_TO_RECEIVE, RTEMS_EVENT_ANY, 1, &out );
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
TEST_END();
rtems_test_exit(0);
@@ -83,6 +84,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
diff --git a/testsuites/sptests/spintrcritical13/init.c b/testsuites/sptests/spintrcritical13/init.c
index 5a43dab6ef..7069938191 100644
--- a/testsuites/sptests/spintrcritical13/init.c
+++ b/testsuites/sptests/spintrcritical13/init.c
@@ -35,7 +35,6 @@ rtems_task Init(rtems_task_argument argument);
rtems_timer_service_routine test_release_from_isr(rtems_id timer, void *arg);
rtems_timer_service_routine TimerMethod(rtems_id timer, void *arg);
-rtems_id Main_task;
rtems_id Timer;
rtems_timer_service_routine TimerMethod(
@@ -53,12 +52,23 @@ rtems_timer_service_routine test_release_from_isr(
(void) rtems_timer_fire_after( Timer, 10, TimerMethod, NULL );
}
+static bool test_body( void *arg )
+{
+ rtems_status_code sc;
+
+ (void) arg;
+
+ sc = TEST_DIRECTIVE( Timer, 10, TimerMethod, NULL );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+ return false;
+}
+
rtems_task Init(
rtems_task_argument ignored
)
{
rtems_status_code sc;
- int resets;
TEST_BEGIN();
@@ -81,17 +91,7 @@ rtems_task Init(
sc = rtems_timer_create( rtems_build_name( 'P', 'E', 'R', '1' ), &Timer);
directive_failed( sc, "rtems_timer_create" );
- Main_task = rtems_task_self();
-
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- for (resets=0 ; resets<10 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- sc = TEST_DIRECTIVE( Timer, 10, TimerMethod, NULL );
- directive_failed( sc, "rtems_timer_fire_after");
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
TEST_END();
rtems_test_exit(0);
@@ -108,6 +108,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 2
#endif
#define CONFIGURE_MAXIMUM_TIMERS 2
+#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/spintrcritical15/init.c b/testsuites/sptests/spintrcritical15/init.c
index ec84165bf8..b68098778a 100644
--- a/testsuites/sptests/spintrcritical15/init.c
+++ b/testsuites/sptests/spintrcritical15/init.c
@@ -23,7 +23,6 @@ rtems_task Secondary_task(rtems_task_argument ignored);
#define INIT_PRIORITY 2
#define BLOCKER_PRIORITY 1
-rtems_id Main_task;
rtems_id Secondary_task_id;
rtems_id Semaphore;
@@ -39,12 +38,26 @@ rtems_task Secondary_task(
}
}
+static bool test_body( void *arg )
+{
+ rtems_status_code sc;
+
+ (void) arg;
+
+ sc = rtems_task_restart( Secondary_task_id, 1 );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+ sc = rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 1 );
+ rtems_test_assert( sc == RTEMS_TIMEOUT );
+
+ return false;
+}
+
rtems_task Init(
rtems_task_argument ignored
)
{
rtems_status_code sc;
- int resets;
TEST_BEGIN();
puts(
@@ -77,20 +90,7 @@ rtems_task Init(
sc = rtems_task_start( Secondary_task_id, Secondary_task, 0 );
directive_failed( sc, "rtems_task_start" );
- Main_task = rtems_task_self();
-
- interrupt_critical_section_test_support_initialize( NULL );
-
- for (resets=0 ; resets<10 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- sc = rtems_task_restart( Secondary_task_id, 1 );
- directive_failed( sc, "rtems_task_restart" );
-
- sc = rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 1 );
- fatal_directive_status( sc, RTEMS_TIMEOUT, "rtems_semaphore_obtain" );
- }
+ interrupt_critical_section_test( test_body, NULL, NULL );
TEST_END();
rtems_test_exit(0);
@@ -103,6 +103,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_MICROSECONDS_PER_TICK 1000
#define CONFIGURE_INIT_TASK_PRIORITY INIT_PRIORITY
#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_PREEMPT
diff --git a/testsuites/sptests/spintrcritical16/init.c b/testsuites/sptests/spintrcritical16/init.c
index f1858000bc..08eeb8b9b4 100644
--- a/testsuites/sptests/spintrcritical16/init.c
+++ b/testsuites/sptests/spintrcritical16/init.c
@@ -24,9 +24,8 @@ rtems_timer_service_routine test_release_from_isr(rtems_id timer, void *arg);
Thread_blocking_operation_States getState(void);
Thread_Control *Main_TCB;
-rtems_id Main_task;
rtems_id Semaphore;
-volatile bool case_hit;
+volatile bool case_hit = false;
Thread_blocking_operation_States getState(void)
{
@@ -59,12 +58,23 @@ rtems_timer_service_routine test_release_from_isr(
}
}
+static bool test_body( void *arg )
+{
+ rtems_status_code sc;
+
+ (void) arg;
+
+ sc = rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 2 );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL || sc == RTEMS_TIMEOUT );
+
+ return case_hit;
+}
+
rtems_task Init(
rtems_task_argument ignored
)
{
rtems_status_code sc;
- int resets;
TEST_BEGIN();
puts(
@@ -82,22 +92,9 @@ rtems_task Init(
);
directive_failed( sc, "rtems_semaphore_create of SM1" );
- Main_task = rtems_task_self();
Main_TCB = _Thread_Get_executing();
- interrupt_critical_section_test_support_initialize( test_release_from_isr );
-
- case_hit = false;
-
- for (resets=0 ; !case_hit && resets<10 ;) {
- if ( interrupt_critical_section_test_support_delay() )
- resets++;
-
- sc = rtems_semaphore_obtain( Semaphore, RTEMS_DEFAULT_OPTIONS, 2 );
- if ( sc == RTEMS_SUCCESSFUL )
- break;
- fatal_directive_status( sc, RTEMS_TIMEOUT, "rtems_semaphore_obtain" );
- }
+ interrupt_critical_section_test( test_body, NULL, test_release_from_isr );
if ( case_hit ) {
puts( "Init - Case hit" );
@@ -117,6 +114,7 @@ rtems_task Init(
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_SEMAPHORES 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/spintrcritical18/init.c b/testsuites/sptests/spintrcritical18/init.c
index c34f4b95c7..f621d21280 100644
--- a/testsuites/sptests/spintrcritical18/init.c
+++ b/testsuites/sptests/spintrcritical18/init.c
@@ -95,11 +95,19 @@ static void high_priority_task( rtems_task_argument arg )
}
}
+static bool test_body( void *arg )
+{
+ test_context *ctx = arg;
+
+ wake_up( ctx->middle_priority_task );
+
+ return false;
+}
+
static void Init( rtems_task_argument ignored )
{
test_context *ctx = &global_ctx;
rtems_status_code sc;
- int resets = 0;
TEST_BEGIN();
@@ -137,17 +145,7 @@ static void Init( rtems_task_argument ignored )
);
ASSERT_SC(sc);
- interrupt_critical_section_test_support_initialize(
- active_high_priority_task
- );
-
- while ( resets < 3 ) {
- if ( interrupt_critical_section_test_support_delay() ) {
- ++resets;
- }
-
- wake_up( ctx->middle_priority_task );
- }
+ interrupt_critical_section_test( test_body, ctx, active_high_priority_task );
TEST_END();
@@ -161,6 +159,7 @@ static void Init( rtems_task_argument ignored )
#define CONFIGURE_MAXIMUM_TASKS 3
#define CONFIGURE_MAXIMUM_TIMERS 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_INIT_TASK_PRIORITY PRIORITY_LOW
#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
diff --git a/testsuites/sptests/spintrcritical20/init.c b/testsuites/sptests/spintrcritical20/init.c
index cae8fdbc4d..daa8ac7f7e 100644
--- a/testsuites/sptests/spintrcritical20/init.c
+++ b/testsuites/sptests/spintrcritical20/init.c
@@ -63,10 +63,52 @@ static void release_semaphore(rtems_id timer, void *arg)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
+static bool test_body(void *arg)
+{
+ test_context *ctx = arg;
+ int busy;
+
+ _Thread_Disable_dispatch();
+
+ rtems_test_assert(
+ ctx->semaphore_task_tcb->Wait.return_code
+ == CORE_SEMAPHORE_STATUS_SUCCESSFUL
+ );
+
+ /*
+ * Spend some time to make it more likely that we hit the test condition
+ * below.
+ */
+ for (busy = 0; busy < 1000; ++busy) {
+ __asm__ volatile ("");
+ }
+
+ if (ctx->semaphore_task_tcb->Wait.queue == NULL) {
+ ctx->thread_queue_was_null = true;
+ }
+
+ _Thread_queue_Process_timeout(ctx->semaphore_task_tcb);
+
+ switch (ctx->semaphore_task_tcb->Wait.return_code) {
+ case CORE_SEMAPHORE_STATUS_SUCCESSFUL:
+ ctx->status_was_successful = true;
+ break;
+ case CORE_SEMAPHORE_TIMEOUT:
+ ctx->status_was_timeout = true;
+ break;
+ default:
+ rtems_test_assert(0);
+ break;
+ }
+
+ _Thread_Enable_dispatch();
+
+ return false;
+}
+
static void Init(rtems_task_argument ignored)
{
test_context *ctx = &ctx_instance;
- int resets = 0;
rtems_status_code sc;
TEST_BEGIN();
@@ -99,42 +141,7 @@ static void Init(rtems_task_argument ignored)
);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
- interrupt_critical_section_test_support_initialize(
- release_semaphore
- );
-
- while (resets < 3) {
- if (interrupt_critical_section_test_support_delay()) {
- ++resets;
- }
-
- _Thread_Disable_dispatch();
-
- rtems_test_assert(
- ctx->semaphore_task_tcb->Wait.return_code
- == CORE_SEMAPHORE_STATUS_SUCCESSFUL
- );
-
- if (ctx->semaphore_task_tcb->Wait.queue == NULL) {
- ctx->thread_queue_was_null = true;
- }
-
- _Thread_queue_Process_timeout(ctx->semaphore_task_tcb);
-
- switch (ctx->semaphore_task_tcb->Wait.return_code) {
- case CORE_SEMAPHORE_STATUS_SUCCESSFUL:
- ctx->status_was_successful = true;
- break;
- case CORE_SEMAPHORE_TIMEOUT:
- ctx->status_was_timeout = true;
- break;
- default:
- rtems_test_assert(0);
- break;
- }
-
- _Thread_Enable_dispatch();
- }
+ interrupt_critical_section_test(test_body, ctx, release_semaphore);
rtems_test_assert(ctx->thread_queue_was_null);
rtems_test_assert(ctx->status_was_successful);
@@ -153,6 +160,7 @@ static void Init(rtems_task_argument ignored)
#define CONFIGURE_MAXIMUM_SEMAPHORES 1
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_TIMERS 1
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
#define CONFIGURE_INIT_TASK_PRIORITY PRIORITY_MASTER
#define CONFIGURE_INIT_TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
diff --git a/testsuites/sptests/spintrcritical_support/intrcritical.c b/testsuites/sptests/spintrcritical_support/intrcritical.c
index d044d141b4..b6b250726c 100644
--- a/testsuites/sptests/spintrcritical_support/intrcritical.c
+++ b/testsuites/sptests/spintrcritical_support/intrcritical.c
@@ -14,14 +14,23 @@
#include <tmacros.h>
#include <intrcritical.h>
-static uint32_t Maximum;
-static uint32_t Maximum_current;
-static rtems_id Timer;
-static rtems_timer_service_routine (*TSR)( rtems_id, void * );
+#define INTERRUPT_CRITICAL_NAME rtems_build_name( 'I', 'C', 'R', 'I' )
-static uint32_t interrupt_critical_remaining_units_of_tick( void )
+typedef struct {
+ rtems_interval minimum;
+ rtems_interval maximum;
+ rtems_interval maximum_current;
+ rtems_timer_service_routine_entry tsr;
+ rtems_id timer;
+ uint64_t t0;
+ uint64_t t1;
+} interrupt_critical_control;
+
+static interrupt_critical_control interrupt_critical;
+
+static rtems_interval estimate_busy_loop_maximum( void )
{
- uint32_t units = 0;
+ rtems_interval units = 0;
rtems_interval initial = rtems_clock_get_ticks_since_boot();
while ( initial == rtems_clock_get_ticks_since_boot() ) {
@@ -31,61 +40,204 @@ static uint32_t interrupt_critical_remaining_units_of_tick( void )
return units;
}
-static bool interrupt_critical_busy_wait( void )
+static rtems_interval wait_for_tick_change( void )
{
- uint32_t max = Maximum_current;
- uint32_t unit = 0;
rtems_interval initial = rtems_clock_get_ticks_since_boot();
+ rtems_interval now;
+
+ do {
+ now = rtems_clock_get_ticks_since_boot();
+ } while ( now == initial );
- while ( unit < max && initial == rtems_clock_get_ticks_since_boot() ) {
- ++unit;
+ return now;
+}
+
+/*
+ * It is important that we use actually use the same busy() function at the
+ * various places, since otherwise the obtained maximum value might be wrong.
+ * So the compiler must not inline this function.
+ */
+static __attribute__( ( noinline ) ) void busy( rtems_interval max )
+{
+ rtems_interval i;
+
+ for ( i = 0; i < max; ++i ) {
+ __asm__ volatile ("");
}
+}
- if ( max > 0 ) {
- Maximum_current = max - 1;
+static bool interrupt_critical_busy_wait( void )
+{
+ rtems_interval max = interrupt_critical.maximum_current;
+ bool reset = max <= interrupt_critical.minimum;
- return false;
+ if ( reset ) {
+ interrupt_critical.maximum_current = interrupt_critical.maximum;
} else {
- Maximum_current = Maximum;
-
- return true;
+ interrupt_critical.maximum_current = max - 1;
}
+
+ busy( max );
+
+ return reset;
}
void interrupt_critical_section_test_support_initialize(
- rtems_timer_service_routine (*tsr)( rtems_id, void * )
+ rtems_timer_service_routine_entry tsr
)
{
- Timer = 0;
- TSR = tsr;
- if ( tsr ) {
- rtems_status_code rc;
-
- puts( "Support - rtems_timer_create - creating timer 1" );
- rc = rtems_timer_create( rtems_build_name( 'T', 'M', '1', ' ' ), &Timer );
- directive_failed( rc, "rtems_timer_create" );
+ rtems_interval last;
+ rtems_interval now;
+ rtems_interval a;
+ rtems_interval b;
+ rtems_interval m;
+
+ interrupt_critical.tsr = tsr;
+
+ if ( tsr != NULL && interrupt_critical.timer == 0 ) {
+ rtems_status_code sc = rtems_timer_create(
+ INTERRUPT_CRITICAL_NAME,
+ &interrupt_critical.timer
+ );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
}
- /* Wait for tick change */
- interrupt_critical_remaining_units_of_tick();
+ /* Choose a lower bound */
+ a = 1;
+
+ /* Estimate an upper bound */
+
+ wait_for_tick_change();
+ b = 2 * estimate_busy_loop_maximum();
+
+ while ( true ) {
+ last = wait_for_tick_change();
+ busy( b );
+ now = rtems_clock_get_ticks_since_boot();
+
+ if ( now != last ) {
+ break;
+ }
- /* Get units for a hole tick */
- Maximum = interrupt_critical_remaining_units_of_tick();
- Maximum_current = Maximum;
+ b *= 2;
+ last = now;
+ }
+
+ /* Find a good value */
+ do {
+ m = ( a + b ) / 2;
+
+ last = wait_for_tick_change();
+ busy( m );
+ now = rtems_clock_get_ticks_since_boot();
+
+ if ( now != last ) {
+ b = m;
+ } else {
+ a = m;
+ }
+ } while ( b - a > 1 );
+
+ interrupt_critical.minimum = 0;
+ interrupt_critical.maximum = m;
+ interrupt_critical.maximum_current = m;
+}
- #if 0
- printf( "%d 0x%08x units\n", Maximum, Maximum );
- #endif
+static void timer_fire_after(void)
+{
+ if ( interrupt_critical.tsr != NULL ) {
+ rtems_status_code sc = rtems_timer_fire_after(
+ interrupt_critical.timer,
+ 1,
+ interrupt_critical.tsr,
+ NULL
+ );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+ }
}
bool interrupt_critical_section_test_support_delay(void)
{
- if (TSR) {
- rtems_status_code rc;
+ timer_fire_after();
- rc = rtems_timer_fire_after( Timer, 1, TSR, NULL );
- directive_failed( rc, "timer_fire_after failed" );
+ return interrupt_critical_busy_wait();
+}
+
+static bool is_idle( const Thread_Control *thread )
+{
+ return thread->Start.entry_point
+ == (Thread_Entry) rtems_configuration_get_idle_task();
+}
+
+static void thread_switch( Thread_Control *executing, Thread_Control *heir )
+{
+ (void) executing;
+ (void) heir;
+
+ if ( interrupt_critical.t1 == 0 && is_idle( heir ) ) {
+ interrupt_critical.t1 = rtems_clock_get_uptime_nanoseconds();
}
+}
- return interrupt_critical_busy_wait();
+static const rtems_extensions_table extensions = {
+ .thread_switch = thread_switch
+};
+
+bool interrupt_critical_section_test(
+ bool ( *test_body )( void * ),
+ void *test_body_arg,
+ rtems_timer_service_routine_entry tsr
+)
+{
+ bool done;
+ rtems_status_code sc;
+ rtems_id id;
+ uint64_t delta;
+ rtems_interval busy_delta;
+ int retries = 3;
+
+ interrupt_critical_section_test_support_initialize( tsr );
+
+ sc = rtems_extension_create(
+ INTERRUPT_CRITICAL_NAME,
+ &extensions,
+ &id
+ );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+ wait_for_tick_change();
+ timer_fire_after();
+
+ /* Get estimate for test body duration */
+ interrupt_critical.t0 = rtems_clock_get_uptime_nanoseconds();
+ done = ( *test_body )( test_body_arg );
+ if ( interrupt_critical.t1 == 0 ) {
+ interrupt_critical.t1 = rtems_clock_get_uptime_nanoseconds();
+ }
+
+ /* Update minimum */
+
+ delta = interrupt_critical.t1 - interrupt_critical.t0;
+ busy_delta = (rtems_interval)
+ ( ( interrupt_critical.maximum * ( 2 * delta ) )
+ / rtems_configuration_get_nanoseconds_per_tick() );
+
+ if ( busy_delta < interrupt_critical.maximum ) {
+ interrupt_critical.minimum = interrupt_critical.maximum - busy_delta;
+ }
+
+ sc = rtems_extension_delete( id );
+ rtems_test_assert( sc == RTEMS_SUCCESSFUL );
+
+ while ( !done && retries >= 0 ) {
+ wait_for_tick_change();
+
+ if ( interrupt_critical_section_test_support_delay() ) {
+ --retries;
+ }
+
+ done = ( *test_body )( test_body_arg );
+ }
+
+ return done;
}
diff --git a/testsuites/sptests/spintrcritical_support/intrcritical.h b/testsuites/sptests/spintrcritical_support/intrcritical.h
index 7989b3f7e2..aca1ee0f2c 100644
--- a/testsuites/sptests/spintrcritical_support/intrcritical.h
+++ b/testsuites/sptests/spintrcritical_support/intrcritical.h
@@ -16,7 +16,7 @@
* @param[in] tsr is the optional timer service routine to fire
*/
void interrupt_critical_section_test_support_initialize(
- rtems_timer_service_routine (*tsr)( rtems_id, void * )
+ rtems_timer_service_routine_entry tsr
);
/**
@@ -29,5 +29,24 @@ void interrupt_critical_section_test_support_initialize(
*/
bool interrupt_critical_section_test_support_delay(void);
+/**
+ * @brief Interrupt critical section test.
+ *
+ * This function first estimates the test body duration and then repeatedly
+ * calls the test body with varying times to the next clock tick interrupt.
+ *
+ * @param[in] test_body The test body function. In case the test body returns
+ * true, then the test iteration stops.
+ * @param[in] test_body_arg The argument for the test body function.
+ * @param[in] tsr An optional timer service routine.
+ *
+ * @return The test body return status.
+ */
+bool interrupt_critical_section_test(
+ bool ( *test_body )( void * ),
+ void *test_body_arg,
+ rtems_timer_service_routine_entry tsr
+);
+
#endif