From 8d3fe04499e39c99158c3fd531233c953a28ff0a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 9 Dec 2021 16:11:43 +0100 Subject: validation: Test Event Manager The test source code is generated from specification items by the "./spec2modules.py" script contained in the git://git.rtems.org/rtems-central.git Git repository. Please read the "How-To" section in the "Software Requirements Engineering" chapter of the RTEMS Software Engineering manual to get more information about the process. Update #3716. --- testsuites/validation/tc-event-performance.c | 550 +++++++++++ testsuites/validation/tc-event-send-receive.c | 203 ++++ testsuites/validation/tc-events.c | 197 ++++ testsuites/validation/tr-event-constant.c | 721 ++++++++++++++ testsuites/validation/tr-event-constant.h | 81 ++ testsuites/validation/tr-event-send-receive.c | 1316 +++++++++++++++++++++++++ testsuites/validation/tr-event-send-receive.h | 152 +++ 7 files changed, 3220 insertions(+) create mode 100644 testsuites/validation/tc-event-performance.c create mode 100644 testsuites/validation/tc-event-send-receive.c create mode 100644 testsuites/validation/tc-events.c create mode 100644 testsuites/validation/tr-event-constant.c create mode 100644 testsuites/validation/tr-event-constant.h create mode 100644 testsuites/validation/tr-event-send-receive.c create mode 100644 testsuites/validation/tr-event-send-receive.h (limited to 'testsuites/validation') diff --git a/testsuites/validation/tc-event-performance.c b/testsuites/validation/tc-event-performance.c new file mode 100644 index 0000000000..1baefecea5 --- /dev/null +++ b/testsuites/validation/tc-event-performance.c @@ -0,0 +1,550 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsEventValPerf + */ + +/* + * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tx-support.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsEventValPerf spec:/rtems/event/val/perf + * + * @ingroup RTEMSTestSuiteTestsuitesPerformanceNoClock0 + * + * @brief This test case provides a context to run @ref RTEMSAPIClassicEvent + * performance tests. + * + * @{ + */ + +/** + * @brief Test context for spec:/rtems/event/val/perf test case. + */ +typedef struct { + /** + * @brief This member provides a worker identifier. + */ + rtems_id worker_id; + + /** + * @brief This member provides a status code. + */ + rtems_status_code status; + + /** + * @brief This member references the measure runtime context. + */ + T_measure_runtime_context *context; + + /** + * @brief This member provides the measure runtime request. + */ + T_measure_runtime_request request; + + /** + * @brief This member provides an optional measurement begin time point. + */ + T_ticks begin; + + /** + * @brief This member provides an optional measurement end time point. + */ + T_ticks end; +} RtemsEventValPerf_Context; + +static RtemsEventValPerf_Context + RtemsEventValPerf_Instance; + +typedef RtemsEventValPerf_Context Context; + +typedef enum { + EVENT_END = RTEMS_EVENT_0, + EVENT_OTHER = RTEMS_EVENT_1 +} Event; + +static void Send( const Context *ctx, rtems_event_set events ) +{ + SendEvents( ctx->worker_id, events ); +} + +static void Satisfy( void *arg ) +{ + Context *ctx; + + ctx = arg; + ctx->begin = T_tick(); + ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER ); +} + +static void Worker( rtems_task_argument arg ) +{ + Context *ctx; + + ctx = (Context *) arg; + + while ( true ) { + rtems_event_set events; + rtems_status_code sc; + T_ticks ticks; + + sc = rtems_event_receive( + EVENT_END | EVENT_OTHER, + RTEMS_EVENT_ALL | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events + ); + ticks = T_tick(); + T_quiet_rsc_success( sc ); + + if ( ( events & EVENT_END ) != 0 ) { + ctx->end = ticks; + } + } +} + +static void RtemsEventValPerf_Setup_Context( RtemsEventValPerf_Context *ctx ) +{ + T_measure_runtime_config config; + + memset( &config, 0, sizeof( config ) ); + config.sample_count = 100; + ctx->request.arg = ctx; + ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES; + ctx->context = T_measure_runtime_create( &config ); + T_assert_not_null( ctx->context ); +} + +/** + * @brief Create a mutex and a worker task. + */ +static void RtemsEventValPerf_Setup( RtemsEventValPerf_Context *ctx ) +{ + SetSelfPriority( PRIO_NORMAL ); + ctx->worker_id = CreateTask( "WORK", PRIO_HIGH ); + StartTask( ctx->worker_id, Worker, ctx ); +} + +static void RtemsEventValPerf_Setup_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventValPerf_Setup_Context( ctx ); + RtemsEventValPerf_Setup( ctx ); +} + +/** + * @brief Delete the worker task and the mutex. + */ +static void RtemsEventValPerf_Teardown( RtemsEventValPerf_Context *ctx ) +{ + DeleteTask( ctx->worker_id ); + RestoreRunnerPriority(); +} + +static void RtemsEventValPerf_Teardown_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventValPerf_Teardown( ctx ); +} + +static T_fixture RtemsEventValPerf_Fixture = { + .setup = RtemsEventValPerf_Setup_Wrap, + .stop = NULL, + .teardown = RtemsEventValPerf_Teardown_Wrap, + .scope = NULL, + .initial_context = &RtemsEventValPerf_Instance +}; + +/** + * @brief Send two events from with interrupt context. Satisfy the event + * condition. + */ +static void RtemsEventReqPerfIsrPreempt_Body( RtemsEventValPerf_Context *ctx ) +{ + CallWithinISR( Satisfy, ctx ); +} + +static void RtemsEventReqPerfIsrPreempt_Body_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventReqPerfIsrPreempt_Body( ctx ); +} + +/** + * @brief Set the measured runtime. Discard samples interrupted by a clock + * tick. + */ +static bool RtemsEventReqPerfIsrPreempt_Teardown( + RtemsEventValPerf_Context *ctx, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + T_quiet_rsc_success( ctx->status ); + + *delta = ctx->end - ctx->begin; + + return tic == toc; +} + +static bool RtemsEventReqPerfIsrPreempt_Teardown_Wrap( + void *arg, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + return RtemsEventReqPerfIsrPreempt_Teardown( ctx, delta, tic, toc, retry ); +} + +/** + * @brief Lower the worker priority. + */ +static void RtemsEventReqPerfOther_Setup( RtemsEventValPerf_Context *ctx ) +{ + SetPriority( ctx->worker_id, PRIO_LOW ); +} + +static void RtemsEventReqPerfOther_Setup_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventReqPerfOther_Setup( ctx ); +} + +/** + * @brief Send two events. Satisfy the event condition. + */ +static void RtemsEventReqPerfOther_Body( RtemsEventValPerf_Context *ctx ) +{ + ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER ); +} + +static void RtemsEventReqPerfOther_Body_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventReqPerfOther_Body( ctx ); +} + +/** + * @brief Restore the worker priority. Discard samples interrupted by a clock + * tick. + */ +static bool RtemsEventReqPerfOther_Teardown( + RtemsEventValPerf_Context *ctx, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + T_quiet_rsc_success( ctx->status ); + + SetPriority( ctx->worker_id, PRIO_HIGH ); + + return tic == toc; +} + +static bool RtemsEventReqPerfOther_Teardown_Wrap( + void *arg, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + return RtemsEventReqPerfOther_Teardown( ctx, delta, tic, toc, retry ); +} + +#if defined(RTEMS_SMP) +/** + * @brief Move worker to scheduler B. + */ +static void RtemsEventReqPerfOtherCpu_Prepare( RtemsEventValPerf_Context *ctx ) +{ + SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL ); +} + +/** + * @brief Send two events. Satisfy the event condition. + */ +static void RtemsEventReqPerfOtherCpu_Body( RtemsEventValPerf_Context *ctx ) +{ + ctx->begin = T_tick(); + ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER ); +} + +static void RtemsEventReqPerfOtherCpu_Body_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventReqPerfOtherCpu_Body( ctx ); +} + +/** + * @brief Make sure the worker waits for the next event. Set the measured + * runtime. Discard samples interrupted by a clock tick. + */ +static bool RtemsEventReqPerfOtherCpu_Teardown( + RtemsEventValPerf_Context *ctx, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + T_quiet_rsc_success( ctx->status ); + + WaitForNextTask( 1, ctx->worker_id ); + *delta = ctx->end - ctx->begin; + + return tic == toc; +} + +static bool RtemsEventReqPerfOtherCpu_Teardown_Wrap( + void *arg, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + return RtemsEventReqPerfOtherCpu_Teardown( ctx, delta, tic, toc, retry ); +} + +/** + * @brief Move worker to scheduler A. + */ +static void RtemsEventReqPerfOtherCpu_Cleanup( RtemsEventValPerf_Context *ctx ) +{ + SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH ); +} +#endif + +/** + * @brief Send an event. Do not satisfy the event condition. + */ +static void RtemsEventReqPerfOtherNotSatisfied_Body( + RtemsEventValPerf_Context *ctx +) +{ + ctx->status = rtems_event_send( ctx->worker_id, EVENT_OTHER ); +} + +static void RtemsEventReqPerfOtherNotSatisfied_Body_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventReqPerfOtherNotSatisfied_Body( ctx ); +} + +/** + * @brief Let the worker wait for the next set of events. Discard samples + * interrupted by a clock tick. + */ +static bool RtemsEventReqPerfOtherNotSatisfied_Teardown( + RtemsEventValPerf_Context *ctx, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + T_quiet_rsc_success( ctx->status ); + + Send( ctx, EVENT_END ); + + return tic == toc; +} + +static bool RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap( + void *arg, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + return RtemsEventReqPerfOtherNotSatisfied_Teardown( + ctx, + delta, + tic, + toc, + retry + ); +} + +/** + * @brief Send two events. Satisfy the event condition. + */ +static void RtemsEventReqPerfOtherPreempt_Body( + RtemsEventValPerf_Context *ctx +) +{ + ctx->begin = T_tick(); + ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER ); +} + +static void RtemsEventReqPerfOtherPreempt_Body_Wrap( void *arg ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + RtemsEventReqPerfOtherPreempt_Body( ctx ); +} + +/** + * @brief Set the measured runtime. Discard samples interrupted by a clock + * tick. + */ +static bool RtemsEventReqPerfOtherPreempt_Teardown( + RtemsEventValPerf_Context *ctx, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + T_quiet_rsc_success( ctx->status ); + + *delta = ctx->end - ctx->begin; + + return tic == toc; +} + +static bool RtemsEventReqPerfOtherPreempt_Teardown_Wrap( + void *arg, + T_ticks *delta, + uint32_t tic, + uint32_t toc, + unsigned int retry +) +{ + RtemsEventValPerf_Context *ctx; + + ctx = arg; + return RtemsEventReqPerfOtherPreempt_Teardown( ctx, delta, tic, toc, retry ); +} + +/** + * @fn void T_case_body_RtemsEventValPerf( void ) + */ +T_TEST_CASE_FIXTURE( RtemsEventValPerf, &RtemsEventValPerf_Fixture ) +{ + RtemsEventValPerf_Context *ctx; + + ctx = T_fixture_context(); + + ctx->request.name = "RtemsEventReqPerfIsrPreempt"; + ctx->request.setup = NULL; + ctx->request.body = RtemsEventReqPerfIsrPreempt_Body_Wrap; + ctx->request.teardown = RtemsEventReqPerfIsrPreempt_Teardown_Wrap; + T_measure_runtime( ctx->context, &ctx->request ); + + ctx->request.name = "RtemsEventReqPerfOther"; + ctx->request.setup = RtemsEventReqPerfOther_Setup_Wrap; + ctx->request.body = RtemsEventReqPerfOther_Body_Wrap; + ctx->request.teardown = RtemsEventReqPerfOther_Teardown_Wrap; + T_measure_runtime( ctx->context, &ctx->request ); + + #if defined(RTEMS_SMP) + RtemsEventReqPerfOtherCpu_Prepare( ctx ); + ctx->request.name = "RtemsEventReqPerfOtherCpu"; + ctx->request.setup = NULL; + ctx->request.body = RtemsEventReqPerfOtherCpu_Body_Wrap; + ctx->request.teardown = RtemsEventReqPerfOtherCpu_Teardown_Wrap; + T_measure_runtime( ctx->context, &ctx->request ); + RtemsEventReqPerfOtherCpu_Cleanup( ctx ); + #endif + + ctx->request.name = "RtemsEventReqPerfOtherNotSatisfied"; + ctx->request.setup = NULL; + ctx->request.body = RtemsEventReqPerfOtherNotSatisfied_Body_Wrap; + ctx->request.teardown = RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap; + T_measure_runtime( ctx->context, &ctx->request ); + + ctx->request.name = "RtemsEventReqPerfOtherPreempt"; + ctx->request.setup = NULL; + ctx->request.body = RtemsEventReqPerfOtherPreempt_Body_Wrap; + ctx->request.teardown = RtemsEventReqPerfOtherPreempt_Teardown_Wrap; + T_measure_runtime( ctx->context, &ctx->request ); +} + +/** @} */ diff --git a/testsuites/validation/tc-event-send-receive.c b/testsuites/validation/tc-event-send-receive.c new file mode 100644 index 0000000000..7db58bedcd --- /dev/null +++ b/testsuites/validation/tc-event-send-receive.c @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsEventValSendReceive + * @ingroup RTEMSTestCaseRtemsEventValSystemSendReceive + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include + +#include "tr-event-send-receive.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsEventValSendReceive \ + * spec:/rtems/event/val/send-receive + * + * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * + * @brief Tests the rtems_event_send() and rtems_event_receive() directives. + * + * This test case performs the following actions: + * + * - Run the event send and receive tests for the application event set defined + * by /rtems/event/req/send-receive. + * + * @{ + */ + +static rtems_status_code EventSend( + rtems_id id, + rtems_event_set event_in +) +{ + return rtems_event_send( id, event_in ); +} + +static rtems_status_code EventReceive( + rtems_id event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +) +{ + return rtems_event_receive( event_in, option_set, ticks, event_out ); +} + +static rtems_event_set GetPendingEvents( Thread_Control *thread ) +{ + RTEMS_API_Control *api; + + api = thread->API_Extensions[ THREAD_API_RTEMS ]; + return api->Event.pending_events; +} + +/** + * @brief Run the event send and receive tests for the application event set + * defined by /rtems/event/req/send-receive. + */ +static void RtemsEventValSendReceive_Action_0( void ) +{ + RtemsEventReqSendReceive_Run( + EventSend, + EventReceive, + GetPendingEvents, + THREAD_WAIT_CLASS_EVENT, + STATES_WAITING_FOR_EVENT + ); +} + +/** + * @fn void T_case_body_RtemsEventValSendReceive( void ) + */ +T_TEST_CASE( RtemsEventValSendReceive ) +{ + RtemsEventValSendReceive_Action_0(); +} + +/** @} */ + +/** + * @defgroup RTEMSTestCaseRtemsEventValSystemSendReceive \ + * spec:/rtems/event/val/system-send-receive + * + * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * + * @brief Tests the rtems_event_system_send() and rtems_event_system_receive() + * directives. + * + * This test case performs the following actions: + * + * - Run the event send and receive tests for the system event set defined by + * /rtems/event/req/send-receive. + * + * @{ + */ + +static rtems_status_code EventSystemSend( + rtems_id id, + rtems_event_set event_in +) +{ + return rtems_event_system_send( id, event_in ); +} + +static rtems_status_code EventSystemReceive( + rtems_id event_in, + rtems_option option_set, + rtems_interval ticks, + rtems_event_set *event_out +) +{ + return rtems_event_system_receive( + event_in, + option_set, + ticks, + event_out + ); +} + +static rtems_event_set GetPendingSystemEvents( Thread_Control *thread ) +{ + RTEMS_API_Control *api; + + api = thread->API_Extensions[ THREAD_API_RTEMS ]; + return api->System_event.pending_events; +} + +/** + * @brief Run the event send and receive tests for the system event set defined + * by /rtems/event/req/send-receive. + */ +static void RtemsEventValSystemSendReceive_Action_0( void ) +{ + RtemsEventReqSendReceive_Run( + EventSystemSend, + EventSystemReceive, + GetPendingSystemEvents, + THREAD_WAIT_CLASS_SYSTEM_EVENT, + STATES_WAITING_FOR_SYSTEM_EVENT + ); +} + +/** + * @fn void T_case_body_RtemsEventValSystemSendReceive( void ) + */ +T_TEST_CASE( RtemsEventValSystemSendReceive ) +{ + RtemsEventValSystemSendReceive_Action_0(); +} + +/** @} */ diff --git a/testsuites/validation/tc-events.c b/testsuites/validation/tc-events.c new file mode 100644 index 0000000000..54df2f7ceb --- /dev/null +++ b/testsuites/validation/tc-events.c @@ -0,0 +1,197 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsEventValEvents + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tr-event-constant.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsEventValEvents spec:/rtems/event/val/events + * + * @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0 + * + * @brief Tests the Event Manager API. + * + * This test case performs the following actions: + * + * - Run the event constant and number test for all 32 event constants. + * + * - Check that RTEMS_PENDING_EVENTS is a constant expression which evaluates + * to a value of zero. + * + * - Calculate the value of a bitwise or of all 32 event constants. + * + * - Check that the value is equal to RTEMS_ALL_EVENTS. + * + * - Validate the Event Manager directive options. + * + * - Check that RTEMS_EVENT_ALL is equal to zero. + * + * - Check that RTEMS_EVENT_ANY is a power of two. + * + * @{ + */ + +static const rtems_event_set events[] = { + RTEMS_EVENT_0, + RTEMS_EVENT_1, + RTEMS_EVENT_2, + RTEMS_EVENT_3, + RTEMS_EVENT_4, + RTEMS_EVENT_5, + RTEMS_EVENT_6, + RTEMS_EVENT_7, + RTEMS_EVENT_8, + RTEMS_EVENT_9, + RTEMS_EVENT_10, + RTEMS_EVENT_11, + RTEMS_EVENT_12, + RTEMS_EVENT_13, + RTEMS_EVENT_14, + RTEMS_EVENT_15, + RTEMS_EVENT_16, + RTEMS_EVENT_17, + RTEMS_EVENT_18, + RTEMS_EVENT_19, + RTEMS_EVENT_20, + RTEMS_EVENT_21, + RTEMS_EVENT_22, + RTEMS_EVENT_23, + RTEMS_EVENT_24, + RTEMS_EVENT_25, + RTEMS_EVENT_26, + RTEMS_EVENT_27, + RTEMS_EVENT_28, + RTEMS_EVENT_29, + RTEMS_EVENT_30, + RTEMS_EVENT_31 +}; + +/** + * @brief Run the event constant and number test for all 32 event constants. + */ +static void RtemsEventValEvents_Action_0( void ) +{ + unsigned int i; + + for ( i = 0; i < 32; ++i ) { + RtemsEventValEventConstant_Run( events[ i ], i ); + T_step( i ); /* Accounts for 32 test plan steps */ + } +} + +/** + * @brief Check that RTEMS_PENDING_EVENTS is a constant expression which + * evaluates to a value of zero. + */ +static void RtemsEventValEvents_Action_1( void ) +{ + RTEMS_STATIC_ASSERT( RTEMS_PENDING_EVENTS == 0, PENDING_EVENTS ); +} + +/** + * @brief Calculate the value of a bitwise or of all 32 event constants. + */ +static void RtemsEventValEvents_Action_2( void ) +{ + rtems_event_set all; + int i; + + all = 0; + + for ( i = 0; i < 32; ++i ) { + all |= events[ i ]; + } + + /* + * Check that the value is equal to RTEMS_ALL_EVENTS. + */ + T_step_eq_u32( 32, all, RTEMS_ALL_EVENTS ); +} + +/** + * @brief Validate the Event Manager directive options. + */ +static void RtemsEventValEvents_Action_3( void ) +{ + /* No action */ + + /* + * Check that RTEMS_EVENT_ALL is equal to zero. + */ + T_step_eq_u32( 33, RTEMS_EVENT_ALL, 0 ); + + /* + * Check that RTEMS_EVENT_ANY is a power of two. + */ + T_step_ne_u32( 34, RTEMS_EVENT_ANY, 0 ); + T_step_eq_u32( 35, RTEMS_EVENT_ANY & ( RTEMS_EVENT_ANY - 1 ), 0 ); +} + +/** + * @fn void T_case_body_RtemsEventValEvents( void ) + */ +T_TEST_CASE( RtemsEventValEvents ) +{ + T_plan( 36 ); + + RtemsEventValEvents_Action_0(); + RtemsEventValEvents_Action_1(); + RtemsEventValEvents_Action_2(); + RtemsEventValEvents_Action_3(); +} + +/** @} */ diff --git a/testsuites/validation/tr-event-constant.c b/testsuites/validation/tr-event-constant.c new file mode 100644 index 0000000000..6895fcc821 --- /dev/null +++ b/testsuites/validation/tr-event-constant.c @@ -0,0 +1,721 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsEventValEventConstant + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tr-event-constant.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsEventValEventConstant \ + * spec:/rtems/event/val/event-constant + * + * @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0 + * + * @brief Tests an event constant and number of the Event Manager using the + * Classic and system event sets of the executing task. + * + * This test case performs the following actions: + * + * - Validate the event constant. + * + * - Check that the event constant is equal to the event number bit in the + * event set. + * + * - Check that the event number bit of the event constant is not set in + * RTEMS_PENDING_EVENTS. + * + * - Get all pending events of the Classic event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that there were no pending events. + * + * - Get all pending events of the system event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that there were no pending events. + * + * - Receive all pending events of the Classic event set of the executing task. + * + * - Check that the directive call was unsatisfied. + * + * - Check that there were no events received. + * + * - Receive all pending events of the system event set of the executing task. + * + * - Check that the directive call was unsatisfied. + * + * - Check that there were no events received. + * + * - Send the event to the Classic event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Get all pending events of the Classic event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that the pending event is equal to the event sent by a previous + * action. + * + * - Get all pending events of the system event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that there were no pending events. + * + * - Receive any event of the Classic event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that the received event is equal to the event sent by a previous + * action. + * + * - Receive any event of the system event set of the executing task. + * + * - Check that the directive call was unsatisfied. + * + * - Check that the no events were received. + * + * - Send the event to the Classic event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Get all pending events of the Classic event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that there were no pending events. + * + * - Get all pending events of the system event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that the pending event is equal to the event sent by a previous + * action. + * + * - Receive any event of the Classic event set of the executing task. + * + * - Check that the directive call was unsatisfied. + * + * - Check that the no events were received. + * + * - Receive any event of the system event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that the received event is equal to the event sent by a previous + * action. + * + * - Get all pending events of the Classic event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that there were no pending events. + * + * - Get all pending events of the system event set of the executing task. + * + * - Check that the directive call was successful. + * + * - Check that there were no pending events. + * + * @{ + */ + +/** + * @brief Test context for spec:/rtems/event/val/event-constant test case. + */ +typedef struct { + /** + * @brief This member contains a copy of the corresponding + * RtemsEventValEventConstant_Run() parameter. + */ + rtems_event_set event; + + /** + * @brief This member contains a copy of the corresponding + * RtemsEventValEventConstant_Run() parameter. + */ + int number; +} RtemsEventValEventConstant_Context; + +static RtemsEventValEventConstant_Context + RtemsEventValEventConstant_Instance; + +static T_fixture RtemsEventValEventConstant_Fixture = { + .setup = NULL, + .stop = NULL, + .teardown = NULL, + .scope = NULL, + .initial_context = &RtemsEventValEventConstant_Instance +}; + +/** + * @brief Validate the event constant. + */ +static void RtemsEventValEventConstant_Action_0( + RtemsEventValEventConstant_Context *ctx +) +{ + /* No action */ + + /* + * Check that the event constant is equal to the event number bit in the + * event set. + */ + T_step_eq_u32( + 0, + ctx->event, + ( (rtems_event_set) 1 ) << ctx->number + ); + + /* + * Check that the event number bit of the event constant is not set in + * RTEMS_PENDING_EVENTS. + */ + T_step_eq_u32( 1, ctx->event & RTEMS_PENDING_EVENTS, 0 ); +} + +/** + * @brief Get all pending events of the Classic event set of the executing + * task. + */ +static void RtemsEventValEventConstant_Action_1( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 2, sc ); + + /* + * Check that there were no pending events. + */ + T_step_eq_u32( 3, out, 0 ); +} + +/** + * @brief Get all pending events of the system event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_2( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_system_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 4, sc ); + + /* + * Check that there were no pending events. + */ + T_step_eq_u32( 5, out, 0 ); +} + +/** + * @brief Receive all pending events of the Classic event set of the executing + * task. + */ +static void RtemsEventValEventConstant_Action_3( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_receive( + RTEMS_ALL_EVENTS, + RTEMS_NO_WAIT | RTEMS_EVENT_ANY, + 0, + &out + ); + + /* + * Check that the directive call was unsatisfied. + */ + T_step_rsc( 6, sc, RTEMS_UNSATISFIED ); + + /* + * Check that there were no events received. + */ + T_step_eq_u32( 7, out, 0 ); +} + +/** + * @brief Receive all pending events of the system event set of the executing + * task. + */ +static void RtemsEventValEventConstant_Action_4( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_system_receive( + RTEMS_ALL_EVENTS, + RTEMS_NO_WAIT | RTEMS_EVENT_ANY, + 0, + &out + ); + + /* + * Check that the directive call was unsatisfied. + */ + T_step_rsc( 8, sc, RTEMS_UNSATISFIED ); + + /* + * Check that there were no events received. + */ + T_step_eq_u32( 9, out, 0 ); +} + +/** + * @brief Send the event to the Classic event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_5( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + + sc = rtems_event_send( RTEMS_SELF, ctx->event ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 10, sc ); +} + +/** + * @brief Get all pending events of the Classic event set of the executing + * task. + */ +static void RtemsEventValEventConstant_Action_6( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 11, sc ); + + /* + * Check that the pending event is equal to the event sent by a previous + * action. + */ + T_step_eq_u32( 12, out, ctx->event ); +} + +/** + * @brief Get all pending events of the system event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_7( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_system_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 13, sc ); + + /* + * Check that there were no pending events. + */ + T_step_eq_u32( 14, out, 0 ); +} + +/** + * @brief Receive any event of the Classic event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_8( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = 0; + sc = rtems_event_receive( + RTEMS_ALL_EVENTS, + RTEMS_NO_WAIT | RTEMS_EVENT_ANY, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 15, sc ); + + /* + * Check that the received event is equal to the event sent by a previous + * action. + */ + T_step_eq_u32( 16, out, ctx->event ); +} + +/** + * @brief Receive any event of the system event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_9( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_system_receive( + RTEMS_ALL_EVENTS, + RTEMS_NO_WAIT | RTEMS_EVENT_ANY, + 0, + &out + ); + + /* + * Check that the directive call was unsatisfied. + */ + T_step_rsc( 17, sc, RTEMS_UNSATISFIED ); + + /* + * Check that the no events were received. + */ + T_step_eq_u32( 18, out, 0 ); +} + +/** + * @brief Send the event to the Classic event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_10( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + + sc = rtems_event_system_send( RTEMS_SELF, ctx->event ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 19, sc ); +} + +/** + * @brief Get all pending events of the Classic event set of the executing + * task. + */ +static void RtemsEventValEventConstant_Action_11( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 20, sc ); + + /* + * Check that there were no pending events. + */ + T_step_eq_u32( 21, out, 0 ); +} + +/** + * @brief Get all pending events of the system event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_12( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_system_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 22, sc ); + + /* + * Check that the pending event is equal to the event sent by a previous + * action. + */ + T_step_eq_u32( 23, out, ctx->event ); +} + +/** + * @brief Receive any event of the Classic event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_13( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_receive( + RTEMS_ALL_EVENTS, + RTEMS_NO_WAIT | RTEMS_EVENT_ANY, + 0, + &out + ); + + /* + * Check that the directive call was unsatisfied. + */ + T_step_rsc( 24, sc, RTEMS_UNSATISFIED ); + + /* + * Check that the no events were received. + */ + T_step_eq_u32( 25, out, 0 ); +} + +/** + * @brief Receive any event of the system event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_14( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = 0; + sc = rtems_event_system_receive( + RTEMS_ALL_EVENTS, + RTEMS_NO_WAIT | RTEMS_EVENT_ANY, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 26, sc ); + + /* + * Check that the received event is equal to the event sent by a previous + * action. + */ + T_step_eq_u32( 27, out, ctx->event ); +} + +/** + * @brief Get all pending events of the Classic event set of the executing + * task. + */ +static void RtemsEventValEventConstant_Action_15( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 28, sc ); + + /* + * Check that there were no pending events. + */ + T_step_eq_u32( 29, out, 0 ); +} + +/** + * @brief Get all pending events of the system event set of the executing task. + */ +static void RtemsEventValEventConstant_Action_16( + RtemsEventValEventConstant_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set out; + + out = RTEMS_ALL_EVENTS; + sc = rtems_event_system_receive( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &out + ); + + /* + * Check that the directive call was successful. + */ + T_step_rsc_success( 30, sc ); + + /* + * Check that there were no pending events. + */ + T_step_eq_u32( 31, out, 0 ); +} + +static T_fixture_node RtemsEventValEventConstant_Node; + +void RtemsEventValEventConstant_Run( rtems_event_set event, int number ) +{ + RtemsEventValEventConstant_Context *ctx; + + ctx = &RtemsEventValEventConstant_Instance; + ctx->event = event; + ctx->number = number; + + ctx = T_push_fixture( + &RtemsEventValEventConstant_Node, + &RtemsEventValEventConstant_Fixture + ); + + T_plan( 32 ); + + RtemsEventValEventConstant_Action_0( ctx ); + RtemsEventValEventConstant_Action_1( ctx ); + RtemsEventValEventConstant_Action_2( ctx ); + RtemsEventValEventConstant_Action_3( ctx ); + RtemsEventValEventConstant_Action_4( ctx ); + RtemsEventValEventConstant_Action_5( ctx ); + RtemsEventValEventConstant_Action_6( ctx ); + RtemsEventValEventConstant_Action_7( ctx ); + RtemsEventValEventConstant_Action_8( ctx ); + RtemsEventValEventConstant_Action_9( ctx ); + RtemsEventValEventConstant_Action_10( ctx ); + RtemsEventValEventConstant_Action_11( ctx ); + RtemsEventValEventConstant_Action_12( ctx ); + RtemsEventValEventConstant_Action_13( ctx ); + RtemsEventValEventConstant_Action_14( ctx ); + RtemsEventValEventConstant_Action_15( ctx ); + RtemsEventValEventConstant_Action_16( ctx ); + + T_pop_fixture(); +} + +/** @} */ diff --git a/testsuites/validation/tr-event-constant.h b/testsuites/validation/tr-event-constant.h new file mode 100644 index 0000000000..b6484874d5 --- /dev/null +++ b/testsuites/validation/tr-event-constant.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsEventValEventConstant + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifndef _TR_EVENT_CONSTANT_H +#define _TR_EVENT_CONSTANT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup RTEMSTestCaseRtemsEventValEventConstant + * + * @{ + */ + +/** + * @brief Runs the parameterized test case. + * + * @param event is the event constant. + * + * @param number is the event number. + */ +void RtemsEventValEventConstant_Run( rtems_event_set event, int number ); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TR_EVENT_CONSTANT_H */ diff --git a/testsuites/validation/tr-event-send-receive.c b/testsuites/validation/tr-event-send-receive.c new file mode 100644 index 0000000000..e7c48dae70 --- /dev/null +++ b/testsuites/validation/tr-event-send-receive.c @@ -0,0 +1,1316 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsEventReqSendReceive + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tr-event-send-receive.h" +#include "tx-support.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsEventReqSendReceive \ + * spec:/rtems/event/req/send-receive + * + * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * + * @{ + */ + +typedef struct { + uint16_t Skip : 1; + uint16_t Pre_Id_NA : 1; + uint16_t Pre_Send_NA : 1; + uint16_t Pre_ReceiverState_NA : 1; + uint16_t Pre_Satisfy_NA : 1; + uint16_t Post_SendStatus : 2; + uint16_t Post_ReceiveStatus : 3; + uint16_t Post_SenderPreemption : 2; +} RtemsEventReqSendReceive_Entry; + +#define PRIO_OTHER UINT32_MAX + +typedef enum { + SENDER_NONE, + SENDER_SELF, + SENDER_SELF_2, + SENDER_WORKER, + SENDER_INTERRUPT +} SenderTypes; + +typedef enum { + RECEIVE_SKIP, + RECEIVE_NORMAL, + RECEIVE_INTERRUPT +} ReceiveTypes; + +typedef enum { + RECEIVE_COND_UNKNOWN, + RECEIVE_COND_SATSIFIED, + RECEIVE_COND_UNSATISFIED +} ReceiveConditionStates; + +/** + * @brief Test context for spec:/rtems/event/req/send-receive test case. + */ +typedef struct { + /** + * @brief This member defines the sender type to perform the event send + * action. + */ + SenderTypes sender_type; + + /** + * @brief This member defines the sender task priority. + */ + rtems_task_priority sender_prio; + + /** + * @brief This member defines the receiver ID used for the event send action. + */ + rtems_id receiver_id; + + /** + * @brief This member defines the events to send for the event send action. + */ + rtems_event_set events_to_send; + + /** + * @brief This member contains the status of the event send action. + */ + rtems_status_code send_status; + + /** + * @brief This member contains the scheduler ID of the runner task. + */ + ReceiveTypes receive_type; + + /** + * @brief This member defines the option set used for the event receive + * action. + */ + rtems_option receive_option_set; + + /** + * @brief This member defines the timeout used for the event receive action. + */ + rtems_interval receive_timeout; + + /** + * @brief This member contains the events received by the event receive + * action. + */ + rtems_event_set received_events; + + /** + * @brief This member references the event set received by the event receive + * action or is NULL. + */ + rtems_event_set *received_events_parameter; + + /** + * @brief This member contains the status of the event receive action. + */ + rtems_status_code receive_status; + + /** + * @brief This member contains the event condition state of the receiver task + * after the event send action. + */ + ReceiveConditionStates receive_condition_state; + + /** + * @brief This member contains the pending events after an event send action + * which did not satisify the event condition of the receiver. + */ + rtems_event_set unsatisfied_pending; + + /** + * @brief This member contains the TCB of the runner task. + */ + Thread_Control *runner_thread; + + /** + * @brief This member contains the ID of the runner task. + */ + rtems_id runner_id; + + /** + * @brief This member contains the task ID of the worker task. + */ + rtems_id worker_id; + + /** + * @brief This member contains the ID of the semaphore used to wake up the + * worker task. + */ + rtems_id worker_wakeup; + + /** + * @brief This member contains the ID of the semaphore used to wake up the + * runner task. + */ + rtems_id runner_wakeup; + + /** + * @brief This member contains the scheduler ID of scheduler used by the + * runner task. + */ + rtems_id runner_sched; + + /** + * @brief This member contains the scheduler ID of another scheduler which is + * not used by the runner task. + */ + rtems_id other_sched; + + /** + * @brief This member contains the thread switch log. + */ + T_thread_switch_log_4 thread_switch_log; + + /** + * @brief This member contains a copy of the corresponding + * RtemsEventReqSendReceive_Run() parameter. + */ + rtems_status_code ( *send )( rtems_id, rtems_event_set ); + + /** + * @brief This member contains a copy of the corresponding + * RtemsEventReqSendReceive_Run() parameter. + */ + rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * ); + + /** + * @brief This member contains a copy of the corresponding + * RtemsEventReqSendReceive_Run() parameter. + */ + rtems_event_set ( *get_pending_events )( Thread_Control * ); + + /** + * @brief This member contains a copy of the corresponding + * RtemsEventReqSendReceive_Run() parameter. + */ + unsigned int wait_class; + + /** + * @brief This member contains a copy of the corresponding + * RtemsEventReqSendReceive_Run() parameter. + */ + int waiting_for_event; + + struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 4 ]; + + /** + * @brief This member defines the pre-condition states for the next action. + */ + size_t pcs[ 4 ]; + + /** + * @brief If this member is true, then the test action loop is executed. + */ + bool in_action_loop; + + /** + * @brief This member contains the next transition map index. + */ + size_t index; + + /** + * @brief This member contains the current transition map entry. + */ + RtemsEventReqSendReceive_Entry entry; + + /** + * @brief If this member is true, then the current transition variant + * should be skipped. + */ + bool skip; + } Map; +} RtemsEventReqSendReceive_Context; + +static RtemsEventReqSendReceive_Context + RtemsEventReqSendReceive_Instance; + +static const char * const RtemsEventReqSendReceive_PreDesc_Id[] = { + "InvId", + "Task", + "NA" +}; + +static const char * const RtemsEventReqSendReceive_PreDesc_Send[] = { + "Zero", + "Unrelated", + "Any", + "All", + "MixedAny", + "MixedAll", + "NA" +}; + +static const char * const RtemsEventReqSendReceive_PreDesc_ReceiverState[] = { + "InvAddr", + "NotWaiting", + "Poll", + "Timeout", + "Lower", + "Equal", + "Higher", + "Other", + "Intend", + "NA" +}; + +static const char * const RtemsEventReqSendReceive_PreDesc_Satisfy[] = { + "All", + "Any", + "NA" +}; + +static const char * const * const RtemsEventReqSendReceive_PreDesc[] = { + RtemsEventReqSendReceive_PreDesc_Id, + RtemsEventReqSendReceive_PreDesc_Send, + RtemsEventReqSendReceive_PreDesc_ReceiverState, + RtemsEventReqSendReceive_PreDesc_Satisfy, + NULL +}; + +#define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 ) + +typedef RtemsEventReqSendReceive_Context Context; + +static rtems_id CreateWakeupSema( void ) +{ + rtems_status_code sc; + rtems_id id; + + sc = rtems_semaphore_create( + rtems_build_name( 'W', 'K', 'U', 'P' ), + 0, + RTEMS_SIMPLE_BINARY_SEMAPHORE, + 0, + &id + ); + T_assert_rsc_success( sc ); + + return id; +} + +static void DeleteWakeupSema( rtems_id id ) +{ + if ( id != 0 ) { + rtems_status_code sc; + + sc = rtems_semaphore_delete( id ); + T_rsc_success( sc ); + } +} + +static void Wait( rtems_id id ) +{ + rtems_status_code sc; + + sc = rtems_semaphore_obtain( id, RTEMS_WAIT, RTEMS_NO_TIMEOUT ); + T_quiet_rsc_success( sc ); +} + +static void Wakeup( rtems_id id ) +{ + rtems_status_code sc; + + sc = rtems_semaphore_release( id ); + T_quiet_rsc_success( sc ); +} + +static bool BlockedForEvent( Context *ctx, Thread_Wait_flags flags ) +{ + return flags == ( ctx->wait_class | THREAD_WAIT_STATE_BLOCKED ); +} + +static bool IntendsToBlockForEvent( Context *ctx, Thread_Wait_flags flags ) +{ + return flags == ( ctx->wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK ); +} + +static bool IsReady( Context *ctx, Thread_Wait_flags flags ) +{ + return flags == THREAD_WAIT_STATE_READY; +} + +static bool IsSatisfiedFlags( Context *ctx ) +{ + return IsReady( + ctx, + _Thread_Wait_flags_get( ctx->runner_thread ) + ); +} + +static bool IsSatisfiedState( Context *ctx ) +{ + return ctx->runner_thread->current_state != ctx->waiting_for_event; +} + +static void SendAction( Context *ctx ) +{ + T_thread_switch_log *log; + + log = T_thread_switch_record_4( &ctx->thread_switch_log ); + T_quiet_null( log ); + ctx->send_status = ( *ctx->send )( ctx->receiver_id, ctx->events_to_send ); + log = T_thread_switch_record( NULL ); + T_quiet_eq_ptr( &log->header, &ctx->thread_switch_log.header ); +} + +static void Send( + Context *ctx, + bool ( *is_satsified )( Context * ) +) +{ + SendAction( ctx ); + + if ( ( *is_satsified )( ctx ) ) { + ctx->receive_condition_state = RECEIVE_COND_SATSIFIED; + } else { + rtems_status_code sc; + rtems_event_set pending; + rtems_event_set missing; + + ctx->receive_condition_state = RECEIVE_COND_UNSATISFIED; + pending = ( *ctx->get_pending_events )( ctx->runner_thread ); + ctx->unsatisfied_pending = pending; + + missing = INPUT_EVENTS & ~ctx->events_to_send; + T_ne_u32( missing, 0 ); + sc = ( *ctx->send )( ctx->runner_id, missing ); + T_rsc_success( sc ); + + pending = ( *ctx->get_pending_events )( ctx->runner_thread ); + T_eq_u32( pending, ctx->events_to_send & ~INPUT_EVENTS ); + } +} + +static void Worker( rtems_task_argument arg ) +{ + Context *ctx; + + ctx = (Context *) arg; + + while ( true ) { + rtems_status_code sc; + rtems_task_priority prio; + T_thread_switch_log *log; + + Wait( ctx->worker_wakeup ); + + switch ( ctx->sender_prio ) { + case PRIO_NORMAL: + case PRIO_HIGH: + prio = SetSelfPriority( ctx->sender_prio ); + T_eq_u32( prio, PRIO_LOW ); + break; + case PRIO_OTHER: + log = T_thread_switch_record_4( &ctx->thread_switch_log ); + T_null( log ); + sc = rtems_task_set_scheduler( + RTEMS_SELF, + ctx->other_sched, + PRIO_LOW + ); + T_rsc_success( sc ); + + /* + * Make sure the context switch to the IDLE thread on the previous + * CPU is recorded, otherwise the preemption check may sporadically + * fail on some targets. + */ + while (ctx->thread_switch_log.header.recorded < 2) { + RTEMS_COMPILER_MEMORY_BARRIER(); + } + + log = T_thread_switch_record( NULL ); + T_eq_ptr( &log->header, &ctx->thread_switch_log.header ); + break; + case PRIO_LOW: + break; + } + + Send( ctx, IsSatisfiedState ); + + sc = rtems_task_set_scheduler( + RTEMS_SELF, + ctx->runner_sched, + PRIO_HIGH + ); + T_rsc_success( sc ); + + Wakeup( ctx->runner_wakeup ); + } +} + +static rtems_event_set GetPendingEvents( Context *ctx ) +{ + rtems_event_set pending; + rtems_status_code sc; + + sc = ( *ctx->receive )( + RTEMS_PENDING_EVENTS, + RTEMS_DEFAULT_OPTIONS, + 0, + &pending + ); + T_quiet_rsc_success( sc ); + + return pending; +} + +static void RtemsEventReqSendReceive_Cleanup( Context *ctx ); + +static void InterruptPrepare( void *arg ) +{ + RtemsEventReqSendReceive_Cleanup( arg ); +} + +static void InterruptAction( void *arg ) +{ + Context *ctx; + + ctx = arg; + ctx->receive_status = ( *ctx->receive )( + INPUT_EVENTS, + ctx->receive_option_set, + ctx->receive_timeout, + &ctx->received_events + ); + T_quiet_rsc_success( ctx->receive_status ); +} + +static void InterruptContinue( Context *ctx ) +{ + rtems_status_code sc; + + sc = ( *ctx->send )( ctx->receiver_id, INPUT_EVENTS ); + T_quiet_rsc_success( sc ); +} + +static T_interrupt_test_state Interrupt( void *arg ) +{ + Context *ctx; + Thread_Wait_flags flags; + T_interrupt_test_state next_state; + T_interrupt_test_state previous_state; + + ctx = arg; + flags = _Thread_Wait_flags_get( ctx->runner_thread ); + + if ( IntendsToBlockForEvent( ctx, flags ) ) { + next_state = T_INTERRUPT_TEST_DONE; + } else if ( BlockedForEvent( ctx, flags ) ) { + next_state = T_INTERRUPT_TEST_LATE; + } else { + next_state = T_INTERRUPT_TEST_EARLY; + } + + previous_state = T_interrupt_test_change_state( + T_INTERRUPT_TEST_ACTION, + next_state + ); + + if ( previous_state == T_INTERRUPT_TEST_ACTION ) { + if ( next_state == T_INTERRUPT_TEST_DONE ) { + Send( ctx, IsSatisfiedFlags ); + } else { + InterruptContinue( ctx ); + } + } + + return next_state; +} + +static const T_interrupt_test_config InterruptConfig = { + .prepare = InterruptPrepare, + .action = InterruptAction, + .interrupt = Interrupt, + .max_iteration_count = 10000 +}; + +static void RtemsEventReqSendReceive_Pre_Id_Prepare( + RtemsEventReqSendReceive_Context *ctx, + RtemsEventReqSendReceive_Pre_Id state +) +{ + switch ( state ) { + case RtemsEventReqSendReceive_Pre_Id_InvId: { + /* + * While the id parameter of the send directive is not associated with a + * task. + */ + ctx->receiver_id = 0xffffffff; + ctx->sender_type = SENDER_SELF; + break; + } + + case RtemsEventReqSendReceive_Pre_Id_Task: { + /* + * While the id parameter of the send directive is is associated with a + * task. + */ + ctx->receiver_id = ctx->runner_id; + break; + } + + case RtemsEventReqSendReceive_Pre_Id_NA: + break; + } +} + +static void RtemsEventReqSendReceive_Pre_Send_Prepare( + RtemsEventReqSendReceive_Context *ctx, + RtemsEventReqSendReceive_Pre_Send state +) +{ + switch ( state ) { + case RtemsEventReqSendReceive_Pre_Send_Zero: { + /* + * While the event set sent is the empty. + */ + ctx->events_to_send = 0; + break; + } + + case RtemsEventReqSendReceive_Pre_Send_Unrelated: { + /* + * While the event set sent is unrelated to the event receive condition. + */ + ctx->events_to_send = RTEMS_EVENT_7; + break; + } + + case RtemsEventReqSendReceive_Pre_Send_Any: { + /* + * While the event set sent is contain at least one but not all events of + * the event receive condition. + */ + ctx->events_to_send = RTEMS_EVENT_5; + break; + } + + case RtemsEventReqSendReceive_Pre_Send_All: { + /* + * While the event set sent is contain all events of the event receive + * condition. + */ + ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_23; + break; + } + + case RtemsEventReqSendReceive_Pre_Send_MixedAny: { + /* + * While the event set sent is contain at least one but not all events of + * the event receive condition and at least one unrelated event. + */ + ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7; + break; + } + + case RtemsEventReqSendReceive_Pre_Send_MixedAll: { + /* + * While the event set sent is contain all events of the event receive + * condition and at least one unrelated event. + */ + ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7 | RTEMS_EVENT_23; + break; + } + + case RtemsEventReqSendReceive_Pre_Send_NA: + break; + } +} + +static void RtemsEventReqSendReceive_Pre_ReceiverState_Prepare( + RtemsEventReqSendReceive_Context *ctx, + RtemsEventReqSendReceive_Pre_ReceiverState state +) +{ + switch ( state ) { + case RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr: { + /* + * While the receiver task calls the receive directive with the event set + * to receive parameter set to NULL. + */ + ctx->sender_type = SENDER_SELF; + ctx->receive_type = RECEIVE_NORMAL; + ctx->received_events_parameter = NULL; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_NotWaiting: { + /* + * While the receiver task is not waiting for events. + */ + ctx->sender_type = SENDER_SELF; + ctx->receive_type = RECEIVE_SKIP; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_Poll: { + /* + * While the receiver task polls for events. + */ + ctx->sender_type = SENDER_SELF; + ctx->receive_type = RECEIVE_NORMAL; + ctx->receive_option_set |= RTEMS_NO_WAIT; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_Timeout: { + /* + * While the receiver task waited for events with a timeout which + * occurred. + */ + ctx->sender_type = SENDER_SELF_2; + ctx->receive_type = RECEIVE_NORMAL; + ctx->receive_timeout = 1; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_Lower: { + /* + * While the receiver task is blocked waiting for events and the receiver + * task shall have a lower priority than the sender task. + */ + ctx->sender_type = SENDER_WORKER; + ctx->sender_prio = PRIO_HIGH; + ctx->receive_type = RECEIVE_NORMAL; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_Equal: { + /* + * While the receiver task is blocked waiting for events and the receiver + * task shall have a priority equal to the sender task. + */ + ctx->sender_type = SENDER_WORKER; + ctx->sender_prio = PRIO_NORMAL; + ctx->receive_type = RECEIVE_NORMAL; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_Higher: { + /* + * While the receiver task is blocked waiting for events and the receiver + * task shall have a higher priority than the sender task. + */ + ctx->sender_type = SENDER_WORKER; + ctx->sender_prio = PRIO_LOW; + ctx->receive_type = RECEIVE_NORMAL; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_Other: { + /* + * While the receiver task is blocked waiting for events and the receiver + * task shall be on another scheduler instance than the sender task. + */ + ctx->sender_type = SENDER_WORKER; + ctx->sender_prio = PRIO_OTHER; + ctx->receive_type = RECEIVE_NORMAL; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_Intend: { + /* + * While the receiver task intends to block for waiting for events. + */ + ctx->sender_type = SENDER_INTERRUPT; + ctx->receive_type = RECEIVE_INTERRUPT; + break; + } + + case RtemsEventReqSendReceive_Pre_ReceiverState_NA: + break; + } +} + +static void RtemsEventReqSendReceive_Pre_Satisfy_Prepare( + RtemsEventReqSendReceive_Context *ctx, + RtemsEventReqSendReceive_Pre_Satisfy state +) +{ + switch ( state ) { + case RtemsEventReqSendReceive_Pre_Satisfy_All: { + /* + * While the receiver task is interested in all input events. + */ + ctx->receive_option_set |= RTEMS_EVENT_ALL; + break; + } + + case RtemsEventReqSendReceive_Pre_Satisfy_Any: { + /* + * While the receiver task is interested in any input event. + */ + ctx->receive_option_set |= RTEMS_EVENT_ANY; + break; + } + + case RtemsEventReqSendReceive_Pre_Satisfy_NA: + break; + } +} + +static void RtemsEventReqSendReceive_Post_SendStatus_Check( + RtemsEventReqSendReceive_Context *ctx, + RtemsEventReqSendReceive_Post_SendStatus state +) +{ + switch ( state ) { + case RtemsEventReqSendReceive_Post_SendStatus_Ok: { + /* + * The send event status shall be RTEMS_SUCCESSFUL. + */ + T_rsc_success( ctx->send_status ); + break; + } + + case RtemsEventReqSendReceive_Post_SendStatus_InvId: { + /* + * The send event status shall be RTEMS_INVALID_ID. + */ + T_rsc( ctx->send_status, RTEMS_INVALID_ID ); + break; + } + + case RtemsEventReqSendReceive_Post_SendStatus_NA: + break; + } +} + +static void RtemsEventReqSendReceive_Post_ReceiveStatus_Check( + RtemsEventReqSendReceive_Context *ctx, + RtemsEventReqSendReceive_Post_ReceiveStatus state +) +{ + switch ( state ) { + case RtemsEventReqSendReceive_Post_ReceiveStatus_None: { + /* + * The receiver task shall not have pending events. + */ + T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); + T_eq_u32( GetPendingEvents( ctx ), 0 ); + break; + } + + case RtemsEventReqSendReceive_Post_ReceiveStatus_Pending: { + /* + * The receiver task shall have all events sent pending. + */ + T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); + T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send ); + break; + } + + case RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout: { + /* + * The receive event status shall be RTEMS_TIMEOUT. The receiver task + * shall have all events sent after the timeout pending. + */ + T_rsc( ctx->receive_status, RTEMS_TIMEOUT ); + T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); + T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send ); + break; + } + + case RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied: { + /* + * The receive event status shall be RTEMS_SUCCESSFUL. The receiver task + * shall receive all events sent which are an element of the input + * events. The receiver task shall have all events sent which are not an + * element of the input events pending. + */ + T_rsc( ctx->receive_status, RTEMS_SUCCESSFUL ); + + if ( ctx->receive_type != RECEIVE_NORMAL ) { + T_eq_int( ctx->receive_condition_state, RECEIVE_COND_SATSIFIED ); + } + + T_eq_u32( ctx->received_events, ctx->events_to_send & INPUT_EVENTS ); + T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send & ~INPUT_EVENTS ); + break; + } + + case RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied: { + /* + * The receive event status shall be RTEMS_UNSATISFIED. The receiver task + * shall have all events sent pending. + */ + T_rsc( ctx->receive_status, RTEMS_UNSATISFIED ); + T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); + T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send ); + break; + } + + case RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked: { + /* + * The receiver task shall remain blocked waiting for events after the + * directive call. The receiver task shall have all events sent pending. + */ + T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNSATISFIED ); + T_eq_u32( ctx->unsatisfied_pending, ctx->events_to_send ); + break; + } + + case RtemsEventReqSendReceive_Post_ReceiveStatus_InvAddr: { + /* + * The receive event status shall be RTEMS_INVALID_ADDRESS. The receiver + * task shall have all events sent pending. + */ + T_rsc( ctx->receive_status, RTEMS_INVALID_ADDRESS ); + T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN ); + T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send ); + break; + } + + case RtemsEventReqSendReceive_Post_ReceiveStatus_NA: + break; + } +} + +static void RtemsEventReqSendReceive_Post_SenderPreemption_Check( + RtemsEventReqSendReceive_Context *ctx, + RtemsEventReqSendReceive_Post_SenderPreemption state +) +{ + const T_thread_switch_log_4 *log; + size_t i; + + log = &ctx->thread_switch_log; + + switch ( state ) { + case RtemsEventReqSendReceive_Post_SenderPreemption_No: { + /* + * When the sender task calls the directive to send the events, the + * sender task shall not be preempted as a result of the call. + */ + /* + * There may be a thread switch to the runner thread if the sender thread + * was on another scheduler instance. + */ + + T_le_sz( log->header.recorded, 1 ); + + for ( i = 0; i < log->header.recorded; ++i ) { + T_ne_u32( log->events[ i ].executing, ctx->worker_id ); + T_eq_u32( log->events[ i ].heir, ctx->runner_id ); + } + break; + } + + case RtemsEventReqSendReceive_Post_SenderPreemption_Yes: { + /* + * When the sender task calls the directive to send the events, the + * sender task shall be preempted as a result of the call. + */ + T_eq_sz( log->header.recorded, 2 ); + T_eq_u32( log->events[ 0 ].heir, ctx->runner_id ); + T_eq_u32( log->events[ 1 ].heir, ctx->worker_id ); + break; + } + + case RtemsEventReqSendReceive_Post_SenderPreemption_NA: + break; + } +} + +static void RtemsEventReqSendReceive_Setup( + RtemsEventReqSendReceive_Context *ctx +) +{ + rtems_status_code sc; + + ctx->runner_thread = _Thread_Get_executing(); + ctx->runner_id = ctx->runner_thread->Object.id; + ctx->worker_wakeup = CreateWakeupSema(); + ctx->runner_wakeup = CreateWakeupSema(); + + sc = rtems_task_get_scheduler( RTEMS_SELF, &ctx->runner_sched ); + T_rsc_success( sc ); + + #if defined(RTEMS_SMP) + sc = rtems_scheduler_ident_by_processor( 1, &ctx->other_sched ); + T_rsc_success( sc ); + T_ne_u32( ctx->runner_sched, ctx->other_sched ); + #endif + + SetSelfPriority( PRIO_NORMAL ); + ctx->worker_id = CreateTask( "WORK", PRIO_LOW ); + StartTask( ctx->worker_id, Worker, ctx ); +} + +static void RtemsEventReqSendReceive_Setup_Wrap( void *arg ) +{ + RtemsEventReqSendReceive_Context *ctx; + + ctx = arg; + ctx->Map.in_action_loop = false; + RtemsEventReqSendReceive_Setup( ctx ); +} + +static void RtemsEventReqSendReceive_Teardown( + RtemsEventReqSendReceive_Context *ctx +) +{ + DeleteTask( ctx->worker_id ); + DeleteWakeupSema( ctx->worker_wakeup ); + DeleteWakeupSema( ctx->runner_wakeup ); + RestoreRunnerPriority(); +} + +static void RtemsEventReqSendReceive_Teardown_Wrap( void *arg ) +{ + RtemsEventReqSendReceive_Context *ctx; + + ctx = arg; + ctx->Map.in_action_loop = false; + RtemsEventReqSendReceive_Teardown( ctx ); +} + +static void RtemsEventReqSendReceive_Prepare( + RtemsEventReqSendReceive_Context *ctx +) +{ + ctx->events_to_send = 0; + ctx->send_status = RTEMS_INCORRECT_STATE; + ctx->received_events = 0xffffffff; + ctx->received_events_parameter = &ctx->received_events; + ctx->receive_option_set = 0; + ctx->receive_timeout = RTEMS_NO_TIMEOUT; + ctx->sender_type = SENDER_NONE; + ctx->sender_prio = PRIO_NORMAL; + ctx->receive_type = RECEIVE_SKIP; + ctx->receive_condition_state = RECEIVE_COND_UNKNOWN; + ctx->unsatisfied_pending = 0xffffffff; + memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) ); + T_eq_u32( GetPendingEvents( ctx ), 0 ); +} + +static void RtemsEventReqSendReceive_Action( + RtemsEventReqSendReceive_Context *ctx +) +{ + if ( ctx->sender_type == SENDER_SELF ) { + SendAction( ctx ); + } else if ( ctx->sender_type == SENDER_WORKER ) { + Wakeup( ctx->worker_wakeup ); + } + + if ( ctx->receive_type == RECEIVE_NORMAL ) { + ctx->receive_status = ( *ctx->receive )( + INPUT_EVENTS, + ctx->receive_option_set, + ctx->receive_timeout, + ctx->received_events_parameter + ); + } else if ( ctx->receive_type == RECEIVE_INTERRUPT ) { + T_interrupt_test_state state; + + state = T_interrupt_test( &InterruptConfig, ctx ); + T_eq_int( state, T_INTERRUPT_TEST_DONE ); + } + + if ( ctx->sender_type == SENDER_SELF_2 ) { + SendAction( ctx ); + } else if ( ctx->sender_type == SENDER_WORKER ) { + rtems_task_priority prio; + + Wait( ctx->runner_wakeup ); + prio = SetPriority( ctx->worker_id, PRIO_LOW ); + T_eq_u32( prio, PRIO_HIGH ); + } +} + +static void RtemsEventReqSendReceive_Cleanup( + RtemsEventReqSendReceive_Context *ctx +) +{ + rtems_status_code sc; + rtems_event_set events; + + events = 0; + sc = ( *ctx->receive )( + RTEMS_ALL_EVENTS, + RTEMS_NO_WAIT | RTEMS_EVENT_ANY, + 0, + &events + ); + if ( sc == RTEMS_SUCCESSFUL ) { + T_quiet_ne_u32( events, 0 ); + } else { + T_quiet_rsc( sc, RTEMS_UNSATISFIED ); + T_quiet_eq_u32( events, 0 ); + } +} + +static const RtemsEventReqSendReceive_Entry +RtemsEventReqSendReceive_Entries[] = { + { 0, 0, 1, 1, 1, RtemsEventReqSendReceive_Post_SendStatus_InvId, + RtemsEventReqSendReceive_Post_ReceiveStatus_None, + RtemsEventReqSendReceive_Post_SenderPreemption_No }, + { 0, 0, 0, 0, 1, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Pending, + RtemsEventReqSendReceive_Post_SenderPreemption_No }, + { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked, + RtemsEventReqSendReceive_Post_SenderPreemption_No }, + { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied, + RtemsEventReqSendReceive_Post_SenderPreemption_No }, + { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout, + RtemsEventReqSendReceive_Post_SenderPreemption_No }, + { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied, + RtemsEventReqSendReceive_Post_SenderPreemption_No }, +#if defined(RTEMS_SMP) + { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked, + RtemsEventReqSendReceive_Post_SenderPreemption_No }, +#else + { 1, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_NA, + RtemsEventReqSendReceive_Post_ReceiveStatus_NA, + RtemsEventReqSendReceive_Post_SenderPreemption_NA }, +#endif + { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied, + RtemsEventReqSendReceive_Post_SenderPreemption_Yes }, +#if defined(RTEMS_SMP) + { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied, + RtemsEventReqSendReceive_Post_SenderPreemption_No } +#else + { 1, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_NA, + RtemsEventReqSendReceive_Post_ReceiveStatus_NA, + RtemsEventReqSendReceive_Post_SenderPreemption_NA } +#endif +}; + +static const uint8_t +RtemsEventReqSendReceive_Map[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, 5, 5, 4, 4, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 1, 1, 1, 1, + 5, 5, 4, 4, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 1, 1, 1, 1, 5, 3, 4, 4, 2, 3, 2, 3, + 2, 7, 6, 8, 2, 3, 1, 1, 1, 1, 3, 3, 4, 4, 3, 3, 3, 3, 7, 7, 8, 8, 3, 3, 1, 1, + 1, 1, 5, 3, 4, 4, 2, 3, 2, 3, 2, 7, 6, 8, 2, 3, 1, 1, 1, 1, 3, 3, 4, 4, 3, 3, + 3, 3, 7, 7, 8, 8, 3, 3 +}; + +static size_t RtemsEventReqSendReceive_Scope( void *arg, char *buf, size_t n ) +{ + RtemsEventReqSendReceive_Context *ctx; + + ctx = arg; + + if ( ctx->Map.in_action_loop ) { + return T_get_scope( + RtemsEventReqSendReceive_PreDesc, + buf, + n, + ctx->Map.pcs + ); + } + + return 0; +} + +static T_fixture RtemsEventReqSendReceive_Fixture = { + .setup = RtemsEventReqSendReceive_Setup_Wrap, + .stop = NULL, + .teardown = RtemsEventReqSendReceive_Teardown_Wrap, + .scope = RtemsEventReqSendReceive_Scope, + .initial_context = &RtemsEventReqSendReceive_Instance +}; + +static inline RtemsEventReqSendReceive_Entry RtemsEventReqSendReceive_PopEntry( + RtemsEventReqSendReceive_Context *ctx +) +{ + size_t index; + + index = ctx->Map.index; + ctx->Map.index = index + 1; + return RtemsEventReqSendReceive_Entries[ + RtemsEventReqSendReceive_Map[ index ] + ]; +} + +static void RtemsEventReqSendReceive_SetPreConditionStates( + RtemsEventReqSendReceive_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + + if ( ctx->Map.entry.Pre_Send_NA ) { + ctx->Map.pcs[ 1 ] = RtemsEventReqSendReceive_Pre_Send_NA; + } else { + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + } + + if ( ctx->Map.entry.Pre_ReceiverState_NA ) { + ctx->Map.pcs[ 2 ] = RtemsEventReqSendReceive_Pre_ReceiverState_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } + + if ( ctx->Map.entry.Pre_Satisfy_NA ) { + ctx->Map.pcs[ 3 ] = RtemsEventReqSendReceive_Pre_Satisfy_NA; + } else { + ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ]; + } +} + +static void RtemsEventReqSendReceive_TestVariant( + RtemsEventReqSendReceive_Context *ctx +) +{ + RtemsEventReqSendReceive_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] ); + RtemsEventReqSendReceive_Pre_Send_Prepare( ctx, ctx->Map.pcs[ 1 ] ); + RtemsEventReqSendReceive_Pre_ReceiverState_Prepare( ctx, ctx->Map.pcs[ 2 ] ); + RtemsEventReqSendReceive_Pre_Satisfy_Prepare( ctx, ctx->Map.pcs[ 3 ] ); + RtemsEventReqSendReceive_Action( ctx ); + RtemsEventReqSendReceive_Post_SendStatus_Check( + ctx, + ctx->Map.entry.Post_SendStatus + ); + RtemsEventReqSendReceive_Post_ReceiveStatus_Check( + ctx, + ctx->Map.entry.Post_ReceiveStatus + ); + RtemsEventReqSendReceive_Post_SenderPreemption_Check( + ctx, + ctx->Map.entry.Post_SenderPreemption + ); +} + +static T_fixture_node RtemsEventReqSendReceive_Node; + +void RtemsEventReqSendReceive_Run( + rtems_status_code ( *send )( rtems_id, rtems_event_set ), + rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * ), + rtems_event_set ( *get_pending_events )( Thread_Control * ), + unsigned int wait_class, + int waiting_for_event +) +{ + RtemsEventReqSendReceive_Context *ctx; + + ctx = &RtemsEventReqSendReceive_Instance; + ctx->send = send; + ctx->receive = receive; + ctx->get_pending_events = get_pending_events; + ctx->wait_class = wait_class; + ctx->waiting_for_event = waiting_for_event; + + ctx = T_push_fixture( + &RtemsEventReqSendReceive_Node, + &RtemsEventReqSendReceive_Fixture + ); + ctx->Map.in_action_loop = true; + ctx->Map.index = 0; + + for ( + ctx->Map.pci[ 0 ] = RtemsEventReqSendReceive_Pre_Id_InvId; + ctx->Map.pci[ 0 ] < RtemsEventReqSendReceive_Pre_Id_NA; + ++ctx->Map.pci[ 0 ] + ) { + for ( + ctx->Map.pci[ 1 ] = RtemsEventReqSendReceive_Pre_Send_Zero; + ctx->Map.pci[ 1 ] < RtemsEventReqSendReceive_Pre_Send_NA; + ++ctx->Map.pci[ 1 ] + ) { + for ( + ctx->Map.pci[ 2 ] = RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr; + ctx->Map.pci[ 2 ] < RtemsEventReqSendReceive_Pre_ReceiverState_NA; + ++ctx->Map.pci[ 2 ] + ) { + for ( + ctx->Map.pci[ 3 ] = RtemsEventReqSendReceive_Pre_Satisfy_All; + ctx->Map.pci[ 3 ] < RtemsEventReqSendReceive_Pre_Satisfy_NA; + ++ctx->Map.pci[ 3 ] + ) { + ctx->Map.entry = RtemsEventReqSendReceive_PopEntry( ctx ); + + if ( ctx->Map.entry.Skip ) { + continue; + } + + RtemsEventReqSendReceive_SetPreConditionStates( ctx ); + RtemsEventReqSendReceive_Prepare( ctx ); + RtemsEventReqSendReceive_TestVariant( ctx ); + RtemsEventReqSendReceive_Cleanup( ctx ); + } + } + } + } + + T_pop_fixture(); +} + +/** @} */ diff --git a/testsuites/validation/tr-event-send-receive.h b/testsuites/validation/tr-event-send-receive.h new file mode 100644 index 0000000000..b246a815ed --- /dev/null +++ b/testsuites/validation/tr-event-send-receive.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsEventReqSendReceive + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifndef _TR_EVENT_SEND_RECEIVE_H +#define _TR_EVENT_SEND_RECEIVE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup RTEMSTestCaseRtemsEventReqSendReceive + * + * @{ + */ + +typedef enum { + RtemsEventReqSendReceive_Pre_Id_InvId, + RtemsEventReqSendReceive_Pre_Id_Task, + RtemsEventReqSendReceive_Pre_Id_NA +} RtemsEventReqSendReceive_Pre_Id; + +typedef enum { + RtemsEventReqSendReceive_Pre_Send_Zero, + RtemsEventReqSendReceive_Pre_Send_Unrelated, + RtemsEventReqSendReceive_Pre_Send_Any, + RtemsEventReqSendReceive_Pre_Send_All, + RtemsEventReqSendReceive_Pre_Send_MixedAny, + RtemsEventReqSendReceive_Pre_Send_MixedAll, + RtemsEventReqSendReceive_Pre_Send_NA +} RtemsEventReqSendReceive_Pre_Send; + +typedef enum { + RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr, + RtemsEventReqSendReceive_Pre_ReceiverState_NotWaiting, + RtemsEventReqSendReceive_Pre_ReceiverState_Poll, + RtemsEventReqSendReceive_Pre_ReceiverState_Timeout, + RtemsEventReqSendReceive_Pre_ReceiverState_Lower, + RtemsEventReqSendReceive_Pre_ReceiverState_Equal, + RtemsEventReqSendReceive_Pre_ReceiverState_Higher, + RtemsEventReqSendReceive_Pre_ReceiverState_Other, + RtemsEventReqSendReceive_Pre_ReceiverState_Intend, + RtemsEventReqSendReceive_Pre_ReceiverState_NA +} RtemsEventReqSendReceive_Pre_ReceiverState; + +typedef enum { + RtemsEventReqSendReceive_Pre_Satisfy_All, + RtemsEventReqSendReceive_Pre_Satisfy_Any, + RtemsEventReqSendReceive_Pre_Satisfy_NA +} RtemsEventReqSendReceive_Pre_Satisfy; + +typedef enum { + RtemsEventReqSendReceive_Post_SendStatus_Ok, + RtemsEventReqSendReceive_Post_SendStatus_InvId, + RtemsEventReqSendReceive_Post_SendStatus_NA +} RtemsEventReqSendReceive_Post_SendStatus; + +typedef enum { + RtemsEventReqSendReceive_Post_ReceiveStatus_None, + RtemsEventReqSendReceive_Post_ReceiveStatus_Pending, + RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout, + RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied, + RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied, + RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked, + RtemsEventReqSendReceive_Post_ReceiveStatus_InvAddr, + RtemsEventReqSendReceive_Post_ReceiveStatus_NA +} RtemsEventReqSendReceive_Post_ReceiveStatus; + +typedef enum { + RtemsEventReqSendReceive_Post_SenderPreemption_No, + RtemsEventReqSendReceive_Post_SenderPreemption_Yes, + RtemsEventReqSendReceive_Post_SenderPreemption_NA +} RtemsEventReqSendReceive_Post_SenderPreemption; + +/** + * @brief Runs the parameterized test case. + * + * @param send is the event send handler. + * + * @param receive is the event receive handler. + * + * @param get_pending_events is the get pending events handler. + * + * @param wait_class is the thread wait class. + * + * @param waiting_for_event is the thread waiting for event state. + */ +void RtemsEventReqSendReceive_Run( + rtems_status_code ( *send )( rtems_id, rtems_event_set ), + rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * ), + rtems_event_set ( *get_pending_events )( Thread_Control * ), + unsigned int wait_class, + int waiting_for_event +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TR_EVENT_SEND_RECEIVE_H */ -- cgit v1.2.3