mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-26 14:18:20 +00:00
Split core message queue and watchdog handler objects into separate files.
This commit is contained in:
@@ -22,6 +22,14 @@ INSTALL_CHANGE = @INSTALL_CHANGE@
|
||||
MP_C_PIECES_yes_V = mpci objectmp threadmp
|
||||
MP_C_PIECES = $(MP_C_PIECES_$(HAS_MP)_V)
|
||||
|
||||
CORE_MESSAGE_QUEUE_C_PIECES= coremsg coremsgbroadcast coremsgclose \
|
||||
coremsgflush coremsgflushsupp coremsgseize coremsgsubmit
|
||||
|
||||
CORE_MUTEX_C_PIECES= coremutex coremutexflush coremutexseize \
|
||||
coremutexsurrender
|
||||
|
||||
CORE_SEMAPHORE_C_PIECES= coresem coresemflush coresemseize coresemsurrender
|
||||
|
||||
HEAP_C_PIECES = heap heapallocate heapextend heapfree \
|
||||
heapsizeofuserarea heapwalk
|
||||
|
||||
@@ -48,11 +56,15 @@ THREADQ_C_PIECES= threadq threadqdequeue threadqdequeuefifo \
|
||||
TOD_C_PIECES= coretod coretodset coretodtickle coretodtoseconds \
|
||||
coretodvalidate
|
||||
|
||||
WATCHDOG_C_PIECES= watchdog watchdogadjust watchdoginsert watchdogremove \
|
||||
watchdogtickle
|
||||
|
||||
# C and C++ source names, if any, go here -- minus the .c or .cc
|
||||
C_PIECES = apiext chain coremsg coremutex coresem $(HEAP_C_PIECES) interr isr \
|
||||
C_PIECES = apiext chain $(CORE_MESSAGE_QUEUE_C_PIECES) $(CORE_MUTEX_C_PIECES) \
|
||||
$(CORE_SEMAPHORE_C_PIECES) $(HEAP_C_PIECES) interr isr \
|
||||
$(OBJECT_C_PIECES) $(THREAD_C_PIECES) $(THREADQ_C_PIECES) \
|
||||
$(TOD_C_PIECES) userext \
|
||||
watchdog wkspace $(MP_C_PIECES)
|
||||
$(WATCHDOG_C_PIECES) wkspace $(MP_C_PIECES)
|
||||
C_FILES = $(C_PIECES:%=%.c)
|
||||
C_O_FILES = $(C_PIECES:%=${ARCH}/%.o)
|
||||
|
||||
|
||||
@@ -107,364 +107,3 @@ boolean _CORE_message_queue_Initialize(
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Close
|
||||
*
|
||||
* This function closes a message by returning all allocated space and
|
||||
* flushing the message_queue's task wait queue.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - the message_queue to be flushed
|
||||
* remote_extract_callout - function to invoke remotely
|
||||
* status - status to pass to thread
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void _CORE_message_queue_Close(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
unsigned32 status
|
||||
)
|
||||
{
|
||||
|
||||
if ( the_message_queue->number_of_pending_messages != 0 )
|
||||
(void) _CORE_message_queue_Flush_support( the_message_queue );
|
||||
else
|
||||
_Thread_queue_Flush(
|
||||
&the_message_queue->Wait_queue,
|
||||
remote_extract_callout,
|
||||
status
|
||||
);
|
||||
|
||||
(void) _Workspace_Free( the_message_queue->message_buffers );
|
||||
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Flush
|
||||
*
|
||||
* This function flushes the message_queue's task wait queue. The number
|
||||
* of messages flushed from the queue is returned.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - the message_queue to be flushed
|
||||
*
|
||||
* Output parameters:
|
||||
* returns - the number of messages flushed from the queue
|
||||
*/
|
||||
|
||||
unsigned32 _CORE_message_queue_Flush(
|
||||
CORE_message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
if ( the_message_queue->number_of_pending_messages != 0 )
|
||||
return _CORE_message_queue_Flush_support( the_message_queue );
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Broadcast
|
||||
*
|
||||
* This function sends a message for every thread waiting on the queue and
|
||||
* returns the number of threads made ready by the message.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - message is submitted to this message queue
|
||||
* buffer - pointer to message buffer
|
||||
* size - size in bytes of message to send
|
||||
* id - id of message queue
|
||||
* api_message_queue_mp_support - api specific mp support callout
|
||||
* count - area to store number of threads made ready
|
||||
*
|
||||
* Output parameters:
|
||||
* count - number of threads made ready
|
||||
* CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
CORE_message_queue_Status _CORE_message_queue_Broadcast(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
Objects_Id id,
|
||||
CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
|
||||
unsigned32 *count
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
unsigned32 number_broadcasted;
|
||||
Thread_Wait_information *waitp;
|
||||
unsigned32 constrained_size;
|
||||
|
||||
number_broadcasted = 0;
|
||||
while ((the_thread = _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
|
||||
waitp = &the_thread->Wait;
|
||||
number_broadcasted += 1;
|
||||
|
||||
constrained_size = size;
|
||||
if ( size > the_message_queue->maximum_message_size )
|
||||
constrained_size = the_message_queue->maximum_message_size;
|
||||
|
||||
_CORE_message_queue_Copy_buffer(
|
||||
buffer,
|
||||
waitp->return_argument,
|
||||
constrained_size
|
||||
);
|
||||
|
||||
*(unsigned32 *)the_thread->Wait.return_argument_1 = size;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
||||
(*api_message_queue_mp_support) ( the_thread, id );
|
||||
#endif
|
||||
|
||||
}
|
||||
*count = number_broadcasted;
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Seize
|
||||
*
|
||||
* This kernel routine dequeues a message, copies the message buffer to
|
||||
* a given destination buffer, and frees the message buffer to the
|
||||
* inactive message pool. The thread will be blocked if wait is TRUE,
|
||||
* otherwise an error will be given to the thread if no messages are available.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - pointer to message queue
|
||||
* id - id of object we are waitig on
|
||||
* buffer - pointer to message buffer to be filled
|
||||
* size - pointer to the size of buffer to be filled
|
||||
* wait - TRUE if wait is allowed, FALSE otherwise
|
||||
* timeout - time to wait for a message
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* NOTE: Dependent on BUFFER_LENGTH
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* available
|
||||
* wait
|
||||
*/
|
||||
|
||||
void _CORE_message_queue_Seize(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 *size,
|
||||
boolean wait,
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
CORE_message_queue_Buffer_control *the_message;
|
||||
Thread_Control *executing;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
_ISR_Disable( level );
|
||||
if ( the_message_queue->number_of_pending_messages != 0 ) {
|
||||
the_message_queue->number_of_pending_messages -= 1;
|
||||
|
||||
the_message = _CORE_message_queue_Get_pending_message( the_message_queue );
|
||||
_ISR_Enable( level );
|
||||
*size = the_message->Contents.size;
|
||||
_CORE_message_queue_Copy_buffer(the_message->Contents.buffer,buffer,*size );
|
||||
_CORE_message_queue_Free_message_buffer(the_message_queue, the_message );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !wait ) {
|
||||
_ISR_Enable( level );
|
||||
executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT;
|
||||
return;
|
||||
}
|
||||
|
||||
_Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
|
||||
executing->Wait.queue = &the_message_queue->Wait_queue;
|
||||
executing->Wait.id = id;
|
||||
executing->Wait.return_argument = (void *)buffer;
|
||||
executing->Wait.return_argument_1 = (void *)size;
|
||||
_ISR_Enable( level );
|
||||
|
||||
_Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Flush_support
|
||||
*
|
||||
* This message handler routine removes all messages from a message queue
|
||||
* and returns them to the inactive message pool. The number of messages
|
||||
* flushed from the queue is returned
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - pointer to message queue
|
||||
*
|
||||
* Output parameters:
|
||||
* returns - number of messages placed on inactive chain
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* only case
|
||||
*/
|
||||
|
||||
unsigned32 _CORE_message_queue_Flush_support(
|
||||
CORE_message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Chain_Node *inactive_first;
|
||||
Chain_Node *message_queue_first;
|
||||
Chain_Node *message_queue_last;
|
||||
unsigned32 count;
|
||||
|
||||
_ISR_Disable( level );
|
||||
inactive_first = the_message_queue->Inactive_messages.first;
|
||||
message_queue_first = the_message_queue->Pending_messages.first;
|
||||
message_queue_last = the_message_queue->Pending_messages.last;
|
||||
|
||||
the_message_queue->Inactive_messages.first = message_queue_first;
|
||||
message_queue_last->next = inactive_first;
|
||||
inactive_first->previous = message_queue_last;
|
||||
message_queue_first->previous =
|
||||
_Chain_Head( &the_message_queue->Inactive_messages );
|
||||
|
||||
_Chain_Initialize_empty( &the_message_queue->Pending_messages );
|
||||
|
||||
count = the_message_queue->number_of_pending_messages;
|
||||
the_message_queue->number_of_pending_messages = 0;
|
||||
_ISR_Enable( level );
|
||||
return count;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Submit
|
||||
*
|
||||
* This routine implements the send and urgent message functions. It
|
||||
* processes a message that is to be submitted to the designated
|
||||
* message queue. The message will either be processed as a
|
||||
* send message which it will be inserted at the rear of the queue
|
||||
* or it will be processed as an urgent message which will be inserted
|
||||
* at the front of the queue.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - message is submitted to this message queue
|
||||
* buffer - pointer to message buffer
|
||||
* size - size in bytes of message to send
|
||||
* id - id of message queue
|
||||
* api_message_queue_mp_support - api specific mp support callout
|
||||
* submit_type - send or urgent message
|
||||
*
|
||||
* Output parameters:
|
||||
* CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
CORE_message_queue_Status _CORE_message_queue_Submit(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
Objects_Id id,
|
||||
CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
|
||||
CORE_message_queue_Submit_types submit_type
|
||||
)
|
||||
{
|
||||
CORE_message_queue_Buffer_control *the_message;
|
||||
Thread_Control *the_thread;
|
||||
|
||||
if ( size > the_message_queue->maximum_message_size )
|
||||
return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
|
||||
|
||||
/*
|
||||
* Is there a thread currently waiting on this message queue?
|
||||
*/
|
||||
|
||||
the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
|
||||
if ( the_thread )
|
||||
{
|
||||
_CORE_message_queue_Copy_buffer(
|
||||
buffer,
|
||||
the_thread->Wait.return_argument,
|
||||
size
|
||||
);
|
||||
*(unsigned32 *)the_thread->Wait.return_argument_1 = size;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
||||
(*api_message_queue_mp_support) ( the_thread, id );
|
||||
#endif
|
||||
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* No one waiting on this one currently.
|
||||
* Allocate a message buffer and store it away
|
||||
*/
|
||||
|
||||
if ( the_message_queue->number_of_pending_messages ==
|
||||
the_message_queue->maximum_pending_messages ) {
|
||||
return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
|
||||
}
|
||||
|
||||
the_message = _CORE_message_queue_Allocate_message_buffer(the_message_queue);
|
||||
if ( the_message == 0)
|
||||
return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
|
||||
|
||||
_CORE_message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
|
||||
the_message->Contents.size = size;
|
||||
the_message->priority = submit_type;
|
||||
|
||||
the_message_queue->number_of_pending_messages += 1;
|
||||
|
||||
switch ( submit_type ) {
|
||||
case CORE_MESSAGE_QUEUE_SEND_REQUEST:
|
||||
_CORE_message_queue_Append( the_message_queue, the_message );
|
||||
break;
|
||||
case CORE_MESSAGE_QUEUE_URGENT_REQUEST:
|
||||
_CORE_message_queue_Prepend( the_message_queue, the_message );
|
||||
break;
|
||||
default:
|
||||
/* XXX interrupt critical section needs to be addressed */
|
||||
{
|
||||
CORE_message_queue_Buffer_control *this_message;
|
||||
Chain_Node *the_node;
|
||||
|
||||
the_message->priority = submit_type;
|
||||
for ( the_node = the_message_queue->Pending_messages.first ;
|
||||
!_Chain_Is_tail( &the_message_queue->Pending_messages, the_node ) ;
|
||||
the_node = the_node->next ) {
|
||||
|
||||
this_message = (CORE_message_queue_Buffer_control *) the_node;
|
||||
|
||||
if ( this_message->priority >= the_message->priority )
|
||||
continue;
|
||||
|
||||
_Chain_Insert( the_node, &the_message->Node );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to POSIX, does this happen before or after the message
|
||||
* is actually enqueued. It is logical to think afterwards, because
|
||||
* the message is actually in the queue at this point.
|
||||
*/
|
||||
|
||||
if ( the_message_queue->number_of_pending_messages == 1 &&
|
||||
the_message_queue->notify_handler )
|
||||
(*the_message_queue->notify_handler)( the_message_queue->notify_argument );
|
||||
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
94
c/src/exec/score/src/coremsgbroadcast.c
Normal file
94
c/src/exec/score/src/coremsgbroadcast.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* CORE Message Queue Handler
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This package is the implementation of the CORE Message Queue Handler.
|
||||
* This core object provides task synchronization and communication functions
|
||||
* via messages passed to queue objects.
|
||||
*
|
||||
* 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/score/chain.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/coremsg.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
#include <rtems/score/mpci.h>
|
||||
#endif
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Broadcast
|
||||
*
|
||||
* This function sends a message for every thread waiting on the queue and
|
||||
* returns the number of threads made ready by the message.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - message is submitted to this message queue
|
||||
* buffer - pointer to message buffer
|
||||
* size - size in bytes of message to send
|
||||
* id - id of message queue
|
||||
* api_message_queue_mp_support - api specific mp support callout
|
||||
* count - area to store number of threads made ready
|
||||
*
|
||||
* Output parameters:
|
||||
* count - number of threads made ready
|
||||
* CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
CORE_message_queue_Status _CORE_message_queue_Broadcast(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
Objects_Id id,
|
||||
CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
|
||||
unsigned32 *count
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
unsigned32 number_broadcasted;
|
||||
Thread_Wait_information *waitp;
|
||||
unsigned32 constrained_size;
|
||||
|
||||
number_broadcasted = 0;
|
||||
while ((the_thread = _Thread_queue_Dequeue(&the_message_queue->Wait_queue))) {
|
||||
waitp = &the_thread->Wait;
|
||||
number_broadcasted += 1;
|
||||
|
||||
constrained_size = size;
|
||||
if ( size > the_message_queue->maximum_message_size )
|
||||
constrained_size = the_message_queue->maximum_message_size;
|
||||
|
||||
_CORE_message_queue_Copy_buffer(
|
||||
buffer,
|
||||
waitp->return_argument,
|
||||
constrained_size
|
||||
);
|
||||
|
||||
*(unsigned32 *)the_thread->Wait.return_argument_1 = size;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
||||
(*api_message_queue_mp_support) ( the_thread, id );
|
||||
#endif
|
||||
|
||||
}
|
||||
*count = number_broadcasted;
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
67
c/src/exec/score/src/coremsgclose.c
Normal file
67
c/src/exec/score/src/coremsgclose.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* CORE Message Queue Handler
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This package is the implementation of the CORE Message Queue Handler.
|
||||
* This core object provides task synchronization and communication functions
|
||||
* via messages passed to queue objects.
|
||||
*
|
||||
* 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/score/chain.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/coremsg.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
#include <rtems/score/mpci.h>
|
||||
#endif
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Close
|
||||
*
|
||||
* This function closes a message by returning all allocated space and
|
||||
* flushing the message_queue's task wait queue.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - the message_queue to be flushed
|
||||
* remote_extract_callout - function to invoke remotely
|
||||
* status - status to pass to thread
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void _CORE_message_queue_Close(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
unsigned32 status
|
||||
)
|
||||
{
|
||||
|
||||
if ( the_message_queue->number_of_pending_messages != 0 )
|
||||
(void) _CORE_message_queue_Flush_support( the_message_queue );
|
||||
else
|
||||
_Thread_queue_Flush(
|
||||
&the_message_queue->Wait_queue,
|
||||
remote_extract_callout,
|
||||
status
|
||||
);
|
||||
|
||||
(void) _Workspace_Free( the_message_queue->message_buffers );
|
||||
|
||||
}
|
||||
|
||||
56
c/src/exec/score/src/coremsgflush.c
Normal file
56
c/src/exec/score/src/coremsgflush.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* CORE Message Queue Handler
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This package is the implementation of the CORE Message Queue Handler.
|
||||
* This core object provides task synchronization and communication functions
|
||||
* via messages passed to queue objects.
|
||||
*
|
||||
* 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/score/chain.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/coremsg.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
#include <rtems/score/mpci.h>
|
||||
#endif
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Flush
|
||||
*
|
||||
* This function flushes the message_queue's task wait queue. The number
|
||||
* of messages flushed from the queue is returned.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - the message_queue to be flushed
|
||||
*
|
||||
* Output parameters:
|
||||
* returns - the number of messages flushed from the queue
|
||||
*/
|
||||
|
||||
unsigned32 _CORE_message_queue_Flush(
|
||||
CORE_message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
if ( the_message_queue->number_of_pending_messages != 0 )
|
||||
return _CORE_message_queue_Flush_support( the_message_queue );
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
79
c/src/exec/score/src/coremsgflushsupp.c
Normal file
79
c/src/exec/score/src/coremsgflushsupp.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* CORE Message Queue Handler
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This package is the implementation of the CORE Message Queue Handler.
|
||||
* This core object provides task synchronization and communication functions
|
||||
* via messages passed to queue objects.
|
||||
*
|
||||
* 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/score/chain.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/coremsg.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
#include <rtems/score/mpci.h>
|
||||
#endif
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Flush_support
|
||||
*
|
||||
* This message handler routine removes all messages from a message queue
|
||||
* and returns them to the inactive message pool. The number of messages
|
||||
* flushed from the queue is returned
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - pointer to message queue
|
||||
*
|
||||
* Output parameters:
|
||||
* returns - number of messages placed on inactive chain
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* only case
|
||||
*/
|
||||
|
||||
unsigned32 _CORE_message_queue_Flush_support(
|
||||
CORE_message_queue_Control *the_message_queue
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Chain_Node *inactive_first;
|
||||
Chain_Node *message_queue_first;
|
||||
Chain_Node *message_queue_last;
|
||||
unsigned32 count;
|
||||
|
||||
_ISR_Disable( level );
|
||||
inactive_first = the_message_queue->Inactive_messages.first;
|
||||
message_queue_first = the_message_queue->Pending_messages.first;
|
||||
message_queue_last = the_message_queue->Pending_messages.last;
|
||||
|
||||
the_message_queue->Inactive_messages.first = message_queue_first;
|
||||
message_queue_last->next = inactive_first;
|
||||
inactive_first->previous = message_queue_last;
|
||||
message_queue_first->previous =
|
||||
_Chain_Head( &the_message_queue->Inactive_messages );
|
||||
|
||||
_Chain_Initialize_empty( &the_message_queue->Pending_messages );
|
||||
|
||||
count = the_message_queue->number_of_pending_messages;
|
||||
the_message_queue->number_of_pending_messages = 0;
|
||||
_ISR_Enable( level );
|
||||
return count;
|
||||
}
|
||||
|
||||
101
c/src/exec/score/src/coremsgseize.c
Normal file
101
c/src/exec/score/src/coremsgseize.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* CORE Message Queue Handler
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This package is the implementation of the CORE Message Queue Handler.
|
||||
* This core object provides task synchronization and communication functions
|
||||
* via messages passed to queue objects.
|
||||
*
|
||||
* 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/score/chain.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/coremsg.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
#include <rtems/score/mpci.h>
|
||||
#endif
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Seize
|
||||
*
|
||||
* This kernel routine dequeues a message, copies the message buffer to
|
||||
* a given destination buffer, and frees the message buffer to the
|
||||
* inactive message pool. The thread will be blocked if wait is TRUE,
|
||||
* otherwise an error will be given to the thread if no messages are available.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - pointer to message queue
|
||||
* id - id of object we are waitig on
|
||||
* buffer - pointer to message buffer to be filled
|
||||
* size - pointer to the size of buffer to be filled
|
||||
* wait - TRUE if wait is allowed, FALSE otherwise
|
||||
* timeout - time to wait for a message
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* NOTE: Dependent on BUFFER_LENGTH
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* available
|
||||
* wait
|
||||
*/
|
||||
|
||||
void _CORE_message_queue_Seize(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
Objects_Id id,
|
||||
void *buffer,
|
||||
unsigned32 *size,
|
||||
boolean wait,
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
CORE_message_queue_Buffer_control *the_message;
|
||||
Thread_Control *executing;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
_ISR_Disable( level );
|
||||
if ( the_message_queue->number_of_pending_messages != 0 ) {
|
||||
the_message_queue->number_of_pending_messages -= 1;
|
||||
|
||||
the_message = _CORE_message_queue_Get_pending_message( the_message_queue );
|
||||
_ISR_Enable( level );
|
||||
*size = the_message->Contents.size;
|
||||
_CORE_message_queue_Copy_buffer(the_message->Contents.buffer,buffer,*size );
|
||||
_CORE_message_queue_Free_message_buffer(the_message_queue, the_message );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !wait ) {
|
||||
_ISR_Enable( level );
|
||||
executing->Wait.return_code = CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED_NOWAIT;
|
||||
return;
|
||||
}
|
||||
|
||||
_Thread_queue_Enter_critical_section( &the_message_queue->Wait_queue );
|
||||
executing->Wait.queue = &the_message_queue->Wait_queue;
|
||||
executing->Wait.id = id;
|
||||
executing->Wait.return_argument = (void *)buffer;
|
||||
executing->Wait.return_argument_1 = (void *)size;
|
||||
_ISR_Enable( level );
|
||||
|
||||
_Thread_queue_Enqueue( &the_message_queue->Wait_queue, timeout );
|
||||
}
|
||||
|
||||
155
c/src/exec/score/src/coremsgsubmit.c
Normal file
155
c/src/exec/score/src/coremsgsubmit.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* CORE Message Queue Handler
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This package is the implementation of the CORE Message Queue Handler.
|
||||
* This core object provides task synchronization and communication functions
|
||||
* via messages passed to queue objects.
|
||||
*
|
||||
* 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/score/chain.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/object.h>
|
||||
#include <rtems/score/coremsg.h>
|
||||
#include <rtems/score/states.h>
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
#include <rtems/score/mpci.h>
|
||||
#endif
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_message_queue_Submit
|
||||
*
|
||||
* This routine implements the send and urgent message functions. It
|
||||
* processes a message that is to be submitted to the designated
|
||||
* message queue. The message will either be processed as a
|
||||
* send message which it will be inserted at the rear of the queue
|
||||
* or it will be processed as an urgent message which will be inserted
|
||||
* at the front of the queue.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_message_queue - message is submitted to this message queue
|
||||
* buffer - pointer to message buffer
|
||||
* size - size in bytes of message to send
|
||||
* id - id of message queue
|
||||
* api_message_queue_mp_support - api specific mp support callout
|
||||
* submit_type - send or urgent message
|
||||
*
|
||||
* Output parameters:
|
||||
* CORE_MESSAGE_QUEUE_SUCCESSFUL - if successful
|
||||
* error code - if unsuccessful
|
||||
*/
|
||||
|
||||
CORE_message_queue_Status _CORE_message_queue_Submit(
|
||||
CORE_message_queue_Control *the_message_queue,
|
||||
void *buffer,
|
||||
unsigned32 size,
|
||||
Objects_Id id,
|
||||
CORE_message_queue_API_mp_support_callout api_message_queue_mp_support,
|
||||
CORE_message_queue_Submit_types submit_type
|
||||
)
|
||||
{
|
||||
CORE_message_queue_Buffer_control *the_message;
|
||||
Thread_Control *the_thread;
|
||||
|
||||
if ( size > the_message_queue->maximum_message_size )
|
||||
return CORE_MESSAGE_QUEUE_STATUS_INVALID_SIZE;
|
||||
|
||||
/*
|
||||
* Is there a thread currently waiting on this message queue?
|
||||
*/
|
||||
|
||||
the_thread = _Thread_queue_Dequeue( &the_message_queue->Wait_queue );
|
||||
if ( the_thread )
|
||||
{
|
||||
_CORE_message_queue_Copy_buffer(
|
||||
buffer,
|
||||
the_thread->Wait.return_argument,
|
||||
size
|
||||
);
|
||||
*(unsigned32 *)the_thread->Wait.return_argument_1 = size;
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
||||
(*api_message_queue_mp_support) ( the_thread, id );
|
||||
#endif
|
||||
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* No one waiting on this one currently.
|
||||
* Allocate a message buffer and store it away
|
||||
*/
|
||||
|
||||
if ( the_message_queue->number_of_pending_messages ==
|
||||
the_message_queue->maximum_pending_messages ) {
|
||||
return CORE_MESSAGE_QUEUE_STATUS_TOO_MANY;
|
||||
}
|
||||
|
||||
the_message = _CORE_message_queue_Allocate_message_buffer(the_message_queue);
|
||||
if ( the_message == 0)
|
||||
return CORE_MESSAGE_QUEUE_STATUS_UNSATISFIED;
|
||||
|
||||
_CORE_message_queue_Copy_buffer( buffer, the_message->Contents.buffer, size );
|
||||
the_message->Contents.size = size;
|
||||
the_message->priority = submit_type;
|
||||
|
||||
the_message_queue->number_of_pending_messages += 1;
|
||||
|
||||
switch ( submit_type ) {
|
||||
case CORE_MESSAGE_QUEUE_SEND_REQUEST:
|
||||
_CORE_message_queue_Append( the_message_queue, the_message );
|
||||
break;
|
||||
case CORE_MESSAGE_QUEUE_URGENT_REQUEST:
|
||||
_CORE_message_queue_Prepend( the_message_queue, the_message );
|
||||
break;
|
||||
default:
|
||||
/* XXX interrupt critical section needs to be addressed */
|
||||
{
|
||||
CORE_message_queue_Buffer_control *this_message;
|
||||
Chain_Node *the_node;
|
||||
|
||||
the_message->priority = submit_type;
|
||||
for ( the_node = the_message_queue->Pending_messages.first ;
|
||||
!_Chain_Is_tail( &the_message_queue->Pending_messages, the_node ) ;
|
||||
the_node = the_node->next ) {
|
||||
|
||||
this_message = (CORE_message_queue_Buffer_control *) the_node;
|
||||
|
||||
if ( this_message->priority >= the_message->priority )
|
||||
continue;
|
||||
|
||||
_Chain_Insert( the_node, &the_message->Node );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* According to POSIX, does this happen before or after the message
|
||||
* is actually enqueued. It is logical to think afterwards, because
|
||||
* the message is actually in the queue at this point.
|
||||
*/
|
||||
|
||||
if ( the_message_queue->number_of_pending_messages == 1 &&
|
||||
the_message_queue->notify_handler )
|
||||
(*the_message_queue->notify_handler)( the_message_queue->notify_argument );
|
||||
|
||||
return CORE_MESSAGE_QUEUE_STATUS_SUCCESSFUL;
|
||||
}
|
||||
@@ -80,272 +80,3 @@ void _CORE_mutex_Initialize(
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_mutex_Seize
|
||||
*
|
||||
* This routine attempts to allocate a mutex to the calling thread.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_mutex - pointer to mutex control block
|
||||
* id - id of object to wait on
|
||||
* wait - TRUE if wait is allowed, FALSE otherwise
|
||||
* timeout - number of ticks to wait (0 means forever)
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* available
|
||||
* wait
|
||||
*/
|
||||
|
||||
void _CORE_mutex_Seize(
|
||||
CORE_mutex_Control *the_mutex,
|
||||
Objects_Id id,
|
||||
boolean wait,
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
Thread_Control *executing;
|
||||
ISR_Level level;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
switch ( the_mutex->Attributes.discipline ) {
|
||||
case CORE_MUTEX_DISCIPLINES_FIFO:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
|
||||
break;
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
|
||||
if ( executing->current_priority <
|
||||
the_mutex->Attributes.priority_ceiling) {
|
||||
executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL;
|
||||
_ISR_Disable( level );
|
||||
if ( ! _CORE_mutex_Is_locked( the_mutex ) ) {
|
||||
the_mutex->lock = CORE_MUTEX_LOCKED;
|
||||
the_mutex->holder = executing;
|
||||
the_mutex->holder_id = executing->Object.id;
|
||||
the_mutex->nest_count = 1;
|
||||
executing->resource_count++;
|
||||
_ISR_Enable( level );
|
||||
switch ( the_mutex->Attributes.discipline ) {
|
||||
case CORE_MUTEX_DISCIPLINES_FIFO:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
|
||||
/* already the highest priority */
|
||||
break;
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
|
||||
if ( the_mutex->Attributes.priority_ceiling <
|
||||
executing->current_priority ) {
|
||||
_Thread_Change_priority(
|
||||
the_mutex->holder,
|
||||
the_mutex->Attributes.priority_ceiling,
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( _Objects_Are_ids_equal(
|
||||
_Thread_Executing->Object.id, the_mutex->holder_id ) ) {
|
||||
if ( _CORE_mutex_Is_nesting_allowed( &the_mutex->Attributes ) )
|
||||
the_mutex->nest_count++;
|
||||
else
|
||||
executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED;
|
||||
|
||||
_ISR_Enable( level );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !wait ) {
|
||||
_ISR_Enable( level );
|
||||
executing->Wait.return_code = CORE_MUTEX_STATUS_UNSATISFIED_NOWAIT;
|
||||
return;
|
||||
}
|
||||
|
||||
_Thread_queue_Enter_critical_section( &the_mutex->Wait_queue );
|
||||
executing->Wait.queue = &the_mutex->Wait_queue;
|
||||
executing->Wait.id = id;
|
||||
_ISR_Enable( level );
|
||||
|
||||
switch ( the_mutex->Attributes.discipline ) {
|
||||
case CORE_MUTEX_DISCIPLINES_FIFO:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
|
||||
break;
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
|
||||
if ( the_mutex->holder->current_priority > executing->current_priority ) {
|
||||
_Thread_Change_priority(
|
||||
the_mutex->holder,
|
||||
executing->current_priority,
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_Thread_queue_Enqueue( &the_mutex->Wait_queue, timeout );
|
||||
|
||||
if ( _Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_SUCCESSFUL ) {
|
||||
switch ( the_mutex->Attributes.discipline ) {
|
||||
case CORE_MUTEX_DISCIPLINES_FIFO:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
|
||||
break;
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
|
||||
if ( the_mutex->Attributes.priority_ceiling <
|
||||
executing->current_priority ) {
|
||||
_Thread_Change_priority(
|
||||
executing,
|
||||
the_mutex->Attributes.priority_ceiling,
|
||||
FALSE
|
||||
);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* _CORE_mutex_Surrender
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* This routine frees a unit to the mutex. If a task was blocked waiting for
|
||||
* a unit from this mutex, then that task will be readied and the unit
|
||||
* given to that task. Otherwise, the unit will be returned to the mutex.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_mutex - the mutex to be flushed
|
||||
* id - id of parent mutex
|
||||
* api_mutex_mp_support - api dependent MP support actions
|
||||
*
|
||||
* Output parameters:
|
||||
* CORE_MUTEX_STATUS_SUCCESSFUL - if successful
|
||||
* core error code - if unsuccessful
|
||||
*/
|
||||
|
||||
CORE_mutex_Status _CORE_mutex_Surrender(
|
||||
CORE_mutex_Control *the_mutex,
|
||||
Objects_Id id,
|
||||
CORE_mutex_API_mp_support_callout api_mutex_mp_support
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
Thread_Control *executing;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
|
||||
/*
|
||||
* The following code allows a thread (or ISR) other than the thread
|
||||
* which acquired the mutex to release that mutex. This is only
|
||||
* allowed when the mutex in quetion is FIFO or simple Priority
|
||||
* discipline. But Priority Ceiling or Priority Inheritance mutexes
|
||||
* must be released by the thread which acquired them.
|
||||
*/
|
||||
|
||||
if ( !_Objects_Are_ids_equal(
|
||||
_Thread_Executing->Object.id, the_mutex->holder_id ) ) {
|
||||
|
||||
switch ( the_mutex->Attributes.discipline ) {
|
||||
case CORE_MUTEX_DISCIPLINES_FIFO:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY:
|
||||
break;
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
|
||||
return( CORE_MUTEX_STATUS_NOT_OWNER_OF_RESOURCE );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
the_mutex->nest_count--;
|
||||
|
||||
if ( the_mutex->nest_count != 0 )
|
||||
return( CORE_MUTEX_STATUS_SUCCESSFUL );
|
||||
|
||||
_Thread_Executing->resource_count--;
|
||||
the_mutex->holder = NULL;
|
||||
the_mutex->holder_id = 0;
|
||||
|
||||
/*
|
||||
* Whether or not someone is waiting for the mutex, an
|
||||
* inherited priority must be lowered if this is the last
|
||||
* mutex (i.e. resource) this task has.
|
||||
*/
|
||||
|
||||
switch ( the_mutex->Attributes.discipline ) {
|
||||
case CORE_MUTEX_DISCIPLINES_FIFO:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY:
|
||||
break;
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING:
|
||||
case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT:
|
||||
if ( executing->resource_count == 0 &&
|
||||
executing->real_priority != executing->current_priority ) {
|
||||
_Thread_Change_priority( executing, executing->real_priority, TRUE );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ( ( the_thread = _Thread_queue_Dequeue( &the_mutex->Wait_queue ) ) ) {
|
||||
|
||||
#if defined(RTEMS_MULTIPROCESSING)
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) ) {
|
||||
|
||||
the_mutex->holder = NULL;
|
||||
the_mutex->holder_id = the_thread->Object.id;
|
||||
the_mutex->nest_count = 1;
|
||||
|
||||
( *api_mutex_mp_support)( the_thread, id );
|
||||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
||||
the_mutex->holder = the_thread;
|
||||
the_mutex->holder_id = the_thread->Object.id;
|
||||
the_thread->resource_count++;
|
||||
the_mutex->nest_count = 1;
|
||||
|
||||
/*
|
||||
* No special action for priority inheritance or priority ceiling
|
||||
* because the_thread is guaranteed to be the highest priority
|
||||
* thread waiting for the mutex.
|
||||
*/
|
||||
}
|
||||
} else
|
||||
the_mutex->lock = CORE_MUTEX_UNLOCKED;
|
||||
|
||||
return( CORE_MUTEX_STATUS_SUCCESSFUL );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_mutex_Flush
|
||||
*
|
||||
* This function a flushes the mutex's task wait queue.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_mutex - the mutex to be flushed
|
||||
* remote_extract_callout - function to invoke remotely
|
||||
* status - status to pass to thread
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void _CORE_mutex_Flush(
|
||||
CORE_mutex_Control *the_mutex,
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
unsigned32 status
|
||||
)
|
||||
{
|
||||
_Thread_queue_Flush(
|
||||
&the_mutex->Wait_queue,
|
||||
remote_extract_callout,
|
||||
status
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,130 +67,3 @@ void _CORE_semaphore_Initialize(
|
||||
CORE_SEMAPHORE_TIMEOUT
|
||||
);
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_semaphore_Surrender
|
||||
*
|
||||
* Input parameters:
|
||||
* the_semaphore - the semaphore to be flushed
|
||||
* id - id of parent semaphore
|
||||
* api_semaphore_mp_support - api dependent MP support actions
|
||||
*
|
||||
* Output parameters:
|
||||
* CORE_SEMAPHORE_STATUS_SUCCESSFUL - if successful
|
||||
* core error code - if unsuccessful
|
||||
*
|
||||
* Output parameters:
|
||||
*/
|
||||
|
||||
CORE_semaphore_Status _CORE_semaphore_Surrender(
|
||||
CORE_semaphore_Control *the_semaphore,
|
||||
Objects_Id id,
|
||||
CORE_semaphore_API_mp_support_callout api_semaphore_mp_support
|
||||
)
|
||||
{
|
||||
Thread_Control *the_thread;
|
||||
ISR_Level level;
|
||||
CORE_semaphore_Status status;
|
||||
|
||||
status = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
|
||||
|
||||
if ( (the_thread = _Thread_queue_Dequeue(&the_semaphore->Wait_queue)) ) {
|
||||
|
||||
if ( !_Objects_Is_local_id( the_thread->Object.id ) )
|
||||
(*api_semaphore_mp_support) ( the_thread, id );
|
||||
|
||||
} else {
|
||||
_ISR_Disable( level );
|
||||
if ( the_semaphore->count <= the_semaphore->Attributes.maximum_count )
|
||||
the_semaphore->count += 1;
|
||||
else
|
||||
status = CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED;
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_semaphore_Seize
|
||||
*
|
||||
* This routine attempts to allocate a core semaphore to the calling thread.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_semaphore - pointer to semaphore control block
|
||||
* id - id of object to wait on
|
||||
* wait - TRUE if wait is allowed, FALSE otherwise
|
||||
* timeout - number of ticks to wait (0 means forever)
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*
|
||||
* INTERRUPT LATENCY:
|
||||
* available
|
||||
* wait
|
||||
*/
|
||||
|
||||
void _CORE_semaphore_Seize(
|
||||
CORE_semaphore_Control *the_semaphore,
|
||||
Objects_Id id,
|
||||
boolean wait,
|
||||
Watchdog_Interval timeout
|
||||
)
|
||||
{
|
||||
Thread_Control *executing;
|
||||
ISR_Level level;
|
||||
|
||||
executing = _Thread_Executing;
|
||||
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_SUCCESSFUL;
|
||||
_ISR_Disable( level );
|
||||
if ( the_semaphore->count != 0 ) {
|
||||
the_semaphore->count -= 1;
|
||||
_ISR_Enable( level );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !wait ) {
|
||||
_ISR_Enable( level );
|
||||
executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT;
|
||||
return;
|
||||
}
|
||||
|
||||
_Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue );
|
||||
executing->Wait.queue = &the_semaphore->Wait_queue;
|
||||
executing->Wait.id = id;
|
||||
_ISR_Enable( level );
|
||||
|
||||
_Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout );
|
||||
}
|
||||
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _CORE_semaphore_Flush
|
||||
*
|
||||
* This function a flushes the semaphore's task wait queue.
|
||||
*
|
||||
* Input parameters:
|
||||
* the_semaphore - the semaphore to be flushed
|
||||
* remote_extract_callout - function to invoke remotely
|
||||
* status - status to pass to thread
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void _CORE_semaphore_Flush(
|
||||
CORE_semaphore_Control *the_semaphore,
|
||||
Thread_queue_Flush_callout remote_extract_callout,
|
||||
unsigned32 status
|
||||
)
|
||||
{
|
||||
|
||||
_Thread_queue_Flush(
|
||||
&the_semaphore->Wait_queue,
|
||||
remote_extract_callout,
|
||||
status
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -37,237 +37,3 @@ void _Watchdog_Handler_initialization( void )
|
||||
_Chain_Initialize_empty( &_Watchdog_Ticks_chain );
|
||||
_Chain_Initialize_empty( &_Watchdog_Seconds_chain );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Remove
|
||||
*
|
||||
* The routine removes a watchdog from a delta chain and updates
|
||||
* the delta counters of the remaining watchdogs.
|
||||
*/
|
||||
|
||||
Watchdog_States _Watchdog_Remove(
|
||||
Watchdog_Control *the_watchdog
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Watchdog_States previous_state;
|
||||
Watchdog_Control *next_watchdog;
|
||||
|
||||
_ISR_Disable( level );
|
||||
previous_state = the_watchdog->state;
|
||||
switch ( previous_state ) {
|
||||
case WATCHDOG_INACTIVE:
|
||||
break;
|
||||
|
||||
case WATCHDOG_BEING_INSERTED:
|
||||
|
||||
/*
|
||||
* It is not actually on the chain so just change the state and
|
||||
* the Insert operation we interrupted will be aborted.
|
||||
*/
|
||||
the_watchdog->state = WATCHDOG_INACTIVE;
|
||||
break;
|
||||
|
||||
case WATCHDOG_ACTIVE:
|
||||
case WATCHDOG_REMOVE_IT:
|
||||
|
||||
the_watchdog->state = WATCHDOG_INACTIVE;
|
||||
next_watchdog = _Watchdog_Next( the_watchdog );
|
||||
|
||||
if ( _Watchdog_Next(next_watchdog) )
|
||||
next_watchdog->delta_interval += the_watchdog->delta_interval;
|
||||
|
||||
if ( _Watchdog_Sync_count )
|
||||
_Watchdog_Sync_level = _ISR_Nest_level;
|
||||
|
||||
_Chain_Extract_unprotected( &the_watchdog->Node );
|
||||
break;
|
||||
}
|
||||
the_watchdog->stop_time = _Watchdog_Ticks_since_boot;
|
||||
|
||||
_ISR_Enable( level );
|
||||
return( previous_state );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Adjust
|
||||
*
|
||||
* This routine adjusts the delta chain backward or forward in response
|
||||
* to a time change.
|
||||
*
|
||||
* Input parameters:
|
||||
* header - pointer to the delta chain to be adjusted
|
||||
* direction - forward or backward adjustment to delta chain
|
||||
* units - units to adjust
|
||||
*
|
||||
* Output parameters:
|
||||
*/
|
||||
|
||||
void _Watchdog_Adjust(
|
||||
Chain_Control *header,
|
||||
Watchdog_Adjust_directions direction,
|
||||
Watchdog_Interval units
|
||||
)
|
||||
{
|
||||
if ( !_Chain_Is_empty( header ) ) {
|
||||
switch ( direction ) {
|
||||
case WATCHDOG_BACKWARD:
|
||||
_Watchdog_First( header )->delta_interval += units;
|
||||
break;
|
||||
case WATCHDOG_FORWARD:
|
||||
while ( units ) {
|
||||
if ( units < _Watchdog_First( header )->delta_interval ) {
|
||||
_Watchdog_First( header )->delta_interval -= units;
|
||||
break;
|
||||
} else {
|
||||
units -= _Watchdog_First( header )->delta_interval;
|
||||
_Watchdog_First( header )->delta_interval = 1;
|
||||
_Watchdog_Tickle( header );
|
||||
if ( _Chain_Is_empty( header ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Insert
|
||||
*
|
||||
* This routine inserts a watchdog timer on to the appropriate delta
|
||||
* chain while updating the delta interval counters.
|
||||
*/
|
||||
|
||||
void _Watchdog_Insert(
|
||||
Chain_Control *header,
|
||||
Watchdog_Control *the_watchdog
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Watchdog_Control *after;
|
||||
unsigned32 insert_isr_nest_level;
|
||||
Watchdog_Interval delta_interval;
|
||||
|
||||
|
||||
insert_isr_nest_level = _ISR_Nest_level;
|
||||
the_watchdog->state = WATCHDOG_BEING_INSERTED;
|
||||
|
||||
_Watchdog_Sync_count++;
|
||||
restart:
|
||||
delta_interval = the_watchdog->initial;
|
||||
|
||||
_ISR_Disable( level );
|
||||
|
||||
for ( after = _Watchdog_First( header ) ;
|
||||
;
|
||||
after = _Watchdog_Next( after ) ) {
|
||||
|
||||
if ( delta_interval == 0 || !_Watchdog_Next( after ) )
|
||||
break;
|
||||
|
||||
if ( delta_interval < after->delta_interval ) {
|
||||
after->delta_interval -= delta_interval;
|
||||
break;
|
||||
}
|
||||
|
||||
delta_interval -= after->delta_interval;
|
||||
|
||||
/*
|
||||
* If you experience problems comment out the _ISR_Flash line.
|
||||
* 3.2.0 was the first release with this critical section redesigned.
|
||||
* Under certain circumstances, the PREVIOUS critical section algorithm
|
||||
* used around this flash point allowed interrupts to execute
|
||||
* which violated the design assumptions. The critical section
|
||||
* mechanism used here WAS redesigned to address this.
|
||||
*/
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( the_watchdog->state != WATCHDOG_BEING_INSERTED ) {
|
||||
goto exit_insert;
|
||||
}
|
||||
|
||||
if ( _Watchdog_Sync_level > insert_isr_nest_level ) {
|
||||
_Watchdog_Sync_level = insert_isr_nest_level;
|
||||
_ISR_Enable( level );
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
_Watchdog_Activate( the_watchdog );
|
||||
|
||||
the_watchdog->delta_interval = delta_interval;
|
||||
|
||||
_Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node );
|
||||
|
||||
the_watchdog->start_time = _Watchdog_Ticks_since_boot;
|
||||
|
||||
exit_insert:
|
||||
_Watchdog_Sync_level = insert_isr_nest_level;
|
||||
_Watchdog_Sync_count--;
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Tickle
|
||||
*
|
||||
* This routine decrements the delta counter in response to a tick. The
|
||||
* delta chain is updated accordingly.
|
||||
*
|
||||
* Input parameters:
|
||||
* header - pointer to the delta chain to be tickled
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void _Watchdog_Tickle(
|
||||
Chain_Control *header
|
||||
)
|
||||
{
|
||||
Watchdog_Control *the_watchdog;
|
||||
|
||||
if ( _Chain_Is_empty( header ) )
|
||||
return;
|
||||
|
||||
the_watchdog = _Watchdog_First( header );
|
||||
the_watchdog->delta_interval--;
|
||||
if ( the_watchdog->delta_interval != 0 )
|
||||
return;
|
||||
|
||||
do {
|
||||
switch( _Watchdog_Remove( the_watchdog ) ) {
|
||||
case WATCHDOG_ACTIVE:
|
||||
(*the_watchdog->routine)(
|
||||
the_watchdog->id,
|
||||
the_watchdog->user_data
|
||||
);
|
||||
break;
|
||||
|
||||
case WATCHDOG_INACTIVE:
|
||||
/*
|
||||
* This state indicates that the watchdog is not on any chain.
|
||||
* Thus, it is NOT on a chain being tickled. This case should
|
||||
* never occur.
|
||||
*/
|
||||
break;
|
||||
|
||||
case WATCHDOG_BEING_INSERTED:
|
||||
/*
|
||||
* This state indicates that the watchdog is in the process of
|
||||
* BEING inserted on the chain. Thus, it can NOT be on a chain
|
||||
* being tickled. This case should never occur.
|
||||
*/
|
||||
break;
|
||||
|
||||
case WATCHDOG_REMOVE_IT:
|
||||
break;
|
||||
}
|
||||
the_watchdog = _Watchdog_First( header );
|
||||
} while ( !_Chain_Is_empty( header ) &&
|
||||
(the_watchdog->delta_interval == 0) );
|
||||
}
|
||||
|
||||
63
c/src/exec/score/src/watchdogadjust.c
Normal file
63
c/src/exec/score/src/watchdogadjust.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Watchdog Handler
|
||||
*
|
||||
*
|
||||
* 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/score/isr.h>
|
||||
#include <rtems/score/watchdog.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Adjust
|
||||
*
|
||||
* This routine adjusts the delta chain backward or forward in response
|
||||
* to a time change.
|
||||
*
|
||||
* Input parameters:
|
||||
* header - pointer to the delta chain to be adjusted
|
||||
* direction - forward or backward adjustment to delta chain
|
||||
* units - units to adjust
|
||||
*
|
||||
* Output parameters:
|
||||
*/
|
||||
|
||||
void _Watchdog_Adjust(
|
||||
Chain_Control *header,
|
||||
Watchdog_Adjust_directions direction,
|
||||
Watchdog_Interval units
|
||||
)
|
||||
{
|
||||
if ( !_Chain_Is_empty( header ) ) {
|
||||
switch ( direction ) {
|
||||
case WATCHDOG_BACKWARD:
|
||||
_Watchdog_First( header )->delta_interval += units;
|
||||
break;
|
||||
case WATCHDOG_FORWARD:
|
||||
while ( units ) {
|
||||
if ( units < _Watchdog_First( header )->delta_interval ) {
|
||||
_Watchdog_First( header )->delta_interval -= units;
|
||||
break;
|
||||
} else {
|
||||
units -= _Watchdog_First( header )->delta_interval;
|
||||
_Watchdog_First( header )->delta_interval = 1;
|
||||
_Watchdog_Tickle( header );
|
||||
if ( _Chain_Is_empty( header ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
97
c/src/exec/score/src/watchdoginsert.c
Normal file
97
c/src/exec/score/src/watchdoginsert.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Watchdog Handler
|
||||
*
|
||||
*
|
||||
* 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/score/isr.h>
|
||||
#include <rtems/score/watchdog.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Insert
|
||||
*
|
||||
* This routine inserts a watchdog timer on to the appropriate delta
|
||||
* chain while updating the delta interval counters.
|
||||
*/
|
||||
|
||||
void _Watchdog_Insert(
|
||||
Chain_Control *header,
|
||||
Watchdog_Control *the_watchdog
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Watchdog_Control *after;
|
||||
unsigned32 insert_isr_nest_level;
|
||||
Watchdog_Interval delta_interval;
|
||||
|
||||
|
||||
insert_isr_nest_level = _ISR_Nest_level;
|
||||
the_watchdog->state = WATCHDOG_BEING_INSERTED;
|
||||
|
||||
_Watchdog_Sync_count++;
|
||||
restart:
|
||||
delta_interval = the_watchdog->initial;
|
||||
|
||||
_ISR_Disable( level );
|
||||
|
||||
for ( after = _Watchdog_First( header ) ;
|
||||
;
|
||||
after = _Watchdog_Next( after ) ) {
|
||||
|
||||
if ( delta_interval == 0 || !_Watchdog_Next( after ) )
|
||||
break;
|
||||
|
||||
if ( delta_interval < after->delta_interval ) {
|
||||
after->delta_interval -= delta_interval;
|
||||
break;
|
||||
}
|
||||
|
||||
delta_interval -= after->delta_interval;
|
||||
|
||||
/*
|
||||
* If you experience problems comment out the _ISR_Flash line.
|
||||
* 3.2.0 was the first release with this critical section redesigned.
|
||||
* Under certain circumstances, the PREVIOUS critical section algorithm
|
||||
* used around this flash point allowed interrupts to execute
|
||||
* which violated the design assumptions. The critical section
|
||||
* mechanism used here WAS redesigned to address this.
|
||||
*/
|
||||
|
||||
_ISR_Flash( level );
|
||||
|
||||
if ( the_watchdog->state != WATCHDOG_BEING_INSERTED ) {
|
||||
goto exit_insert;
|
||||
}
|
||||
|
||||
if ( _Watchdog_Sync_level > insert_isr_nest_level ) {
|
||||
_Watchdog_Sync_level = insert_isr_nest_level;
|
||||
_ISR_Enable( level );
|
||||
goto restart;
|
||||
}
|
||||
}
|
||||
|
||||
_Watchdog_Activate( the_watchdog );
|
||||
|
||||
the_watchdog->delta_interval = delta_interval;
|
||||
|
||||
_Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node );
|
||||
|
||||
the_watchdog->start_time = _Watchdog_Ticks_since_boot;
|
||||
|
||||
exit_insert:
|
||||
_Watchdog_Sync_level = insert_isr_nest_level;
|
||||
_Watchdog_Sync_count--;
|
||||
_ISR_Enable( level );
|
||||
}
|
||||
|
||||
71
c/src/exec/score/src/watchdogremove.c
Normal file
71
c/src/exec/score/src/watchdogremove.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Watchdog Handler
|
||||
*
|
||||
*
|
||||
* 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/score/isr.h>
|
||||
#include <rtems/score/watchdog.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Remove
|
||||
*
|
||||
* The routine removes a watchdog from a delta chain and updates
|
||||
* the delta counters of the remaining watchdogs.
|
||||
*/
|
||||
|
||||
Watchdog_States _Watchdog_Remove(
|
||||
Watchdog_Control *the_watchdog
|
||||
)
|
||||
{
|
||||
ISR_Level level;
|
||||
Watchdog_States previous_state;
|
||||
Watchdog_Control *next_watchdog;
|
||||
|
||||
_ISR_Disable( level );
|
||||
previous_state = the_watchdog->state;
|
||||
switch ( previous_state ) {
|
||||
case WATCHDOG_INACTIVE:
|
||||
break;
|
||||
|
||||
case WATCHDOG_BEING_INSERTED:
|
||||
|
||||
/*
|
||||
* It is not actually on the chain so just change the state and
|
||||
* the Insert operation we interrupted will be aborted.
|
||||
*/
|
||||
the_watchdog->state = WATCHDOG_INACTIVE;
|
||||
break;
|
||||
|
||||
case WATCHDOG_ACTIVE:
|
||||
case WATCHDOG_REMOVE_IT:
|
||||
|
||||
the_watchdog->state = WATCHDOG_INACTIVE;
|
||||
next_watchdog = _Watchdog_Next( the_watchdog );
|
||||
|
||||
if ( _Watchdog_Next(next_watchdog) )
|
||||
next_watchdog->delta_interval += the_watchdog->delta_interval;
|
||||
|
||||
if ( _Watchdog_Sync_count )
|
||||
_Watchdog_Sync_level = _ISR_Nest_level;
|
||||
|
||||
_Chain_Extract_unprotected( &the_watchdog->Node );
|
||||
break;
|
||||
}
|
||||
the_watchdog->stop_time = _Watchdog_Ticks_since_boot;
|
||||
|
||||
_ISR_Enable( level );
|
||||
return( previous_state );
|
||||
}
|
||||
|
||||
78
c/src/exec/score/src/watchdogtickle.c
Normal file
78
c/src/exec/score/src/watchdogtickle.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Watchdog Handler
|
||||
*
|
||||
*
|
||||
* 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/score/isr.h>
|
||||
#include <rtems/score/watchdog.h>
|
||||
|
||||
/*PAGE
|
||||
*
|
||||
* _Watchdog_Tickle
|
||||
*
|
||||
* This routine decrements the delta counter in response to a tick. The
|
||||
* delta chain is updated accordingly.
|
||||
*
|
||||
* Input parameters:
|
||||
* header - pointer to the delta chain to be tickled
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void _Watchdog_Tickle(
|
||||
Chain_Control *header
|
||||
)
|
||||
{
|
||||
Watchdog_Control *the_watchdog;
|
||||
|
||||
if ( _Chain_Is_empty( header ) )
|
||||
return;
|
||||
|
||||
the_watchdog = _Watchdog_First( header );
|
||||
the_watchdog->delta_interval--;
|
||||
if ( the_watchdog->delta_interval != 0 )
|
||||
return;
|
||||
|
||||
do {
|
||||
switch( _Watchdog_Remove( the_watchdog ) ) {
|
||||
case WATCHDOG_ACTIVE:
|
||||
(*the_watchdog->routine)(
|
||||
the_watchdog->id,
|
||||
the_watchdog->user_data
|
||||
);
|
||||
break;
|
||||
|
||||
case WATCHDOG_INACTIVE:
|
||||
/*
|
||||
* This state indicates that the watchdog is not on any chain.
|
||||
* Thus, it is NOT on a chain being tickled. This case should
|
||||
* never occur.
|
||||
*/
|
||||
break;
|
||||
|
||||
case WATCHDOG_BEING_INSERTED:
|
||||
/*
|
||||
* This state indicates that the watchdog is in the process of
|
||||
* BEING inserted on the chain. Thus, it can NOT be on a chain
|
||||
* being tickled. This case should never occur.
|
||||
*/
|
||||
break;
|
||||
|
||||
case WATCHDOG_REMOVE_IT:
|
||||
break;
|
||||
}
|
||||
the_watchdog = _Watchdog_First( header );
|
||||
} while ( !_Chain_Is_empty( header ) &&
|
||||
(the_watchdog->delta_interval == 0) );
|
||||
}
|
||||
Reference in New Issue
Block a user