summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Butterfield <Andrew.Butterfield@scss.tcd.ie>2020-12-09 15:10:24 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-07-12 15:09:24 +0200
commit0f8077b2587af83c6ec0e434a565372b00961727 (patch)
treec3cfc9c9fbc17c67da81dc1bbc03fd64337fe689
parent297ba8fa1bc68aee79d8972097e7ba57e0f3fc53 (diff)
Adds four test runner files, all work
-rw-r--r--spec/build/testsuites/validation/model-0.yml5
-rw-r--r--[-rwxr-xr-x]testsuites/validation/tc-model-events-mgr.c74
-rw-r--r--testsuites/validation/tr-model-events-mgr-0.c550
-rw-r--r--testsuites/validation/tr-model-events-mgr-1.c550
-rw-r--r--testsuites/validation/tr-model-events-mgr-2.c550
-rw-r--r--testsuites/validation/tr-model-events-mgr-3.c550
-rw-r--r--[-rwxr-xr-x]testsuites/validation/tr-model-events-mgr.c280
-rw-r--r--[-rwxr-xr-x]testsuites/validation/tr-model-events-mgr.h26
8 files changed, 2384 insertions, 201 deletions
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
index a58ec6e8c8..08097467db 100755..100644
--- 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 <rtems/score/threadimpl.h>
+
+#include "tr-model-events-mgr.h"
+
+#include <rtems/test.h>
+
+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 <rtems/score/threadimpl.h>
+
+#include "tr-model-events-mgr.h"
+
+#include <rtems/test.h>
+
+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 <rtems/score/threadimpl.h>
+
+#include "tr-model-events-mgr.h"
+
+#include <rtems/test.h>
+
+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 <rtems/score/threadimpl.h>
+
+#include "tr-model-events-mgr.h"
+
+#include <rtems/test.h>
+
+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
index b677fb3c82..4bb8f9773d 100755..100644
--- 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
index 95678e2ee1..94daaa5c79 100755..100644
--- 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 * ),