[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