/*
|
/*
|
* Chain Handler
|
* Chain Handler
|
*
|
*
|
* NOTE:
|
* NOTE:
|
*
|
*
|
* The order of this file is to allow proper compilation due to the
|
* The order of this file is to allow proper compilation due to the
|
* order of inlining required by the compiler.
|
* order of inlining required by the compiler.
|
*
|
*
|
* COPYRIGHT (c) 1989-1999.
|
* COPYRIGHT (c) 1989-1999.
|
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
*
|
*
|
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
*
|
*
|
* chain.c,v 1.10 1999/11/17 17:50:38 joel Exp
|
* chain.c,v 1.10 1999/11/17 17:50:38 joel Exp
|
*/
|
*/
|
|
|
#include <rtems/system.h>
|
#include <rtems/system.h>
|
#include <rtems/score/address.h>
|
#include <rtems/score/address.h>
|
#include <rtems/score/chain.h>
|
#include <rtems/score/chain.h>
|
#include <rtems/score/isr.h>
|
#include <rtems/score/isr.h>
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Chain_Initialize
|
* _Chain_Initialize
|
*
|
*
|
* This kernel routine initializes a doubly linked chain.
|
* This kernel routine initializes a doubly linked chain.
|
*
|
*
|
* Input parameters:
|
* Input parameters:
|
* the_chain - pointer to chain header
|
* the_chain - pointer to chain header
|
* starting_address - starting address of first node
|
* starting_address - starting address of first node
|
* number_nodes - number of nodes in chain
|
* number_nodes - number of nodes in chain
|
* node_size - size of node in bytes
|
* node_size - size of node in bytes
|
*
|
*
|
* Output parameters: NONE
|
* Output parameters: NONE
|
*/
|
*/
|
|
|
void _Chain_Initialize(
|
void _Chain_Initialize(
|
Chain_Control *the_chain,
|
Chain_Control *the_chain,
|
void *starting_address,
|
void *starting_address,
|
unsigned32 number_nodes,
|
unsigned32 number_nodes,
|
unsigned32 node_size
|
unsigned32 node_size
|
)
|
)
|
{
|
{
|
unsigned32 count;
|
unsigned32 count;
|
Chain_Node *current;
|
Chain_Node *current;
|
Chain_Node *next;
|
Chain_Node *next;
|
|
|
count = number_nodes;
|
count = number_nodes;
|
current = _Chain_Head( the_chain );
|
current = _Chain_Head( the_chain );
|
the_chain->permanent_null = NULL;
|
the_chain->permanent_null = NULL;
|
next = (Chain_Node *)starting_address;
|
next = (Chain_Node *)starting_address;
|
while ( count-- ) {
|
while ( count-- ) {
|
current->next = next;
|
current->next = next;
|
next->previous = current;
|
next->previous = current;
|
current = next;
|
current = next;
|
next = (Chain_Node *)
|
next = (Chain_Node *)
|
_Addresses_Add_offset( (void *) next, node_size );
|
_Addresses_Add_offset( (void *) next, node_size );
|
}
|
}
|
current->next = _Chain_Tail( the_chain );
|
current->next = _Chain_Tail( the_chain );
|
the_chain->last = current;
|
the_chain->last = current;
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Chain_Get_first_unprotected
|
* _Chain_Get_first_unprotected
|
*/
|
*/
|
|
|
#ifndef USE_INLINES
|
#ifndef USE_INLINES
|
Chain_Node *_Chain_Get_first_unprotected(
|
Chain_Node *_Chain_Get_first_unprotected(
|
Chain_Control *the_chain
|
Chain_Control *the_chain
|
)
|
)
|
{
|
{
|
Chain_Node *return_node;
|
Chain_Node *return_node;
|
Chain_Node *new_first;
|
Chain_Node *new_first;
|
|
|
return_node = the_chain->first;
|
return_node = the_chain->first;
|
new_first = return_node->next;
|
new_first = return_node->next;
|
the_chain->first = new_first;
|
the_chain->first = new_first;
|
new_first->previous = _Chain_Head( the_chain );
|
new_first->previous = _Chain_Head( the_chain );
|
|
|
return return_node;
|
return return_node;
|
}
|
}
|
#endif /* USE_INLINES */
|
#endif /* USE_INLINES */
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Chain_Get
|
* _Chain_Get
|
*
|
*
|
* This kernel routine returns a pointer to a node taken from the
|
* This kernel routine returns a pointer to a node taken from the
|
* given chain.
|
* given chain.
|
*
|
*
|
* Input parameters:
|
* Input parameters:
|
* the_chain - pointer to chain header
|
* the_chain - pointer to chain header
|
*
|
*
|
* Output parameters:
|
* Output parameters:
|
* return_node - pointer to node in chain allocated
|
* return_node - pointer to node in chain allocated
|
* CHAIN_END - if no nodes available
|
* CHAIN_END - if no nodes available
|
*
|
*
|
* INTERRUPT LATENCY:
|
* INTERRUPT LATENCY:
|
* only case
|
* only case
|
*/
|
*/
|
|
|
Chain_Node *_Chain_Get(
|
Chain_Node *_Chain_Get(
|
Chain_Control *the_chain
|
Chain_Control *the_chain
|
)
|
)
|
{
|
{
|
ISR_Level level;
|
ISR_Level level;
|
Chain_Node *return_node;
|
Chain_Node *return_node;
|
|
|
return_node = NULL;
|
return_node = NULL;
|
_ISR_Disable( level );
|
_ISR_Disable( level );
|
if ( !_Chain_Is_empty( the_chain ) )
|
if ( !_Chain_Is_empty( the_chain ) )
|
return_node = _Chain_Get_first_unprotected( the_chain );
|
return_node = _Chain_Get_first_unprotected( the_chain );
|
_ISR_Enable( level );
|
_ISR_Enable( level );
|
return return_node;
|
return return_node;
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Chain_Append
|
* _Chain_Append
|
*
|
*
|
* This kernel routine puts a node on the end of the specified chain.
|
* This kernel routine puts a node on the end of the specified chain.
|
*
|
*
|
* Input parameters:
|
* Input parameters:
|
* the_chain - pointer to chain header
|
* the_chain - pointer to chain header
|
* node - address of node to put at rear of chain
|
* node - address of node to put at rear of chain
|
*
|
*
|
* Output parameters: NONE
|
* Output parameters: NONE
|
*
|
*
|
* INTERRUPT LATENCY:
|
* INTERRUPT LATENCY:
|
* only case
|
* only case
|
*/
|
*/
|
|
|
void _Chain_Append(
|
void _Chain_Append(
|
Chain_Control *the_chain,
|
Chain_Control *the_chain,
|
Chain_Node *node
|
Chain_Node *node
|
)
|
)
|
{
|
{
|
ISR_Level level;
|
ISR_Level level;
|
|
|
_ISR_Disable( level );
|
_ISR_Disable( level );
|
_Chain_Append_unprotected( the_chain, node );
|
_Chain_Append_unprotected( the_chain, node );
|
_ISR_Enable( level );
|
_ISR_Enable( level );
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Chain_Extract
|
* _Chain_Extract
|
*
|
*
|
* This kernel routine deletes the given node from a chain.
|
* This kernel routine deletes the given node from a chain.
|
*
|
*
|
* Input parameters:
|
* Input parameters:
|
* node - pointer to node in chain to be deleted
|
* node - pointer to node in chain to be deleted
|
*
|
*
|
* Output parameters: NONE
|
* Output parameters: NONE
|
*
|
*
|
* INTERRUPT LATENCY:
|
* INTERRUPT LATENCY:
|
* only case
|
* only case
|
*/
|
*/
|
|
|
void _Chain_Extract(
|
void _Chain_Extract(
|
Chain_Node *node
|
Chain_Node *node
|
)
|
)
|
{
|
{
|
ISR_Level level;
|
ISR_Level level;
|
|
|
_ISR_Disable( level );
|
_ISR_Disable( level );
|
_Chain_Extract_unprotected( node );
|
_Chain_Extract_unprotected( node );
|
_ISR_Enable( level );
|
_ISR_Enable( level );
|
}
|
}
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Chain_Insert
|
* _Chain_Insert
|
*
|
*
|
* This kernel routine inserts a given node after a specified node
|
* This kernel routine inserts a given node after a specified node
|
* a requested chain.
|
* a requested chain.
|
*
|
*
|
* Input parameters:
|
* Input parameters:
|
* after_node - pointer to node in chain to be inserted after
|
* after_node - pointer to node in chain to be inserted after
|
* node - pointer to node to be inserted
|
* node - pointer to node to be inserted
|
*
|
*
|
* Output parameters: NONE
|
* Output parameters: NONE
|
*
|
*
|
* INTERRUPT LATENCY:
|
* INTERRUPT LATENCY:
|
* only case
|
* only case
|
*/
|
*/
|
|
|
void _Chain_Insert(
|
void _Chain_Insert(
|
Chain_Node *after_node,
|
Chain_Node *after_node,
|
Chain_Node *node
|
Chain_Node *node
|
)
|
)
|
{
|
{
|
ISR_Level level;
|
ISR_Level level;
|
|
|
_ISR_Disable( level );
|
_ISR_Disable( level );
|
_Chain_Insert_unprotected( after_node, node );
|
_Chain_Insert_unprotected( after_node, node );
|
_ISR_Enable( level );
|
_ISR_Enable( level );
|
}
|
}
|
|
|