Changeset 0edf263 in rtems


Ignore:
Timestamp:
Oct 26, 2012, 8:05:07 AM (9 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
ee82825d
Parents:
990575c
git-author:
Sebastian Huber <sebastian.huber@…> (10/26/12 08:05:07)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/30/12 17:03:02)
Message:

rtems: Add system events

System events are similar to normal events. They offer a second set of
events. These events are intended for internal RTEMS use and should not
be used by applications (with the exception of the transient system
event).

Files:
10 added
9 edited

Legend:

Unmodified
Added
Removed
  • cpukit/rtems/Makefile.am

    r990575c r0edf263  
    210210librtems_a_SOURCES += src/eventtimeout.c
    211211librtems_a_SOURCES += src/eventdata.c
     212librtems_a_SOURCES += src/systemeventsend.c
     213librtems_a_SOURCES += src/systemeventreceive.c
    212214
    213215## SIGNAL_C_FILES
  • cpukit/rtems/include/rtems/rtems/event.h

    r990575c r0edf263  
    208208
    209209/**
     210 * @defgroup ClassicEventSystem System Events
     211 *
     212 * @ingroup ClassicEvent
     213 *
     214 * System events are similar to normal events.  They offer a second set of
     215 * events.  These events are intended for internal RTEMS use and should not be
     216 * used by applications (with the exception of the transient system event).
     217 *
     218 * The event @ref RTEMS_EVENT_SYSTEM_TRANSIENT is used for transient usage.
     219 * See also @ref ClassicEventTransient.  This event may be used by every entity
     220 * that fulfils its usage pattern.
     221 *
     222 * @{
     223 */
     224
     225/**
     226 * @brief Reserved system event for transient usage.
     227 */
     228#define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_0
     229
     230/**
     231 * @brief See rtems_event_send().
     232 */
     233rtems_status_code rtems_event_system_send(
     234  rtems_id id,
     235  rtems_event_set event_in
     236);
     237
     238/**
     239 * @brief See rtems_event_receive().
     240 */
     241rtems_status_code rtems_event_system_receive(
     242  rtems_event_set event_in,
     243  rtems_option option_set,
     244  rtems_interval ticks,
     245  rtems_event_set *event_out
     246);
     247
     248/** @} */
     249
     250/**
     251 * @defgroup ClassicEventTransient Transient Event
     252 *
     253 * @ingroup ClassicEvent
     254 *
     255 * The transient event can be used by a client task to issue a request to
     256 * another task or interrupt service (server).  The server can send the
     257 * transient event to the client task to notify about a request completion, see
     258 * rtems_event_transient_send().  The client task can wait for the transient
     259 * event reception with rtems_event_transient_receive().
     260 *
     261 * The user of the transient event must ensure that this event is not pending
     262 * once the request is finished or cancelled.  A successful reception of the
     263 * transient event with rtems_event_transient_receive() will clear the
     264 * transient event.  If a reception with timeout is used the transient event
     265 * state is undefined after a timeout return status.  The transient event can
     266 * be cleared unconditionally with the non-blocking
     267 * rtems_event_transient_clear().
     268 *
     269 * @msc
     270 *   hscale="1.6";
     271 *   M [label="Main Task"], IDLE [label="Idle Task"], S [label="Server"], TIME [label="System Tick Handler"];
     272 *   |||;
     273 *   --- [label="sequence with request completion"];
     274 *   M box M [label="prepare request\nissue request\ncall rtems_event_transient_receive()"];
     275 *   M=>>IDLE [label="blocking operation"];
     276 *   IDLE=>>S [label="request completion"];
     277 *   S box S [label="call rtems_event_transient_send()"];
     278 *   S=>>M [label="task is ready again"];
     279 *   M box M [label="finish request"];
     280 *   |||;
     281 *   --- [label="sequence with early request completion"];
     282 *   M box M [label="prepare request\nissue request"];
     283 *   M=>>S [label="request completion"];
     284 *   S box S [label="call rtems_event_transient_send()"];
     285 *   S=>>M [label="transient event is now pending"];
     286 *   M box M [label="call rtems_event_transient_receive()\nfinish request"];
     287 *   |||;
     288 *   --- [label="sequence with timeout event"];
     289 *   M box M [label="prepare request\nissue request\ncall rtems_event_transient_receive()"];
     290 *   M=>>IDLE [label="blocking operation"];
     291 *   IDLE=>>TIME [label="timeout expired"];
     292 *   TIME box TIME [label="cancel blocking operation"];
     293 *   TIME=>>M [label="task is ready again"];
     294 *   M box M [label="cancel request\ncall rtems_event_transient_clear()"];
     295 * @endmsc
     296 *
     297 * Suppose you have a task that wants to issue a certain request and then waits
     298 * for request completion.  It can create a request structure and store its
     299 * task identifier there.  Now it can place the request on a work queue of
     300 * another task (or interrupt handler).  Afterwards the task waits for the
     301 * reception of the transient event.  Once the server task is finished with the
     302 * request it can send the transient event to the waiting task and wake it up.
     303 *
     304 * @code
     305 * #include <assert.h>
     306 * #include <rtems.h>
     307 *
     308 * typedef struct {
     309 *   rtems_id task_id;
     310 *   bool work_done;
     311 * } request;
     312 *
     313 * void server(rtems_task_argument arg)
     314 * {
     315 *   rtems_status_code sc;
     316 *   request *req = (request *) arg;
     317 *
     318 *   req->work_done = true;
     319 *
     320 *   sc = rtems_event_transient_send(req->task_id);
     321 *   assert(sc == RTEMS_SUCCESSFUL);
     322 *
     323 *   sc = rtems_task_delete(RTEMS_SELF);
     324 *   assert(sc == RTEMS_SUCCESSFUL);
     325 * }
     326 *
     327 * void issue_request_and_wait_for_completion(void)
     328 * {
     329 *   rtems_status_code sc;
     330 *   rtems_id id;
     331 *   request req;
     332 *
     333 *   req.task_id = rtems_task_self();
     334 *   req.work_done = false;
     335 *
     336 *   sc = rtems_task_create(
     337 *     rtems_build_name('S', 'E', 'R', 'V'),
     338 *     1,
     339 *     RTEMS_MINIMUM_STACK_SIZE,
     340 *     RTEMS_DEFAULT_MODES,
     341 *     RTEMS_DEFAULT_ATTRIBUTES,
     342 *     &id
     343 *   );
     344 *   assert(sc == RTEMS_SUCCESSFUL);
     345 *
     346 *   sc = rtems_task_start(id, server, (rtems_task_argument) &req);
     347 *   assert(sc == RTEMS_SUCCESSFUL);
     348 *
     349 *   sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     350 *   assert(sc == RTEMS_SUCCESSFUL);
     351 *
     352 *   assert(req.work_done);
     353 * }
     354 * @endcode
     355 *
     356 * @{
     357 */
     358
     359/**
     360 * @brief See rtems_event_system_send().
     361 *
     362 * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be sent.
     363 */
     364RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_send(
     365  rtems_id id
     366)
     367{
     368  return rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TRANSIENT );
     369}
     370
     371/**
     372 * @brief See rtems_event_system_receive().
     373 *
     374 * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be received.
     375 */
     376RTEMS_INLINE_ROUTINE rtems_status_code rtems_event_transient_receive(
     377  rtems_option option_set,
     378  rtems_interval ticks
     379)
     380{
     381  rtems_event_set event_out;
     382
     383  return rtems_event_system_receive(
     384    RTEMS_EVENT_SYSTEM_TRANSIENT,
     385    RTEMS_EVENT_ALL | option_set,
     386    ticks,
     387    &event_out
     388  );
     389}
     390
     391/**
     392 * @brief See rtems_event_system_receive().
     393 *
     394 * The system event @ref RTEMS_EVENT_SYSTEM_TRANSIENT will be cleared.
     395 */
     396RTEMS_INLINE_ROUTINE void rtems_event_transient_clear( void )
     397{
     398  rtems_event_set event_out;
     399
     400  rtems_event_system_receive(
     401    RTEMS_EVENT_SYSTEM_TRANSIENT,
     402    RTEMS_EVENT_ALL | RTEMS_NO_WAIT,
     403    0,
     404    &event_out
     405  );
     406}
     407
     408/** @} */
     409
     410/**
    210411 *  @defgroup ScoreEvent Event Handler
    211412 *
     
    253454RTEMS_EVENT_EXTERN Thread_blocking_operation_States _Event_Sync_state;
    254455
     456RTEMS_EVENT_EXTERN Thread_blocking_operation_States _System_event_Sync_state;
     457
    255458/** @} */
    256459
  • cpukit/rtems/include/rtems/rtems/tasks.h

    r990575c r0edf263  
    213213  /** This field contains the event control for this task. */
    214214  Event_Control            Event;
     215  /** This field contains the system event control for this task. */
     216  Event_Control            System_event;
    215217  /** This field contains the Classic API Signal information for this task. */
    216218  ASR_Information          Signal;
  • cpukit/rtems/src/event.c

    r990575c r0edf263  
    3535{
    3636  _Event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
     37  _System_event_Sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
    3738
    3839  /*
  • cpukit/rtems/src/tasks.c

    r990575c r0edf263  
    6666
    6767  _Event_Initialize( &api->Event );
     68  _Event_Initialize( &api->System_event );
    6869  _ASR_Initialize( &api->Signal );
    6970  created->task_variables = NULL;
     
    9495
    9596  _Event_Initialize( &api->Event );
     97  _Event_Initialize( &api->System_event );
    9698}
    9799
  • cpukit/score/include/rtems/score/states.h

    r990575c r0edf263  
    8282/** This macro corresponds to a task waiting for a RWLock. */
    8383#define STATES_WAITING_FOR_RWLOCK              0x20000
     84/** This macro corresponds to a task waiting for a system event. */
     85#define STATES_WAITING_FOR_SYSTEM_EVENT        0x40000
    8486
    8587/** This macro corresponds to a task which is in an interruptible
     
    111113                                 STATES_WAITING_FOR_PERIOD      | \
    112114                                 STATES_WAITING_FOR_EVENT       | \
     115                                 STATES_WAITING_FOR_SYSTEM_EVENT | \
    113116                                 STATES_WAITING_ON_THREAD_QUEUE | \
    114117                                 STATES_INTERRUPTIBLE_BY_SIGNAL )
  • cpukit/score/inline/rtems/score/states.inl

    r990575c r0edf263  
    214214
    215215/**
     216 *  This function returns true if the WAITING_FOR_SYSTEM_EVENT state is set in
     217 *  the_states, and false otherwise.
     218 *
     219 *  @param[in] the_states is the task state set to test
     220 *
     221 *  @return This method returns true if the desired state condition is set.
     222 */
     223RTEMS_INLINE_ROUTINE bool _States_Is_waiting_for_system_event (
     224  States_Control the_states
     225)
     226{
     227   return (the_states & STATES_WAITING_FOR_SYSTEM_EVENT);
     228}
     229
     230/**
    216231 *  This function returns true if the WAITING_FOR_MUTEX state
    217232 *  is set in the_states, and false otherwise.
  • testsuites/sptests/Makefile.am

    r990575c r0edf263  
    2929    spedfsched01 spedfsched02 spedfsched03 \
    3030    spcbssched01 spcbssched02 spcbssched03 spqreslib sptimespec01
     31SUBDIRS += speventtransient01
     32SUBDIRS += speventsystem01
    3133
    3234include $(top_srcdir)/../automake/subdirs.am
  • testsuites/sptests/configure.ac

    r990575c r0edf263  
    2828# Explicitly list all Makefiles here
    2929AC_CONFIG_FILES([Makefile
     30speventsystem01/Makefile
     31speventtransient01/Makefile
    3032spintrcritical18/Makefile
    3133sp01/Makefile
Note: See TracChangeset for help on using the changeset viewer.