summaryrefslogtreecommitdiffstats
path: root/cpukit/sapi/src/chainsmp.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-26 15:14:33 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-08-30 11:16:28 +0200
commit1215fd4d9426a59d568560e9a485628560363133 (patch)
tree1fa51c2c86080bdbf80d20386732f34f08e708be /cpukit/sapi/src/chainsmp.c
parentsmptests/smpatomic08: Fix race conditions (diff)
downloadrtems-1215fd4d9426a59d568560e9a485628560363133.tar.bz2
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.
Diffstat (limited to 'cpukit/sapi/src/chainsmp.c')
-rw-r--r--cpukit/sapi/src/chainsmp.c138
1 files changed, 138 insertions, 0 deletions
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 ) */