[PATCH 1/3] rtems: Reusable event implementation
Sebastian Huber
sebastian.huber at embedded-brains.de
Wed Oct 24 16:11:31 UTC 2012
Change event implementation to enable reuse for system events.
---
cpukit/rtems/include/rtems/rtems/event.h | 46 ++++-------------
cpukit/rtems/inline/rtems/rtems/eventset.inl | 7 +--
cpukit/rtems/src/eventreceive.c | 15 +++++-
cpukit/rtems/src/eventseize.c | 70 +++++++------------------
cpukit/rtems/src/eventsend.c | 9 +++-
cpukit/rtems/src/eventsurrender.c | 61 ++++++++---------------
6 files changed, 73 insertions(+), 135 deletions(-)
diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h
index 5280c94..dc7f445 100644
--- a/cpukit/rtems/include/rtems/rtems/event.h
+++ b/cpukit/rtems/include/rtems/rtems/event.h
@@ -220,57 +220,33 @@ rtems_status_code rtems_event_receive (
*/
#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
+ rtems_event_set *event_out,
+ Thread_Control *executing,
+ rtems_event_set *pending_events,
+ 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
+ Thread_Control *the_thread,
+ rtems_event_set event_in,
+ rtems_event_set *pending_events,
+ 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 (
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/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..f82e12d 100644
--- a/cpukit/rtems/src/eventreceive.c
+++ b/cpukit/rtems/src/eventreceive.c
@@ -47,12 +47,14 @@ rtems_status_code rtems_event_receive(
rtems_event_set *event_out
)
{
+ Thread_Control *executing;
RTEMS_API_Control *api;
if ( !event_out )
return RTEMS_INVALID_ADDRESS;
- api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
+ executing = _Thread_Executing;
+ api = executing->API_Extensions[ THREAD_API_RTEMS ];
if ( _Event_sets_Is_empty( event_in ) ) {
*event_out = api->pending_events;
@@ -60,7 +62,16 @@ rtems_status_code rtems_event_receive(
}
_Thread_Disable_dispatch();
- _Event_Seize( event_in, option_set, ticks, event_out );
+ _Event_Seize(
+ event_in,
+ option_set,
+ ticks,
+ event_out,
+ executing,
+ &api->pending_events,
+ &_Event_Sync_state,
+ STATES_WAITING_FOR_EVENT
+ );
_Thread_Enable_dispatch();
return( _Thread_Executing->Wait.return_code );
}
diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c
index b1ad80d..158b175 100644
--- a/cpukit/rtems/src/eventseize.c
+++ b/cpukit/rtems/src/eventseize.c
@@ -10,67 +10,37 @@
*/
#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_out,
+ Thread_Control *executing,
+ rtems_event_set *pending_events,
+ Thread_blocking_operation_States *sync_state,
+ States_Control wait_state
)
{
- Thread_Control *executing;
rtems_event_set seized_events;
- rtems_event_set pending_events;
+ rtems_event_set current_pending_events;
ISR_Level level;
- RTEMS_API_Control *api;
- Thread_blocking_operation_States sync_state;
+ 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;
- seized_events = _Event_sets_Get( pending_events, event_in );
+ current_pending_events = *pending_events;
+ seized_events = _Event_sets_Get( current_pending_events, event_in );
if ( !_Event_sets_Is_empty( seized_events ) &&
(seized_events == event_in || _Options_Is_any( option_set )) ) {
- api->pending_events =
- _Event_sets_Clear( pending_events, seized_events );
+ *pending_events =
+ _Event_sets_Clear( current_pending_events, seized_events );
_ISR_Enable( level );
*event_out = seized_events;
return;
@@ -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..372f941 100644
--- a/cpukit/rtems/src/eventsend.c
+++ b/cpukit/rtems/src/eventsend.c
@@ -51,8 +51,13 @@ rtems_status_code rtems_event_send(
case OBJECTS_LOCAL:
api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
- _Event_sets_Post( event_in, &api->pending_events );
- _Event_Surrender( the_thread );
+ _Event_Surrender(
+ the_thread,
+ event_in,
+ &api->pending_events,
+ &_Event_Sync_state,
+ STATES_WAITING_FOR_EVENT
+ );
_Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL;
diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c
index 9761c78..cccaed3 100644
--- a/cpukit/rtems/src/eventsurrender.c
+++ b/cpukit/rtems/src/eventsurrender.c
@@ -10,55 +10,33 @@
*/
#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,
+ rtems_event_set *pending_events,
+ Thread_blocking_operation_States *sync_state,
+ States_Control wait_state
)
{
ISR_Level level;
- rtems_event_set pending_events;
+ rtems_event_set current_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 ];
- 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, pending_events );
+ current_pending_events = *pending_events;
+ event_condition = the_thread->Wait.count;
- seized_events = _Event_sets_Get( pending_events, event_condition );
+ seized_events = _Event_sets_Get( current_pending_events, event_condition );
/*
* No events were seized in this operation
@@ -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 );
+ *pending_events = _Event_sets_Clear(
+ current_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,9 @@ 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 );
+ *pending_events = _Event_sets_Clear( current_pending_events, seized_events );
the_thread->Wait.count = 0;
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
--
1.7.7
More information about the devel
mailing list