[PATCH 2/3] score: Add system events

Gedare Bloom gedare at rtems.org
Wed Oct 24 16:56:04 UTC 2012


On Wed, Oct 24, 2012 at 12:49 PM, Gedare Bloom <gedare at rtems.org> wrote:
> On Wed, Oct 24, 2012 at 12:11 PM, Sebastian Huber
> <sebastian.huber at embedded-brains.de> wrote:
>> ---
>>  cpukit/rtems/Makefile.am                   |    2 +
>>  cpukit/rtems/include/rtems/rtems/event.h   |   81 ++++++++++++++++++++++++++++
>>  cpukit/rtems/src/event.c                   |    1 +
>>  cpukit/rtems/src/systemeventreceive.c      |   67 +++++++++++++++++++++++
>>  cpukit/rtems/src/systemeventsend.c         |   65 ++++++++++++++++++++++
>>  cpukit/score/include/rtems/score/states.h  |    3 +
>>  cpukit/score/inline/rtems/score/states.inl |   15 +++++
>>  7 files changed, 234 insertions(+), 0 deletions(-)
>>  create mode 100644 cpukit/rtems/src/systemeventreceive.c
>>  create mode 100644 cpukit/rtems/src/systemeventsend.c
>>
>> diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am
>> index bbf8611..ff3174e 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 dc7f445..0ff1d5a 100644
>> --- a/cpukit/rtems/include/rtems/rtems/event.h
>> +++ b/cpukit/rtems/include/rtems/rtems/event.h
>> @@ -207,6 +207,85 @@ rtems_status_code rtems_event_receive (
>>  /** @} */
>>
>>  /**
>> + *  @defgroup ClassicSystemEvent System Events
>> + *
>> + *  @ingroup ClassicRTEMS
>> + *
>> + *  @{
>> + */
>> +
>> +/**
>> + * @brief Reserved system event for transient usage.
>> + *
>> + * The executing task must ensure that this event is not pending after the last
>> + * call to rtems_system_event_receive() in the last usage context.
>> + */
>> +#define RTEMS_SYSTEM_EVENT_TRANSIENT RTEMS_EVENT_0
>> +
>> +/**
>> + * @brief See rtems_event_send().
>> + */
>> +rtems_status_code rtems_system_event_send(
>> +  rtems_id id,
>> +  rtems_event_set event_in
>> +);
>> +
>> +/**
>> + * @brief See rtems_event_receive().
>> + */
>> +rtems_status_code rtems_system_event_receive(
>> +  rtems_event_set event_in,
>> +  rtems_option option_set,
>> +  rtems_interval ticks,
>> +  rtems_event_set *event_out
>> +);
>> +
>> +/**
>> + * @brief See rtems_system_event_send() and RTEMS_SYSTEM_EVENT_TRANSIENT.
>> + */
>> +RTEMS_INLINE_ROUTINE rtems_status_code rtems_transient_event_send(
>> +  rtems_id id
>> +)
>> +{
>> +  return rtems_system_event_send( id, RTEMS_SYSTEM_EVENT_TRANSIENT );
>> +}
>> +
>> +/**
>> + * @brief See rtems_system_event_receive() and RTEMS_SYSTEM_EVENT_TRANSIENT.
>> + */
>> +RTEMS_INLINE_ROUTINE rtems_status_code rtems_transient_event_receive(
>> +  rtems_option option_set,
>> +  rtems_interval ticks
>> +)
>> +{
>> +  rtems_event_set event_out;
>> +
>> +  return rtems_system_event_receive(
>> +    RTEMS_SYSTEM_EVENT_TRANSIENT,
>> +    RTEMS_EVENT_ALL | option_set,
>> +    ticks,
>> +    &event_out
>> +  );
>> +}
>> +
>> +/**
>> + * @brief See rtems_system_event_receive() and RTEMS_SYSTEM_EVENT_TRANSIENT.
>> + */
>> +RTEMS_INLINE_ROUTINE void rtems_transient_event_clear( void )
>> +{
>> +  rtems_event_set event_out;
>> +
>> +  rtems_system_event_receive(
>> +    RTEMS_SYSTEM_EVENT_TRANSIENT,
>> +    RTEMS_EVENT_ALL | RTEMS_NO_WAIT,
>> +    0,
>> +    &event_out
>> +  );
>> +}
>> +
>> +/** @} */
>> +
>> +/**
>>   *  @defgroup ScoreEvent Event Handler
>>   *
>>   *  @ingroup Score
>> @@ -248,6 +327,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/src/event.c b/cpukit/rtems/src/event.c
>> index ed148e8..d5c29f6 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 0000000..22ab473
>> --- /dev/null
>> +++ b/cpukit/rtems/src/systemeventreceive.c
>> @@ -0,0 +1,67 @@
>> +/**
>> + * @file
>> + *
>> + * @ingroup ClassicSystemEvent
>> + *
>> + * @brief rtems_system_event_receive() implementation.
>> + */
>> +
>> +/*
>> + * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
>> + *
>> + *  embedded brains GmbH
>> + *  Obere Lagerstr. 30
>> + *  82178 Puchheim
>> + *  Germany
>> + *  <rtems at 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_system_event_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 ];
>> +
>> +    if ( !_Event_sets_Is_empty( event_in ) ) {
>> +      _Thread_Disable_dispatch();
> The preceding accesses to _Thread_Executing seem fishy without
> disabling dispatching or doing Thread_Get.
>
>> +      _Event_Seize(
>> +        event_in,
>> +        option_set,
>> +        ticks,
>> +        event_out,
>> +        executing,
>> +        &api->pending_events,
>> +        &_System_event_Sync_state,
>> +        STATES_WAITING_FOR_SYSTEM_EVENT
>> +      );
>> +      _Thread_Enable_dispatch();
>> +
>> +      sc = _Thread_Executing->Wait.return_code;
> I noticed the pattern of _Thread_Executing->Wait.return_code in the
> existing event code, is it thread-safe to access _Thread_Executing
> like this or should it be using the "executing" variable from before?
>
Nevermind. I spoke without thinking deeply. It's safe because the
thread executing this code is obviously the  Thread_Executing even if
it is preempted and then returns.

>> +    } else {
>> +      *event_out = api->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 0000000..aafa03e
>> --- /dev/null
>> +++ b/cpukit/rtems/src/systemeventsend.c
>> @@ -0,0 +1,65 @@
>> +/**
>> + * @file
>> + *
>> + * @ingroup ClassicSystemEvent
>> + *
>> + * @brief rtems_system_event_send() implementation.
>> + */
>> +
>> +/*
>> + * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
>> + *
>> + *  embedded brains GmbH
>> + *  Obere Lagerstr. 30
>> + *  82178 Puchheim
>> + *  Germany
>> + *  <rtems at 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_system_event_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->pending_events,
>> +        &_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/score/include/rtems/score/states.h b/cpukit/score/include/rtems/score/states.h
>> index eb4658e..f71bf93 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 7bad0c9..f5d816a 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.
>>   *
>> --
>> 1.7.7
>>
>> _______________________________________________
>> rtems-devel mailing list
>> rtems-devel at rtems.org
>> http://www.rtems.org/mailman/listinfo/rtems-devel



More information about the devel mailing list