From a19ae9ec60ee19600fca7c24fd28c47b37903bbb Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 23 Aug 2010 16:10:53 +0000 Subject: 2010-08-23 Sebastian Huber PR 1673/cpukit * score/src/chainappendempty.c, score/src/chaingetempty.c, score/src/chainprependempty.c: New files. * score/Makefile.am: Reflect changes above. * score/include/rtems/score/chain.h: Declare _Chain_Append_with_empty_check(), _Chain_Prepend_with_empty_check(), and _Chain_Get_with_empty_check(). * score/inline/rtems/score/chain.inl: Define _Chain_Append_with_empty_check_unprotected(), _Chain_Prepend_with_empty_check_unprotected(), and _Chain_Get_with_empty_check_unprotected(). --- cpukit/ChangeLog | 14 ++++ cpukit/score/Makefile.am | 1 + cpukit/score/include/rtems/score/chain.h | 71 +++++++++++++++++++- cpukit/score/inline/rtems/score/chain.inl | 104 ++++++++++++++++++++++++++++-- cpukit/score/src/chainappendempty.c | 44 +++++++++++++ cpukit/score/src/chaingetempty.c | 44 +++++++++++++ cpukit/score/src/chainprependempty.c | 44 +++++++++++++ 7 files changed, 313 insertions(+), 9 deletions(-) create mode 100644 cpukit/score/src/chainappendempty.c create mode 100644 cpukit/score/src/chaingetempty.c create mode 100644 cpukit/score/src/chainprependempty.c diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 26c11faa63..85e1423e26 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,17 @@ +2010-08-23 Sebastian Huber + + PR 1673/cpukit + * score/src/chainappendempty.c, score/src/chaingetempty.c, + score/src/chainprependempty.c: New files. + * score/Makefile.am: Reflect changes above. + * score/include/rtems/score/chain.h: Declare + _Chain_Append_with_empty_check(), _Chain_Prepend_with_empty_check(), + and _Chain_Get_with_empty_check(). + * score/inline/rtems/score/chain.inl: Define + _Chain_Append_with_empty_check_unprotected(), + _Chain_Prepend_with_empty_check_unprotected(), and + _Chain_Get_with_empty_check_unprotected(). + 2010-08-23 Sebastian Huber PR 1671/cpukit diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 43d53e0526..fd1f2a90e2 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -200,6 +200,7 @@ libscore_a_SOURCES += src/userextaddset.c \ ## STD_C_FILES libscore_a_SOURCES += src/apiext.c src/chain.c src/chainappend.c \ src/chainextract.c src/chainget.c src/chaininsert.c \ + src/chainappendempty.c src/chainprependempty.c src/chaingetempty.c \ src/interr.c src/isr.c src/wkspace.c EXTRA_DIST = src/Unlimited.txt diff --git a/cpukit/score/include/rtems/score/chain.h b/cpukit/score/include/rtems/score/chain.h index 3d18adf64f..4d298b3cd2 100644 --- a/cpukit/score/include/rtems/score/chain.h +++ b/cpukit/score/include/rtems/score/chain.h @@ -1,11 +1,14 @@ /** - * @file rtems/score/chain.h + * @file * - * This include file contains all the constants and structures associated - * with the Doubly-Linked Chain Handler. + * @ingroup ScoreChain + * + * @brief Chain Handler API. */ /* + * Copyright (c) 2010 embedded brains GmbH. + * * COPYRIGHT (c) 1989-2006. * On-Line Applications Research Corporation (OAR). * @@ -22,6 +25,8 @@ /** * @defgroup ScoreChain Chain Handler * + * @ingroup Score + * * The Chain Handler is used to manage sets of entities. This handler * provides two data structures. The Chain Node data structure is included * as the first part of every data structure that will be placed on @@ -185,6 +190,66 @@ void _Chain_Append( Chain_Node *the_node ); +/** + * @brief Append a node and check if the chain was empty before. + * + * This routine appends the_node onto the end of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be appended. + * + * @note It disables interrupts to ensure the atomicity of the append + * operation. + * + * @retval true The chain was empty before. + * @retval false The chain contained at least one node before. + */ +bool _Chain_Append_with_empty_check( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/** + * @brief Prepend a node and check if the chain was empty before. + * + * This routine prepends the_node onto the front of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be prepended. + * + * @note It disables interrupts to ensure the atomicity of the append + * operation. + * + * @retval true The chain was empty before. + * @retval false The chain contained at least one node before. + */ +bool _Chain_Prepend_with_empty_check( + Chain_Control *the_chain, + Chain_Node *the_node +); + +/** + * @brief Get the first node and check if the chain is empty afterwards. + * + * This function removes the first node from the_chain and returns + * a pointer to that node in @a the_node. If the_chain is empty, then NULL is + * returned. + * + * @param[in] the_chain is the chain to attempt to get the first node from. + * @param[out] the_node is the first node on the chain or NULL if the chain is + * empty. + * + * @note It disables interrupts to ensure the atomicity of the append + * operation. + * + * @retval true The chain is empty now. + * @retval false The chain contains at least one node now. + */ +bool _Chain_Get_with_empty_check( + Chain_Control *the_chain, + Chain_Node **the_node +); + #ifndef __RTEMS_APPLICATION__ #include #endif diff --git a/cpukit/score/inline/rtems/score/chain.inl b/cpukit/score/inline/rtems/score/chain.inl index 3bde7fb229..ae1b6e4024 100644 --- a/cpukit/score/inline/rtems/score/chain.inl +++ b/cpukit/score/inline/rtems/score/chain.inl @@ -1,15 +1,14 @@ /** - * @file rtems/score/chain.inl + * @file * - * This include file contains the bodies of the routines which are - * associated with doubly linked chains and inlined. + * @ingroup ScoreChain * - * @note The routines in this file are ordered from simple - * to complex. No other Chain Handler routine is referenced - * unless it has already been defined. + * @brief Chain Handler API. */ /* + * Copyright (c) 2010 embedded brains GmbH. + * * COPYRIGHT (c) 1989-2006. * On-Line Applications Research Corporation (OAR). * @@ -481,6 +480,99 @@ RTEMS_INLINE_ROUTINE void _Chain_Prepend( _Chain_Insert(_Chain_Head(the_chain), the_node); } +/** + * @brief Append a node and check if the chain was empty before (unprotected). + * + * This routine appends the_node onto the end of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be appended. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * append operation. + * + * @retval true The chain was empty before. + * @retval false The chain contained at least one node before. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Append_with_empty_check_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + bool was_empty = _Chain_Is_empty( the_chain ); + + _Chain_Append_unprotected( the_chain, the_node ); + + return was_empty; +} + +/** + * @brief Prepend a node and check if the chain was empty before (unprotected). + * + * This routine prepends the_node onto the front of the_chain. + * + * @param[in] the_chain is the chain to be operated upon. + * @param[in] the_node is the node to be prepended. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * prepend operation. + * + * @retval true The chain was empty before. + * @retval false The chain contained at least one node before. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Prepend_with_empty_check_unprotected( + Chain_Control *the_chain, + Chain_Node *the_node +) +{ + bool was_empty = _Chain_Is_empty( the_chain ); + + _Chain_Prepend_unprotected( the_chain, the_node ); + + return was_empty; +} + +/** + * @brief Get the first node and check if the chain is empty afterwards + * (unprotected). + * + * This function removes the first node from the_chain and returns + * a pointer to that node in @a the_node. If the_chain is empty, then NULL is + * returned. + * + * @param[in] the_chain is the chain to attempt to get the first node from. + * @param[out] the_node is the first node on the chain or NULL if the chain is + * empty. + * + * @note It does NOT disable interrupts to ensure the atomicity of the + * get operation. + * + * @retval true The chain is empty now. + * @retval false The chain contains at least one node now. + */ +RTEMS_INLINE_ROUTINE bool _Chain_Get_with_empty_check_unprotected( + Chain_Control *the_chain, + Chain_Node **the_node +) +{ + bool is_empty_now = true; + Chain_Node *first = the_chain->first; + + if ( first != _Chain_Tail( the_chain ) ) { + Chain_Node *new_first = first->next; + + the_chain->first = new_first; + new_first->previous = _Chain_Head( the_chain ); + + *the_node = first; + + is_empty_now = new_first == _Chain_Tail( the_chain ); + } else + *the_node = NULL; + + return is_empty_now; +} + /**@}*/ #endif diff --git a/cpukit/score/src/chainappendempty.c b/cpukit/score/src/chainappendempty.c new file mode 100644 index 0000000000..33033df8ed --- /dev/null +++ b/cpukit/score/src/chainappendempty.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ScoreChain + * + * @brief _Chain_Append_with_empty_check() implementation. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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 +#include +#include + +bool _Chain_Append_with_empty_check( + Chain_Control *chain, + Chain_Node *node +) +{ + ISR_Level level; + bool was_empty; + + _ISR_Disable( level ); + was_empty = _Chain_Append_with_empty_check_unprotected( chain, node ); + _ISR_Enable( level ); + + return was_empty; +} diff --git a/cpukit/score/src/chaingetempty.c b/cpukit/score/src/chaingetempty.c new file mode 100644 index 0000000000..3f9be4de5b --- /dev/null +++ b/cpukit/score/src/chaingetempty.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ScoreChain + * + * @brief _Chain_Get_with_empty_check() implementation. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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 +#include +#include + +bool _Chain_Get_with_empty_check( + Chain_Control *chain, + Chain_Node **node +) +{ + ISR_Level level; + bool is_empty_now; + + _ISR_Disable( level ); + is_empty_now = _Chain_Get_with_empty_check_unprotected( chain, node ); + _ISR_Enable( level ); + + return is_empty_now; +} diff --git a/cpukit/score/src/chainprependempty.c b/cpukit/score/src/chainprependempty.c new file mode 100644 index 0000000000..9dfd9a653f --- /dev/null +++ b/cpukit/score/src/chainprependempty.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ScoreChain + * + * @brief _Chain_Prepend_with_empty_check() implementation. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * + * + * 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 +#include +#include + +bool _Chain_Prepend_with_empty_check( + Chain_Control *chain, + Chain_Node *node +) +{ + ISR_Level level; + bool was_empty; + + _ISR_Disable( level ); + was_empty = _Chain_Prepend_with_empty_check_unprotected( chain, node ); + _ISR_Enable( level ); + + return was_empty; +} -- cgit v1.2.3