[PATCH 2/3] score: Add system events
Gedare Bloom
gedare at rtems.org
Wed Oct 24 16:49:34 UTC 2012
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?
> + } 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