diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-10-26 10:05:07 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-10-30 18:03:02 +0100 |
commit | 0edf263139088e8ac0ff1f0d52513f6fc85677d2 (patch) | |
tree | 62f376215aa7ae30aa77e9386c2191ae20b70258 | |
parent | rtems: Reusable event implementation (diff) | |
download | rtems-0edf263139088e8ac0ff1f0d52513f6fc85677d2.tar.bz2 |
rtems: Add system events
System events are similar to normal events. They 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).
19 files changed, 663 insertions, 0 deletions
diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index bbf861177e..ff3174ebbc 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 381b328de2..b8d9987848 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. They 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_EVENT_SYSTEM_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_EVENT_SYSTEM_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_EVENT_SYSTEM_TRANSIENT will be sent. + */ +RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send( + rtems_id id +) +{ + return rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TRANSIENT ); +} + +/** + * @brief See rtems_event_system_receive(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_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_EVENT_SYSTEM_TRANSIENT, + RTEMS_EVENT_ALL | option_set, + ticks, + &event_out + ); +} + +/** + * @brief See rtems_event_system_receive(). + * + * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be cleared. + */ +RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void ) +{ + rtems_event_set event_out; + + rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_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/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h index d11e0bc522..f141c102e6 100644 --- a/cpukit/rtems/include/rtems/rtems/tasks.h +++ b/cpukit/rtems/include/rtems/rtems/tasks.h @@ -212,6 +212,8 @@ typedef struct { typedef struct { /** This field contains the event control for this task. */ Event_Control Event; + /** This field contains the system event control for this task. */ + Event_Control System_event; /** This field contains the Classic API Signal information for this task. */ ASR_Information Signal; /** diff --git a/cpukit/rtems/src/event.c b/cpukit/rtems/src/event.c index ed148e8b37..d5c29f6a3e 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 0000000000..43f2bec048 --- /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@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 0000000000..13d31ccf85 --- /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@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 325eba0546..c679f1e6f2 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 eb4658e3be..f71bf9399e 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 7bad0c9f12..f5d816a8d3 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 a0dc24af36..dd79451dab 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 32063e2221..5bee64c92d 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 0000000000..f3a49ef8f9 --- /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@.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 0000000000..4c919f70a8 --- /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@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 0000000000..1d27b1a871 --- /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 work. diff --git a/testsuites/sptests/speventsystem01/speventsystem01.scn b/testsuites/sptests/speventsystem01/speventsystem01.scn new file mode 100644 index 0000000000..90ddfe7203 --- /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 0000000000..d8aa2b5250 --- /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@.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 0000000000..b885ba6032 --- /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@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 0000000000..6b4190259c --- /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 0000000000..03df8da9e1 --- /dev/null +++ b/testsuites/sptests/speventtransient01/speventtransient01.scn @@ -0,0 +1,2 @@ +*** TEST SPEVENTTRANSIENT 1 *** +*** END OF TEST SPEVENTTRANSIENT 1 *** |