diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-08-26 15:14:33 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2013-08-30 11:16:28 +0200 |
commit | 1215fd4d9426a59d568560e9a485628560363133 (patch) | |
tree | 1fa51c2c86080bdbf80d20386732f34f08e708be /cpukit/sapi/src/chainsmp.c | |
parent | smptests/smpatomic08: Fix race conditions (diff) | |
download | rtems-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.c | 138 |
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 ) */ |