mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 23:23:13 +00:00
Split Event Manager into one routine per file.
This commit is contained in:
@@ -40,11 +40,14 @@ SEMAPHORE_PIECES=\
|
|||||||
sem semcreate semdelete semident semobtain semrelease \
|
sem semcreate semdelete semident semobtain semrelease \
|
||||||
semtranslatereturncode
|
semtranslatereturncode
|
||||||
|
|
||||||
|
EVENT_PIECES=\
|
||||||
|
event eventreceive eventseize eventsend eventsurrender eventtimeout
|
||||||
|
|
||||||
RATEMON_PIECES=\
|
RATEMON_PIECES=\
|
||||||
ratemon ratemoncancel ratemoncreate ratemondelete ratemongetstatus \
|
ratemon ratemoncancel ratemoncreate ratemondelete ratemongetstatus \
|
||||||
ratemonident ratemonperiod ratemontimeout
|
ratemonident ratemonperiod ratemontimeout
|
||||||
|
|
||||||
C_PIECES=attr $(CLOCK_PIECES) dpmem event intr intrbody \
|
C_PIECES=attr $(CLOCK_PIECES) dpmem $(EVENT_PIECES) intr intrbody \
|
||||||
$(MESSAGE_QUEUE_PIECES) \
|
$(MESSAGE_QUEUE_PIECES) \
|
||||||
part $(RATEMON_PIECES) $(REGION_PIECES) $(SEMAPHORE_PIECES) signal \
|
part $(RATEMON_PIECES) $(REGION_PIECES) $(SEMAPHORE_PIECES) signal \
|
||||||
$(TASK_PIECES) timer $(MP_PIECES)
|
$(TASK_PIECES) timer $(MP_PIECES)
|
||||||
|
|||||||
@@ -43,345 +43,3 @@ void _Event_Manager_initialization( void )
|
|||||||
_MPCI_Register_packet_processor( MP_PACKET_EVENT, _Event_MP_Process_packet );
|
_MPCI_Register_packet_processor( MP_PACKET_EVENT, _Event_MP_Process_packet );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 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(
|
|
||||||
Objects_Id id,
|
|
||||||
rtems_event_set event_in
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register Thread_Control *the_thread;
|
|
||||||
Objects_Locations location;
|
|
||||||
RTEMS_API_Control *api;
|
|
||||||
|
|
||||||
the_thread = _Thread_Get( id, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return(
|
|
||||||
_Event_MP_Send_request_packet(
|
|
||||||
EVENT_MP_SEND_REQUEST,
|
|
||||||
id,
|
|
||||||
event_in
|
|
||||||
)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return RTEMS_INVALID_ID;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
|
|
||||||
_Event_sets_Post( event_in, &api->pending_events );
|
|
||||||
_Event_Surrender( the_thread );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return RTEMS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 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,
|
|
||||||
rtems_interval ticks,
|
|
||||||
rtems_event_set *event_out
|
|
||||||
)
|
|
||||||
{
|
|
||||||
RTEMS_API_Control *api;
|
|
||||||
|
|
||||||
api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
|
|
||||||
|
|
||||||
if ( _Event_sets_Is_empty( event_in ) ) {
|
|
||||||
*event_out = api->pending_events;
|
|
||||||
return RTEMS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
_Event_Seize( event_in, option_set, ticks, event_out );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return( _Thread_Executing->Wait.return_code );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _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
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Thread_Control *executing;
|
|
||||||
rtems_event_set seized_events;
|
|
||||||
rtems_event_set pending_events;
|
|
||||||
ISR_Level level;
|
|
||||||
RTEMS_API_Control *api;
|
|
||||||
Event_Sync_states 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 );
|
|
||||||
|
|
||||||
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 );
|
|
||||||
_ISR_Enable( level );
|
|
||||||
*event_out = seized_events;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( _Options_Is_no_wait( option_set ) ) {
|
|
||||||
_ISR_Enable( level );
|
|
||||||
executing->Wait.return_code = RTEMS_UNSATISFIED;
|
|
||||||
*event_out = seized_events;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
|
|
||||||
|
|
||||||
executing->Wait.option = (unsigned32) option_set;
|
|
||||||
executing->Wait.count = (unsigned32) event_in;
|
|
||||||
executing->Wait.return_argument = event_out;
|
|
||||||
|
|
||||||
_ISR_Enable( level );
|
|
||||||
|
|
||||||
if ( ticks ) {
|
|
||||||
_Watchdog_Initialize(
|
|
||||||
&executing->Timer,
|
|
||||||
_Event_Timeout,
|
|
||||||
executing->Object.id,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
_Watchdog_Insert_ticks( &executing->Timer, ticks );
|
|
||||||
}
|
|
||||||
|
|
||||||
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
|
|
||||||
|
|
||||||
_ISR_Disable( level );
|
|
||||||
|
|
||||||
sync_state = _Event_Sync_state;
|
|
||||||
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
|
|
||||||
|
|
||||||
switch ( sync_state ) {
|
|
||||||
case EVENT_SYNC_SYNCHRONIZED:
|
|
||||||
/*
|
|
||||||
* This cannot happen. It indicates that this routine did not
|
|
||||||
* enter the synchronization states above.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
|
|
||||||
case EVENT_SYNC_NOTHING_HAPPENED:
|
|
||||||
_ISR_Enable( level );
|
|
||||||
return;
|
|
||||||
|
|
||||||
case EVENT_SYNC_TIMEOUT:
|
|
||||||
executing->Wait.return_code = RTEMS_TIMEOUT;
|
|
||||||
_ISR_Enable( level );
|
|
||||||
_Thread_Unblock( executing );
|
|
||||||
return;
|
|
||||||
|
|
||||||
case EVENT_SYNC_SATISFIED:
|
|
||||||
if ( _Watchdog_Is_active( &executing->Timer ) ) {
|
|
||||||
_Watchdog_Deactivate( &executing->Timer );
|
|
||||||
_ISR_Enable( level );
|
|
||||||
(void) _Watchdog_Remove( &executing->Timer );
|
|
||||||
} else
|
|
||||||
_ISR_Enable( level );
|
|
||||||
_Thread_Unblock( executing );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _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
|
|
||||||
)
|
|
||||||
{
|
|
||||||
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 ];
|
|
||||||
|
|
||||||
option_set = (rtems_option) the_thread->Wait.option;
|
|
||||||
|
|
||||||
_ISR_Disable( level );
|
|
||||||
pending_events = api->pending_events;
|
|
||||||
event_condition = (rtems_event_set) the_thread->Wait.count;
|
|
||||||
|
|
||||||
seized_events = _Event_sets_Get( pending_events, event_condition );
|
|
||||||
|
|
||||||
if ( !_Event_sets_Is_empty( seized_events ) ) {
|
|
||||||
if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
|
|
||||||
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
|
|
||||||
api->pending_events =
|
|
||||||
_Event_sets_Clear( pending_events, seized_events );
|
|
||||||
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
|
||||||
|
|
||||||
_ISR_Flash( level );
|
|
||||||
|
|
||||||
if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
|
|
||||||
_ISR_Enable( level );
|
|
||||||
_Thread_Unblock( the_thread );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_Watchdog_Deactivate( &the_thread->Timer );
|
|
||||||
_ISR_Enable( level );
|
|
||||||
(void) _Watchdog_Remove( &the_thread->Timer );
|
|
||||||
_Thread_Unblock( the_thread );
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( _Event_Sync_state ) {
|
|
||||||
case EVENT_SYNC_SYNCHRONIZED:
|
|
||||||
case EVENT_SYNC_SATISFIED:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EVENT_SYNC_NOTHING_HAPPENED:
|
|
||||||
case EVENT_SYNC_TIMEOUT:
|
|
||||||
if ( !_Thread_Is_executing( the_thread ) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
|
|
||||||
api->pending_events =
|
|
||||||
_Event_sets_Clear( pending_events,seized_events );
|
|
||||||
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
|
||||||
_Event_Sync_state = EVENT_SYNC_SATISFIED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ISR_Enable( level );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _Event_Timeout
|
|
||||||
*
|
|
||||||
* This routine processes a thread which timeouts while waiting to
|
|
||||||
* receive an event_set. It is called by the watchdog handler.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* id - thread id
|
|
||||||
*
|
|
||||||
* Output parameters: NONE
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _Event_Timeout(
|
|
||||||
Objects_Id id,
|
|
||||||
void *ignored
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Thread_Control *the_thread;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_thread = _Thread_Get( id, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE: /* impossible */
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
break;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the event manager is not synchronized, then it is either
|
|
||||||
* "nothing happened", "timeout", or "satisfied". If the_thread
|
|
||||||
* is the executing thread, then it is in the process of blocking
|
|
||||||
* and it is the thread which is responsible for the synchronization
|
|
||||||
* process.
|
|
||||||
*
|
|
||||||
* If it is not satisfied, then it is "nothing happened" and
|
|
||||||
* this is the "timeout" transition. After a request is satisfied,
|
|
||||||
* a timeout is not allowed to occur.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( _Event_Sync_state != EVENT_SYNC_SYNCHRONIZED &&
|
|
||||||
_Thread_Is_executing( the_thread ) ) {
|
|
||||||
if ( _Event_Sync_state != EVENT_SYNC_SATISFIED )
|
|
||||||
_Event_Sync_state = EVENT_SYNC_TIMEOUT;
|
|
||||||
} else {
|
|
||||||
the_thread->Wait.return_code = RTEMS_TIMEOUT;
|
|
||||||
_Thread_Unblock( the_thread );
|
|
||||||
}
|
|
||||||
_Thread_Unnest_dispatch();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
63
c/src/exec/rtems/src/eventreceive.c
Normal file
63
c/src/exec/rtems/src/eventreceive.c
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
|
rtems_interval ticks,
|
||||||
|
rtems_event_set *event_out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RTEMS_API_Control *api;
|
||||||
|
|
||||||
|
api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
|
||||||
|
|
||||||
|
if ( _Event_sets_Is_empty( event_in ) ) {
|
||||||
|
*event_out = api->pending_events;
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Thread_Disable_dispatch();
|
||||||
|
_Event_Seize( event_in, option_set, ticks, event_out );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return( _Thread_Executing->Wait.return_code );
|
||||||
|
}
|
||||||
139
c/src/exec/rtems/src/eventseize.c
Normal file
139
c/src/exec/rtems/src/eventseize.c
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Thread_Control *executing;
|
||||||
|
rtems_event_set seized_events;
|
||||||
|
rtems_event_set pending_events;
|
||||||
|
ISR_Level level;
|
||||||
|
RTEMS_API_Control *api;
|
||||||
|
Event_Sync_states 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 );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
_ISR_Enable( level );
|
||||||
|
*event_out = seized_events;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _Options_Is_no_wait( option_set ) ) {
|
||||||
|
_ISR_Enable( level );
|
||||||
|
executing->Wait.return_code = RTEMS_UNSATISFIED;
|
||||||
|
*event_out = seized_events;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
|
||||||
|
|
||||||
|
executing->Wait.option = (unsigned32) option_set;
|
||||||
|
executing->Wait.count = (unsigned32) event_in;
|
||||||
|
executing->Wait.return_argument = event_out;
|
||||||
|
|
||||||
|
_ISR_Enable( level );
|
||||||
|
|
||||||
|
if ( ticks ) {
|
||||||
|
_Watchdog_Initialize(
|
||||||
|
&executing->Timer,
|
||||||
|
_Event_Timeout,
|
||||||
|
executing->Object.id,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
_Watchdog_Insert_ticks( &executing->Timer, ticks );
|
||||||
|
}
|
||||||
|
|
||||||
|
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
|
||||||
|
|
||||||
|
_ISR_Disable( level );
|
||||||
|
|
||||||
|
sync_state = _Event_Sync_state;
|
||||||
|
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
|
||||||
|
|
||||||
|
switch ( sync_state ) {
|
||||||
|
case EVENT_SYNC_SYNCHRONIZED:
|
||||||
|
/*
|
||||||
|
* This cannot happen. It indicates that this routine did not
|
||||||
|
* enter the synchronization states above.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EVENT_SYNC_NOTHING_HAPPENED:
|
||||||
|
_ISR_Enable( level );
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EVENT_SYNC_TIMEOUT:
|
||||||
|
executing->Wait.return_code = RTEMS_TIMEOUT;
|
||||||
|
_ISR_Enable( level );
|
||||||
|
_Thread_Unblock( executing );
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EVENT_SYNC_SATISFIED:
|
||||||
|
if ( _Watchdog_Is_active( &executing->Timer ) ) {
|
||||||
|
_Watchdog_Deactivate( &executing->Timer );
|
||||||
|
_ISR_Enable( level );
|
||||||
|
(void) _Watchdog_Remove( &executing->Timer );
|
||||||
|
} else
|
||||||
|
_ISR_Enable( level );
|
||||||
|
_Thread_Unblock( executing );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
72
c/src/exec/rtems/src/eventsend.c
Normal file
72
c/src/exec/rtems/src/eventsend.c
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 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(
|
||||||
|
Objects_Id id,
|
||||||
|
rtems_event_set event_in
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register Thread_Control *the_thread;
|
||||||
|
Objects_Locations location;
|
||||||
|
RTEMS_API_Control *api;
|
||||||
|
|
||||||
|
the_thread = _Thread_Get( id, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
return(
|
||||||
|
_Event_MP_Send_request_packet(
|
||||||
|
EVENT_MP_SEND_REQUEST,
|
||||||
|
id,
|
||||||
|
event_in
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return RTEMS_INVALID_ID;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
|
||||||
|
_Event_sets_Post( event_in, &api->pending_events );
|
||||||
|
_Event_Surrender( the_thread );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
|
||||||
|
}
|
||||||
106
c/src/exec/rtems/src/eventsurrender.c
Normal file
106
c/src/exec/rtems/src/eventsurrender.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
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 ];
|
||||||
|
|
||||||
|
option_set = (rtems_option) the_thread->Wait.option;
|
||||||
|
|
||||||
|
_ISR_Disable( level );
|
||||||
|
pending_events = api->pending_events;
|
||||||
|
event_condition = (rtems_event_set) the_thread->Wait.count;
|
||||||
|
|
||||||
|
seized_events = _Event_sets_Get( pending_events, event_condition );
|
||||||
|
|
||||||
|
if ( !_Event_sets_Is_empty( seized_events ) ) {
|
||||||
|
if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
|
||||||
|
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
|
||||||
|
api->pending_events =
|
||||||
|
_Event_sets_Clear( pending_events, seized_events );
|
||||||
|
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
||||||
|
|
||||||
|
_ISR_Flash( level );
|
||||||
|
|
||||||
|
if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
|
||||||
|
_ISR_Enable( level );
|
||||||
|
_Thread_Unblock( the_thread );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_Watchdog_Deactivate( &the_thread->Timer );
|
||||||
|
_ISR_Enable( level );
|
||||||
|
(void) _Watchdog_Remove( &the_thread->Timer );
|
||||||
|
_Thread_Unblock( the_thread );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( _Event_Sync_state ) {
|
||||||
|
case EVENT_SYNC_SYNCHRONIZED:
|
||||||
|
case EVENT_SYNC_SATISFIED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_SYNC_NOTHING_HAPPENED:
|
||||||
|
case EVENT_SYNC_TIMEOUT:
|
||||||
|
if ( !_Thread_Is_executing( the_thread ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
|
||||||
|
api->pending_events =
|
||||||
|
_Event_sets_Clear( pending_events,seized_events );
|
||||||
|
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
||||||
|
_Event_Sync_state = EVENT_SYNC_SATISFIED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ISR_Enable( level );
|
||||||
|
}
|
||||||
76
c/src/exec/rtems/src/eventtimeout.c
Normal file
76
c/src/exec/rtems/src/eventtimeout.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _Event_Timeout
|
||||||
|
*
|
||||||
|
* This routine processes a thread which timeouts while waiting to
|
||||||
|
* receive an event_set. It is called by the watchdog handler.
|
||||||
|
*
|
||||||
|
* Input parameters:
|
||||||
|
* id - thread id
|
||||||
|
*
|
||||||
|
* Output parameters: NONE
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _Event_Timeout(
|
||||||
|
Objects_Id id,
|
||||||
|
void *ignored
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Thread_Control *the_thread;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_thread = _Thread_Get( id, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE: /* impossible */
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
break;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the event manager is not synchronized, then it is either
|
||||||
|
* "nothing happened", "timeout", or "satisfied". If the_thread
|
||||||
|
* is the executing thread, then it is in the process of blocking
|
||||||
|
* and it is the thread which is responsible for the synchronization
|
||||||
|
* process.
|
||||||
|
*
|
||||||
|
* If it is not satisfied, then it is "nothing happened" and
|
||||||
|
* this is the "timeout" transition. After a request is satisfied,
|
||||||
|
* a timeout is not allowed to occur.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( _Event_Sync_state != EVENT_SYNC_SYNCHRONIZED &&
|
||||||
|
_Thread_Is_executing( the_thread ) ) {
|
||||||
|
if ( _Event_Sync_state != EVENT_SYNC_SATISFIED )
|
||||||
|
_Event_Sync_state = EVENT_SYNC_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
the_thread->Wait.return_code = RTEMS_TIMEOUT;
|
||||||
|
_Thread_Unblock( the_thread );
|
||||||
|
}
|
||||||
|
_Thread_Unnest_dispatch();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,345 +43,3 @@ void _Event_Manager_initialization( void )
|
|||||||
_MPCI_Register_packet_processor( MP_PACKET_EVENT, _Event_MP_Process_packet );
|
_MPCI_Register_packet_processor( MP_PACKET_EVENT, _Event_MP_Process_packet );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 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(
|
|
||||||
Objects_Id id,
|
|
||||||
rtems_event_set event_in
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register Thread_Control *the_thread;
|
|
||||||
Objects_Locations location;
|
|
||||||
RTEMS_API_Control *api;
|
|
||||||
|
|
||||||
the_thread = _Thread_Get( id, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE:
|
|
||||||
#if defined(RTEMS_MULTIPROCESSING)
|
|
||||||
return(
|
|
||||||
_Event_MP_Send_request_packet(
|
|
||||||
EVENT_MP_SEND_REQUEST,
|
|
||||||
id,
|
|
||||||
event_in
|
|
||||||
)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
return RTEMS_INVALID_ID;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
|
|
||||||
_Event_sets_Post( event_in, &api->pending_events );
|
|
||||||
_Event_Surrender( the_thread );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return RTEMS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* 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,
|
|
||||||
rtems_interval ticks,
|
|
||||||
rtems_event_set *event_out
|
|
||||||
)
|
|
||||||
{
|
|
||||||
RTEMS_API_Control *api;
|
|
||||||
|
|
||||||
api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
|
|
||||||
|
|
||||||
if ( _Event_sets_Is_empty( event_in ) ) {
|
|
||||||
*event_out = api->pending_events;
|
|
||||||
return RTEMS_SUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
|
||||||
_Event_Seize( event_in, option_set, ticks, event_out );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
return( _Thread_Executing->Wait.return_code );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _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
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Thread_Control *executing;
|
|
||||||
rtems_event_set seized_events;
|
|
||||||
rtems_event_set pending_events;
|
|
||||||
ISR_Level level;
|
|
||||||
RTEMS_API_Control *api;
|
|
||||||
Event_Sync_states 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 );
|
|
||||||
|
|
||||||
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 );
|
|
||||||
_ISR_Enable( level );
|
|
||||||
*event_out = seized_events;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( _Options_Is_no_wait( option_set ) ) {
|
|
||||||
_ISR_Enable( level );
|
|
||||||
executing->Wait.return_code = RTEMS_UNSATISFIED;
|
|
||||||
*event_out = seized_events;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
|
|
||||||
|
|
||||||
executing->Wait.option = (unsigned32) option_set;
|
|
||||||
executing->Wait.count = (unsigned32) event_in;
|
|
||||||
executing->Wait.return_argument = event_out;
|
|
||||||
|
|
||||||
_ISR_Enable( level );
|
|
||||||
|
|
||||||
if ( ticks ) {
|
|
||||||
_Watchdog_Initialize(
|
|
||||||
&executing->Timer,
|
|
||||||
_Event_Timeout,
|
|
||||||
executing->Object.id,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
_Watchdog_Insert_ticks( &executing->Timer, ticks );
|
|
||||||
}
|
|
||||||
|
|
||||||
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
|
|
||||||
|
|
||||||
_ISR_Disable( level );
|
|
||||||
|
|
||||||
sync_state = _Event_Sync_state;
|
|
||||||
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
|
|
||||||
|
|
||||||
switch ( sync_state ) {
|
|
||||||
case EVENT_SYNC_SYNCHRONIZED:
|
|
||||||
/*
|
|
||||||
* This cannot happen. It indicates that this routine did not
|
|
||||||
* enter the synchronization states above.
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
|
|
||||||
case EVENT_SYNC_NOTHING_HAPPENED:
|
|
||||||
_ISR_Enable( level );
|
|
||||||
return;
|
|
||||||
|
|
||||||
case EVENT_SYNC_TIMEOUT:
|
|
||||||
executing->Wait.return_code = RTEMS_TIMEOUT;
|
|
||||||
_ISR_Enable( level );
|
|
||||||
_Thread_Unblock( executing );
|
|
||||||
return;
|
|
||||||
|
|
||||||
case EVENT_SYNC_SATISFIED:
|
|
||||||
if ( _Watchdog_Is_active( &executing->Timer ) ) {
|
|
||||||
_Watchdog_Deactivate( &executing->Timer );
|
|
||||||
_ISR_Enable( level );
|
|
||||||
(void) _Watchdog_Remove( &executing->Timer );
|
|
||||||
} else
|
|
||||||
_ISR_Enable( level );
|
|
||||||
_Thread_Unblock( executing );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _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
|
|
||||||
)
|
|
||||||
{
|
|
||||||
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 ];
|
|
||||||
|
|
||||||
option_set = (rtems_option) the_thread->Wait.option;
|
|
||||||
|
|
||||||
_ISR_Disable( level );
|
|
||||||
pending_events = api->pending_events;
|
|
||||||
event_condition = (rtems_event_set) the_thread->Wait.count;
|
|
||||||
|
|
||||||
seized_events = _Event_sets_Get( pending_events, event_condition );
|
|
||||||
|
|
||||||
if ( !_Event_sets_Is_empty( seized_events ) ) {
|
|
||||||
if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
|
|
||||||
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
|
|
||||||
api->pending_events =
|
|
||||||
_Event_sets_Clear( pending_events, seized_events );
|
|
||||||
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
|
||||||
|
|
||||||
_ISR_Flash( level );
|
|
||||||
|
|
||||||
if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
|
|
||||||
_ISR_Enable( level );
|
|
||||||
_Thread_Unblock( the_thread );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_Watchdog_Deactivate( &the_thread->Timer );
|
|
||||||
_ISR_Enable( level );
|
|
||||||
(void) _Watchdog_Remove( &the_thread->Timer );
|
|
||||||
_Thread_Unblock( the_thread );
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ( _Event_Sync_state ) {
|
|
||||||
case EVENT_SYNC_SYNCHRONIZED:
|
|
||||||
case EVENT_SYNC_SATISFIED:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EVENT_SYNC_NOTHING_HAPPENED:
|
|
||||||
case EVENT_SYNC_TIMEOUT:
|
|
||||||
if ( !_Thread_Is_executing( the_thread ) )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
|
|
||||||
api->pending_events =
|
|
||||||
_Event_sets_Clear( pending_events,seized_events );
|
|
||||||
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
|
||||||
_Event_Sync_state = EVENT_SYNC_SATISFIED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ISR_Enable( level );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*PAGE
|
|
||||||
*
|
|
||||||
* _Event_Timeout
|
|
||||||
*
|
|
||||||
* This routine processes a thread which timeouts while waiting to
|
|
||||||
* receive an event_set. It is called by the watchdog handler.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* id - thread id
|
|
||||||
*
|
|
||||||
* Output parameters: NONE
|
|
||||||
*/
|
|
||||||
|
|
||||||
void _Event_Timeout(
|
|
||||||
Objects_Id id,
|
|
||||||
void *ignored
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Thread_Control *the_thread;
|
|
||||||
Objects_Locations location;
|
|
||||||
|
|
||||||
the_thread = _Thread_Get( id, &location );
|
|
||||||
switch ( location ) {
|
|
||||||
case OBJECTS_REMOTE: /* impossible */
|
|
||||||
case OBJECTS_ERROR:
|
|
||||||
break;
|
|
||||||
case OBJECTS_LOCAL:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the event manager is not synchronized, then it is either
|
|
||||||
* "nothing happened", "timeout", or "satisfied". If the_thread
|
|
||||||
* is the executing thread, then it is in the process of blocking
|
|
||||||
* and it is the thread which is responsible for the synchronization
|
|
||||||
* process.
|
|
||||||
*
|
|
||||||
* If it is not satisfied, then it is "nothing happened" and
|
|
||||||
* this is the "timeout" transition. After a request is satisfied,
|
|
||||||
* a timeout is not allowed to occur.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( _Event_Sync_state != EVENT_SYNC_SYNCHRONIZED &&
|
|
||||||
_Thread_Is_executing( the_thread ) ) {
|
|
||||||
if ( _Event_Sync_state != EVENT_SYNC_SATISFIED )
|
|
||||||
_Event_Sync_state = EVENT_SYNC_TIMEOUT;
|
|
||||||
} else {
|
|
||||||
the_thread->Wait.return_code = RTEMS_TIMEOUT;
|
|
||||||
_Thread_Unblock( the_thread );
|
|
||||||
}
|
|
||||||
_Thread_Unnest_dispatch();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
63
cpukit/rtems/src/eventreceive.c
Normal file
63
cpukit/rtems/src/eventreceive.c
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 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,
|
||||||
|
rtems_interval ticks,
|
||||||
|
rtems_event_set *event_out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
RTEMS_API_Control *api;
|
||||||
|
|
||||||
|
api = _Thread_Executing->API_Extensions[ THREAD_API_RTEMS ];
|
||||||
|
|
||||||
|
if ( _Event_sets_Is_empty( event_in ) ) {
|
||||||
|
*event_out = api->pending_events;
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Thread_Disable_dispatch();
|
||||||
|
_Event_Seize( event_in, option_set, ticks, event_out );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return( _Thread_Executing->Wait.return_code );
|
||||||
|
}
|
||||||
139
cpukit/rtems/src/eventseize.c
Normal file
139
cpukit/rtems/src/eventseize.c
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Thread_Control *executing;
|
||||||
|
rtems_event_set seized_events;
|
||||||
|
rtems_event_set pending_events;
|
||||||
|
ISR_Level level;
|
||||||
|
RTEMS_API_Control *api;
|
||||||
|
Event_Sync_states 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 );
|
||||||
|
|
||||||
|
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 );
|
||||||
|
_ISR_Enable( level );
|
||||||
|
*event_out = seized_events;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _Options_Is_no_wait( option_set ) ) {
|
||||||
|
_ISR_Enable( level );
|
||||||
|
executing->Wait.return_code = RTEMS_UNSATISFIED;
|
||||||
|
*event_out = seized_events;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_Event_Sync_state = EVENT_SYNC_NOTHING_HAPPENED;
|
||||||
|
|
||||||
|
executing->Wait.option = (unsigned32) option_set;
|
||||||
|
executing->Wait.count = (unsigned32) event_in;
|
||||||
|
executing->Wait.return_argument = event_out;
|
||||||
|
|
||||||
|
_ISR_Enable( level );
|
||||||
|
|
||||||
|
if ( ticks ) {
|
||||||
|
_Watchdog_Initialize(
|
||||||
|
&executing->Timer,
|
||||||
|
_Event_Timeout,
|
||||||
|
executing->Object.id,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
_Watchdog_Insert_ticks( &executing->Timer, ticks );
|
||||||
|
}
|
||||||
|
|
||||||
|
_Thread_Set_state( executing, STATES_WAITING_FOR_EVENT );
|
||||||
|
|
||||||
|
_ISR_Disable( level );
|
||||||
|
|
||||||
|
sync_state = _Event_Sync_state;
|
||||||
|
_Event_Sync_state = EVENT_SYNC_SYNCHRONIZED;
|
||||||
|
|
||||||
|
switch ( sync_state ) {
|
||||||
|
case EVENT_SYNC_SYNCHRONIZED:
|
||||||
|
/*
|
||||||
|
* This cannot happen. It indicates that this routine did not
|
||||||
|
* enter the synchronization states above.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EVENT_SYNC_NOTHING_HAPPENED:
|
||||||
|
_ISR_Enable( level );
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EVENT_SYNC_TIMEOUT:
|
||||||
|
executing->Wait.return_code = RTEMS_TIMEOUT;
|
||||||
|
_ISR_Enable( level );
|
||||||
|
_Thread_Unblock( executing );
|
||||||
|
return;
|
||||||
|
|
||||||
|
case EVENT_SYNC_SATISFIED:
|
||||||
|
if ( _Watchdog_Is_active( &executing->Timer ) ) {
|
||||||
|
_Watchdog_Deactivate( &executing->Timer );
|
||||||
|
_ISR_Enable( level );
|
||||||
|
(void) _Watchdog_Remove( &executing->Timer );
|
||||||
|
} else
|
||||||
|
_ISR_Enable( level );
|
||||||
|
_Thread_Unblock( executing );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
72
cpukit/rtems/src/eventsend.c
Normal file
72
cpukit/rtems/src/eventsend.c
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* 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(
|
||||||
|
Objects_Id id,
|
||||||
|
rtems_event_set event_in
|
||||||
|
)
|
||||||
|
{
|
||||||
|
register Thread_Control *the_thread;
|
||||||
|
Objects_Locations location;
|
||||||
|
RTEMS_API_Control *api;
|
||||||
|
|
||||||
|
the_thread = _Thread_Get( id, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE:
|
||||||
|
#if defined(RTEMS_MULTIPROCESSING)
|
||||||
|
return(
|
||||||
|
_Event_MP_Send_request_packet(
|
||||||
|
EVENT_MP_SEND_REQUEST,
|
||||||
|
id,
|
||||||
|
event_in
|
||||||
|
)
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
return RTEMS_INVALID_ID;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
|
||||||
|
_Event_sets_Post( event_in, &api->pending_events );
|
||||||
|
_Event_Surrender( the_thread );
|
||||||
|
_Thread_Enable_dispatch();
|
||||||
|
return RTEMS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */
|
||||||
|
}
|
||||||
106
cpukit/rtems/src/eventsurrender.c
Normal file
106
cpukit/rtems/src/eventsurrender.c
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _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
|
||||||
|
)
|
||||||
|
{
|
||||||
|
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 ];
|
||||||
|
|
||||||
|
option_set = (rtems_option) the_thread->Wait.option;
|
||||||
|
|
||||||
|
_ISR_Disable( level );
|
||||||
|
pending_events = api->pending_events;
|
||||||
|
event_condition = (rtems_event_set) the_thread->Wait.count;
|
||||||
|
|
||||||
|
seized_events = _Event_sets_Get( pending_events, event_condition );
|
||||||
|
|
||||||
|
if ( !_Event_sets_Is_empty( seized_events ) ) {
|
||||||
|
if ( _States_Is_waiting_for_event( the_thread->current_state ) ) {
|
||||||
|
if ( seized_events == event_condition || _Options_Is_any( option_set ) ) {
|
||||||
|
api->pending_events =
|
||||||
|
_Event_sets_Clear( pending_events, seized_events );
|
||||||
|
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
||||||
|
|
||||||
|
_ISR_Flash( level );
|
||||||
|
|
||||||
|
if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
|
||||||
|
_ISR_Enable( level );
|
||||||
|
_Thread_Unblock( the_thread );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_Watchdog_Deactivate( &the_thread->Timer );
|
||||||
|
_ISR_Enable( level );
|
||||||
|
(void) _Watchdog_Remove( &the_thread->Timer );
|
||||||
|
_Thread_Unblock( the_thread );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( _Event_Sync_state ) {
|
||||||
|
case EVENT_SYNC_SYNCHRONIZED:
|
||||||
|
case EVENT_SYNC_SATISFIED:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EVENT_SYNC_NOTHING_HAPPENED:
|
||||||
|
case EVENT_SYNC_TIMEOUT:
|
||||||
|
if ( !_Thread_Is_executing( the_thread ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( seized_events == event_condition || _Options_Is_any(option_set) ) {
|
||||||
|
api->pending_events =
|
||||||
|
_Event_sets_Clear( pending_events,seized_events );
|
||||||
|
*(rtems_event_set *)the_thread->Wait.return_argument = seized_events;
|
||||||
|
_Event_Sync_state = EVENT_SYNC_SATISFIED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ISR_Enable( level );
|
||||||
|
}
|
||||||
76
cpukit/rtems/src/eventtimeout.c
Normal file
76
cpukit/rtems/src/eventtimeout.c
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Event Manager
|
||||||
|
*
|
||||||
|
* COPYRIGHT (c) 1989-1998.
|
||||||
|
* On-Line Applications Research Corporation (OAR).
|
||||||
|
* Copyright assigned to U.S. Government, 1994.
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.OARcorp.com/rtems/license.html.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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>
|
||||||
|
|
||||||
|
/*PAGE
|
||||||
|
*
|
||||||
|
* _Event_Timeout
|
||||||
|
*
|
||||||
|
* This routine processes a thread which timeouts while waiting to
|
||||||
|
* receive an event_set. It is called by the watchdog handler.
|
||||||
|
*
|
||||||
|
* Input parameters:
|
||||||
|
* id - thread id
|
||||||
|
*
|
||||||
|
* Output parameters: NONE
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _Event_Timeout(
|
||||||
|
Objects_Id id,
|
||||||
|
void *ignored
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Thread_Control *the_thread;
|
||||||
|
Objects_Locations location;
|
||||||
|
|
||||||
|
the_thread = _Thread_Get( id, &location );
|
||||||
|
switch ( location ) {
|
||||||
|
case OBJECTS_REMOTE: /* impossible */
|
||||||
|
case OBJECTS_ERROR:
|
||||||
|
break;
|
||||||
|
case OBJECTS_LOCAL:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the event manager is not synchronized, then it is either
|
||||||
|
* "nothing happened", "timeout", or "satisfied". If the_thread
|
||||||
|
* is the executing thread, then it is in the process of blocking
|
||||||
|
* and it is the thread which is responsible for the synchronization
|
||||||
|
* process.
|
||||||
|
*
|
||||||
|
* If it is not satisfied, then it is "nothing happened" and
|
||||||
|
* this is the "timeout" transition. After a request is satisfied,
|
||||||
|
* a timeout is not allowed to occur.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( _Event_Sync_state != EVENT_SYNC_SYNCHRONIZED &&
|
||||||
|
_Thread_Is_executing( the_thread ) ) {
|
||||||
|
if ( _Event_Sync_state != EVENT_SYNC_SATISFIED )
|
||||||
|
_Event_Sync_state = EVENT_SYNC_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
the_thread->Wait.return_code = RTEMS_TIMEOUT;
|
||||||
|
_Thread_Unblock( the_thread );
|
||||||
|
}
|
||||||
|
_Thread_Unnest_dispatch();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user