[PATCH 1/3] rtems: Reusable event implementation
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Oct 26 15:42:29 UTC 2012
Change event implementation to enable reuse for system events.
---
cpukit/libmisc/monitor/mon-task.c | 2 +-
cpukit/rtems/include/rtems/rtems/event.h | 62 +++++++--------------
cpukit/rtems/include/rtems/rtems/tasks.h | 10 ++--
cpukit/rtems/inline/rtems/rtems/event.inl | 5 ++
cpukit/rtems/inline/rtems/rtems/eventset.inl | 7 +--
cpukit/rtems/src/eventreceive.c | 63 +++++++++------------
cpukit/rtems/src/eventseize.c | 76 ++++++++------------------
cpukit/rtems/src/eventsend.c | 71 +++++++++---------------
cpukit/rtems/src/eventsurrender.c | 70 +++++++++---------------
cpukit/rtems/src/tasks.c | 5 +-
10 files changed, 139 insertions(+), 232 deletions(-)
diff --git a/cpukit/libmisc/monitor/mon-task.c b/cpukit/libmisc/monitor/mon-task.c
index d468956..c728df2 100644
--- a/cpukit/libmisc/monitor/mon-task.c
+++ b/cpukit/libmisc/monitor/mon-task.c
@@ -30,7 +30,7 @@ rtems_monitor_task_canonical(
canonical_task->priority = rtems_thread->current_priority;
canonical_task->state = rtems_thread->current_state;
canonical_task->wait_id = rtems_thread->Wait.id;
- canonical_task->events = api->pending_events;
+ canonical_task->events = api->Event.pending_events;
/*
* FIXME: make this optionally cpu_time_executed
*/
diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h
index 5280c94..381b328 100644
--- a/cpukit/rtems/include/rtems/rtems/event.h
+++ b/cpukit/rtems/include/rtems/rtems/event.h
@@ -214,63 +214,43 @@ rtems_status_code rtems_event_receive (
* @{
*/
+typedef struct {
+ rtems_event_set pending_events;
+} Event_Control;
+
/**
* This constant is passed as the event_in to the
* rtems_event_receive directive to determine which events are pending.
*/
#define EVENT_CURRENT 0
-/**
- * @brief Event_Manager_initialization
- *
- * This routine performs the initialization necessary for this manager.
- */
void _Event_Manager_initialization( void );
-/**
- * @brief Event_Seize
- *
- * This routine determines if the event condition event_in is
- * satisfied. If so or if the no_wait option is enabled in option_set,
- * then the procedure returns immediately. If neither of these
- * conditions is true, then the calling task is blocked with an
- * optional timeout of ticks clock ticks.
- */
-void _Event_Seize (
- rtems_event_set event_in,
- rtems_option option_set,
- rtems_interval ticks,
- rtems_event_set *event_out
+void _Event_Seize(
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out,
+ Thread_Control *executing,
+ Event_Control *event,
+ Thread_blocking_operation_States *sync_state,
+ States_Control wait_state
);
-/**
- * @brief Event_Surrender
- *
- * This routine determines if the event condition of the_thread
- * has been satisfied. If so, it unblocks the_thread.
- */
-void _Event_Surrender (
- Thread_Control *the_thread
+void _Event_Surrender(
+ Thread_Control *the_thread,
+ rtems_event_set event_in,
+ Event_Control *event,
+ Thread_blocking_operation_States *sync_state,
+ States_Control wait_state
);
-/**
- * @brief Event_Timeout
- *
- * This routine is invoked when a task's event receive request
- * has not been satisfied after the specified timeout interval.
- * The task represented by ID will be unblocked and its status
- * code will be set in it's control block to indicate that a timeout
- * has occurred.
- */
-void _Event_Timeout (
+void _Event_Timeout(
Objects_Id id,
void *ignored
);
-/**
- * @brief he following defines the synchronization flag used by the
- */
-RTEMS_EVENT_EXTERN volatile Thread_blocking_operation_States _Event_Sync_state;
+RTEMS_EVENT_EXTERN Thread_blocking_operation_States _Event_Sync_state;
/** @} */
diff --git a/cpukit/rtems/include/rtems/rtems/tasks.h b/cpukit/rtems/include/rtems/rtems/tasks.h
index b6f51a1..f141c10 100644
--- a/cpukit/rtems/include/rtems/rtems/tasks.h
+++ b/cpukit/rtems/include/rtems/rtems/tasks.h
@@ -38,7 +38,7 @@
#include <rtems/score/states.h>
#include <rtems/score/thread.h>
#include <rtems/rtems/types.h>
-#include <rtems/rtems/eventset.h>
+#include <rtems/rtems/event.h>
#include <rtems/rtems/asr.h>
#include <rtems/rtems/attr.h>
#include <rtems/rtems/status.h>
@@ -210,10 +210,10 @@ typedef struct {
* notespads are disabled by the application configuration.
*/
typedef struct {
- /** This field contains the pending events for this task. */
- rtems_event_set pending_events;
- /** This field contains the event wait condition for this task. */
- rtems_event_set event_condition;
+ /** 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/inline/rtems/rtems/event.inl b/cpukit/rtems/inline/rtems/rtems/event.inl
index 320eee8..32999fa 100644
--- a/cpukit/rtems/inline/rtems/rtems/event.inl
+++ b/cpukit/rtems/inline/rtems/rtems/event.inl
@@ -25,6 +25,11 @@
* @{
*/
+RTEMS_INLINE_ROUTINE void _Event_Initialize( Event_Control *event )
+{
+ event->pending_events = EVENT_SETS_NONE_PENDING;
+}
+
/**@}*/
#endif
diff --git a/cpukit/rtems/inline/rtems/rtems/eventset.inl b/cpukit/rtems/inline/rtems/rtems/eventset.inl
index 4e11e81..22919ea 100644
--- a/cpukit/rtems/inline/rtems/rtems/eventset.inl
+++ b/cpukit/rtems/inline/rtems/rtems/eventset.inl
@@ -20,7 +20,6 @@
#define _RTEMS_RTEMS_EVENTSET_INL
#include <rtems/score/basedefs.h> /* RTEMS_INLINE_ROUTINE */
-#include <rtems/score/isr.h> /* ISR_Level */
/**
* @addtogroup ScoreEvent
@@ -51,11 +50,7 @@ RTEMS_INLINE_ROUTINE void _Event_sets_Post(
rtems_event_set *the_event_set
)
{
- ISR_Level level;
-
- _ISR_Disable( level );
- *the_event_set |= the_new_events;
- _ISR_Enable( level );
+ *the_event_set |= the_new_events;
}
/**
diff --git a/cpukit/rtems/src/eventreceive.c b/cpukit/rtems/src/eventreceive.c
index 48568eb..0361d2c 100644
--- a/cpukit/rtems/src/eventreceive.c
+++ b/cpukit/rtems/src/eventreceive.c
@@ -10,36 +10,12 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/rtems/status.h>
#include <rtems/rtems/event.h>
-#include <rtems/score/isr.h>
-#include <rtems/score/object.h>
-#include <rtems/rtems/options.h>
-#include <rtems/score/states.h>
-#include <rtems/score/thread.h>
#include <rtems/rtems/tasks.h>
-/*
- * rtems_event_receive
- *
- * This directive allows a thread to receive a set of events.
- *
- * Input parameters:
- * event_in - input event condition
- * option_set - options
- * ticks - number of ticks to wait (0 means wait forever)
- * event_out - pointer to output event set
- *
- * Output parameters:
- * event out - event set
- * RTEMS_SUCCESSFUL - if successful
- * error code - if unsuccessful
- */
-
rtems_status_code rtems_event_receive(
rtems_event_set event_in,
rtems_option option_set,
@@ -47,20 +23,35 @@ rtems_status_code rtems_event_receive(
rtems_event_set *event_out
)
{
- RTEMS_API_Control *api;
+ rtems_status_code sc;
- if ( !event_out )
- return RTEMS_INVALID_ADDRESS;
+ if ( event_out != NULL ) {
+ Thread_Control *executing = _Thread_Executing;
+ RTEMS_API_Control *api = executing->API_Extensions[ THREAD_API_RTEMS ];
+ Event_Control *event = &api->Event;
- api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
+ if ( !_Event_sets_Is_empty( event_in ) ) {
+ _Thread_Disable_dispatch();
+ _Event_Seize(
+ event_in,
+ option_set,
+ ticks,
+ event_out,
+ executing,
+ event,
+ &_Event_Sync_state,
+ STATES_WAITING_FOR_EVENT
+ );
+ _Thread_Enable_dispatch();
- if ( _Event_sets_Is_empty( event_in ) ) {
- *event_out = api->pending_events;
- return RTEMS_SUCCESSFUL;
+ sc = executing->Wait.return_code;
+ } else {
+ *event_out = event->pending_events;
+ sc = RTEMS_SUCCESSFUL;
+ }
+ } else {
+ sc = RTEMS_INVALID_ADDRESS;
}
- _Thread_Disable_dispatch();
- _Event_Seize( event_in, option_set, ticks, event_out );
- _Thread_Enable_dispatch();
- return( _Thread_Executing->Wait.return_code );
+ return sc;
}
diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c
index b1ad80d..ab92d12 100644
--- a/cpukit/rtems/src/eventseize.c
+++ b/cpukit/rtems/src/eventseize.c
@@ -10,66 +10,36 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/rtems/status.h>
#include <rtems/rtems/event.h>
-#include <rtems/score/isr.h>
-#include <rtems/score/object.h>
-#include <rtems/rtems/options.h>
-#include <rtems/score/states.h>
-#include <rtems/score/thread.h>
-#include <rtems/rtems/tasks.h>
-
-/*
- * _Event_Seize
- *
- * This routine attempts to satisfy the requested event condition
- * for the running thread.
- *
- * Input parameters:
- * event_in - the event condition to satisfy
- * option_set - acquire event options
- * ticks - interval to wait
- * event_out - pointer to event set output area
- *
- * Output parameters: NONE
- * *event_out - event set output area filled in
- *
- * INTERRUPT LATENCY:
- * available
- * wait
- * check sync
- */
void _Event_Seize(
- rtems_event_set event_in,
- rtems_option option_set,
- rtems_interval ticks,
- rtems_event_set *event_out
+ rtems_event_set event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out,
+ Thread_Control *executing,
+ Event_Control *event,
+ Thread_blocking_operation_States *sync_state,
+ States_Control wait_state
)
{
- Thread_Control *executing;
- rtems_event_set seized_events;
- rtems_event_set pending_events;
- ISR_Level level;
- RTEMS_API_Control *api;
- Thread_blocking_operation_States sync_state;
+ rtems_event_set seized_events;
+ rtems_event_set pending_events;
+ ISR_Level level;
+ Thread_blocking_operation_States current_sync_state;
- executing = _Thread_Executing;
executing->Wait.return_code = RTEMS_SUCCESSFUL;
- api = executing->API_Extensions[ THREAD_API_RTEMS ];
-
_ISR_Disable( level );
- pending_events = api->pending_events;
+ pending_events = event->pending_events;
seized_events = _Event_sets_Get( pending_events, event_in );
if ( !_Event_sets_Is_empty( seized_events ) &&
(seized_events == event_in || _Options_Is_any( option_set )) ) {
- api->pending_events =
+ event->pending_events =
_Event_sets_Clear( pending_events, seized_events );
_ISR_Enable( level );
*event_out = seized_events;
@@ -91,11 +61,11 @@ void _Event_Seize(
* NOTE: Since interrupts are disabled, this isn't that much of an
* issue but better safe than sorry.
*/
- executing->Wait.option = (uint32_t) option_set;
- executing->Wait.count = (uint32_t) event_in;
+ executing->Wait.option = option_set;
+ executing->Wait.count = event_in;
executing->Wait.return_argument = event_out;
- _Event_Sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
+ *sync_state = THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
_ISR_Enable( level );
@@ -109,13 +79,13 @@ void _Event_Seize(
_Watchdog_Insert_ticks( &executing->Timer, ticks );
}
- _Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
+ _Thread_Set_state( executing, wait_state );
_ISR_Disable( level );
- sync_state = _Event_Sync_state;
- _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
- if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
+ current_sync_state = *sync_state;
+ *sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
+ if ( current_sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
_ISR_Enable( level );
return;
}
@@ -127,5 +97,5 @@ void _Event_Seize(
* WARNING! Entering with interrupts disabled and returning with interrupts
* enabled!
*/
- _Thread_blocking_operation_Cancel( sync_state, executing, level );
+ _Thread_blocking_operation_Cancel( current_sync_state, executing, level );
}
diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c
index cc06cfa..8f0b027 100644
--- a/cpukit/rtems/src/eventsend.c
+++ b/cpukit/rtems/src/eventsend.c
@@ -10,66 +10,49 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/rtems/status.h>
#include <rtems/rtems/event.h>
-#include <rtems/score/isr.h>
-#include <rtems/score/object.h>
-#include <rtems/rtems/options.h>
-#include <rtems/score/states.h>
-#include <rtems/score/thread.h>
#include <rtems/rtems/tasks.h>
-/*
- * rtems_event_send
- *
- * This directive allows a thread send an event set to another thread.
- *
- * Input parameters:
- * id - thread id
- * event - event set
- *
- * Output parameters:
- * RTEMS_SUCCESSFUL - if successful
- * error code - if unsuccessful
- */
-
rtems_status_code rtems_event_send(
- rtems_id id,
- rtems_event_set event_in
+ rtems_id id,
+ rtems_event_set event_in
)
{
- register Thread_Control *the_thread;
- Objects_Locations location;
- RTEMS_API_Control *api;
+ rtems_status_code sc;
+ Thread_Control *thread;
+ Objects_Locations location;
+ RTEMS_API_Control *api;
- the_thread = _Thread_Get( id, &location );
+ thread = _Thread_Get( id, &location );
switch ( location ) {
-
case OBJECTS_LOCAL:
- api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
- _Event_sets_Post( event_in, &api->pending_events );
- _Event_Surrender( the_thread );
+ api = thread->API_Extensions[ THREAD_API_RTEMS ];
+ _Event_Surrender(
+ thread,
+ event_in,
+ &api->Event,
+ &_Event_Sync_state,
+ STATES_WAITING_FOR_EVENT
+ );
_Thread_Enable_dispatch();
- return RTEMS_SUCCESSFUL;
-
-#if defined(RTEMS_MULTIPROCESSING)
+ sc = RTEMS_SUCCESSFUL;
+ break;
+#ifdef RTEMS_MULTIPROCESSING
case OBJECTS_REMOTE:
- return(
- _Event_MP_Send_request_packet(
- EVENT_MP_SEND_REQUEST,
- id,
- event_in
- )
+ sc = _Event_MP_Send_request_packet(
+ EVENT_MP_SEND_REQUEST,
+ id,
+ event_in
);
+ break;
#endif
-
- case OBJECTS_ERROR:
+ default:
+ sc = RTEMS_INVALID_ID;
break;
}
- return RTEMS_INVALID_ID;
+ return sc;
}
diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c
index 9761c78..28cc91a 100644
--- a/cpukit/rtems/src/eventsurrender.c
+++ b/cpukit/rtems/src/eventsurrender.c
@@ -10,53 +10,31 @@
*/
#if HAVE_CONFIG_H
-#include "config.h"
+ #include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/rtems/status.h>
#include <rtems/rtems/event.h>
-#include <rtems/score/isr.h>
-#include <rtems/score/object.h>
-#include <rtems/rtems/options.h>
-#include <rtems/score/states.h>
-#include <rtems/score/thread.h>
-#include <rtems/rtems/tasks.h>
-
-/*
- * _Event_Surrender
- *
- * This routines remove a thread from the specified threadq.
- *
- * Input parameters:
- * the_thread - pointer to thread to be dequeued
- *
- * Output parameters: NONE
- *
- * INTERRUPT LATENCY:
- * before flash
- * after flash
- * check sync
- */
void _Event_Surrender(
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ rtems_event_set event_in,
+ Event_Control *event,
+ Thread_blocking_operation_States *sync_state,
+ States_Control wait_state
)
{
- ISR_Level level;
- rtems_event_set pending_events;
- rtems_event_set event_condition;
- rtems_event_set seized_events;
- rtems_option option_set;
- RTEMS_API_Control *api;
-
- api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
+ ISR_Level level;
+ rtems_event_set pending_events;
+ rtems_event_set event_condition;
+ rtems_event_set seized_events;
+ rtems_option option_set;
- option_set = (rtems_option) the_thread->Wait.option;
+ option_set = the_thread->Wait.option;
_ISR_Disable( level );
- pending_events = api->pending_events;
- event_condition = (rtems_event_set) the_thread->Wait.count;
+ _Event_sets_Post( event_in, &event->pending_events );
+ pending_events = event->pending_events;
+ event_condition = the_thread->Wait.count;
seized_events = _Event_sets_Get( pending_events, event_condition );
@@ -74,13 +52,16 @@ void _Event_Surrender(
*/
if ( _ISR_Is_in_progress() &&
_Thread_Is_executing( the_thread ) &&
- ((_Event_Sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT) ||
- (_Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED)) ) {
+ ((*sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT) ||
+ (*sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED)) ) {
if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
- api->pending_events = _Event_sets_Clear( pending_events,seized_events );
+ event->pending_events = _Event_sets_Clear(
+ pending_events,
+ seized_events
+ );
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
- _Event_Sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
+ *sync_state = THREAD_BLOCKING_OPERATION_SATISFIED;
}
_ISR_Enable( level );
return;
@@ -89,9 +70,12 @@ void _Event_Surrender(
/*
* Otherwise, this is a normal send to another thread
*/
- if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
+ if ( _States_Are_set( the_thread->current_state, wait_state ) ) {
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
- api->pending_events = _Event_sets_Clear( pending_events, seized_events );
+ event->pending_events = _Event_sets_Clear(
+ pending_events,
+ seized_events
+ );
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c
index 663a02c..325eba0 100644
--- a/cpukit/rtems/src/tasks.c
+++ b/cpukit/rtems/src/tasks.c
@@ -64,8 +64,7 @@ static bool _RTEMS_tasks_Create_extension(
created->API_Extensions[ THREAD_API_RTEMS ] = api;
- api->pending_events = EVENT_SETS_NONE_PENDING;
- api->event_condition = 0;
+ _Event_Initialize( &api->Event );
_ASR_Initialize( &api->Signal );
created->task_variables = NULL;
@@ -93,7 +92,7 @@ static void _RTEMS_tasks_Start_extension(
api = started->API_Extensions[ THREAD_API_RTEMS ];
- api->pending_events = EVENT_SETS_NONE_PENDING;
+ _Event_Initialize( &api->Event );
}
/*
--
1.7.7
More information about the devel
mailing list