[PATCH 2/3] score: Add system events

Sebastian Huber sebastian.huber at embedded-brains.de
Fri Oct 26 15:42:30 UTC 2012


---
 cpukit/rtems/Makefile.am                           |    2 +
 cpukit/rtems/include/rtems/rtems/event.h           |  203 ++++++++++++++++++++
 cpukit/rtems/src/event.c                           |    1 +
 cpukit/rtems/src/systemeventreceive.c              |   68 +++++++
 cpukit/rtems/src/systemeventsend.c                 |   65 +++++++
 cpukit/rtems/src/tasks.c                           |    2 +
 cpukit/score/include/rtems/score/states.h          |    3 +
 cpukit/score/inline/rtems/score/states.inl         |   15 ++
 testsuites/sptests/Makefile.am                     |    2 +
 testsuites/sptests/configure.ac                    |    2 +
 testsuites/sptests/speventsystem01/Makefile.am     |   19 ++
 testsuites/sptests/speventsystem01/init.c          |  101 ++++++++++
 .../sptests/speventsystem01/speventsystem01.doc    |   14 ++
 .../sptests/speventsystem01/speventsystem01.scn    |    2 +
 testsuites/sptests/speventtransient01/Makefile.am  |   19 ++
 testsuites/sptests/speventtransient01/init.c       |  128 ++++++++++++
 .../speventtransient01/speventtransient01.doc      |   13 ++
 .../speventtransient01/speventtransient01.scn      |    2 +
 18 files changed, 661 insertions(+), 0 deletions(-)
 create mode 100644 cpukit/rtems/src/systemeventreceive.c
 create mode 100644 cpukit/rtems/src/systemeventsend.c
 create mode 100644 testsuites/sptests/speventsystem01/Makefile.am
 create mode 100644 testsuites/sptests/speventsystem01/init.c
 create mode 100644 testsuites/sptests/speventsystem01/speventsystem01.doc
 create mode 100644 testsuites/sptests/speventsystem01/speventsystem01.scn
 create mode 100644 testsuites/sptests/speventtransient01/Makefile.am
 create mode 100644 testsuites/sptests/speventtransient01/init.c
 create mode 100644 testsuites/sptests/speventtransient01/speventtransient01.doc
 create mode 100644 testsuites/sptests/speventtransient01/speventtransient01.scn

diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am
index bbf8611..ff3174e 100644
--- a/cpukit/rtems/Makefile.am
+++ b/cpukit/rtems/Makefile.am
@@ -209,6 +209,8 @@ librtems_a_SOURCES += src/eventsend.c
 librtems_a_SOURCES += src/eventsurrender.c
 librtems_a_SOURCES += src/eventtimeout.c
 librtems_a_SOURCES += src/eventdata.c
+librtems_a_SOURCES += src/systemeventsend.c
+librtems_a_SOURCES += src/systemeventreceive.c
 
 ## SIGNAL_C_FILES
 librtems_a_SOURCES += src/signal.c
diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h
index 381b328..355cf4a 100644
--- a/cpukit/rtems/include/rtems/rtems/event.h
+++ b/cpukit/rtems/include/rtems/rtems/event.h
@@ -207,6 +207,207 @@ rtems_status_code rtems_event_receive (
 /** @} */
 
 /**
+ * @defgroup ClassicEventSystem System Events
+ *
+ * @ingroup ClassicEvent
+ *
+ * System events are similar to normal events.  The offer a second set of
+ * events.  These events are intended for internal RTEMS use and should not be
+ * used by applications (with the exception of the transient system event).
+ *
+ * The event @ref RTEMS_SYSTEM_EVENT_TRANSIENT is used for transient usage.
+ * See also @ref ClassicEventTransient.  This event may be used by every entity
+ * that fulfils its usage pattern.
+ *
+ * @{
+ */
+
+/**
+ * @brief Reserved system event for transient usage.
+ */
+#define RTEMS_SYSTEM_EVENT_TRANSIENT RTEMS_EVENT_0
+
+/**
+ * @brief See rtems_event_send().
+ */
+rtems_status_code rtems_event_system_send(
+  rtems_id id,
+  rtems_event_set event_in
+);
+
+/**
+ * @brief See rtems_event_receive().
+ */
+rtems_status_code rtems_event_system_receive(
+  rtems_event_set event_in,
+  rtems_option option_set,
+  rtems_interval ticks,
+  rtems_event_set *event_out
+);
+
+/** @} */
+
+/**
+ * @defgroup ClassicEventTransient Transient Event
+ *
+ * @ingroup ClassicEvent
+ *
+ * The transient event can be used by a client task to issue a request to
+ * another task or interrupt service (server).  The server can send the
+ * transient event to the client task to notify about a request completion, see
+ * rtems_event_transient_send().  The client task can wait for the transient
+ * event reception with rtems_event_transient_receive().
+ *
+ * The user of the transient event must ensure that this event is not pending
+ * once the request is finished or cancelled.  A successful reception of the
+ * transient event with rtems_event_transient_receive() will clear the
+ * transient event.  If a reception with timeout is used the transient event
+ * state is undefined after a timeout return status.  The transient event can
+ * be cleared unconditionally with the non-blocking
+ * rtems_event_transient_clear().
+ *
+ * @msc
+ *   hscale="1.6";
+ *   M [label="Main Task"], IDLE [label="Idle Task"], S [label="Server"], TIME [label="System Tick Handler"];
+ *   |||;
+ *   --- [label="sequence with request completion"];
+ *   M box M [label="prepare request\nissue request\ncall rtems_event_transient_receive()"];
+ *   M=>>IDLE [label="blocking operation"];
+ *   IDLE=>>S [label="request completion"];
+ *   S box S [label="call rtems_event_transient_send()"];
+ *   S=>>M [label="task is ready again"];
+ *   M box M [label="finish request"];
+ *   |||;
+ *   --- [label="sequence with early request completion"];
+ *   M box M [label="prepare request\nissue request"];
+ *   M=>>S [label="request completion"];
+ *   S box S [label="call rtems_event_transient_send()"];
+ *   S=>>M [label="transient event is now pending"];
+ *   M box M [label="call rtems_event_transient_receive()\nfinish request"];
+ *   |||;
+ *   --- [label="sequence with timeout event"];
+ *   M box M [label="prepare request\nissue request\ncall rtems_event_transient_receive()"];
+ *   M=>>IDLE [label="blocking operation"];
+ *   IDLE=>>TIME [label="timeout expired"];
+ *   TIME box TIME [label="cancel blocking operation"];
+ *   TIME=>>M [label="task is ready again"];
+ *   M box M [label="cancel request\ncall rtems_event_transient_clear()"];
+ * @endmsc
+ *
+ * Suppose you have a task that wants to issue a certain request and then waits
+ * for request completion.  It can create a request structure and store its
+ * task identifier there.  Now it can place the request on a work queue of
+ * another task (or interrupt handler).  Afterwards the task waits for the
+ * reception of the transient event.  Once the server task is finished with the
+ * request it can send the transient event to the waiting task and wake it up.
+ *
+ * @code
+ * #include <assert.h>
+ * #include <rtems.h>
+ *
+ * typedef struct {
+ *   rtems_id task_id;
+ *   bool work_done;
+ * } request;
+ *
+ * void server(rtems_task_argument arg)
+ * {
+ *   rtems_status_code sc;
+ *   request *req = (request *) arg;
+ *
+ *   req->work_done = true;
+ *
+ *   sc = rtems_event_transient_send(req->task_id);
+ *   assert(sc == RTEMS_SUCCESSFUL);
+ *
+ *   sc = rtems_task_delete(RTEMS_SELF);
+ *   assert(sc == RTEMS_SUCCESSFUL);
+ * }
+ *
+ * void issue_request_and_wait_for_completion(void)
+ * {
+ *   rtems_status_code sc;
+ *   rtems_id id;
+ *   request req;
+ *
+ *   req.task_id = rtems_task_self();
+ *   req.work_done = false;
+ *
+ *   sc = rtems_task_create(
+ *     rtems_build_name('S', 'E', 'R', 'V'),
+ *     1,
+ *     RTEMS_MINIMUM_STACK_SIZE,
+ *     RTEMS_DEFAULT_MODES,
+ *     RTEMS_DEFAULT_ATTRIBUTES,
+ *     &id
+ *   );
+ *   assert(sc == RTEMS_SUCCESSFUL);
+ *
+ *   sc = rtems_task_start(id, server, (rtems_task_argument) &req);
+ *   assert(sc == RTEMS_SUCCESSFUL);
+ *
+ *   sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ *   assert(sc == RTEMS_SUCCESSFUL);
+ *
+ *   assert(req.work_done);
+ * }
+ * @endcode
+ *
+ * @{
+ */
+
+/**
+ * @brief See rtems_event_system_send().
+ *
+ * The system event @ref RTEMS_SYSTEM_EVENT_TRANSIENT will be sent.
+ */
+RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send(
+  rtems_id id
+)
+{
+  return rtems_event_system_send( id, RTEMS_SYSTEM_EVENT_TRANSIENT );
+}
+
+/**
+ * @brief See rtems_event_system_receive().
+ *
+ * The system event @ref RTEMS_SYSTEM_EVENT_TRANSIENT will be received.
+ */
+RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_receive(
+  rtems_option option_set,
+  rtems_interval ticks
+)
+{
+  rtems_event_set event_out;
+
+  return rtems_event_system_receive(
+    RTEMS_SYSTEM_EVENT_TRANSIENT,
+    RTEMS_EVENT_ALL | option_set,
+    ticks,
+    &event_out
+  );
+}
+
+/**
+ * @brief See rtems_event_system_receive().
+ *
+ * The system event @ref RTEMS_SYSTEM_EVENT_TRANSIENT will be cleared.
+ */
+RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void )
+{
+  rtems_event_set event_out;
+
+  rtems_event_system_receive(
+    RTEMS_SYSTEM_EVENT_TRANSIENT,
+    RTEMS_EVENT_ALL | RTEMS_NO_WAIT,
+    0,
+    &event_out
+  );
+}
+
+/** @} */
+
+/**
  *  @defgroup ScoreEvent Event Handler
  *
  *  @ingroup Score
@@ -252,6 +453,8 @@ void _Event_Timeout(
 
 RTEMS_EVENT_EXTERN Thread_blocking_operation_States _Event_Sync_state;
 
+RTEMS_EVENT_EXTERN Thread_blocking_operation_States _System_event_Sync_state;
+
 /** @} */
 
 #if defined(RTEMS_MULTIPROCESSING)
diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c
index ed148e8..d5c29f6 100644
--- a/cpukit/rtems/src/event.c
+++ b/cpukit/rtems/src/event.c
@@ -34,6 +34,7 @@
 void _Event_Manager_initialization( void )
 {
   _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
+  _System_event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
 
   /*
    *  Register the MP Process Packet routine.
diff --git a/cpukit/rtems/src/systemeventreceive.c b/cpukit/rtems/src/systemeventreceive.c
new file mode 100644
index 0000000..43f2bec
--- /dev/null
+++ b/cpukit/rtems/src/systemeventreceive.c
@@ -0,0 +1,68 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicEventSystem
+ *
+ * @brief rtems_event_system_receive() implementation.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/rtems/event.h>
+#include <rtems/rtems/tasks.h>
+
+rtems_status_code rtems_event_system_receive(
+  rtems_event_set  event_in,
+  rtems_option     option_set,
+  rtems_interval   ticks,
+  rtems_event_set *event_out
+)
+{
+  rtems_status_code sc;
+
+  if ( event_out != NULL ) {
+    Thread_Control    *executing = _Thread_Executing;
+    RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
+    Event_Control     *event = &api->System_event;
+
+    if ( !_Event_sets_Is_empty( event_in ) ) {
+      _Thread_Disable_dispatch();
+      _Event_Seize(
+        event_in,
+        option_set,
+        ticks,
+        event_out,
+        executing,
+        event,
+        &_System_event_Sync_state,
+        STATES_WAITING_FOR_SYSTEM_EVENT
+      );
+      _Thread_Enable_dispatch();
+
+      sc = executing->Wait.return_code;
+    } else {
+      *event_out = event->pending_events;
+      sc = RTEMS_SUCCESSFUL;
+    }
+  } else {
+    sc = RTEMS_INVALID_ADDRESS;
+  }
+
+  return sc;
+}
diff --git a/cpukit/rtems/src/systemeventsend.c b/cpukit/rtems/src/systemeventsend.c
new file mode 100644
index 0000000..13d31cc
--- /dev/null
+++ b/cpukit/rtems/src/systemeventsend.c
@@ -0,0 +1,65 @@
+/**
+ * @file
+ *
+ * @ingroup ClassicEventSystem
+ *
+ * @brief rtems_event_system_send() implementation.
+ */
+
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/rtems/event.h>
+#include <rtems/rtems/tasks.h>
+
+rtems_status_code rtems_event_system_send(
+  rtems_id        id,
+  rtems_event_set event_in
+)
+{
+  rtems_status_code  sc;
+  Thread_Control    *thread;
+  Objects_Locations  location;
+  RTEMS_API_Control *api;
+
+  thread = _Thread_Get( id, &location );
+  switch ( location ) {
+    case OBJECTS_LOCAL:
+      api = thread->API_Extensions[ THREAD_API_RTEMS ];
+      _Event_Surrender(
+        thread,
+        event_in,
+        &api->System_event,
+        &_System_event_Sync_state,
+        STATES_WAITING_FOR_SYSTEM_EVENT
+      );
+      _Thread_Enable_dispatch();
+      sc = RTEMS_SUCCESSFUL;
+      break;
+#ifdef RTEMS_MULTIPROCESSING
+    case OBJECTS_REMOTE:
+      sc = RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
+      break;
+#endif
+    default:
+      sc = RTEMS_INVALID_ID;
+      break;
+  }
+
+  return sc;
+}
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
index 325eba0..c679f1e 100644
--- a/cpukit/rtems/src/tasks.c
+++ b/cpukit/rtems/src/tasks.c
@@ -65,6 +65,7 @@ static bool _RTEMS_tasks_Create_extension(
   created->API_Extensions[ THREAD_API_RTEMS ] = api;
 
   _Event_Initialize( &api->Event );
+  _Event_Initialize( &api->System_event );
   _ASR_Initialize( &api->Signal );
   created->task_variables = NULL;
 
@@ -93,6 +94,7 @@ static void _RTEMS_tasks_Start_extension(
   api = started->API_Extensions[ THREAD_API_RTEMS ];
 
   _Event_Initialize( &api->Event );
+  _Event_Initialize( &api->System_event );
 }
 
 /*
diff --git a/cpukit/score/include/rtems/score/states.h b/cpukit/score/include/rtems/score/states.h
index eb4658e..f71bf93 100644
--- a/cpukit/score/include/rtems/score/states.h
+++ b/cpukit/score/include/rtems/score/states.h
@@ -81,6 +81,8 @@ typedef uint32_t   States_Control;
 #define STATES_WAITING_FOR_BARRIER             0x10000
 /** This macro corresponds to a task waiting for a RWLock. */
 #define STATES_WAITING_FOR_RWLOCK              0x20000
+/** This macro corresponds to a task waiting for a system event. */
+#define STATES_WAITING_FOR_SYSTEM_EVENT        0x40000
 
 /** This macro corresponds to a task which is in an interruptible
  *  blocking state.
@@ -110,6 +112,7 @@ typedef uint32_t   States_Control;
                                  STATES_WAITING_FOR_TIME        | \
                                  STATES_WAITING_FOR_PERIOD      | \
                                  STATES_WAITING_FOR_EVENT       | \
+                                 STATES_WAITING_FOR_SYSTEM_EVENT | \
                                  STATES_WAITING_ON_THREAD_QUEUE | \
                                  STATES_INTERRUPTIBLE_BY_SIGNAL )
 
diff --git a/cpukit/score/inline/rtems/score/states.inl b/cpukit/score/inline/rtems/score/states.inl
index 7bad0c9..f5d816a 100644
--- a/cpukit/score/inline/rtems/score/states.inl
+++ b/cpukit/score/inline/rtems/score/states.inl
@@ -213,6 +213,21 @@ RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_event (
 }
 
 /**
+ *  This function returns true if the WAITING_FOR_SYSTEM_EVENT state is set in
+ *  the_states, and false otherwise.
+ *
+ *  @param[in] the_states is the task state set to test
+ *
+ *  @return This method returns true if the desired state condition is set.
+ */
+RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_system_event (
+  States_Control the_states
+)
+{
+   return (the_states & STATES_WAITING_FOR_SYSTEM_EVENT);
+}
+
+/**
  *  This function returns true if the WAITING_FOR_MUTEX state
  *  is set in the_states, and false otherwise.
  *
diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am
index a0dc24a..dd79451 100644
--- a/testsuites/sptests/Makefile.am
+++ b/testsuites/sptests/Makefile.am
@@ -28,6 +28,8 @@ SUBDIRS = \
     spsimplesched01 spsimplesched02 spsimplesched03 spnsext01 \
     spedfsched01 spedfsched02 spedfsched03 \
     spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01
+SUBDIRS += speventtransient01
+SUBDIRS += speventsystem01
 
 include $(top_srcdir)/../automake/subdirs.am
 include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac
index 32063e2..5bee64c 100644
--- a/testsuites/sptests/configure.ac
+++ b/testsuites/sptests/configure.ac
@@ -27,6 +27,8 @@ AC_CHECK_SIZEOF([time_t])
 
 # Explicitly list all Makefiles here
 AC_CONFIG_FILES([Makefile
+speventsystem01/Makefile
+speventtransient01/Makefile
 spintrcritical18/Makefile
 sp01/Makefile
 sp02/Makefile
diff --git a/testsuites/sptests/speventsystem01/Makefile.am b/testsuites/sptests/speventsystem01/Makefile.am
new file mode 100644
index 0000000..f3a49ef
--- /dev/null
+++ b/testsuites/sptests/speventsystem01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = speventsystem01
+speventsystem01_SOURCES = init.c
+
+dist_rtems_tests_DATA = speventsystem01.scn speventsystem01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(speventsystem01_OBJECTS)
+LINK_LIBS = $(speventsystem01_LDLIBS)
+
+speventsystem01$(EXEEXT): $(speventsystem01_OBJECTS) $(speventsystem01_DEPENDENCIES)
+	@rm -f speventsystem01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/speventsystem01/init.c b/testsuites/sptests/speventsystem01/init.c
new file mode 100644
index 0000000..4c919f7
--- /dev/null
+++ b/testsuites/sptests/speventsystem01/init.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tmacros.h"
+
+#define EVENT RTEMS_EVENT_0
+
+static void test_with_normal_and_system_event(void)
+{
+  rtems_status_code sc;
+  rtems_event_set out;
+
+  /* Assert no events pending */
+
+  sc = rtems_event_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  /* Send system event */
+
+  sc = rtems_event_system_send(rtems_task_self(), EVENT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_event_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  out = 0;
+  sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+  rtems_test_assert(out == EVENT);
+
+  /* Send normal event */
+
+  sc = rtems_event_send(rtems_task_self(), EVENT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  out = 0;
+  sc = rtems_event_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+  rtems_test_assert(out == EVENT);
+
+  sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+}
+
+static void test_with_timeout(void)
+{
+  rtems_status_code sc;
+  rtems_event_set out;
+
+  sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  sc = rtems_event_system_receive(EVENT, RTEMS_WAIT, 1, &out);
+  rtems_test_assert(sc == RTEMS_TIMEOUT);
+
+  sc = rtems_event_system_receive(EVENT, RTEMS_NO_WAIT, 0, &out);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+}
+
+static void Init(rtems_task_argument arg)
+{
+  puts("\n\n*** TEST SPEVENTSYSTEM 1 ***");
+
+  test_with_normal_and_system_event();
+  test_with_timeout();
+
+  puts("*** END OF TEST SPEVENTSYSTEM 1 ***");
+
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/speventsystem01/speventsystem01.doc b/testsuites/sptests/speventsystem01/speventsystem01.doc
new file mode 100644
index 0000000..b1f7427
--- /dev/null
+++ b/testsuites/sptests/speventsystem01/speventsystem01.doc
@@ -0,0 +1,14 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: speventsystem01
+
+directives:
+
+  - rtems_event_send()
+  - rtems_event_receive()
+  - rtems_event_system_send()
+  - rtems_event_system_receive()
+
+concepts:
+
+  Ensure that the Classic System Events works.
diff --git a/testsuites/sptests/speventsystem01/speventsystem01.scn b/testsuites/sptests/speventsystem01/speventsystem01.scn
new file mode 100644
index 0000000..90ddfe7
--- /dev/null
+++ b/testsuites/sptests/speventsystem01/speventsystem01.scn
@@ -0,0 +1,2 @@
+*** TEST SPEVENTSYSTEM 1 ***
+*** END OF TEST SPEVENTSYSTEM 1 ***
diff --git a/testsuites/sptests/speventtransient01/Makefile.am b/testsuites/sptests/speventtransient01/Makefile.am
new file mode 100644
index 0000000..d8aa2b5
--- /dev/null
+++ b/testsuites/sptests/speventtransient01/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = speventtransient01
+speventtransient01_SOURCES = init.c
+
+dist_rtems_tests_DATA = speventtransient01.scn speventtransient01.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(speventtransient01_OBJECTS)
+LINK_LIBS = $(speventtransient01_LDLIBS)
+
+speventtransient01$(EXEEXT): $(speventtransient01_OBJECTS) $(speventtransient01_DEPENDENCIES)
+	@rm -f speventtransient01$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/sptests/speventtransient01/init.c b/testsuites/sptests/speventtransient01/init.c
new file mode 100644
index 0000000..b885ba6
--- /dev/null
+++ b/testsuites/sptests/speventtransient01/init.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tmacros.h"
+
+typedef struct {
+  rtems_id client;
+  bool complete;
+} request;
+
+static void server_task(rtems_task_argument arg)
+{
+  rtems_status_code sc;
+  request *req = (request *) arg;
+
+  req->complete = true;
+
+  sc = rtems_event_transient_send(req->client);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_delete(RTEMS_SELF);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void test_with_request_server(void)
+{
+  rtems_status_code sc;
+  rtems_id id;
+  request req;
+
+  sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  req.client = rtems_task_self();
+  req.complete = false;
+
+  sc = rtems_task_create(
+    rtems_build_name('S', 'E', 'R', 'V'),
+    1,
+    RTEMS_MINIMUM_STACK_SIZE,
+    RTEMS_DEFAULT_MODES,
+    RTEMS_DEFAULT_ATTRIBUTES,
+    &id
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_task_start(id, server_task, (rtems_task_argument) &req);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(req.complete);
+}
+
+static void test_with_request_self(void)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  sc = rtems_event_transient_send(rtems_task_self());
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_event_transient_clear();
+
+  sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+}
+
+static void test_with_timeout(void)
+{
+  rtems_status_code sc;
+
+  sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+
+  sc = rtems_event_transient_receive(RTEMS_WAIT, 1);
+  rtems_test_assert(sc == RTEMS_TIMEOUT);
+
+  sc = rtems_event_transient_receive(RTEMS_NO_WAIT, 0);
+  rtems_test_assert(sc == RTEMS_UNSATISFIED);
+}
+
+static void Init(rtems_task_argument arg)
+{
+  puts("\n\n*** TEST SPEVENTTRANSIENT 1 ***");
+
+  test_with_request_server();
+  test_with_request_self();
+  test_with_timeout();
+
+  puts("*** END OF TEST SPEVENTTRANSIENT 1 ***");
+
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 2
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/sptests/speventtransient01/speventtransient01.doc b/testsuites/sptests/speventtransient01/speventtransient01.doc
new file mode 100644
index 0000000..6b41902
--- /dev/null
+++ b/testsuites/sptests/speventtransient01/speventtransient01.doc
@@ -0,0 +1,13 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: speventtransient01
+
+directives:
+
+  - rtems_event_transient_send()
+  - rtems_event_transient_receive()
+  - rtems_event_transient_clear()
+
+concepts:
+
+  Ensure that the Classic Transient Event works.
diff --git a/testsuites/sptests/speventtransient01/speventtransient01.scn b/testsuites/sptests/speventtransient01/speventtransient01.scn
new file mode 100644
index 0000000..03df8da
--- /dev/null
+++ b/testsuites/sptests/speventtransient01/speventtransient01.scn
@@ -0,0 +1,2 @@
+*** TEST SPEVENTTRANSIENT 1 ***
+*** END OF TEST SPEVENTTRANSIENT 1 ***
-- 
1.7.7




More information about the devel mailing list