forked from Imagelibrary/rtems
sapi: SMP support for chains
Add ISR lock to chain control for proper SMP protection. Replace rtems_chain_extract() with rtems_chain_explicit_extract() and rtems_chain_insert() with rtems_chain_explicit_insert() on SMP configurations. Use rtems_chain_explicit_extract() and rtems_chain_explicit_insert() to provide SMP support.
This commit is contained in:
@@ -275,7 +275,7 @@ void mpc55xx_edma_release_channel(edma_channel_context *ctx)
|
|||||||
unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
|
unsigned channel_index = edma_channel_index_of_tcd(ctx->edma_tcd);
|
||||||
|
|
||||||
mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
|
mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
|
||||||
rtems_chain_extract(&ctx->node);
|
rtems_chain_explicit_extract(&edma_channel_chain, &ctx->node);
|
||||||
|
|
||||||
sc = rtems_interrupt_handler_remove(
|
sc = rtems_interrupt_handler_remove(
|
||||||
MPC55XX_IRQ_EDMA(channel_index),
|
MPC55XX_IRQ_EDMA(channel_index),
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ATA_EXEC_CALLBACK(areq, status);
|
ATA_EXEC_CALLBACK(areq, status);
|
||||||
rtems_chain_extract(&areq->link);
|
rtems_chain_explicit_extract(&ata_ide_ctrls[ctrl_minor].reqs, &areq->link);
|
||||||
|
|
||||||
if (!rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
|
if (!rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
|
|
||||||
int aio_cancel(int fildes, struct aiocb *aiocbp)
|
int aio_cancel(int fildes, struct aiocb *aiocbp)
|
||||||
{
|
{
|
||||||
|
rtems_chain_control *idle_req_chain = &aio_request_queue.idle_req;
|
||||||
|
rtems_chain_control *work_req_chain = &aio_request_queue.work_req;
|
||||||
rtems_aio_request_chain *r_chain;
|
rtems_aio_request_chain *r_chain;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@@ -40,12 +42,12 @@ int aio_cancel(int fildes, struct aiocb *aiocbp)
|
|||||||
if (aiocbp == NULL) {
|
if (aiocbp == NULL) {
|
||||||
AIO_printf ("Cancel all requests\n");
|
AIO_printf ("Cancel all requests\n");
|
||||||
|
|
||||||
r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0);
|
r_chain = rtems_aio_search_fd (work_req_chain, fildes, 0);
|
||||||
if (r_chain == NULL) {
|
if (r_chain == NULL) {
|
||||||
AIO_printf ("Request chain not on [WQ]\n");
|
AIO_printf ("Request chain not on [WQ]\n");
|
||||||
|
|
||||||
if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) {
|
if (!rtems_chain_is_empty (idle_req_chain)) {
|
||||||
r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0);
|
r_chain = rtems_aio_search_fd (idle_req_chain, fildes, 0);
|
||||||
if (r_chain == NULL) {
|
if (r_chain == NULL) {
|
||||||
pthread_mutex_unlock(&aio_request_queue.mutex);
|
pthread_mutex_unlock(&aio_request_queue.mutex);
|
||||||
return AIO_ALLDONE;
|
return AIO_ALLDONE;
|
||||||
@@ -53,7 +55,7 @@ int aio_cancel(int fildes, struct aiocb *aiocbp)
|
|||||||
|
|
||||||
AIO_printf ("Request chain on [IQ]\n");
|
AIO_printf ("Request chain on [IQ]\n");
|
||||||
|
|
||||||
rtems_chain_extract (&r_chain->next_fd);
|
rtems_chain_explicit_extract (idle_req_chain, &r_chain->next_fd);
|
||||||
rtems_aio_remove_fd (r_chain);
|
rtems_aio_remove_fd (r_chain);
|
||||||
pthread_mutex_destroy (&r_chain->mutex);
|
pthread_mutex_destroy (&r_chain->mutex);
|
||||||
pthread_cond_destroy (&r_chain->mutex);
|
pthread_cond_destroy (&r_chain->mutex);
|
||||||
@@ -70,7 +72,7 @@ int aio_cancel(int fildes, struct aiocb *aiocbp)
|
|||||||
AIO_printf ("Request chain on [WQ]\n");
|
AIO_printf ("Request chain on [WQ]\n");
|
||||||
|
|
||||||
pthread_mutex_lock (&r_chain->mutex);
|
pthread_mutex_lock (&r_chain->mutex);
|
||||||
rtems_chain_extract (&r_chain->next_fd);
|
rtems_chain_explicit_extract (work_req_chain, &r_chain->next_fd);
|
||||||
rtems_aio_remove_fd (r_chain);
|
rtems_aio_remove_fd (r_chain);
|
||||||
pthread_mutex_unlock (&r_chain->mutex);
|
pthread_mutex_unlock (&r_chain->mutex);
|
||||||
pthread_mutex_unlock (&aio_request_queue.mutex);
|
pthread_mutex_unlock (&aio_request_queue.mutex);
|
||||||
@@ -83,10 +85,10 @@ int aio_cancel(int fildes, struct aiocb *aiocbp)
|
|||||||
rtems_set_errno_and_return_minus_one (EINVAL);
|
rtems_set_errno_and_return_minus_one (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0);
|
r_chain = rtems_aio_search_fd (work_req_chain, fildes, 0);
|
||||||
if (r_chain == NULL) {
|
if (r_chain == NULL) {
|
||||||
if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) {
|
if (!rtems_chain_is_empty (idle_req_chain)) {
|
||||||
r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0);
|
r_chain = rtems_aio_search_fd (idle_req_chain, fildes, 0);
|
||||||
if (r_chain == NULL) {
|
if (r_chain == NULL) {
|
||||||
pthread_mutex_unlock (&aio_request_queue.mutex);
|
pthread_mutex_unlock (&aio_request_queue.mutex);
|
||||||
rtems_set_errno_and_return_minus_one (EINVAL);
|
rtems_set_errno_and_return_minus_one (EINVAL);
|
||||||
|
|||||||
@@ -120,7 +120,9 @@ rtems_aio_search_fd (rtems_chain_control *chain, int fildes, int create)
|
|||||||
if (rtems_chain_is_empty (chain))
|
if (rtems_chain_is_empty (chain))
|
||||||
rtems_chain_prepend (chain, &r_chain->next_fd);
|
rtems_chain_prepend (chain, &r_chain->next_fd);
|
||||||
else
|
else
|
||||||
rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd);
|
rtems_chain_explicit_insert (chain,
|
||||||
|
rtems_chain_previous (node),
|
||||||
|
&r_chain->next_fd);
|
||||||
|
|
||||||
r_chain->new_fd = 1;
|
r_chain->new_fd = 1;
|
||||||
r_chain->fildes = fildes;
|
r_chain->fildes = fildes;
|
||||||
@@ -144,19 +146,22 @@ rtems_aio_search_fd (rtems_chain_control *chain, int fildes, int create)
|
|||||||
static void
|
static void
|
||||||
rtems_aio_move_to_work (rtems_aio_request_chain *r_chain)
|
rtems_aio_move_to_work (rtems_aio_request_chain *r_chain)
|
||||||
{
|
{
|
||||||
|
rtems_chain_control *work_req_chain = &aio_request_queue.work_req;
|
||||||
rtems_aio_request_chain *temp;
|
rtems_aio_request_chain *temp;
|
||||||
rtems_chain_node *node;
|
rtems_chain_node *node;
|
||||||
|
|
||||||
node = rtems_chain_first (&aio_request_queue.work_req);
|
node = rtems_chain_first (work_req_chain);
|
||||||
temp = (rtems_aio_request_chain *) node;
|
temp = (rtems_aio_request_chain *) node;
|
||||||
|
|
||||||
while (temp->fildes < r_chain->fildes &&
|
while (temp->fildes < r_chain->fildes &&
|
||||||
!rtems_chain_is_tail (&aio_request_queue.work_req, node)) {
|
!rtems_chain_is_tail (work_req_chain, node)) {
|
||||||
node = rtems_chain_next (node);
|
node = rtems_chain_next (node);
|
||||||
temp = (rtems_aio_request_chain *) node;
|
temp = (rtems_aio_request_chain *) node;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd);
|
rtems_chain_explicit_insert (work_req_chain,
|
||||||
|
rtems_chain_previous (node),
|
||||||
|
&r_chain->next_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -195,7 +200,7 @@ rtems_aio_insert_prio (rtems_chain_control *chain, rtems_aio_request *req)
|
|||||||
prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio;
|
prio = ((rtems_aio_request *) node)->aiocbp->aio_reqprio;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtems_chain_insert (node->previous, &req->next_prio);
|
rtems_chain_explicit_insert (chain, node->previous, &req->next_prio);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,7 +226,7 @@ void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain)
|
|||||||
|
|
||||||
while (!rtems_chain_is_tail (chain, node))
|
while (!rtems_chain_is_tail (chain, node))
|
||||||
{
|
{
|
||||||
rtems_chain_extract (node);
|
rtems_chain_explicit_extract (chain, node);
|
||||||
rtems_aio_request *req = (rtems_aio_request *) node;
|
rtems_aio_request *req = (rtems_aio_request *) node;
|
||||||
node = rtems_chain_next (node);
|
node = rtems_chain_next (node);
|
||||||
req->aiocbp->error_code = ECANCELED;
|
req->aiocbp->error_code = ECANCELED;
|
||||||
@@ -265,7 +270,7 @@ int rtems_aio_remove_req (rtems_chain_control *chain, struct aiocb *aiocbp)
|
|||||||
return AIO_NOTCANCELED;
|
return AIO_NOTCANCELED;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rtems_chain_extract (node);
|
rtems_chain_explicit_extract (chain, node);
|
||||||
current->aiocbp->error_code = ECANCELED;
|
current->aiocbp->error_code = ECANCELED;
|
||||||
current->aiocbp->return_value = -1;
|
current->aiocbp->return_value = -1;
|
||||||
free (current);
|
free (current);
|
||||||
@@ -440,7 +445,7 @@ rtems_aio_handle (void *arg)
|
|||||||
param.sched_priority = req->priority;
|
param.sched_priority = req->priority;
|
||||||
pthread_setschedparam (pthread_self(), req->policy, ¶m);
|
pthread_setschedparam (pthread_self(), req->policy, ¶m);
|
||||||
|
|
||||||
rtems_chain_extract (node);
|
rtems_chain_explicit_extract (chain, node);
|
||||||
|
|
||||||
pthread_mutex_unlock (&r_chain->mutex);
|
pthread_mutex_unlock (&r_chain->mutex);
|
||||||
|
|
||||||
@@ -506,7 +511,8 @@ rtems_aio_handle (void *arg)
|
|||||||
/* If no requests were added to the chain we delete the fd chain from
|
/* If no requests were added to the chain we delete the fd chain from
|
||||||
the queue and start working with idle fd chains */
|
the queue and start working with idle fd chains */
|
||||||
if (result == ETIMEDOUT) {
|
if (result == ETIMEDOUT) {
|
||||||
rtems_chain_extract (&r_chain->next_fd);
|
rtems_chain_explicit_extract (&aio_request_queue.work_req,
|
||||||
|
&r_chain->next_fd);
|
||||||
pthread_mutex_destroy (&r_chain->mutex);
|
pthread_mutex_destroy (&r_chain->mutex);
|
||||||
pthread_cond_destroy (&r_chain->cond);
|
pthread_cond_destroy (&r_chain->cond);
|
||||||
free (r_chain);
|
free (r_chain);
|
||||||
@@ -542,7 +548,7 @@ rtems_aio_handle (void *arg)
|
|||||||
++aio_request_queue.active_threads;
|
++aio_request_queue.active_threads;
|
||||||
|
|
||||||
node = rtems_chain_first (&aio_request_queue.idle_req);
|
node = rtems_chain_first (&aio_request_queue.idle_req);
|
||||||
rtems_chain_extract (node);
|
rtems_chain_explicit_extract (&aio_request_queue.idle_req, node);
|
||||||
|
|
||||||
r_chain = (rtems_aio_request_chain *) node;
|
r_chain = (rtems_aio_request_chain *) node;
|
||||||
rtems_aio_move_to_work (r_chain);
|
rtems_aio_move_to_work (r_chain);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ libsapi_a_SOURCES = src/debug.c src/extension.c src/extensioncreate.c \
|
|||||||
src/chainappendnotify.c src/chaingetnotify.c src/chaingetwait.c \
|
src/chainappendnotify.c src/chaingetnotify.c src/chaingetwait.c \
|
||||||
src/chainprependnotify.c src/rbheap.c src/interrdesc.c \
|
src/chainprependnotify.c src/rbheap.c src/interrdesc.c \
|
||||||
src/fatal2.c src/fatalsrcdesc.c
|
src/fatal2.c src/fatalsrcdesc.c
|
||||||
|
libsapi_a_SOURCES += src/chainsmp.c
|
||||||
libsapi_a_CPPFLAGS = $(AM_CPPFLAGS)
|
libsapi_a_CPPFLAGS = $(AM_CPPFLAGS)
|
||||||
|
|
||||||
include $(srcdir)/preinstall.am
|
include $(srcdir)/preinstall.am
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#define _RTEMS_CHAIN_H
|
#define _RTEMS_CHAIN_H
|
||||||
|
|
||||||
#include <rtems/score/chainimpl.h>
|
#include <rtems/score/chainimpl.h>
|
||||||
|
#include <rtems/score/isrlock.h>
|
||||||
#include <rtems/rtems/event.h>
|
#include <rtems/rtems/event.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -36,13 +37,16 @@ extern "C" {
|
|||||||
|
|
||||||
typedef Chain_Node rtems_chain_node;
|
typedef Chain_Node rtems_chain_node;
|
||||||
|
|
||||||
typedef Chain_Control rtems_chain_control;
|
typedef struct {
|
||||||
|
Chain_Control Chain;
|
||||||
|
ISR_lock_Control Lock;
|
||||||
|
} rtems_chain_control;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Chain initializer for an empty chain with designator @a name.
|
* @brief Chain initializer for an empty chain with designator @a name.
|
||||||
*/
|
*/
|
||||||
#define RTEMS_CHAIN_INITIALIZER_EMPTY( name ) \
|
#define RTEMS_CHAIN_INITIALIZER_EMPTY( name ) \
|
||||||
CHAIN_INITIALIZER_EMPTY(name)
|
{ CHAIN_INITIALIZER_EMPTY( name.Chain ), ISR_LOCK_INITIALIZER }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Chain initializer for a chain with one @a node.
|
* @brief Chain initializer for a chain with one @a node.
|
||||||
@@ -50,7 +54,7 @@ typedef Chain_Control rtems_chain_control;
|
|||||||
* @see RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN().
|
* @see RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN().
|
||||||
*/
|
*/
|
||||||
#define RTEMS_CHAIN_INITIALIZER_ONE_NODE( node ) \
|
#define RTEMS_CHAIN_INITIALIZER_ONE_NODE( node ) \
|
||||||
CHAIN_INITIALIZER_ONE_NODE( node )
|
{ CHAIN_INITIALIZER_ONE_NODE( node ), ISR_LOCK_INITIALIZER }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Chain node initializer for a @a chain containing exactly this node.
|
* @brief Chain node initializer for a @a chain containing exactly this node.
|
||||||
@@ -58,13 +62,13 @@ typedef Chain_Control rtems_chain_control;
|
|||||||
* @see RTEMS_CHAIN_INITIALIZER_ONE_NODE().
|
* @see RTEMS_CHAIN_INITIALIZER_ONE_NODE().
|
||||||
*/
|
*/
|
||||||
#define RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
|
#define RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
|
||||||
CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain )
|
CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( &( chain )->Chain )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Chain definition for an empty chain with designator @a name.
|
* @brief Chain definition for an empty chain with designator @a name.
|
||||||
*/
|
*/
|
||||||
#define RTEMS_CHAIN_DEFINE_EMPTY( name ) \
|
#define RTEMS_CHAIN_DEFINE_EMPTY( name ) \
|
||||||
CHAIN_DEFINE_EMPTY(name)
|
rtems_chain_control name = RTEMS_CHAIN_INITIALIZER_EMPTY( name )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Appends the @a node to the @a chain and sends the @a events to the
|
* @brief Appends the @a node to the @a chain and sends the @a events to the
|
||||||
@@ -150,7 +154,13 @@ RTEMS_INLINE_ROUTINE void rtems_chain_initialize(
|
|||||||
size_t node_size
|
size_t node_size
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_Chain_Initialize( the_chain, starting_address, number_nodes, node_size );
|
_ISR_lock_Initialize( &the_chain->Lock );
|
||||||
|
_Chain_Initialize(
|
||||||
|
&the_chain->Chain,
|
||||||
|
starting_address,
|
||||||
|
number_nodes,
|
||||||
|
node_size
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -164,7 +174,8 @@ RTEMS_INLINE_ROUTINE void rtems_chain_initialize_empty(
|
|||||||
rtems_chain_control *the_chain
|
rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_Chain_Initialize_empty( the_chain );
|
_ISR_lock_Initialize( &the_chain->Lock );
|
||||||
|
_Chain_Initialize_empty( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,7 +241,7 @@ RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_head(
|
|||||||
rtems_chain_control *the_chain
|
rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Head( the_chain );
|
return _Chain_Head( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -246,7 +257,7 @@ RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_head(
|
|||||||
const rtems_chain_control *the_chain
|
const rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Immutable_head( the_chain );
|
return _Chain_Immutable_head( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -262,7 +273,7 @@ RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_tail(
|
|||||||
rtems_chain_control *the_chain
|
rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Tail( the_chain );
|
return _Chain_Tail( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -278,7 +289,7 @@ RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_tail(
|
|||||||
const rtems_chain_control *the_chain
|
const rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Immutable_tail( the_chain );
|
return _Chain_Immutable_tail( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -295,7 +306,7 @@ RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_first(
|
|||||||
rtems_chain_control *the_chain
|
rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_First( the_chain );
|
return _Chain_First( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -312,7 +323,7 @@ RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_first(
|
|||||||
const rtems_chain_control *the_chain
|
const rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Immutable_first( the_chain );
|
return _Chain_Immutable_first( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -329,7 +340,7 @@ RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_last(
|
|||||||
rtems_chain_control *the_chain
|
rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Last( the_chain );
|
return _Chain_Last( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -346,7 +357,7 @@ RTEMS_INLINE_ROUTINE const rtems_chain_node *rtems_chain_immutable_last(
|
|||||||
const rtems_chain_control *the_chain
|
const rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Immutable_last( the_chain );
|
return _Chain_Immutable_last( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -448,7 +459,7 @@ RTEMS_INLINE_ROUTINE bool rtems_chain_is_empty(
|
|||||||
const rtems_chain_control *the_chain
|
const rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Is_empty( the_chain );
|
return _Chain_Is_empty( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -503,7 +514,7 @@ RTEMS_INLINE_ROUTINE bool rtems_chain_has_only_one_node(
|
|||||||
const rtems_chain_control *the_chain
|
const rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Has_only_one_node( the_chain );
|
return _Chain_Has_only_one_node( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -523,7 +534,7 @@ RTEMS_INLINE_ROUTINE bool rtems_chain_is_head(
|
|||||||
const rtems_chain_node *the_node
|
const rtems_chain_node *the_node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Is_head( the_chain, the_node );
|
return _Chain_Is_head( &the_chain->Chain, the_node );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -543,9 +554,10 @@ RTEMS_INLINE_ROUTINE bool rtems_chain_is_tail(
|
|||||||
const rtems_chain_node *the_node
|
const rtems_chain_node *the_node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Is_tail( the_chain, the_node );
|
return _Chain_Is_tail( &the_chain->Chain, the_node );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( RTEMS_SMP )
|
||||||
/**
|
/**
|
||||||
* @brief Extract the specified node from a chain.
|
* @brief Extract the specified node from a chain.
|
||||||
*
|
*
|
||||||
@@ -561,6 +573,29 @@ RTEMS_INLINE_ROUTINE void rtems_chain_extract(
|
|||||||
{
|
{
|
||||||
_Chain_Extract( the_node );
|
_Chain_Extract( the_node );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
/**
|
||||||
|
* @brief Extract the specified node from a chain.
|
||||||
|
*
|
||||||
|
* @param[in,out] chain The chain containing the node.
|
||||||
|
* @param[in,out] node The node to extract.
|
||||||
|
*/
|
||||||
|
void rtems_chain_explicit_extract(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
RTEMS_INLINE_ROUTINE void rtems_chain_explicit_extract(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
( void ) chain;
|
||||||
|
rtems_chain_extract( node );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extract the specified node from a chain (unprotected).
|
* @brief Extract the specified node from a chain (unprotected).
|
||||||
@@ -589,12 +624,18 @@ RTEMS_INLINE_ROUTINE void rtems_chain_extract_unprotected(
|
|||||||
*
|
*
|
||||||
* NOTE: It disables interrupts to ensure the atomicity of the get operation.
|
* NOTE: It disables interrupts to ensure the atomicity of the get operation.
|
||||||
*/
|
*/
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
rtems_chain_node *rtems_chain_get(
|
||||||
|
rtems_chain_control *the_chain
|
||||||
|
);
|
||||||
|
#else
|
||||||
RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get(
|
RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get(
|
||||||
rtems_chain_control *the_chain
|
rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Get( the_chain );
|
return _Chain_Get( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief See _Chain_Get_unprotected().
|
* @brief See _Chain_Get_unprotected().
|
||||||
@@ -603,9 +644,10 @@ RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_unprotected(
|
|||||||
rtems_chain_control *the_chain
|
rtems_chain_control *the_chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Get_unprotected( the_chain );
|
return _Chain_Get_unprotected( &the_chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined( RTEMS_SMP )
|
||||||
/**
|
/**
|
||||||
* @brief Insert a node on a chain
|
* @brief Insert a node on a chain
|
||||||
*
|
*
|
||||||
@@ -622,6 +664,32 @@ RTEMS_INLINE_ROUTINE void rtems_chain_insert(
|
|||||||
{
|
{
|
||||||
_Chain_Insert( after_node, the_node );
|
_Chain_Insert( after_node, the_node );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Insert a node on a chain
|
||||||
|
*
|
||||||
|
* @param[in,out] chain The chain containing the after node.
|
||||||
|
* @param[in,out] after_node Insert the node after this node.
|
||||||
|
* @param[in,out] node The node to insert.
|
||||||
|
*/
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
void rtems_chain_explicit_insert(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *after_node,
|
||||||
|
rtems_chain_node *node
|
||||||
|
);
|
||||||
|
#else
|
||||||
|
RTEMS_INLINE_ROUTINE void rtems_chain_explicit_insert(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *after_node,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
( void ) chain;
|
||||||
|
rtems_chain_insert( after_node, node );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief See _Chain_Insert_unprotected().
|
* @brief See _Chain_Insert_unprotected().
|
||||||
@@ -642,13 +710,20 @@ RTEMS_INLINE_ROUTINE void rtems_chain_insert_unprotected(
|
|||||||
* NOTE: It disables interrupts to ensure the atomicity of the
|
* NOTE: It disables interrupts to ensure the atomicity of the
|
||||||
* append operation.
|
* append operation.
|
||||||
*/
|
*/
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
void rtems_chain_append(
|
||||||
|
rtems_chain_control *the_chain,
|
||||||
|
rtems_chain_node *the_node
|
||||||
|
);
|
||||||
|
#else
|
||||||
RTEMS_INLINE_ROUTINE void rtems_chain_append(
|
RTEMS_INLINE_ROUTINE void rtems_chain_append(
|
||||||
rtems_chain_control *the_chain,
|
rtems_chain_control *the_chain,
|
||||||
rtems_chain_node *the_node
|
rtems_chain_node *the_node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_Chain_Append( the_chain, the_node );
|
_Chain_Append( &the_chain->Chain, the_node );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Append a node on the end of a chain (unprotected).
|
* @brief Append a node on the end of a chain (unprotected).
|
||||||
@@ -663,7 +738,7 @@ RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected(
|
|||||||
rtems_chain_node *the_node
|
rtems_chain_node *the_node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_Chain_Append_unprotected( the_chain, the_node );
|
_Chain_Append_unprotected( &the_chain->Chain, the_node );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -677,13 +752,20 @@ RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected(
|
|||||||
* NOTE: It disables interrupts to ensure the atomicity of the
|
* NOTE: It disables interrupts to ensure the atomicity of the
|
||||||
* prepend operation.
|
* prepend operation.
|
||||||
*/
|
*/
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
void rtems_chain_prepend(
|
||||||
|
rtems_chain_control *the_chain,
|
||||||
|
rtems_chain_node *the_node
|
||||||
|
);
|
||||||
|
#else
|
||||||
RTEMS_INLINE_ROUTINE void rtems_chain_prepend(
|
RTEMS_INLINE_ROUTINE void rtems_chain_prepend(
|
||||||
rtems_chain_control *the_chain,
|
rtems_chain_control *the_chain,
|
||||||
rtems_chain_node *the_node
|
rtems_chain_node *the_node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_Chain_Prepend( the_chain, the_node );
|
_Chain_Prepend( &the_chain->Chain, the_node );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prepend a node (unprotected).
|
* @brief Prepend a node (unprotected).
|
||||||
@@ -701,7 +783,7 @@ RTEMS_INLINE_ROUTINE void rtems_chain_prepend_unprotected(
|
|||||||
rtems_chain_node *the_node
|
rtems_chain_node *the_node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_Chain_Prepend_unprotected( the_chain, the_node );
|
_Chain_Prepend_unprotected( &the_chain->Chain, the_node );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -712,13 +794,20 @@ RTEMS_INLINE_ROUTINE void rtems_chain_prepend_unprotected(
|
|||||||
* @retval true The chain was empty before the append.
|
* @retval true The chain was empty before the append.
|
||||||
* @retval false The chain contained at least one node before the append.
|
* @retval false The chain contained at least one node before the append.
|
||||||
*/
|
*/
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
bool rtems_chain_append_with_empty_check(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
);
|
||||||
|
#else
|
||||||
RTEMS_INLINE_ROUTINE bool rtems_chain_append_with_empty_check(
|
RTEMS_INLINE_ROUTINE bool rtems_chain_append_with_empty_check(
|
||||||
rtems_chain_control *chain,
|
rtems_chain_control *chain,
|
||||||
rtems_chain_node *node
|
rtems_chain_node *node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Append_with_empty_check( chain, node );
|
return _Chain_Append_with_empty_check( &chain->Chain, node );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if the @a chain is empty and prepends the @a node.
|
* @brief Checks if the @a chain is empty and prepends the @a node.
|
||||||
@@ -728,13 +817,20 @@ RTEMS_INLINE_ROUTINE bool rtems_chain_append_with_empty_check(
|
|||||||
* @retval true The chain was empty before the prepend.
|
* @retval true The chain was empty before the prepend.
|
||||||
* @retval false The chain contained at least one node before the prepend.
|
* @retval false The chain contained at least one node before the prepend.
|
||||||
*/
|
*/
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
bool rtems_chain_prepend_with_empty_check(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
);
|
||||||
|
#else
|
||||||
RTEMS_INLINE_ROUTINE bool rtems_chain_prepend_with_empty_check(
|
RTEMS_INLINE_ROUTINE bool rtems_chain_prepend_with_empty_check(
|
||||||
rtems_chain_control *chain,
|
rtems_chain_control *chain,
|
||||||
rtems_chain_node *node
|
rtems_chain_node *node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Prepend_with_empty_check( chain, node );
|
return _Chain_Prepend_with_empty_check( &chain->Chain, node );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tries to get the first @a node and check if the @a chain is empty
|
* @brief Tries to get the first @a node and check if the @a chain is empty
|
||||||
@@ -748,13 +844,20 @@ RTEMS_INLINE_ROUTINE bool rtems_chain_prepend_with_empty_check(
|
|||||||
* @retval true The chain is empty after the node removal.
|
* @retval true The chain is empty after the node removal.
|
||||||
* @retval false The chain contained at least one node after the node removal.
|
* @retval false The chain contained at least one node after the node removal.
|
||||||
*/
|
*/
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
bool rtems_chain_get_with_empty_check(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node **node
|
||||||
|
);
|
||||||
|
#else
|
||||||
RTEMS_INLINE_ROUTINE bool rtems_chain_get_with_empty_check(
|
RTEMS_INLINE_ROUTINE bool rtems_chain_get_with_empty_check(
|
||||||
rtems_chain_control *chain,
|
rtems_chain_control *chain,
|
||||||
rtems_chain_node **node
|
rtems_chain_node **node
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Get_with_empty_check( chain, node );
|
return _Chain_Get_with_empty_check( &chain->Chain, node );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the node count of the chain.
|
* @brief Returns the node count of the chain.
|
||||||
@@ -770,7 +873,7 @@ RTEMS_INLINE_ROUTINE size_t rtems_chain_node_count_unprotected(
|
|||||||
const rtems_chain_control *chain
|
const rtems_chain_control *chain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return _Chain_Node_count_unprotected( chain );
|
return _Chain_Node_count_unprotected( &chain->Chain );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
138
cpukit/sapi/src/chainsmp.c
Normal file
138
cpukit/sapi/src/chainsmp.c
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||||
|
*
|
||||||
|
* embedded brains GmbH
|
||||||
|
* Dornierstr. 4
|
||||||
|
* 82178 Puchheim
|
||||||
|
* Germany
|
||||||
|
* <rtems@embedded-brains.de>
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rtems.com/license/LICENSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <rtems/chain.h>
|
||||||
|
|
||||||
|
#if defined( RTEMS_SMP )
|
||||||
|
|
||||||
|
void rtems_chain_explicit_extract(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
_Chain_Extract_unprotected( node );
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
}
|
||||||
|
|
||||||
|
rtems_chain_node *rtems_chain_get( rtems_chain_control *chain )
|
||||||
|
{
|
||||||
|
rtems_chain_node *node;
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
node = _Chain_Get_unprotected( &chain->Chain );
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtems_chain_explicit_insert(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *after_node,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
_Chain_Insert_unprotected( after_node, node );
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtems_chain_append(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
_Chain_Append_unprotected( &chain->Chain, node );
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtems_chain_prepend(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
_Chain_Prepend_unprotected( &chain->Chain, node );
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rtems_chain_append_with_empty_check(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool was_empty;
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
was_empty = _Chain_Append_with_empty_check_unprotected(
|
||||||
|
&chain->Chain,
|
||||||
|
node
|
||||||
|
);
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
|
||||||
|
return was_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rtems_chain_prepend_with_empty_check(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node *node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool was_empty;
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
was_empty = _Chain_Prepend_with_empty_check_unprotected(
|
||||||
|
&chain->Chain,
|
||||||
|
node
|
||||||
|
);
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
|
||||||
|
return was_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rtems_chain_get_with_empty_check(
|
||||||
|
rtems_chain_control *chain,
|
||||||
|
rtems_chain_node **node
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool is_empty_now;
|
||||||
|
ISR_Level level;
|
||||||
|
|
||||||
|
_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
|
||||||
|
is_empty_now = _Chain_Get_with_empty_check_unprotected(
|
||||||
|
&chain->Chain,
|
||||||
|
node
|
||||||
|
);
|
||||||
|
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
|
||||||
|
|
||||||
|
return is_empty_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* defined( RTEMS_SMP ) */
|
||||||
@@ -1130,14 +1130,14 @@ bdbuf_tests_task_0_test_8 (bdbuf_task_control* tc)
|
|||||||
|
|
||||||
bd = (rtems_bdbuf_buffer*) node;
|
bd = (rtems_bdbuf_buffer*) node;
|
||||||
pnode = node->previous;
|
pnode = node->previous;
|
||||||
rtems_chain_extract (node);
|
rtems_chain_explicit_extract (&buffers, node);
|
||||||
node = pnode;
|
node = pnode;
|
||||||
bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[4]: ", tc->name);
|
bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[4]: ", tc->name);
|
||||||
passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);
|
passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);
|
||||||
|
|
||||||
bd = (rtems_bdbuf_buffer*) node;
|
bd = (rtems_bdbuf_buffer*) node;
|
||||||
pnode = node->previous;
|
pnode = node->previous;
|
||||||
rtems_chain_extract (node);
|
rtems_chain_explicit_extract (&buffers, node);
|
||||||
node = pnode;
|
node = pnode;
|
||||||
bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name);
|
bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name);
|
||||||
passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);
|
passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true);
|
||||||
|
|||||||
@@ -60,17 +60,29 @@ static void test_chain_control_initializer(void)
|
|||||||
|
|
||||||
static void test_chain_control_layout(void)
|
static void test_chain_control_layout(void)
|
||||||
{
|
{
|
||||||
rtems_chain_control chain;
|
Chain_Control chain;
|
||||||
|
|
||||||
puts( "INIT - Verify rtems_chain_control layout" );
|
puts( "INIT - Verify rtems_chain_control layout" );
|
||||||
|
|
||||||
rtems_test_assert(
|
rtems_test_assert(
|
||||||
sizeof(rtems_chain_control)
|
sizeof(Chain_Control)
|
||||||
== sizeof(rtems_chain_node) + sizeof(rtems_chain_node *)
|
== sizeof(Chain_Node) + sizeof(Chain_Node *)
|
||||||
);
|
);
|
||||||
rtems_test_assert(
|
rtems_test_assert(
|
||||||
sizeof(rtems_chain_control)
|
sizeof(Chain_Control)
|
||||||
== 3 * sizeof(rtems_chain_node *)
|
== 3 * sizeof(Chain_Node *)
|
||||||
);
|
);
|
||||||
rtems_test_assert( &chain.Head.Node.previous == &chain.Tail.Node.next );
|
rtems_test_assert(
|
||||||
|
_Chain_Previous( _Chain_Head( &chain ) )
|
||||||
|
== _Chain_Next( _Chain_Tail( &chain ) )
|
||||||
|
);
|
||||||
|
|
||||||
|
#if !defined( RTEMS_SMP )
|
||||||
|
rtems_test_assert(
|
||||||
|
sizeof(Chain_Control)
|
||||||
|
== sizeof(rtems_chain_control)
|
||||||
|
);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_chain_get_with_wait(void)
|
static void test_chain_get_with_wait(void)
|
||||||
@@ -94,7 +106,7 @@ static void test_chain_first_and_last(void)
|
|||||||
|
|
||||||
rtems_chain_initialize_empty( &chain );
|
rtems_chain_initialize_empty( &chain );
|
||||||
rtems_chain_append( &chain, &node1 );
|
rtems_chain_append( &chain, &node1 );
|
||||||
rtems_chain_insert( &node1, &node2 );
|
rtems_chain_explicit_insert( &chain, &node1, &node2 );
|
||||||
|
|
||||||
puts( "INIT - Verify rtems_chain_is_first" );
|
puts( "INIT - Verify rtems_chain_is_first" );
|
||||||
cnode = rtems_chain_first(&chain);
|
cnode = rtems_chain_first(&chain);
|
||||||
@@ -296,7 +308,7 @@ rtems_task Init(
|
|||||||
node1.id = 1;
|
node1.id = 1;
|
||||||
node2.id = 2;
|
node2.id = 2;
|
||||||
rtems_chain_append( &chain1, &node1.Node );
|
rtems_chain_append( &chain1, &node1.Node );
|
||||||
rtems_chain_insert( &node1.Node, &node2.Node );
|
rtems_chain_explicit_insert( &chain1, &node1.Node, &node2.Node );
|
||||||
|
|
||||||
for ( p = rtems_chain_first(&chain1), id = 1 ;
|
for ( p = rtems_chain_first(&chain1), id = 1 ;
|
||||||
!rtems_chain_is_tail(&chain1, p) ;
|
!rtems_chain_is_tail(&chain1, p) ;
|
||||||
|
|||||||
Reference in New Issue
Block a user