diff options
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c | 2 | ||||
-rw-r--r-- | c/src/libchip/ide/ata.c | 2 | ||||
-rw-r--r-- | cpukit/posix/src/aio_cancel.c | 18 | ||||
-rw-r--r-- | cpukit/posix/src/aio_misc.c | 32 | ||||
-rw-r--r-- | cpukit/sapi/Makefile.am | 1 | ||||
-rw-r--r-- | cpukit/sapi/include/rtems/chain.h | 165 | ||||
-rw-r--r-- | cpukit/sapi/src/chainsmp.c | 138 | ||||
-rw-r--r-- | testsuites/libtests/block06/init.c | 4 | ||||
-rw-r--r-- | testsuites/sptests/spchain/init.c | 28 |
9 files changed, 326 insertions, 64 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c b/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c index 7b9eab422a..0856ad7535 100644 --- a/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c +++ b/c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c @@ -275,7 +275,7 @@ void mpc55xx_edma_release_channel(edma_channel_context *ctx) unsigned channel_index = edma_channel_index_of_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( MPC55XX_IRQ_EDMA(channel_index), diff --git a/c/src/libchip/ide/ata.c b/c/src/libchip/ide/ata.c index 8229714035..64238b7386 100644 --- a/c/src/libchip/ide/ata.c +++ b/c/src/libchip/ide/ata.c @@ -491,7 +491,7 @@ ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor, #endif 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)) { diff --git a/cpukit/posix/src/aio_cancel.c b/cpukit/posix/src/aio_cancel.c index 561e2f8776..aec554eec8 100644 --- a/cpukit/posix/src/aio_cancel.c +++ b/cpukit/posix/src/aio_cancel.c @@ -26,6 +26,8 @@ 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; int result; @@ -40,12 +42,12 @@ int aio_cancel(int fildes, struct aiocb *aiocbp) if (aiocbp == NULL) { 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) { AIO_printf ("Request chain not on [WQ]\n"); - if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) { - r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0); + if (!rtems_chain_is_empty (idle_req_chain)) { + r_chain = rtems_aio_search_fd (idle_req_chain, fildes, 0); if (r_chain == NULL) { pthread_mutex_unlock(&aio_request_queue.mutex); return AIO_ALLDONE; @@ -53,7 +55,7 @@ int aio_cancel(int fildes, struct aiocb *aiocbp) 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); pthread_mutex_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"); 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); pthread_mutex_unlock (&r_chain->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); } - 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 (!rtems_chain_is_empty (&aio_request_queue.idle_req)) { - r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0); + if (!rtems_chain_is_empty (idle_req_chain)) { + r_chain = rtems_aio_search_fd (idle_req_chain, fildes, 0); if (r_chain == NULL) { pthread_mutex_unlock (&aio_request_queue.mutex); rtems_set_errno_and_return_minus_one (EINVAL); diff --git a/cpukit/posix/src/aio_misc.c b/cpukit/posix/src/aio_misc.c index e4c40df84e..656ba41bab 100644 --- a/cpukit/posix/src/aio_misc.c +++ b/cpukit/posix/src/aio_misc.c @@ -120,7 +120,9 @@ rtems_aio_search_fd (rtems_chain_control *chain, int fildes, int create) if (rtems_chain_is_empty (chain)) rtems_chain_prepend (chain, &r_chain->next_fd); 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->fildes = fildes; @@ -144,19 +146,22 @@ rtems_aio_search_fd (rtems_chain_control *chain, int fildes, int create) static void 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_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; - while (temp->fildes < r_chain->fildes && - !rtems_chain_is_tail (&aio_request_queue.work_req, node)) { + while (temp->fildes < r_chain->fildes && + !rtems_chain_is_tail (work_req_chain, node)) { node = rtems_chain_next (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; } - 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)) { - rtems_chain_extract (node); + rtems_chain_explicit_extract (chain, node); rtems_aio_request *req = (rtems_aio_request *) node; node = rtems_chain_next (node); req->aiocbp->error_code = ECANCELED; @@ -265,7 +270,7 @@ int rtems_aio_remove_req (rtems_chain_control *chain, struct aiocb *aiocbp) return AIO_NOTCANCELED; else { - rtems_chain_extract (node); + rtems_chain_explicit_extract (chain, node); current->aiocbp->error_code = ECANCELED; current->aiocbp->return_value = -1; free (current); @@ -440,7 +445,7 @@ rtems_aio_handle (void *arg) param.sched_priority = req->priority; pthread_setschedparam (pthread_self(), req->policy, ¶m); - rtems_chain_extract (node); + rtems_chain_explicit_extract (chain, node); 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 the queue and start working with idle fd chains */ 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_cond_destroy (&r_chain->cond); free (r_chain); @@ -542,7 +548,7 @@ rtems_aio_handle (void *arg) ++aio_request_queue.active_threads; 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; rtems_aio_move_to_work (r_chain); diff --git a/cpukit/sapi/Makefile.am b/cpukit/sapi/Makefile.am index eaea5916e2..2a88aa3242 100644 --- a/cpukit/sapi/Makefile.am +++ b/cpukit/sapi/Makefile.am @@ -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/chainprependnotify.c src/rbheap.c src/interrdesc.c \ src/fatal2.c src/fatalsrcdesc.c +libsapi_a_SOURCES += src/chainsmp.c libsapi_a_CPPFLAGS = $(AM_CPPFLAGS) include $(srcdir)/preinstall.am diff --git a/cpukit/sapi/include/rtems/chain.h b/cpukit/sapi/include/rtems/chain.h index 7e48dc7470..09270558d8 100644 --- a/cpukit/sapi/include/rtems/chain.h +++ b/cpukit/sapi/include/rtems/chain.h @@ -19,6 +19,7 @@ #define _RTEMS_CHAIN_H #include <rtems/score/chainimpl.h> +#include <rtems/score/isrlock.h> #include <rtems/rtems/event.h> #ifdef __cplusplus @@ -36,13 +37,16 @@ extern "C" { 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. */ -#define RTEMS_CHAIN_INITIALIZER_EMPTY(name) \ - CHAIN_INITIALIZER_EMPTY(name) +#define RTEMS_CHAIN_INITIALIZER_EMPTY( name ) \ + { CHAIN_INITIALIZER_EMPTY( name.Chain ), ISR_LOCK_INITIALIZER } /** * @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(). */ #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. @@ -58,13 +62,13 @@ typedef Chain_Control rtems_chain_control; * @see RTEMS_CHAIN_INITIALIZER_ONE_NODE(). */ #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. */ -#define RTEMS_CHAIN_DEFINE_EMPTY(name) \ - CHAIN_DEFINE_EMPTY(name) +#define RTEMS_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 @@ -150,7 +154,13 @@ RTEMS_INLINE_ROUTINE void rtems_chain_initialize( 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 ) { - _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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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 ) { - 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. * @@ -561,6 +573,29 @@ RTEMS_INLINE_ROUTINE void rtems_chain_extract( { _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). @@ -589,12 +624,18 @@ RTEMS_INLINE_ROUTINE void rtems_chain_extract_unprotected( * * 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_chain_control *the_chain ) { - return _Chain_Get( the_chain ); + return _Chain_Get( &the_chain->Chain ); } +#endif /** * @brief See _Chain_Get_unprotected(). @@ -603,9 +644,10 @@ RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get_unprotected( 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 * @@ -622,6 +664,32 @@ RTEMS_INLINE_ROUTINE void rtems_chain_insert( { _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(). @@ -642,13 +710,20 @@ RTEMS_INLINE_ROUTINE void rtems_chain_insert_unprotected( * NOTE: It disables interrupts to ensure the atomicity of the * 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_chain_control *the_chain, 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). @@ -663,7 +738,7 @@ RTEMS_INLINE_ROUTINE void rtems_chain_append_unprotected( 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 * 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_chain_control *the_chain, rtems_chain_node *the_node ) { - _Chain_Prepend( the_chain, the_node ); + _Chain_Prepend( &the_chain->Chain, the_node ); } +#endif /** * @brief Prepend a node (unprotected). @@ -701,7 +783,7 @@ RTEMS_INLINE_ROUTINE void rtems_chain_prepend_unprotected( 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 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_chain_control *chain, 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. @@ -728,13 +817,20 @@ RTEMS_INLINE_ROUTINE bool rtems_chain_append_with_empty_check( * @retval true The chain was empty 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_chain_control *chain, 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 @@ -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 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_chain_control *chain, 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. @@ -770,7 +873,7 @@ RTEMS_INLINE_ROUTINE size_t rtems_chain_node_count_unprotected( const rtems_chain_control *chain ) { - return _Chain_Node_count_unprotected( chain ); + return _Chain_Node_count_unprotected( &chain->Chain ); } /** @} */ diff --git a/cpukit/sapi/src/chainsmp.c b/cpukit/sapi/src/chainsmp.c new file mode 100644 index 0000000000..ea8de83a0b --- /dev/null +++ b/cpukit/sapi/src/chainsmp.c @@ -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 ) */ diff --git a/testsuites/libtests/block06/init.c b/testsuites/libtests/block06/init.c index 6352aba933..e51bf2791c 100644 --- a/testsuites/libtests/block06/init.c +++ b/testsuites/libtests/block06/init.c @@ -1130,14 +1130,14 @@ bdbuf_tests_task_0_test_8 (bdbuf_task_control* tc) bd = (rtems_bdbuf_buffer*) node; pnode = node->previous; - rtems_chain_extract (node); + rtems_chain_explicit_extract (&buffers, node); node = pnode; bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[4]: ", tc->name); passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true); bd = (rtems_bdbuf_buffer*) node; pnode = node->previous; - rtems_chain_extract (node); + rtems_chain_explicit_extract (&buffers, node); node = pnode; bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name); passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true); diff --git a/testsuites/sptests/spchain/init.c b/testsuites/sptests/spchain/init.c index 219d0f3b52..747f4045c4 100644 --- a/testsuites/sptests/spchain/init.c +++ b/testsuites/sptests/spchain/init.c @@ -60,17 +60,29 @@ static void test_chain_control_initializer(void) static void test_chain_control_layout(void) { - rtems_chain_control chain; + Chain_Control chain; + puts( "INIT - Verify rtems_chain_control layout" ); + + rtems_test_assert( + sizeof(Chain_Control) + == sizeof(Chain_Node) + sizeof(Chain_Node *) + ); rtems_test_assert( - sizeof(rtems_chain_control) - == sizeof(rtems_chain_node) + sizeof(rtems_chain_node *) + sizeof(Chain_Control) + == 3 * sizeof(Chain_Node *) ); rtems_test_assert( - sizeof(rtems_chain_control) - == 3 * sizeof(rtems_chain_node *) + _Chain_Previous( _Chain_Head( &chain ) ) + == _Chain_Next( _Chain_Tail( &chain ) ) ); - rtems_test_assert( &chain.Head.Node.previous == &chain.Tail.Node.next ); + +#if !defined( RTEMS_SMP ) + rtems_test_assert( + sizeof(Chain_Control) + == sizeof(rtems_chain_control) + ); +#endif } 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_append( &chain, &node1 ); - rtems_chain_insert( &node1, &node2 ); + rtems_chain_explicit_insert( &chain, &node1, &node2 ); puts( "INIT - Verify rtems_chain_is_first" ); cnode = rtems_chain_first(&chain); @@ -296,7 +308,7 @@ rtems_task Init( node1.id = 1; node2.id = 2; 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 ; !rtems_chain_is_tail(&chain1, p) ; |