[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