From 69f2a078c876de5eb13c2f2eb440160b849dff15 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 24 Aug 2010 14:29:55 +0000 Subject: 2010-08-24 Sebastian Huber PR 1673/cpukit * sapi/src/chainappendnotify.c, sapi/src/chaingetnotify.c, sapi/src/chaingetwait.c, sapi/src/chainprependnotify.c: New files. * sapi/Makefile.am: Reflect changes above. * sapi/include/rtems/chain.h: Declare rtems_chain_append_with_notification(), rtems_chain_prepend_with_notification(), rtems_chain_get_with_notification(), and rtems_chain_get_with_wait(). * sapi/inline/rtems/chain.inl: Define rtems_chain_append_with_empty_check(), rtems_chain_prepend_with_empty_check(), and rtems_chain_get_with_empty_check(). --- cpukit/sapi/Makefile.am | 4 +- cpukit/sapi/include/rtems/chain.h | 99 +++++++++++++++++++++++++++++++----- cpukit/sapi/inline/rtems/chain.inl | 78 +++++++++++++++++++++++----- cpukit/sapi/src/chainappendnotify.c | 44 ++++++++++++++++ cpukit/sapi/src/chaingetnotify.c | 44 ++++++++++++++++ cpukit/sapi/src/chaingetwait.c | 55 ++++++++++++++++++++ cpukit/sapi/src/chainprependnotify.c | 44 ++++++++++++++++ 7 files changed, 342 insertions(+), 26 deletions(-) create mode 100644 cpukit/sapi/src/chainappendnotify.c create mode 100644 cpukit/sapi/src/chaingetnotify.c create mode 100644 cpukit/sapi/src/chaingetwait.c create mode 100644 cpukit/sapi/src/chainprependnotify.c (limited to 'cpukit/sapi') diff --git a/cpukit/sapi/Makefile.am b/cpukit/sapi/Makefile.am index 16c2e87e06..fb35b914f0 100644 --- a/cpukit/sapi/Makefile.am +++ b/cpukit/sapi/Makefile.am @@ -27,7 +27,9 @@ libsapi_a_SOURCES = src/debug.c src/extension.c src/extensioncreate.c \ src/exshutdown.c src/io.c src/ioclose.c src/iocontrol.c src/iodata.c \ src/ioinitialize.c src/ioopen.c src/ioread.c src/ioregisterdriver.c \ src/iounregisterdriver.c src/iowrite.c src/posixapi.c \ - src/rtemsapi.c src/extensiondata.c src/getversionstring.c + src/rtemsapi.c src/extensiondata.c src/getversionstring.c \ + src/chainappendnotify.c src/chaingetnotify.c src/chaingetwait.c \ + src/chainprependnotify.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 01b335d666..a80bb9c1e2 100644 --- a/cpukit/sapi/include/rtems/chain.h +++ b/cpukit/sapi/include/rtems/chain.h @@ -1,14 +1,14 @@ /** - * @file rtems/chain.h + * @file * - * This include file contains all the constants and structures associated - * with the Chain API in RTEMS. The chain is a double linked list that - * is part of the Super Core. This is the published interface to that - * code. + * @ingroup ClassicChains * + * @brief Chain API. */ /* + * Copyright (c) 2010 embedded brains GmbH. + * * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * @@ -24,23 +24,24 @@ #include #include +#include #ifdef __cplusplus extern "C" { #endif /** - * @typedef rtems_chain_node + * @defgroup ClassicChains Chains + * + * @ingroup ClassicRTEMS + * + * @brief Chain API. * - * A node that can be manipulated in the chain. + * @{ */ + typedef Chain_Node rtems_chain_node; -/** - * @typedef rtems_chain_control - * - * The chain's control anchors the chain. - */ typedef Chain_Control rtems_chain_control; /** @@ -55,8 +56,82 @@ typedef Chain_Control rtems_chain_control; #define RTEMS_CHAIN_DEFINE_EMPTY(name) \ CHAIN_DEFINE_EMPTY(name) +/** @} */ + #include +/** + * @addtogroup ClassicChains + * + * @{ + */ + +/** + * @brief Appends the @a node to the @a chain and sends the @a events to the + * @a task if the @a chain was empty before the append. + * + * @see rtems_chain_append_with_empty_check() and rtems_event_send(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No such task. + */ +rtems_status_code rtems_chain_append_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +); + +/** + * @brief Prepends the @a node to the @a chain and sends the @a events to the + * @a task if the @a chain was empty before the prepend. + * + * @see rtems_chain_prepend_with_empty_check() and rtems_event_send(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No such task. + */ +rtems_status_code rtems_chain_prepend_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +); + +/** + * @brief Gets the first @a node of the @a chain and sends the @a events to the + * @a task if the @a chain is empty after the get. + * + * @see rtems_chain_get_with_empty_check() and rtems_event_send(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_INVALID_ID No such task. + */ +rtems_status_code rtems_chain_get_with_notification( + rtems_chain_control *chain, + rtems_id task, + rtems_event_set events, + rtems_chain_node **node +); + +/** + * @brief Gets the first @a node of the @a chain and sends the @a events to the + * @a task if the @a chain is empty afterwards. + * + * @see rtems_chain_get() and rtems_event_receive(). + * + * @retval RTEMS_SUCCESSFUL Successful operation. + * @retval RTEMS_TIMEOUT Timeout. + */ +rtems_status_code rtems_chain_get_with_wait( + rtems_chain_control *chain, + rtems_event_set events, + rtems_interval timeout, + rtems_chain_node **node +); + +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpukit/sapi/inline/rtems/chain.inl b/cpukit/sapi/inline/rtems/chain.inl index 58b6770525..2816e81b41 100644 --- a/cpukit/sapi/inline/rtems/chain.inl +++ b/cpukit/sapi/inline/rtems/chain.inl @@ -1,22 +1,14 @@ /** - * @file rtems/chain.inl + * @file * - * This include file contains all the constants and structures associated - * with the Chain API in RTEMS. The chain is a double linked list that - * is part of the Super Core. This is the published interface to that - * code. + * @ingroup ClassicChains * - * Iterate the node of a chain can be performed with the following code: - * - * rtems_chain_control* cc = &object->pending; - * rtems_chain_node* cn = cc->first; - * while (!rtems_chain_is_tail (cc, cn)) - * { - * cn = cn->next; - * } + * @brief Chain API. */ /* + * Copyright (c) 2010 embedded brains GmbH. + * * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * @@ -36,6 +28,12 @@ #include +/** + * @addtogroup ClassicChains + * + * @{ + */ + /** * @brief Initialize a Chain Header * @@ -505,5 +503,59 @@ RTEMS_INLINE_ROUTINE void rtems_chain_prepend_unprotected( _Chain_Prepend_unprotected( the_chain, the_node ); } +/** + * @brief Checks if the @a chain is empty and appends the @a node. + * + * Interrupts are disabled to ensure the atomicity of the operation. + * + * @retval true The chain was empty before the append. + * @retval false The chain contained at least one node before the append. + */ +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 ); +} + +/** + * @brief Checks if the @a chain is empty and prepends the @a node. + * + * Interrupts are disabled to ensure the atomicity of the operation. + * + * @retval true The chain was empty before the prepend. + * @retval false The chain contained at least one node before the prepend. + */ +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 ); +} + +/** + * @brief Tries to get the first @a node and check if the @a chain is empty + * afterwards. + * + * This function removes the first node from the @a chain and returns a pointer + * to that node in @a node. If the @a chain is empty, then @c NULL is returned. + * + * Interrupts are disabled to ensure the atomicity of the operation. + * + * @retval true The chain is empty after the node removal. + * @retval false The chain contained at least one node after the node removal. + */ +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 ); +} + +/** @} */ + #endif /* end of include file */ diff --git a/cpukit/sapi/src/chainappendnotify.c b/cpukit/sapi/src/chainappendnotify.c new file mode 100644 index 0000000000..df89d74b48 --- /dev/null +++ b/cpukit/sapi/src/chainappendnotify.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_append_with_notification() 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 + +rtems_status_code rtems_chain_append_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + bool was_empty = rtems_chain_append_with_empty_check( chain, node ); + + if ( was_empty ) { + sc = rtems_event_send( task, events ); + } + + return sc; +} diff --git a/cpukit/sapi/src/chaingetnotify.c b/cpukit/sapi/src/chaingetnotify.c new file mode 100644 index 0000000000..88f411b4f9 --- /dev/null +++ b/cpukit/sapi/src/chaingetnotify.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_get_with_notification() 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 + +rtems_status_code rtems_chain_get_with_notification( + rtems_chain_control *chain, + rtems_id task, + rtems_event_set events, + rtems_chain_node **node +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + bool is_empty = rtems_chain_get_with_empty_check( chain, node ); + + if ( is_empty ) { + sc = rtems_event_send( task, events ); + } + + return sc; +} diff --git a/cpukit/sapi/src/chaingetwait.c b/cpukit/sapi/src/chaingetwait.c new file mode 100644 index 0000000000..38986bc9c1 --- /dev/null +++ b/cpukit/sapi/src/chaingetwait.c @@ -0,0 +1,55 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_get_with_wait() 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 + +rtems_status_code rtems_chain_get_with_wait( + rtems_chain_control *chain, + rtems_event_set events, + rtems_interval timeout, + rtems_chain_node **node_ptr +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_chain_node *node = NULL; + + while ( + sc == RTEMS_SUCCESSFUL + && (node = rtems_chain_get( chain )) == NULL + ) { + rtems_event_set out; + sc = rtems_event_receive( + events, + RTEMS_EVENT_ALL | RTEMS_WAIT, + timeout, + &out + ); + } + + *node_ptr = node; + + return sc; +} diff --git a/cpukit/sapi/src/chainprependnotify.c b/cpukit/sapi/src/chainprependnotify.c new file mode 100644 index 0000000000..057e4fbde6 --- /dev/null +++ b/cpukit/sapi/src/chainprependnotify.c @@ -0,0 +1,44 @@ +/** + * @file + * + * @ingroup ClassicChains + * + * @brief rtems_chain_prepend_with_notification() 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 + +rtems_status_code rtems_chain_prepend_with_notification( + rtems_chain_control *chain, + rtems_chain_node *node, + rtems_id task, + rtems_event_set events +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + bool was_empty = rtems_chain_prepend_with_empty_check( chain, node ); + + if (was_empty) { + sc = rtems_event_send( task, events ); + } + + return sc; +} -- cgit v1.2.3