From 0f8077b2587af83c6ec0e434a565372b00961727 Mon Sep 17 00:00:00 2001 From: Andrew Butterfield Date: Wed, 9 Dec 2020 15:10:24 +0000 Subject: Adds four test runner files, all work --- spec/build/testsuites/validation/model-0.yml | 5 +- testsuites/validation/tc-model-events-mgr.c | 74 +++- testsuites/validation/tr-model-events-mgr-0.c | 550 ++++++++++++++++++++++++++ testsuites/validation/tr-model-events-mgr-1.c | 550 ++++++++++++++++++++++++++ testsuites/validation/tr-model-events-mgr-2.c | 550 ++++++++++++++++++++++++++ testsuites/validation/tr-model-events-mgr-3.c | 550 ++++++++++++++++++++++++++ testsuites/validation/tr-model-events-mgr.c | 280 ++++--------- testsuites/validation/tr-model-events-mgr.h | 26 +- 8 files changed, 2384 insertions(+), 201 deletions(-) mode change 100755 => 100644 testsuites/validation/tc-model-events-mgr.c create mode 100644 testsuites/validation/tr-model-events-mgr-0.c create mode 100644 testsuites/validation/tr-model-events-mgr-1.c create mode 100644 testsuites/validation/tr-model-events-mgr-2.c create mode 100644 testsuites/validation/tr-model-events-mgr-3.c mode change 100755 => 100644 testsuites/validation/tr-model-events-mgr.c mode change 100755 => 100644 testsuites/validation/tr-model-events-mgr.h diff --git a/spec/build/testsuites/validation/model-0.yml b/spec/build/testsuites/validation/model-0.yml index 425bd26a2b..14b5b6c757 100644 --- a/spec/build/testsuites/validation/model-0.yml +++ b/spec/build/testsuites/validation/model-0.yml @@ -13,7 +13,10 @@ links: [] source: - testsuites/validation/ts-model-0.c - testsuites/validation/tc-model-events-mgr.c -- testsuites/validation/tr-model-events-mgr.c +- testsuites/validation/tr-model-events-mgr-0.c +- testsuites/validation/tr-model-events-mgr-1.c +- testsuites/validation/tr-model-events-mgr-2.c +- testsuites/validation/tr-model-events-mgr-3.c stlib: [] target: testsuites/validation/ts-model-0.exe type: build diff --git a/testsuites/validation/tc-model-events-mgr.c b/testsuites/validation/tc-model-events-mgr.c old mode 100755 new mode 100644 index a58ec6e8c8..08097467db --- a/testsuites/validation/tc-model-events-mgr.c +++ b/testsuites/validation/tc-model-events-mgr.c @@ -104,9 +104,42 @@ static rtems_event_set GetPendingEvents( Thread_Control *thread ) /** * @fn void T_case_body_RtemsEventValSendReceive( void ) */ -T_TEST_CASE( RtemsModelEventsMgr ) +T_TEST_CASE( RtemsModelEventsMgr0 ) { - RtemsModelEventsMgr_Run( + RtemsModelEventsMgr0_Run( + EventSend, + EventReceive, + GetPendingEvents, + THREAD_WAIT_CLASS_EVENT, + STATES_WAITING_FOR_EVENT + ); +} + +T_TEST_CASE( RtemsModelEventsMgr1 ) +{ + RtemsModelEventsMgr1_Run( + EventSend, + EventReceive, + GetPendingEvents, + THREAD_WAIT_CLASS_EVENT, + STATES_WAITING_FOR_EVENT + ); +} + +T_TEST_CASE( RtemsModelEventsMgr2 ) +{ + RtemsModelEventsMgr2_Run( + EventSend, + EventReceive, + GetPendingEvents, + THREAD_WAIT_CLASS_EVENT, + STATES_WAITING_FOR_EVENT + ); +} + +T_TEST_CASE( RtemsModelEventsMgr3 ) +{ + RtemsModelEventsMgr3_Run( EventSend, EventReceive, GetPendingEvents, @@ -168,9 +201,42 @@ static rtems_event_set GetPendingSystemEvents( Thread_Control *thread ) /** * @fn void T_case_body_RtemsEventValSystemSendReceive( void ) */ -T_TEST_CASE( RtemsModelSystemEventsMgr ) +T_TEST_CASE( RtemsModelSystemEventsMgr0 ) +{ + RtemsModelEventsMgr0_Run( + EventSystemSend, + EventSystemReceive, + GetPendingSystemEvents, + THREAD_WAIT_CLASS_SYSTEM_EVENT, + STATES_WAITING_FOR_SYSTEM_EVENT + ); +} + +T_TEST_CASE( RtemsModelSystemEventsMgr1 ) +{ + RtemsModelEventsMgr1_Run( + EventSystemSend, + EventSystemReceive, + GetPendingSystemEvents, + THREAD_WAIT_CLASS_SYSTEM_EVENT, + STATES_WAITING_FOR_SYSTEM_EVENT + ); +} + +T_TEST_CASE( RtemsModelSystemEventsMgr2 ) +{ + RtemsModelEventsMgr2_Run( + EventSystemSend, + EventSystemReceive, + GetPendingSystemEvents, + THREAD_WAIT_CLASS_SYSTEM_EVENT, + STATES_WAITING_FOR_SYSTEM_EVENT + ); +} + +T_TEST_CASE( RtemsModelSystemEventsMgr3 ) { - RtemsModelEventsMgr_Run( + RtemsModelEventsMgr3_Run( EventSystemSend, EventSystemReceive, GetPendingSystemEvents, diff --git a/testsuites/validation/tr-model-events-mgr-0.c b/testsuites/validation/tr-model-events-mgr-0.c new file mode 100644 index 0000000000..960b11d521 --- /dev/null +++ b/testsuites/validation/tr-model-events-mgr-0.c @@ -0,0 +1,550 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsModelEventsMgr0 + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Trinity College Dublin (http://www.tcd.ie) + * + * 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 was automatically generated. Do not edit it manually. + * Please have a look at + * + * https://docs.rtems.org/branches/master/eng/req/howto.html + * + * for information how to maintain and re-generate this file. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tr-model-events-mgr.h" + +#include + +typedef enum { + PRIO_HIGH = 1, + PRIO_NORMAL, + PRIO_LOW, + PRIO_OTHER +} Priorities; + + +typedef struct { + rtems_status_code ( *send )( rtems_id, rtems_event_set ); // copy of the + // corresponding RtemsModelEventsMgr0_Run() parameter + rtems_status_code ( *receive ) + ( rtems_event_set, rtems_option + , rtems_interval, rtems_event_set * ); // copy of the + // corresponding RtemsModelEventsMgr0_Run() parameter + rtems_event_set ( *get_pending_events )( Thread_Control * ); // copy of the + // corresponding RtemsModelEventsMgr0_Run() parameter + unsigned int wait_class; // copy of the corresponding + // RtemsModelEventsMgr0_Run() parameter + int waiting_for_event; // copy of the corresponding + // RtemsModelEventsMgr0_Run() parameter + rtems_id receiver_id; // receiver ID used for the event send action. + rtems_event_set events_to_send; // events to send for the event send action + rtems_status_code send_status; // status of the event send action. + rtems_option receive_option_set; // option set used for the event receive action + rtems_interval receive_timeout; // timeout used for the event receive action + rtems_event_set received_events; // events received by the event receive action + rtems_status_code receive_status; // status of the event receive action + rtems_event_set unsatisfied_pending; // pending events after an event send action + // which did not satsify the event condition of the receiver + Thread_Control *runner_thread; // TCB of the runner task + rtems_id runner_id; // ID of the runner task + rtems_id worker_id; // task ID of the worker task + rtems_id worker_wakeup; // ID of the semaphore used to wake up the worker task + rtems_id runner_wakeup; // ID of the semaphore used to wake up the runner task + rtems_id runner_sched; // scheduler ID of scheduler used by the runner task + rtems_id other_sched; // scheduler ID of another scheduler + // which is not used by the runner task + T_thread_switch_log_4 thread_switch_log; // thread switch log +} RtemsModelEventsMgr0_Context; + +static RtemsModelEventsMgr0_Context + RtemsModelEventsMgr0_Instance; + +static const char PromelaModelEventsMgr[] = "/PML-EventsMgr0"; + +#define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 ) + +#define WORKER_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES + +#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT ) + +typedef RtemsModelEventsMgr0_Context Context; + +RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char WorkerStorage[ + RTEMS_TASK_STORAGE_SIZE( + MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, + WORKER_ATTRIBUTES + ) +]; + +static const rtems_task_config WorkerConfig = { + .name = rtems_build_name( 'W', 'O', 'R', 'K' ), + .initial_priority = PRIO_LOW, + .storage_area = WorkerStorage, + .storage_size = sizeof( WorkerStorage ), + .maximum_thread_local_storage_size = MAX_TLS_SIZE, + .initial_modes = RTEMS_DEFAULT_MODES, + .attributes = WORKER_ATTRIBUTES +}; + +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 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 rtems_option mergeopts( bool wait, bool wantall ) +{ + rtems_option opts; + + if ( wait ) { opts = RTEMS_WAIT; } + else { opts = RTEMS_NO_WAIT; } ; + if ( wantall ) { opts |= RTEMS_EVENT_ALL; } + else { opts |= RTEMS_EVENT_ANY; } ; + return opts; +} + + +/* + * Here we need a mapping from model "task numbers/names" to thread Id's here + * Promela Process 3 corresponds to Task 0 (Worker), doing Send + * Promela Process 4 corresponds to Task 1 (Runner), doing Receive + */ +static rtems_id mapid( Context *ctx, int pid ) +{ + rtems_id mapped_id; + + switch ( pid ) { + case 0 : mapped_id = ctx->worker_id ; break; + case 1 : mapped_id = ctx->runner_id; break; + default : mapped_id = 0xffffffff; break; + } + return mapped_id; +} + +static void checkTaskIs( rtems_id expected_id ) +{ + rtems_id own_id; + + own_id = _Thread_Get_executing()->Object.id; + T_eq_u32( own_id, expected_id ); +} + +static void initialise_pending( rtems_event_set pending[], int max ) +{ + int i; + + for( i=0; i < max; i++ ) { + pending[i] = 0; + } +} + +static void initialise_semaphore( Context *ctx, rtems_id semaphore[] ) +{ + semaphore[0] = ctx->worker_wakeup; + semaphore[1] = ctx->runner_wakeup; +} + +/* =============================================== */ + +// @@@ 0 NAME Event_Manager_TestGen +// @@@ 0 DEF NO_OF_EVENTS 4 +#define NO_OF_EVENTS 4 +// @@@ 0 DEF EVTS_NONE 0 +#define EVTS_NONE 0 +// @@@ 0 DEF EVTS_PENDING 0 +#define EVTS_PENDING 0 +// @@@ 0 DEF EVT_0 1 +#define EVT_0 1 +// @@@ 0 DEF EVT_1 2 +#define EVT_1 2 +// @@@ 0 DEF EVT_2 4 +#define EVT_2 4 +// @@@ 0 DEF EVT_3 8 +#define EVT_3 8 +// @@@ 0 DEF NO_TIMEOUT 0 +#define NO_TIMEOUT 0 +// @@@ 0 DEF TASK_MAX 2 +#define TASK_MAX 2 +// @@@ 0 DEF BAD_ID 2 +#define BAD_ID 2 +// @@@ 0 DEF SEMA_MAX 2 +#define SEMA_MAX 2 +// @@@ 0 DEF RC_OK RTEMS_SUCCESSFUL +#define RC_OK RTEMS_SUCCESSFUL +// @@@ 0 DEF RC_InvId RTEMS_INVALID_ID +#define RC_InvId RTEMS_INVALID_ID +// @@@ 0 DEF RC_InvAddr RTEMS_INVALID_ADDRESS +#define RC_InvAddr RTEMS_INVALID_ADDRESS +// @@@ 0 DEF RC_Unsat RTEMS_UNSATISFIED +#define RC_Unsat RTEMS_UNSATISFIED +// @@@ 0 DEF RC_Timeout RTEMS_TIMEOUT +#define RC_Timeout RTEMS_TIMEOUT +// @@@ 0 DCLARRAY EvtSet pending TASK_MAX +static rtems_event_set pending[TASK_MAX]; +// @@@ 0 DECL byte sendrc 0 +static rtems_status_code sendrc = 0; +// @@@ 0 DECL byte recrc 0 +static rtems_status_code recrc = 0; +// @@@ 0 DECL byte recout 0 +static rtems_event_set recout = 0; +// @@@ 0 DCLARRAY Semaphore semaphore SEMA_MAX +static rtems_id semaphore[SEMA_MAX]; + +/* ===== TEST CODE SEGMENT 0 =====*/ + +static void TestSegment0( Context* ctx ) { + /* Test Name is defined in the Test Case code (tc-model-events-mgr.c) */ + + T_log(T_NORMAL,"@@@ 0 INIT"); + initialise_pending( pending, TASK_MAX ); + initialise_semaphore( ctx, semaphore ); + +} + +/* ===== TEST CODE SEGMENT 3 =====*/ + +static void TestSegment3( Context* ctx ) { + T_log(T_NORMAL,"@@@ 3 TASK Worker"); + checkTaskIs( ctx->worker_id ); + T_log(T_NORMAL,"@@@ 3 WAIT 0"); + Wait( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 3 CALL event_send 0 1 14 sendrc"); + T_log( T_NORMAL, "Calling Send(%d,%d)", mapid( ctx, 1), 14 ); + sendrc = ( *ctx->send )( mapid( ctx, 1 ), 14 ); + T_log( T_NORMAL, "Returned 0x%x from Send", sendrc ); + + T_log(T_NORMAL,"@@@ 3 SCALAR sendrc 0"); + T_rsc_success( sendrc ); + T_log(T_NORMAL,"@@@ 3 SIGNAL 1"); + Wakeup( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 3 STATE 0 Zombie"); + /* Code to check that Task 0 has terminated */ +} + +/* ===== TEST CODE SEGMENT 4 =====*/ + +static void TestSegment4( Context* ctx ) { + T_log(T_NORMAL,"@@@ 4 TASK Runner"); + checkTaskIs( ctx->runner_id ); + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 WAIT 1"); + Wait( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 14"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 14 ); + + T_log(T_NORMAL,"@@@ 4 CALL event_receive 10 1 1 0 recout recrc"); + T_log( T_NORMAL, "Calling Receive(%d,%d,%d,%d)", 10, mergeopts( 1, 1 ) ,0 ,&recout ); + recrc = ( *ctx->receive )( 10, mergeopts( 1, 1 ), 0, &recout ); + T_log( T_NORMAL, "Returned 0x%x from Receive", recrc ); + + T_log(T_NORMAL,"@@@ 4 SCALAR recrc 0"); + T_rsc_success( recrc ); + T_log(T_NORMAL,"@@@ 4 SCALAR recout 10"); + T_eq_int( recout, 10 ); + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 4"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 4 ); + + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 STATE 1 Zombie"); + /* Code to check that Task 1 has terminated */ +} + +/* =============================================== */ + + +static void Worker( rtems_task_argument arg ) +{ + Context *ctx; + + ctx = (Context *) arg; + + T_log( T_NORMAL, "Worker Running" ); + TestSegment3( ctx ); + T_log( T_NORMAL, "Worker finished" ); + + rtems_task_exit(); + +} + + +static void Runner( RtemsModelEventsMgr0_Context *ctx ) +{ + T_log( T_NORMAL, "Runner running" ); + TestSegment4( ctx ); + T_log( T_NORMAL, "Runner finished" ); +} + + +static void RtemsModelEventsMgr0_Setup( + RtemsModelEventsMgr0_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Setup" ); + + memset( ctx, 0, sizeof( *ctx ) ); + 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 + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_HIGH ); + + sc = rtems_task_construct( &WorkerConfig, &ctx->worker_id ); + T_log( T_NORMAL, "Construct Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); + + T_log( T_NORMAL, "Starting Worker..." ); + sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx ); + T_log( T_NORMAL, "Started Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); +} + +static void RtemsModelEventsMgr0_Setup_Wrap( void *arg ) +{ + RtemsModelEventsMgr0_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr0_Setup( ctx ); +} + +static void RtemsModelEventsMgr0_Teardown( + RtemsModelEventsMgr0_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Teardown" ); + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_NORMAL ); + + if ( ctx->worker_id != 0 ) { + sc = rtems_task_delete( ctx->worker_id ); + T_rsc_success( sc ); + } + + DeleteWakeupSema( ctx->worker_wakeup ); + DeleteWakeupSema( ctx->runner_wakeup ); +} + +static void RtemsModelEventsMgr0_Teardown_Wrap( void *arg ) +{ + RtemsModelEventsMgr0_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr0_Teardown( ctx ); +} + +static size_t RtemsModelEventsMgr0_Scope( void *arg, char *buf, size_t n ) +{ + size_t pme_size; + + pme_size = strlen(PromelaModelEventsMgr); + return T_str_copy(buf, PromelaModelEventsMgr, pme_size); +} + +static T_fixture RtemsModelEventsMgr0_Fixture = { + .setup = RtemsModelEventsMgr0_Setup_Wrap, + .stop = NULL, + .teardown = RtemsModelEventsMgr0_Teardown_Wrap, + .scope = RtemsModelEventsMgr0_Scope, + .initial_context = &RtemsModelEventsMgr0_Instance +}; + + + +static void RtemsModelEventsMgr0_Cleanup( + RtemsModelEventsMgr0_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 T_fixture_node RtemsModelEventsMgr0_Node; + +void RtemsModelEventsMgr0_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 +) +{ + RtemsModelEventsMgr0_Context *ctx; + + T_set_verbosity( T_NORMAL ); + + T_log( T_NORMAL, "Runner Invoked" ); + T_log( T_NORMAL, "Runner Wait Class: %d", wait_class ); + T_log( T_NORMAL, "Runner WaitForEvent: %d", waiting_for_event ); + + T_log( T_NORMAL, "Pushing Test Fixture..." ); + + ctx = T_push_fixture( + &RtemsModelEventsMgr0_Node, + &RtemsModelEventsMgr0_Fixture + ); + + T_log( T_NORMAL, "Test Fixture Pushed" ); + + 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; + + // RtemsModelEventsMgr0_Prepare( ctx ); + ctx->events_to_send = 0; + ctx->send_status = RTEMS_INCORRECT_STATE; + ctx->received_events = 0xffffffff; + ctx->receive_option_set = 0; + ctx->receive_timeout = RTEMS_NO_TIMEOUT; + ctx->unsatisfied_pending = 0xffffffff; + memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) ); + T_eq_u32( GetPendingEvents( ctx ), 0 ); + _Thread_Wait_flags_set( ctx->runner_thread, THREAD_WAIT_FLAGS_INITIAL ); + + TestSegment0( ctx ); + + Runner( ctx ); + + RtemsModelEventsMgr0_Cleanup( ctx ); + + T_log( T_NORMAL, "Run Pop Fixture" ); + T_pop_fixture(); +} + +/** @} */ diff --git a/testsuites/validation/tr-model-events-mgr-1.c b/testsuites/validation/tr-model-events-mgr-1.c new file mode 100644 index 0000000000..99d2697711 --- /dev/null +++ b/testsuites/validation/tr-model-events-mgr-1.c @@ -0,0 +1,550 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsModelEventsMgr1 + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Trinity College Dublin (http://www.tcd.ie) + * + * 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 was automatically generated. Do not edit it manually. + * Please have a look at + * + * https://docs.rtems.org/branches/master/eng/req/howto.html + * + * for information how to maintain and re-generate this file. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tr-model-events-mgr.h" + +#include + +typedef enum { + PRIO_HIGH = 1, + PRIO_NORMAL, + PRIO_LOW, + PRIO_OTHER +} Priorities; + + +typedef struct { + rtems_status_code ( *send )( rtems_id, rtems_event_set ); // copy of the + // corresponding RtemsModelEventsMgr1_Run() parameter + rtems_status_code ( *receive ) + ( rtems_event_set, rtems_option + , rtems_interval, rtems_event_set * ); // copy of the + // corresponding RtemsModelEventsMgr1_Run() parameter + rtems_event_set ( *get_pending_events )( Thread_Control * ); // copy of the + // corresponding RtemsModelEventsMgr1_Run() parameter + unsigned int wait_class; // copy of the corresponding + // RtemsModelEventsMgr1_Run() parameter + int waiting_for_event; // copy of the corresponding + // RtemsModelEventsMgr1_Run() parameter + rtems_id receiver_id; // receiver ID used for the event send action. + rtems_event_set events_to_send; // events to send for the event send action + rtems_status_code send_status; // status of the event send action. + rtems_option receive_option_set; // option set used for the event receive action + rtems_interval receive_timeout; // timeout used for the event receive action + rtems_event_set received_events; // events received by the event receive action + rtems_status_code receive_status; // status of the event receive action + rtems_event_set unsatisfied_pending; // pending events after an event send action + // which did not satsify the event condition of the receiver + Thread_Control *runner_thread; // TCB of the runner task + rtems_id runner_id; // ID of the runner task + rtems_id worker_id; // task ID of the worker task + rtems_id worker_wakeup; // ID of the semaphore used to wake up the worker task + rtems_id runner_wakeup; // ID of the semaphore used to wake up the runner task + rtems_id runner_sched; // scheduler ID of scheduler used by the runner task + rtems_id other_sched; // scheduler ID of another scheduler + // which is not used by the runner task + T_thread_switch_log_4 thread_switch_log; // thread switch log +} RtemsModelEventsMgr1_Context; + +static RtemsModelEventsMgr1_Context + RtemsModelEventsMgr1_Instance; + +static const char PromelaModelEventsMgr[] = "/PML-EventsMgr1"; + +#define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 ) + +#define WORKER_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES + +#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT ) + +typedef RtemsModelEventsMgr1_Context Context; + +RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char WorkerStorage[ + RTEMS_TASK_STORAGE_SIZE( + MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, + WORKER_ATTRIBUTES + ) +]; + +static const rtems_task_config WorkerConfig = { + .name = rtems_build_name( 'W', 'O', 'R', 'K' ), + .initial_priority = PRIO_LOW, + .storage_area = WorkerStorage, + .storage_size = sizeof( WorkerStorage ), + .maximum_thread_local_storage_size = MAX_TLS_SIZE, + .initial_modes = RTEMS_DEFAULT_MODES, + .attributes = WORKER_ATTRIBUTES +}; + +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 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 rtems_option mergeopts( bool wait, bool wantall ) +{ + rtems_option opts; + + if ( wait ) { opts = RTEMS_WAIT; } + else { opts = RTEMS_NO_WAIT; } ; + if ( wantall ) { opts |= RTEMS_EVENT_ALL; } + else { opts |= RTEMS_EVENT_ANY; } ; + return opts; +} + + +/* + * Here we need a mapping from model "task numbers/names" to thread Id's here + * Promela Process 3 corresponds to Task 0 (Worker), doing Send + * Promela Process 4 corresponds to Task 1 (Runner), doing Receive + */ +static rtems_id mapid( Context *ctx, int pid ) +{ + rtems_id mapped_id; + + switch ( pid ) { + case 0 : mapped_id = ctx->worker_id ; break; + case 1 : mapped_id = ctx->runner_id; break; + default : mapped_id = 0xffffffff; break; + } + return mapped_id; +} + +static void checkTaskIs( rtems_id expected_id ) +{ + rtems_id own_id; + + own_id = _Thread_Get_executing()->Object.id; + T_eq_u32( own_id, expected_id ); +} + +static void initialise_pending( rtems_event_set pending[], int max ) +{ + int i; + + for( i=0; i < max; i++ ) { + pending[i] = 0; + } +} + +static void initialise_semaphore( Context *ctx, rtems_id semaphore[] ) +{ + semaphore[0] = ctx->worker_wakeup; + semaphore[1] = ctx->runner_wakeup; +} + +/* =============================================== */ + +// @@@ 0 NAME Event_Manager_TestGen +// @@@ 0 DEF NO_OF_EVENTS 4 +#define NO_OF_EVENTS 4 +// @@@ 0 DEF EVTS_NONE 0 +#define EVTS_NONE 0 +// @@@ 0 DEF EVTS_PENDING 0 +#define EVTS_PENDING 0 +// @@@ 0 DEF EVT_0 1 +#define EVT_0 1 +// @@@ 0 DEF EVT_1 2 +#define EVT_1 2 +// @@@ 0 DEF EVT_2 4 +#define EVT_2 4 +// @@@ 0 DEF EVT_3 8 +#define EVT_3 8 +// @@@ 0 DEF NO_TIMEOUT 0 +#define NO_TIMEOUT 0 +// @@@ 0 DEF TASK_MAX 2 +#define TASK_MAX 2 +// @@@ 0 DEF BAD_ID 2 +#define BAD_ID 2 +// @@@ 0 DEF SEMA_MAX 2 +#define SEMA_MAX 2 +// @@@ 0 DEF RC_OK RTEMS_SUCCESSFUL +#define RC_OK RTEMS_SUCCESSFUL +// @@@ 0 DEF RC_InvId RTEMS_INVALID_ID +#define RC_InvId RTEMS_INVALID_ID +// @@@ 0 DEF RC_InvAddr RTEMS_INVALID_ADDRESS +#define RC_InvAddr RTEMS_INVALID_ADDRESS +// @@@ 0 DEF RC_Unsat RTEMS_UNSATISFIED +#define RC_Unsat RTEMS_UNSATISFIED +// @@@ 0 DEF RC_Timeout RTEMS_TIMEOUT +#define RC_Timeout RTEMS_TIMEOUT +// @@@ 0 DCLARRAY EvtSet pending TASK_MAX +static rtems_event_set pending[TASK_MAX]; +// @@@ 0 DECL byte sendrc 0 +static rtems_status_code sendrc = 0; +// @@@ 0 DECL byte recrc 0 +static rtems_status_code recrc = 0; +// @@@ 0 DECL byte recout 0 +static rtems_event_set recout = 0; +// @@@ 0 DCLARRAY Semaphore semaphore SEMA_MAX +static rtems_id semaphore[SEMA_MAX]; + +/* ===== TEST CODE SEGMENT 0 =====*/ + +static void TestSegment0( Context* ctx ) { + /* Test Name is defined in the Test Case code (tc-model-events-mgr.c) */ + + T_log(T_NORMAL,"@@@ 0 INIT"); + initialise_pending( pending, TASK_MAX ); + initialise_semaphore( ctx, semaphore ); + +} + +/* ===== TEST CODE SEGMENT 3 =====*/ + +static void TestSegment3( Context* ctx ) { + T_log(T_NORMAL,"@@@ 3 TASK Worker"); + checkTaskIs( ctx->worker_id ); + T_log(T_NORMAL,"@@@ 3 WAIT 0"); + Wait( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 3 CALL event_send 0 1 14 sendrc"); + T_log( T_NORMAL, "Calling Send(%d,%d)", mapid( ctx, 1), 14 ); + sendrc = ( *ctx->send )( mapid( ctx, 1 ), 14 ); + T_log( T_NORMAL, "Returned 0x%x from Send", sendrc ); + + T_log(T_NORMAL,"@@@ 3 SCALAR sendrc 0"); + T_rsc_success( sendrc ); + T_log(T_NORMAL,"@@@ 3 SIGNAL 1"); + Wakeup( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 3 STATE 0 Zombie"); + /* Code to check that Task 0 has terminated */ +} + +/* ===== TEST CODE SEGMENT 4 =====*/ + +static void TestSegment4( Context* ctx ) { + T_log(T_NORMAL,"@@@ 4 TASK Runner"); + checkTaskIs( ctx->runner_id ); + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 WAIT 1"); + Wait( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 14"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 14 ); + + T_log(T_NORMAL,"@@@ 4 CALL event_receive 6 1 1 0 recout recrc"); + T_log( T_NORMAL, "Calling Receive(%d,%d,%d,%d)", 6, mergeopts( 1, 1 ) ,0 ,&recout ); + recrc = ( *ctx->receive )( 6, mergeopts( 1, 1 ), 0, &recout ); + T_log( T_NORMAL, "Returned 0x%x from Receive", recrc ); + + T_log(T_NORMAL,"@@@ 4 SCALAR recrc 0"); + T_rsc_success( recrc ); + T_log(T_NORMAL,"@@@ 4 SCALAR recout 6"); + T_eq_int( recout, 6 ); + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 8"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 8 ); + + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 STATE 1 Zombie"); + /* Code to check that Task 1 has terminated */ +} + +/* =============================================== */ + + +static void Worker( rtems_task_argument arg ) +{ + Context *ctx; + + ctx = (Context *) arg; + + T_log( T_NORMAL, "Worker Running" ); + TestSegment3( ctx ); + T_log( T_NORMAL, "Worker finished" ); + + rtems_task_exit(); + +} + + +static void Runner( RtemsModelEventsMgr1_Context *ctx ) +{ + T_log( T_NORMAL, "Runner running" ); + TestSegment4( ctx ); + T_log( T_NORMAL, "Runner finished" ); +} + + +static void RtemsModelEventsMgr1_Setup( + RtemsModelEventsMgr1_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Setup" ); + + memset( ctx, 0, sizeof( *ctx ) ); + 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 + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_HIGH ); + + sc = rtems_task_construct( &WorkerConfig, &ctx->worker_id ); + T_log( T_NORMAL, "Construct Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); + + T_log( T_NORMAL, "Starting Worker..." ); + sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx ); + T_log( T_NORMAL, "Started Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); +} + +static void RtemsModelEventsMgr1_Setup_Wrap( void *arg ) +{ + RtemsModelEventsMgr1_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr1_Setup( ctx ); +} + +static void RtemsModelEventsMgr1_Teardown( + RtemsModelEventsMgr1_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Teardown" ); + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_NORMAL ); + + if ( ctx->worker_id != 0 ) { + sc = rtems_task_delete( ctx->worker_id ); + T_rsc_success( sc ); + } + + DeleteWakeupSema( ctx->worker_wakeup ); + DeleteWakeupSema( ctx->runner_wakeup ); +} + +static void RtemsModelEventsMgr1_Teardown_Wrap( void *arg ) +{ + RtemsModelEventsMgr1_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr1_Teardown( ctx ); +} + +static size_t RtemsModelEventsMgr1_Scope( void *arg, char *buf, size_t n ) +{ + size_t pme_size; + + pme_size = strlen(PromelaModelEventsMgr); + return T_str_copy(buf, PromelaModelEventsMgr, pme_size); +} + +static T_fixture RtemsModelEventsMgr1_Fixture = { + .setup = RtemsModelEventsMgr1_Setup_Wrap, + .stop = NULL, + .teardown = RtemsModelEventsMgr1_Teardown_Wrap, + .scope = RtemsModelEventsMgr1_Scope, + .initial_context = &RtemsModelEventsMgr1_Instance +}; + + + +static void RtemsModelEventsMgr1_Cleanup( + RtemsModelEventsMgr1_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 T_fixture_node RtemsModelEventsMgr1_Node; + +void RtemsModelEventsMgr1_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 +) +{ + RtemsModelEventsMgr1_Context *ctx; + + T_set_verbosity( T_NORMAL ); + + T_log( T_NORMAL, "Runner Invoked" ); + T_log( T_NORMAL, "Runner Wait Class: %d", wait_class ); + T_log( T_NORMAL, "Runner WaitForEvent: %d", waiting_for_event ); + + T_log( T_NORMAL, "Pushing Test Fixture..." ); + + ctx = T_push_fixture( + &RtemsModelEventsMgr1_Node, + &RtemsModelEventsMgr1_Fixture + ); + + T_log( T_NORMAL, "Test Fixture Pushed" ); + + 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; + + // RtemsModelEventsMgr1_Prepare( ctx ); + ctx->events_to_send = 0; + ctx->send_status = RTEMS_INCORRECT_STATE; + ctx->received_events = 0xffffffff; + ctx->receive_option_set = 0; + ctx->receive_timeout = RTEMS_NO_TIMEOUT; + ctx->unsatisfied_pending = 0xffffffff; + memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) ); + T_eq_u32( GetPendingEvents( ctx ), 0 ); + _Thread_Wait_flags_set( ctx->runner_thread, THREAD_WAIT_FLAGS_INITIAL ); + + TestSegment0( ctx ); + + Runner( ctx ); + + RtemsModelEventsMgr1_Cleanup( ctx ); + + T_log( T_NORMAL, "Run Pop Fixture" ); + T_pop_fixture(); +} + +/** @} */ diff --git a/testsuites/validation/tr-model-events-mgr-2.c b/testsuites/validation/tr-model-events-mgr-2.c new file mode 100644 index 0000000000..9ebc89e108 --- /dev/null +++ b/testsuites/validation/tr-model-events-mgr-2.c @@ -0,0 +1,550 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsModelEventsMgr2 + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Trinity College Dublin (http://www.tcd.ie) + * + * 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 was automatically generated. Do not edit it manually. + * Please have a look at + * + * https://docs.rtems.org/branches/master/eng/req/howto.html + * + * for information how to maintain and re-generate this file. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tr-model-events-mgr.h" + +#include + +typedef enum { + PRIO_HIGH = 1, + PRIO_NORMAL, + PRIO_LOW, + PRIO_OTHER +} Priorities; + + +typedef struct { + rtems_status_code ( *send )( rtems_id, rtems_event_set ); // copy of the + // corresponding RtemsModelEventsMgr2_Run() parameter + rtems_status_code ( *receive ) + ( rtems_event_set, rtems_option + , rtems_interval, rtems_event_set * ); // copy of the + // corresponding RtemsModelEventsMgr2_Run() parameter + rtems_event_set ( *get_pending_events )( Thread_Control * ); // copy of the + // corresponding RtemsModelEventsMgr2_Run() parameter + unsigned int wait_class; // copy of the corresponding + // RtemsModelEventsMgr2_Run() parameter + int waiting_for_event; // copy of the corresponding + // RtemsModelEventsMgr2_Run() parameter + rtems_id receiver_id; // receiver ID used for the event send action. + rtems_event_set events_to_send; // events to send for the event send action + rtems_status_code send_status; // status of the event send action. + rtems_option receive_option_set; // option set used for the event receive action + rtems_interval receive_timeout; // timeout used for the event receive action + rtems_event_set received_events; // events received by the event receive action + rtems_status_code receive_status; // status of the event receive action + rtems_event_set unsatisfied_pending; // pending events after an event send action + // which did not satsify the event condition of the receiver + Thread_Control *runner_thread; // TCB of the runner task + rtems_id runner_id; // ID of the runner task + rtems_id worker_id; // task ID of the worker task + rtems_id worker_wakeup; // ID of the semaphore used to wake up the worker task + rtems_id runner_wakeup; // ID of the semaphore used to wake up the runner task + rtems_id runner_sched; // scheduler ID of scheduler used by the runner task + rtems_id other_sched; // scheduler ID of another scheduler + // which is not used by the runner task + T_thread_switch_log_4 thread_switch_log; // thread switch log +} RtemsModelEventsMgr2_Context; + +static RtemsModelEventsMgr2_Context + RtemsModelEventsMgr2_Instance; + +static const char PromelaModelEventsMgr[] = "/PML-EventsMgr2"; + +#define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 ) + +#define WORKER_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES + +#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT ) + +typedef RtemsModelEventsMgr2_Context Context; + +RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char WorkerStorage[ + RTEMS_TASK_STORAGE_SIZE( + MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, + WORKER_ATTRIBUTES + ) +]; + +static const rtems_task_config WorkerConfig = { + .name = rtems_build_name( 'W', 'O', 'R', 'K' ), + .initial_priority = PRIO_LOW, + .storage_area = WorkerStorage, + .storage_size = sizeof( WorkerStorage ), + .maximum_thread_local_storage_size = MAX_TLS_SIZE, + .initial_modes = RTEMS_DEFAULT_MODES, + .attributes = WORKER_ATTRIBUTES +}; + +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 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 rtems_option mergeopts( bool wait, bool wantall ) +{ + rtems_option opts; + + if ( wait ) { opts = RTEMS_WAIT; } + else { opts = RTEMS_NO_WAIT; } ; + if ( wantall ) { opts |= RTEMS_EVENT_ALL; } + else { opts |= RTEMS_EVENT_ANY; } ; + return opts; +} + + +/* + * Here we need a mapping from model "task numbers/names" to thread Id's here + * Promela Process 3 corresponds to Task 0 (Worker), doing Send + * Promela Process 4 corresponds to Task 1 (Runner), doing Receive + */ +static rtems_id mapid( Context *ctx, int pid ) +{ + rtems_id mapped_id; + + switch ( pid ) { + case 0 : mapped_id = ctx->worker_id ; break; + case 1 : mapped_id = ctx->runner_id; break; + default : mapped_id = 0xffffffff; break; + } + return mapped_id; +} + +static void checkTaskIs( rtems_id expected_id ) +{ + rtems_id own_id; + + own_id = _Thread_Get_executing()->Object.id; + T_eq_u32( own_id, expected_id ); +} + +static void initialise_pending( rtems_event_set pending[], int max ) +{ + int i; + + for( i=0; i < max; i++ ) { + pending[i] = 0; + } +} + +static void initialise_semaphore( Context *ctx, rtems_id semaphore[] ) +{ + semaphore[0] = ctx->worker_wakeup; + semaphore[1] = ctx->runner_wakeup; +} + +/* =============================================== */ + +// @@@ 0 NAME Event_Manager_TestGen +// @@@ 0 DEF NO_OF_EVENTS 4 +#define NO_OF_EVENTS 4 +// @@@ 0 DEF EVTS_NONE 0 +#define EVTS_NONE 0 +// @@@ 0 DEF EVTS_PENDING 0 +#define EVTS_PENDING 0 +// @@@ 0 DEF EVT_0 1 +#define EVT_0 1 +// @@@ 0 DEF EVT_1 2 +#define EVT_1 2 +// @@@ 0 DEF EVT_2 4 +#define EVT_2 4 +// @@@ 0 DEF EVT_3 8 +#define EVT_3 8 +// @@@ 0 DEF NO_TIMEOUT 0 +#define NO_TIMEOUT 0 +// @@@ 0 DEF TASK_MAX 2 +#define TASK_MAX 2 +// @@@ 0 DEF BAD_ID 2 +#define BAD_ID 2 +// @@@ 0 DEF SEMA_MAX 2 +#define SEMA_MAX 2 +// @@@ 0 DEF RC_OK RTEMS_SUCCESSFUL +#define RC_OK RTEMS_SUCCESSFUL +// @@@ 0 DEF RC_InvId RTEMS_INVALID_ID +#define RC_InvId RTEMS_INVALID_ID +// @@@ 0 DEF RC_InvAddr RTEMS_INVALID_ADDRESS +#define RC_InvAddr RTEMS_INVALID_ADDRESS +// @@@ 0 DEF RC_Unsat RTEMS_UNSATISFIED +#define RC_Unsat RTEMS_UNSATISFIED +// @@@ 0 DEF RC_Timeout RTEMS_TIMEOUT +#define RC_Timeout RTEMS_TIMEOUT +// @@@ 0 DCLARRAY EvtSet pending TASK_MAX +static rtems_event_set pending[TASK_MAX]; +// @@@ 0 DECL byte sendrc 0 +static rtems_status_code sendrc = 0; +// @@@ 0 DECL byte recrc 0 +static rtems_status_code recrc = 0; +// @@@ 0 DECL byte recout 0 +static rtems_event_set recout = 0; +// @@@ 0 DCLARRAY Semaphore semaphore SEMA_MAX +static rtems_id semaphore[SEMA_MAX]; + +/* ===== TEST CODE SEGMENT 0 =====*/ + +static void TestSegment0( Context* ctx ) { + /* Test Name is defined in the Test Case code (tc-model-events-mgr.c) */ + + T_log(T_NORMAL,"@@@ 0 INIT"); + initialise_pending( pending, TASK_MAX ); + initialise_semaphore( ctx, semaphore ); + +} + +/* ===== TEST CODE SEGMENT 3 =====*/ + +static void TestSegment3( Context* ctx ) { + T_log(T_NORMAL,"@@@ 3 TASK Worker"); + checkTaskIs( ctx->worker_id ); + T_log(T_NORMAL,"@@@ 3 WAIT 0"); + Wait( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 3 CALL event_send 0 1 15 sendrc"); + T_log( T_NORMAL, "Calling Send(%d,%d)", mapid( ctx, 1), 15 ); + sendrc = ( *ctx->send )( mapid( ctx, 1 ), 15 ); + T_log( T_NORMAL, "Returned 0x%x from Send", sendrc ); + + T_log(T_NORMAL,"@@@ 3 SCALAR sendrc 0"); + T_rsc_success( sendrc ); + T_log(T_NORMAL,"@@@ 3 SIGNAL 1"); + Wakeup( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 3 STATE 0 Zombie"); + /* Code to check that Task 0 has terminated */ +} + +/* ===== TEST CODE SEGMENT 4 =====*/ + +static void TestSegment4( Context* ctx ) { + T_log(T_NORMAL,"@@@ 4 TASK Runner"); + checkTaskIs( ctx->runner_id ); + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 WAIT 1"); + Wait( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 15"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 15 ); + + T_log(T_NORMAL,"@@@ 4 CALL event_receive 10 1 1 0 recout recrc"); + T_log( T_NORMAL, "Calling Receive(%d,%d,%d,%d)", 10, mergeopts( 1, 1 ) ,0 ,&recout ); + recrc = ( *ctx->receive )( 10, mergeopts( 1, 1 ), 0, &recout ); + T_log( T_NORMAL, "Returned 0x%x from Receive", recrc ); + + T_log(T_NORMAL,"@@@ 4 SCALAR recrc 0"); + T_rsc_success( recrc ); + T_log(T_NORMAL,"@@@ 4 SCALAR recout 10"); + T_eq_int( recout, 10 ); + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 5"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 5 ); + + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 STATE 1 Zombie"); + /* Code to check that Task 1 has terminated */ +} + +/* =============================================== */ + + +static void Worker( rtems_task_argument arg ) +{ + Context *ctx; + + ctx = (Context *) arg; + + T_log( T_NORMAL, "Worker Running" ); + TestSegment3( ctx ); + T_log( T_NORMAL, "Worker finished" ); + + rtems_task_exit(); + +} + + +static void Runner( RtemsModelEventsMgr2_Context *ctx ) +{ + T_log( T_NORMAL, "Runner running" ); + TestSegment4( ctx ); + T_log( T_NORMAL, "Runner finished" ); +} + + +static void RtemsModelEventsMgr2_Setup( + RtemsModelEventsMgr2_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Setup" ); + + memset( ctx, 0, sizeof( *ctx ) ); + 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 + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_HIGH ); + + sc = rtems_task_construct( &WorkerConfig, &ctx->worker_id ); + T_log( T_NORMAL, "Construct Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); + + T_log( T_NORMAL, "Starting Worker..." ); + sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx ); + T_log( T_NORMAL, "Started Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); +} + +static void RtemsModelEventsMgr2_Setup_Wrap( void *arg ) +{ + RtemsModelEventsMgr2_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr2_Setup( ctx ); +} + +static void RtemsModelEventsMgr2_Teardown( + RtemsModelEventsMgr2_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Teardown" ); + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_NORMAL ); + + if ( ctx->worker_id != 0 ) { + sc = rtems_task_delete( ctx->worker_id ); + T_rsc_success( sc ); + } + + DeleteWakeupSema( ctx->worker_wakeup ); + DeleteWakeupSema( ctx->runner_wakeup ); +} + +static void RtemsModelEventsMgr2_Teardown_Wrap( void *arg ) +{ + RtemsModelEventsMgr2_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr2_Teardown( ctx ); +} + +static size_t RtemsModelEventsMgr2_Scope( void *arg, char *buf, size_t n ) +{ + size_t pme_size; + + pme_size = strlen(PromelaModelEventsMgr); + return T_str_copy(buf, PromelaModelEventsMgr, pme_size); +} + +static T_fixture RtemsModelEventsMgr2_Fixture = { + .setup = RtemsModelEventsMgr2_Setup_Wrap, + .stop = NULL, + .teardown = RtemsModelEventsMgr2_Teardown_Wrap, + .scope = RtemsModelEventsMgr2_Scope, + .initial_context = &RtemsModelEventsMgr2_Instance +}; + + + +static void RtemsModelEventsMgr2_Cleanup( + RtemsModelEventsMgr2_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 T_fixture_node RtemsModelEventsMgr2_Node; + +void RtemsModelEventsMgr2_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 +) +{ + RtemsModelEventsMgr2_Context *ctx; + + T_set_verbosity( T_NORMAL ); + + T_log( T_NORMAL, "Runner Invoked" ); + T_log( T_NORMAL, "Runner Wait Class: %d", wait_class ); + T_log( T_NORMAL, "Runner WaitForEvent: %d", waiting_for_event ); + + T_log( T_NORMAL, "Pushing Test Fixture..." ); + + ctx = T_push_fixture( + &RtemsModelEventsMgr2_Node, + &RtemsModelEventsMgr2_Fixture + ); + + T_log( T_NORMAL, "Test Fixture Pushed" ); + + 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; + + // RtemsModelEventsMgr2_Prepare( ctx ); + ctx->events_to_send = 0; + ctx->send_status = RTEMS_INCORRECT_STATE; + ctx->received_events = 0xffffffff; + ctx->receive_option_set = 0; + ctx->receive_timeout = RTEMS_NO_TIMEOUT; + ctx->unsatisfied_pending = 0xffffffff; + memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) ); + T_eq_u32( GetPendingEvents( ctx ), 0 ); + _Thread_Wait_flags_set( ctx->runner_thread, THREAD_WAIT_FLAGS_INITIAL ); + + TestSegment0( ctx ); + + Runner( ctx ); + + RtemsModelEventsMgr2_Cleanup( ctx ); + + T_log( T_NORMAL, "Run Pop Fixture" ); + T_pop_fixture(); +} + +/** @} */ diff --git a/testsuites/validation/tr-model-events-mgr-3.c b/testsuites/validation/tr-model-events-mgr-3.c new file mode 100644 index 0000000000..379fb98aa0 --- /dev/null +++ b/testsuites/validation/tr-model-events-mgr-3.c @@ -0,0 +1,550 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsModelEventsMgr3 + */ + +/* + * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Trinity College Dublin (http://www.tcd.ie) + * + * 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 was automatically generated. Do not edit it manually. + * Please have a look at + * + * https://docs.rtems.org/branches/master/eng/req/howto.html + * + * for information how to maintain and re-generate this file. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include "tr-model-events-mgr.h" + +#include + +typedef enum { + PRIO_HIGH = 1, + PRIO_NORMAL, + PRIO_LOW, + PRIO_OTHER +} Priorities; + + +typedef struct { + rtems_status_code ( *send )( rtems_id, rtems_event_set ); // copy of the + // corresponding RtemsModelEventsMgr3_Run() parameter + rtems_status_code ( *receive ) + ( rtems_event_set, rtems_option + , rtems_interval, rtems_event_set * ); // copy of the + // corresponding RtemsModelEventsMgr3_Run() parameter + rtems_event_set ( *get_pending_events )( Thread_Control * ); // copy of the + // corresponding RtemsModelEventsMgr3_Run() parameter + unsigned int wait_class; // copy of the corresponding + // RtemsModelEventsMgr3_Run() parameter + int waiting_for_event; // copy of the corresponding + // RtemsModelEventsMgr3_Run() parameter + rtems_id receiver_id; // receiver ID used for the event send action. + rtems_event_set events_to_send; // events to send for the event send action + rtems_status_code send_status; // status of the event send action. + rtems_option receive_option_set; // option set used for the event receive action + rtems_interval receive_timeout; // timeout used for the event receive action + rtems_event_set received_events; // events received by the event receive action + rtems_status_code receive_status; // status of the event receive action + rtems_event_set unsatisfied_pending; // pending events after an event send action + // which did not satsify the event condition of the receiver + Thread_Control *runner_thread; // TCB of the runner task + rtems_id runner_id; // ID of the runner task + rtems_id worker_id; // task ID of the worker task + rtems_id worker_wakeup; // ID of the semaphore used to wake up the worker task + rtems_id runner_wakeup; // ID of the semaphore used to wake up the runner task + rtems_id runner_sched; // scheduler ID of scheduler used by the runner task + rtems_id other_sched; // scheduler ID of another scheduler + // which is not used by the runner task + T_thread_switch_log_4 thread_switch_log; // thread switch log +} RtemsModelEventsMgr3_Context; + +static RtemsModelEventsMgr3_Context + RtemsModelEventsMgr3_Instance; + +static const char PromelaModelEventsMgr[] = "/PML-EventsMgr3"; + +#define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 ) + +#define WORKER_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES + +#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT ) + +typedef RtemsModelEventsMgr3_Context Context; + +RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char WorkerStorage[ + RTEMS_TASK_STORAGE_SIZE( + MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, + WORKER_ATTRIBUTES + ) +]; + +static const rtems_task_config WorkerConfig = { + .name = rtems_build_name( 'W', 'O', 'R', 'K' ), + .initial_priority = PRIO_LOW, + .storage_area = WorkerStorage, + .storage_size = sizeof( WorkerStorage ), + .maximum_thread_local_storage_size = MAX_TLS_SIZE, + .initial_modes = RTEMS_DEFAULT_MODES, + .attributes = WORKER_ATTRIBUTES +}; + +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 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 rtems_option mergeopts( bool wait, bool wantall ) +{ + rtems_option opts; + + if ( wait ) { opts = RTEMS_WAIT; } + else { opts = RTEMS_NO_WAIT; } ; + if ( wantall ) { opts |= RTEMS_EVENT_ALL; } + else { opts |= RTEMS_EVENT_ANY; } ; + return opts; +} + + +/* + * Here we need a mapping from model "task numbers/names" to thread Id's here + * Promela Process 3 corresponds to Task 0 (Worker), doing Send + * Promela Process 4 corresponds to Task 1 (Runner), doing Receive + */ +static rtems_id mapid( Context *ctx, int pid ) +{ + rtems_id mapped_id; + + switch ( pid ) { + case 0 : mapped_id = ctx->worker_id ; break; + case 1 : mapped_id = ctx->runner_id; break; + default : mapped_id = 0xffffffff; break; + } + return mapped_id; +} + +static void checkTaskIs( rtems_id expected_id ) +{ + rtems_id own_id; + + own_id = _Thread_Get_executing()->Object.id; + T_eq_u32( own_id, expected_id ); +} + +static void initialise_pending( rtems_event_set pending[], int max ) +{ + int i; + + for( i=0; i < max; i++ ) { + pending[i] = 0; + } +} + +static void initialise_semaphore( Context *ctx, rtems_id semaphore[] ) +{ + semaphore[0] = ctx->worker_wakeup; + semaphore[1] = ctx->runner_wakeup; +} + +/* =============================================== */ + +// @@@ 0 NAME Event_Manager_TestGen +// @@@ 0 DEF NO_OF_EVENTS 4 +#define NO_OF_EVENTS 4 +// @@@ 0 DEF EVTS_NONE 0 +#define EVTS_NONE 0 +// @@@ 0 DEF EVTS_PENDING 0 +#define EVTS_PENDING 0 +// @@@ 0 DEF EVT_0 1 +#define EVT_0 1 +// @@@ 0 DEF EVT_1 2 +#define EVT_1 2 +// @@@ 0 DEF EVT_2 4 +#define EVT_2 4 +// @@@ 0 DEF EVT_3 8 +#define EVT_3 8 +// @@@ 0 DEF NO_TIMEOUT 0 +#define NO_TIMEOUT 0 +// @@@ 0 DEF TASK_MAX 2 +#define TASK_MAX 2 +// @@@ 0 DEF BAD_ID 2 +#define BAD_ID 2 +// @@@ 0 DEF SEMA_MAX 2 +#define SEMA_MAX 2 +// @@@ 0 DEF RC_OK RTEMS_SUCCESSFUL +#define RC_OK RTEMS_SUCCESSFUL +// @@@ 0 DEF RC_InvId RTEMS_INVALID_ID +#define RC_InvId RTEMS_INVALID_ID +// @@@ 0 DEF RC_InvAddr RTEMS_INVALID_ADDRESS +#define RC_InvAddr RTEMS_INVALID_ADDRESS +// @@@ 0 DEF RC_Unsat RTEMS_UNSATISFIED +#define RC_Unsat RTEMS_UNSATISFIED +// @@@ 0 DEF RC_Timeout RTEMS_TIMEOUT +#define RC_Timeout RTEMS_TIMEOUT +// @@@ 0 DCLARRAY EvtSet pending TASK_MAX +static rtems_event_set pending[TASK_MAX]; +// @@@ 0 DECL byte sendrc 0 +static rtems_status_code sendrc = 0; +// @@@ 0 DECL byte recrc 0 +static rtems_status_code recrc = 0; +// @@@ 0 DECL byte recout 0 +static rtems_event_set recout = 0; +// @@@ 0 DCLARRAY Semaphore semaphore SEMA_MAX +static rtems_id semaphore[SEMA_MAX]; + +/* ===== TEST CODE SEGMENT 0 =====*/ + +static void TestSegment0( Context* ctx ) { + /* Test Name is defined in the Test Case code (tc-model-events-mgr.c) */ + + T_log(T_NORMAL,"@@@ 0 INIT"); + initialise_pending( pending, TASK_MAX ); + initialise_semaphore( ctx, semaphore ); + +} + +/* ===== TEST CODE SEGMENT 3 =====*/ + +static void TestSegment3( Context* ctx ) { + T_log(T_NORMAL,"@@@ 3 TASK Worker"); + checkTaskIs( ctx->worker_id ); + T_log(T_NORMAL,"@@@ 3 WAIT 0"); + Wait( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 3 CALL event_send 0 1 15 sendrc"); + T_log( T_NORMAL, "Calling Send(%d,%d)", mapid( ctx, 1), 15 ); + sendrc = ( *ctx->send )( mapid( ctx, 1 ), 15 ); + T_log( T_NORMAL, "Returned 0x%x from Send", sendrc ); + + T_log(T_NORMAL,"@@@ 3 SCALAR sendrc 0"); + T_rsc_success( sendrc ); + T_log(T_NORMAL,"@@@ 3 SIGNAL 1"); + Wakeup( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 3 STATE 0 Zombie"); + /* Code to check that Task 0 has terminated */ +} + +/* ===== TEST CODE SEGMENT 4 =====*/ + +static void TestSegment4( Context* ctx ) { + T_log(T_NORMAL,"@@@ 4 TASK Runner"); + checkTaskIs( ctx->runner_id ); + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 WAIT 1"); + Wait( semaphore[1] ); + + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 15"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 15 ); + + T_log(T_NORMAL,"@@@ 4 CALL event_receive 6 1 1 0 recout recrc"); + T_log( T_NORMAL, "Calling Receive(%d,%d,%d,%d)", 6, mergeopts( 1, 1 ) ,0 ,&recout ); + recrc = ( *ctx->receive )( 6, mergeopts( 1, 1 ), 0, &recout ); + T_log( T_NORMAL, "Returned 0x%x from Receive", recrc ); + + T_log(T_NORMAL,"@@@ 4 SCALAR recrc 0"); + T_rsc_success( recrc ); + T_log(T_NORMAL,"@@@ 4 SCALAR recout 6"); + T_eq_int( recout, 6 ); + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 9"); + pending[1] = GetPendingEvents( ctx ); + T_eq_int( pending[1], 9 ); + + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); + Wakeup( semaphore[0] ); + + T_log(T_NORMAL,"@@@ 4 STATE 1 Zombie"); + /* Code to check that Task 1 has terminated */ +} + +/* =============================================== */ + + +static void Worker( rtems_task_argument arg ) +{ + Context *ctx; + + ctx = (Context *) arg; + + T_log( T_NORMAL, "Worker Running" ); + TestSegment3( ctx ); + T_log( T_NORMAL, "Worker finished" ); + + rtems_task_exit(); + +} + + +static void Runner( RtemsModelEventsMgr3_Context *ctx ) +{ + T_log( T_NORMAL, "Runner running" ); + TestSegment4( ctx ); + T_log( T_NORMAL, "Runner finished" ); +} + + +static void RtemsModelEventsMgr3_Setup( + RtemsModelEventsMgr3_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Setup" ); + + memset( ctx, 0, sizeof( *ctx ) ); + 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 + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_NORMAL, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_HIGH ); + + sc = rtems_task_construct( &WorkerConfig, &ctx->worker_id ); + T_log( T_NORMAL, "Construct Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); + + T_log( T_NORMAL, "Starting Worker..." ); + sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx ); + T_log( T_NORMAL, "Started Worker, sc = %x", sc ); + T_assert_rsc_success( sc ); +} + +static void RtemsModelEventsMgr3_Setup_Wrap( void *arg ) +{ + RtemsModelEventsMgr3_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr3_Setup( ctx ); +} + +static void RtemsModelEventsMgr3_Teardown( + RtemsModelEventsMgr3_Context *ctx +) +{ + rtems_status_code sc; + rtems_task_priority prio; + + T_log( T_NORMAL, "Runner Teardown" ); + + prio = 0; + sc = rtems_task_set_priority( RTEMS_SELF, PRIO_HIGH, &prio ); + T_rsc_success( sc ); + T_eq_u32( prio, PRIO_NORMAL ); + + if ( ctx->worker_id != 0 ) { + sc = rtems_task_delete( ctx->worker_id ); + T_rsc_success( sc ); + } + + DeleteWakeupSema( ctx->worker_wakeup ); + DeleteWakeupSema( ctx->runner_wakeup ); +} + +static void RtemsModelEventsMgr3_Teardown_Wrap( void *arg ) +{ + RtemsModelEventsMgr3_Context *ctx; + + ctx = arg; + RtemsModelEventsMgr3_Teardown( ctx ); +} + +static size_t RtemsModelEventsMgr3_Scope( void *arg, char *buf, size_t n ) +{ + size_t pme_size; + + pme_size = strlen(PromelaModelEventsMgr); + return T_str_copy(buf, PromelaModelEventsMgr, pme_size); +} + +static T_fixture RtemsModelEventsMgr3_Fixture = { + .setup = RtemsModelEventsMgr3_Setup_Wrap, + .stop = NULL, + .teardown = RtemsModelEventsMgr3_Teardown_Wrap, + .scope = RtemsModelEventsMgr3_Scope, + .initial_context = &RtemsModelEventsMgr3_Instance +}; + + + +static void RtemsModelEventsMgr3_Cleanup( + RtemsModelEventsMgr3_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 T_fixture_node RtemsModelEventsMgr3_Node; + +void RtemsModelEventsMgr3_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 +) +{ + RtemsModelEventsMgr3_Context *ctx; + + T_set_verbosity( T_NORMAL ); + + T_log( T_NORMAL, "Runner Invoked" ); + T_log( T_NORMAL, "Runner Wait Class: %d", wait_class ); + T_log( T_NORMAL, "Runner WaitForEvent: %d", waiting_for_event ); + + T_log( T_NORMAL, "Pushing Test Fixture..." ); + + ctx = T_push_fixture( + &RtemsModelEventsMgr3_Node, + &RtemsModelEventsMgr3_Fixture + ); + + T_log( T_NORMAL, "Test Fixture Pushed" ); + + 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; + + // RtemsModelEventsMgr3_Prepare( ctx ); + ctx->events_to_send = 0; + ctx->send_status = RTEMS_INCORRECT_STATE; + ctx->received_events = 0xffffffff; + ctx->receive_option_set = 0; + ctx->receive_timeout = RTEMS_NO_TIMEOUT; + ctx->unsatisfied_pending = 0xffffffff; + memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) ); + T_eq_u32( GetPendingEvents( ctx ), 0 ); + _Thread_Wait_flags_set( ctx->runner_thread, THREAD_WAIT_FLAGS_INITIAL ); + + TestSegment0( ctx ); + + Runner( ctx ); + + RtemsModelEventsMgr3_Cleanup( ctx ); + + T_log( T_NORMAL, "Run Pop Fixture" ); + T_pop_fixture(); +} + +/** @} */ diff --git a/testsuites/validation/tr-model-events-mgr.c b/testsuites/validation/tr-model-events-mgr.c old mode 100755 new mode 100644 index b677fb3c82..4bb8f9773d --- a/testsuites/validation/tr-model-events-mgr.c +++ b/testsuites/validation/tr-model-events-mgr.c @@ -1,7 +1,14 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsModelEventsMgr + */ + /* * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Trinity College Dublin (http://www.tcd.ie) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,39 +58,27 @@ typedef enum { PRIO_OTHER } Priorities; -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; typedef struct { - SenderTypes sender_type; - Priorities sender_prio; // sender task priority. + rtems_status_code ( *send )( rtems_id, rtems_event_set ); // copy of the + // corresponding RtemsModelEventsMgr_Run() parameter + rtems_status_code ( *receive ) + ( rtems_event_set, rtems_option + , rtems_interval, rtems_event_set * ); // copy of the + // corresponding RtemsModelEventsMgr_Run() parameter + rtems_event_set ( *get_pending_events )( Thread_Control * ); // copy of the + // corresponding RtemsModelEventsMgr_Run() parameter + unsigned int wait_class; // copy of the corresponding + // RtemsModelEventsMgr_Run() parameter + int waiting_for_event; // copy of the corresponding + // RtemsModelEventsMgr_Run() parameter rtems_id receiver_id; // receiver ID used for the event send action. rtems_event_set events_to_send; // events to send for the event send action rtems_status_code send_status; // status of the event send action. - ReceiveTypes receive_type; // scheduler ID of the runner task. rtems_option receive_option_set; // option set used for the event receive action rtems_interval receive_timeout; // timeout used for the event receive action rtems_event_set received_events; // events received by the event receive action rtems_status_code receive_status; // status of the event receive action - ReceiveConditionStates receive_condition_state; // event conditon state of the - // receiver task after the event send action rtems_event_set unsatisfied_pending; // pending events after an event send action // which did not satsify the event condition of the receiver Thread_Control *runner_thread; // TCB of the runner task @@ -95,66 +90,12 @@ typedef struct { rtems_id other_sched; // scheduler ID of another scheduler // which is not used by the runner task T_thread_switch_log_4 thread_switch_log; // thread switch log - rtems_status_code ( *send )( rtems_id, rtems_event_set ); // copy of the - // corresponding RtemsModelEventsMgr_Run() parameter - rtems_status_code ( *receive ) - ( rtems_event_set, rtems_option - , rtems_interval, rtems_event_set * ); // copy of the - // corresponding RtemsModelEventsMgr_Run() parameter - rtems_event_set ( *get_pending_events )( Thread_Control * ); // copy of the - // corresponding RtemsModelEventsMgr_Run() parameter - unsigned int wait_class; // copy of the corresponding - // RtemsModelEventsMgr_Run() parameter - int waiting_for_event; // copy of the corresponding - // RtemsModelEventsMgr_Run() parameter - size_t pcs[ 4 ]; // pre-condition states for the next action - bool in_action_loop; // indicates if test action loop is currently executed. } RtemsModelEventsMgr_Context; static RtemsModelEventsMgr_Context RtemsModelEventsMgr_Instance; -static const char * const RtemsModelEventsMgr_PreDesc_Id[] = { - "InvId", - "Task", - "NA" -}; - -static const char * const RtemsModelEventsMgr_PreDesc_Send[] = { - "Zero", - "Unrelated", - "Any", - "All", - "MixedAny", - "MixedAll", - "NA" -}; - -static const char * const RtemsModelEventsMgr_PreDesc_ReceiverState[] = { - "NotWaiting", - "Poll", - "Timeout", - "Lower", - "Equal", - "Higher", - "Other", - "Intend", - "NA" -}; - -static const char * const RtemsModelEventsMgr_PreDesc_Satisfy[] = { - "All", - "Any", - "NA" -}; - -static const char * const * const RtemsModelEventsMgr_PreDesc[] = { - RtemsModelEventsMgr_PreDesc_Id, - RtemsModelEventsMgr_PreDesc_Send, - RtemsModelEventsMgr_PreDesc_ReceiverState, - RtemsModelEventsMgr_PreDesc_Satisfy, - NULL -}; +static const char PromelaModelEventsMgr[] = "/PML-EventsMgr"; #define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 ) @@ -224,51 +165,6 @@ static void Wakeup( rtems_id id ) T_quiet_rsc_success( sc ); } - -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, &ctx->thread_switch_log.log ); -} - -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 rtems_event_set GetPendingEvents( Context *ctx ) { rtems_event_set pending; @@ -340,31 +236,56 @@ static void initialise_semaphore( Context *ctx, rtems_id semaphore[] ) /* =============================================== */ +// @@@ 0 NAME Event_Manager_TestGen +// @@@ 0 DEF NO_OF_EVENTS 4 #define NO_OF_EVENTS 4 +// @@@ 0 DEF EVTS_NONE 0 #define EVTS_NONE 0 +// @@@ 0 DEF EVTS_PENDING 0 #define EVTS_PENDING 0 +// @@@ 0 DEF EVT_0 1 #define EVT_0 1 +// @@@ 0 DEF EVT_1 2 #define EVT_1 2 +// @@@ 0 DEF EVT_2 4 #define EVT_2 4 +// @@@ 0 DEF EVT_3 8 #define EVT_3 8 +// @@@ 0 DEF NO_TIMEOUT 0 #define NO_TIMEOUT 0 +// @@@ 0 DEF TASK_MAX 2 #define TASK_MAX 2 +// @@@ 0 DEF BAD_ID 2 #define BAD_ID 2 +// @@@ 0 DEF SEMA_MAX 2 #define SEMA_MAX 2 +// @@@ 0 DEF RC_OK RTEMS_SUCCESSFUL #define RC_OK RTEMS_SUCCESSFUL +// @@@ 0 DEF RC_InvId RTEMS_INVALID_ID #define RC_InvId RTEMS_INVALID_ID +// @@@ 0 DEF RC_InvAddr RTEMS_INVALID_ADDRESS #define RC_InvAddr RTEMS_INVALID_ADDRESS +// @@@ 0 DEF RC_Unsat RTEMS_UNSATISFIED #define RC_Unsat RTEMS_UNSATISFIED +// @@@ 0 DEF RC_Timeout RTEMS_TIMEOUT #define RC_Timeout RTEMS_TIMEOUT -rtems_event_set pending[TASK_MAX]; -static unsigned int sendrc = 0; -static unsigned int recrc = 0; -static unsigned int recout = 0; -rtems_id semaphore[SEMA_MAX]; +// @@@ 0 DCLARRAY EvtSet pending TASK_MAX +static rtems_event_set pending[TASK_MAX]; +// @@@ 0 DECL byte sendrc 0 +static rtems_status_code sendrc = 0; +// @@@ 0 DECL byte recrc 0 +static rtems_status_code recrc = 0; +// @@@ 0 DECL byte recout 0 +static rtems_event_set recout = 0; +// @@@ 0 DCLARRAY Semaphore semaphore SEMA_MAX +static rtems_id semaphore[SEMA_MAX]; /* ===== TEST CODE SEGMENT 0 =====*/ static void TestSegment0( Context* ctx ) { + /* Test Name is defined in the Test Case code (tc-model-events-mgr.c) */ + + T_log(T_NORMAL,"@@@ 0 INIT"); initialise_pending( pending, TASK_MAX ); initialise_semaphore( ctx, semaphore ); @@ -373,47 +294,57 @@ static void TestSegment0( Context* ctx ) { /* ===== TEST CODE SEGMENT 3 =====*/ static void TestSegment3( Context* ctx ) { + T_log(T_NORMAL,"@@@ 3 TASK Worker"); checkTaskIs( ctx->worker_id ); + T_log(T_NORMAL,"@@@ 3 WAIT 0"); Wait( semaphore[0] ); - pending[1] = GetPendingEvents( ctx ); - T_eq_int( pending[1], 0 ); - - T_log( T_NORMAL, "Calling Send(%d,%d)", mapid( ctx, 1), 14 ); - sendrc = rtems_event_send( mapid( ctx, 1 ), 14 ); + T_log(T_NORMAL,"@@@ 3 CALL event_send 0 1 15 sendrc"); + T_log( T_NORMAL, "Calling Send(%d,%d)", mapid( ctx, 1), 15 ); + sendrc = ( *ctx->send )( mapid( ctx, 1 ), 15 ); T_log( T_NORMAL, "Returned 0x%x from Send", sendrc ); - T_eq_int( sendrc, 0 ); - pending[1] = GetPendingEvents( ctx ); - T_eq_int( pending[1], 14 ); - + T_log(T_NORMAL,"@@@ 3 SCALAR sendrc 0"); + T_rsc_success( sendrc ); + T_log(T_NORMAL,"@@@ 3 SIGNAL 1"); Wakeup( semaphore[1] ); + T_log(T_NORMAL,"@@@ 3 STATE 0 Zombie"); /* Code to check that Task 0 has terminated */ } /* ===== TEST CODE SEGMENT 4 =====*/ static void TestSegment4( Context* ctx ) { + T_log(T_NORMAL,"@@@ 4 TASK Runner"); checkTaskIs( ctx->runner_id ); + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); Wakeup( semaphore[0] ); + T_log(T_NORMAL,"@@@ 4 WAIT 1"); Wait( semaphore[1] ); + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 15"); pending[1] = GetPendingEvents( ctx ); - T_eq_int( pending[1], 14 ); + T_eq_int( pending[1], 15 ); - T_log( T_NORMAL, "Calling Receive(%d,%d,%d,%d)", 10, mergeopts( 1, 1 ) ,0 ,&recout ); - recrc = rtems_event_receive( 10, mergeopts( 1, 1 ), 0, &recout ); + T_log(T_NORMAL,"@@@ 4 CALL event_receive 6 1 1 0 recout recrc"); + T_log( T_NORMAL, "Calling Receive(%d,%d,%d,%d)", 6, mergeopts( 1, 1 ) ,0 ,&recout ); + recrc = ( *ctx->receive )( 6, mergeopts( 1, 1 ), 0, &recout ); T_log( T_NORMAL, "Returned 0x%x from Receive", recrc ); - T_eq_int( recrc, 0 ); - T_eq_int( recout, 10 ); + T_log(T_NORMAL,"@@@ 4 SCALAR recrc 0"); + T_rsc_success( recrc ); + T_log(T_NORMAL,"@@@ 4 SCALAR recout 6"); + T_eq_int( recout, 6 ); + T_log(T_NORMAL,"@@@ 4 SCALAR pending 1 9"); pending[1] = GetPendingEvents( ctx ); - T_eq_int( pending[1], 4 ); + T_eq_int( pending[1], 9 ); + T_log(T_NORMAL,"@@@ 4 SIGNAL 0"); Wakeup( semaphore[0] ); + T_log(T_NORMAL,"@@@ 4 STATE 1 Zombie"); /* Code to check that Task 1 has terminated */ } @@ -432,40 +363,6 @@ static void Worker( rtems_task_argument arg ) rtems_task_exit(); - // while(true) { - // Wait( ctx->worker_wakeup ); - // - // switch ( ctx->sender_prio ) { - // case PRIO_NORMAL: - // case PRIO_HIGH: - // prio = 0; - // sc = rtems_task_set_priority( RTEMS_SELF, ctx->sender_prio, &prio ); - // T_rsc_success( sc ); - // T_eq_u32( prio, PRIO_LOW ); - // break; - // case PRIO_OTHER: - // sc = rtems_task_set_scheduler( - // RTEMS_SELF, - // ctx->other_sched, - // PRIO_LOW - // ); - // T_rsc_success( sc ); - // 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 ); - // } } @@ -510,8 +407,9 @@ static void RtemsModelEventsMgr_Setup( T_log( T_NORMAL, "Construct Worker, sc = %x", sc ); T_assert_rsc_success( sc ); + T_log( T_NORMAL, "Starting Worker..." ); sc = rtems_task_start( ctx->worker_id, Worker, (rtems_task_argument) ctx ); - T_log( T_NORMAL, "Start Worker, sc = %x", sc ); + T_log( T_NORMAL, "Started Worker, sc = %x", sc ); T_assert_rsc_success( sc ); } @@ -520,7 +418,6 @@ static void RtemsModelEventsMgr_Setup_Wrap( void *arg ) RtemsModelEventsMgr_Context *ctx; ctx = arg; - ctx->in_action_loop = false; RtemsModelEventsMgr_Setup( ctx ); } @@ -552,21 +449,15 @@ static void RtemsModelEventsMgr_Teardown_Wrap( void *arg ) RtemsModelEventsMgr_Context *ctx; ctx = arg; - ctx->in_action_loop = false; RtemsModelEventsMgr_Teardown( ctx ); } static size_t RtemsModelEventsMgr_Scope( void *arg, char *buf, size_t n ) { - RtemsModelEventsMgr_Context *ctx; + size_t pme_size; - ctx = arg; - - if ( ctx->in_action_loop ) { - return T_get_scope( RtemsModelEventsMgr_PreDesc, buf, n, ctx->pcs ); - } - - return 0; + pme_size = strlen(PromelaModelEventsMgr); + return T_str_copy(buf, PromelaModelEventsMgr, pme_size); } static T_fixture RtemsModelEventsMgr_Fixture = { @@ -614,7 +505,11 @@ void RtemsModelEventsMgr_Run( { RtemsModelEventsMgr_Context *ctx; - // T_set_verbosity( T_VERBOSE ); + T_set_verbosity( T_NORMAL ); + + T_log( T_NORMAL, "Runner Invoked" ); + T_log( T_NORMAL, "Runner Wait Class: %d", wait_class ); + T_log( T_NORMAL, "Runner WaitForEvent: %d", waiting_for_event ); T_log( T_NORMAL, "Pushing Test Fixture..." ); @@ -630,7 +525,6 @@ void RtemsModelEventsMgr_Run( ctx->get_pending_events = get_pending_events; ctx->wait_class = wait_class; ctx->waiting_for_event = waiting_for_event; - ctx->in_action_loop = true; // RtemsModelEventsMgr_Prepare( ctx ); ctx->events_to_send = 0; @@ -638,10 +532,6 @@ void RtemsModelEventsMgr_Run( ctx->received_events = 0xffffffff; 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 ); diff --git a/testsuites/validation/tr-model-events-mgr.h b/testsuites/validation/tr-model-events-mgr.h old mode 100755 new mode 100644 index 95678e2ee1..94daaa5c79 --- a/testsuites/validation/tr-model-events-mgr.h +++ b/testsuites/validation/tr-model-events-mgr.h @@ -74,7 +74,31 @@ extern "C" { * * @param waiting_for_event is the thread waiting for event state. */ -void RtemsModelEventsMgr_Run( +void RtemsModelEventsMgr0_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 +); + +void RtemsModelEventsMgr1_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 +); + +void RtemsModelEventsMgr2_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 +); + +void RtemsModelEventsMgr3_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 * ), -- cgit v1.2.3