Changeset 1215fd4 in rtems for cpukit/sapi


Ignore:
Timestamp:
Aug 26, 2013, 1:14:33 PM (6 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
bf30999
Parents:
e127c4c
git-author:
Sebastian Huber <sebastian.huber@…> (08/26/13 13:14:33)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/30/13 09:16:28)
Message:

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.

Location:
cpukit/sapi
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/sapi/Makefile.am

    re127c4c r1215fd4  
    3232    src/chainprependnotify.c src/rbheap.c src/interrdesc.c \
    3333    src/fatal2.c src/fatalsrcdesc.c
     34libsapi_a_SOURCES += src/chainsmp.c
    3435libsapi_a_CPPFLAGS = $(AM_CPPFLAGS)
    3536
  • cpukit/sapi/include/rtems/chain.h

    re127c4c r1215fd4  
    2020
    2121#include <rtems/score/chainimpl.h>
     22#include <rtems/score/isrlock.h>
    2223#include <rtems/rtems/event.h>
    2324
     
    3738typedef Chain_Node rtems_chain_node;
    3839
    39 typedef Chain_Control rtems_chain_control;
     40typedef struct {
     41  Chain_Control Chain;
     42  ISR_lock_Control Lock;
     43} rtems_chain_control;
    4044
    4145/**
    4246 *  @brief Chain initializer for an empty chain with designator @a name.
    4347 */
    44 #define RTEMS_CHAIN_INITIALIZER_EMPTY(name) \
    45   CHAIN_INITIALIZER_EMPTY(name)
     48#define RTEMS_CHAIN_INITIALIZER_EMPTY( name ) \
     49  { CHAIN_INITIALIZER_EMPTY( name.Chain ), ISR_LOCK_INITIALIZER }
    4650
    4751/**
     
    5155 */
    5256#define RTEMS_CHAIN_INITIALIZER_ONE_NODE( node ) \
    53   CHAIN_INITIALIZER_ONE_NODE( node )
     57  { CHAIN_INITIALIZER_ONE_NODE( node ), ISR_LOCK_INITIALIZER }
    5458
    5559/**
     
    5963 */
    6064#define RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
    61   CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain )
     65  CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( &( chain )->Chain )
    6266
    6367/**
    6468 *  @brief Chain definition for an empty chain with designator @a name.
    6569 */
    66 #define RTEMS_CHAIN_DEFINE_EMPTY(name) \
    67   CHAIN_DEFINE_EMPTY(name)
     70#define RTEMS_CHAIN_DEFINE_EMPTY( name ) \
     71  rtems_chain_control name = RTEMS_CHAIN_INITIALIZER_EMPTY( name )
    6872
    6973/**
     
    151155)
    152156{
    153   _Chain_Initialize( the_chain, starting_address, number_nodes, node_size );
     157  _ISR_lock_Initialize( &the_chain->Lock );
     158  _Chain_Initialize(
     159    &the_chain->Chain,
     160    starting_address,
     161    number_nodes,
     162    node_size
     163  );
    154164}
    155165
     
    165175)
    166176{
    167   _Chain_Initialize_empty( the_chain );
     177  _ISR_lock_Initialize( &the_chain->Lock );
     178  _Chain_Initialize_empty( &the_chain->Chain );
    168179}
    169180
     
    231242)
    232243{
    233   return _Chain_Head( the_chain );
     244  return _Chain_Head( &the_chain->Chain );
    234245}
    235246
     
    247258)
    248259{
    249   return _Chain_Immutable_head( the_chain );
     260  return _Chain_Immutable_head( &the_chain->Chain );
    250261}
    251262
     
    263274)
    264275{
    265   return _Chain_Tail( the_chain );
     276  return _Chain_Tail( &the_chain->Chain );
    266277}
    267278
     
    279290)
    280291{
    281   return _Chain_Immutable_tail( the_chain );
     292  return _Chain_Immutable_tail( &the_chain->Chain );
    282293}
    283294
     
    296307)
    297308{
    298   return _Chain_First( the_chain );
     309  return _Chain_First( &the_chain->Chain );
    299310}
    300311
     
    313324)
    314325{
    315   return _Chain_Immutable_first( the_chain );
     326  return _Chain_Immutable_first( &the_chain->Chain );
    316327}
    317328
     
    330341)
    331342{
    332   return _Chain_Last( the_chain );
     343  return _Chain_Last( &the_chain->Chain );
    333344}
    334345
     
    347358)
    348359{
    349   return _Chain_Immutable_last( the_chain );
     360  return _Chain_Immutable_last( &the_chain->Chain );
    350361}
    351362
     
    449460)
    450461{
    451   return _Chain_Is_empty( the_chain );
     462  return _Chain_Is_empty( &the_chain->Chain );
    452463}
    453464
     
    504515)
    505516{
    506   return _Chain_Has_only_one_node( the_chain );
     517  return _Chain_Has_only_one_node( &the_chain->Chain );
    507518}
    508519
     
    524535)
    525536{
    526   return _Chain_Is_head( the_chain, the_node );
     537  return _Chain_Is_head( &the_chain->Chain, the_node );
    527538}
    528539
     
    544555)
    545556{
    546   return _Chain_Is_tail( the_chain, the_node );
    547 }
    548 
     557  return _Chain_Is_tail( &the_chain->Chain, the_node );
     558}
     559
     560#if !defined( RTEMS_SMP )
    549561/**
    550562 * @brief Extract the specified node from a chain.
     
    562574  _Chain_Extract( the_node );
    563575}
     576#endif
     577
     578#if defined( RTEMS_SMP )
     579/**
     580 * @brief Extract the specified node from a chain.
     581 *
     582 * @param[in,out] chain The chain containing the node.
     583 * @param[in,out] node The node to extract.
     584 */
     585void rtems_chain_explicit_extract(
     586  rtems_chain_control *chain,
     587  rtems_chain_node *node
     588);
     589#else
     590RTEMS_INLINE_ROUTINE void rtems_chain_explicit_extract(
     591  rtems_chain_control *chain,
     592  rtems_chain_node *node
     593)
     594{
     595  ( void ) chain;
     596  rtems_chain_extract( node );
     597}
     598#endif
    564599
    565600/**
     
    590625 *  NOTE: It disables interrupts to ensure the atomicity of the get operation.
    591626 */
     627#if defined( RTEMS_SMP )
     628rtems_chain_node *rtems_chain_get(
     629  rtems_chain_control *the_chain
     630);
     631#else
    592632RTEMS_INLINE_ROUTINE rtems_chain_node *rtems_chain_get(
    593633  rtems_chain_control *the_chain
    594634)
    595635{
    596   return _Chain_Get( the_chain );
    597 }
     636  return _Chain_Get( &the_chain->Chain );
     637}
     638#endif
    598639
    599640/**
     
    604645)
    605646{
    606   return _Chain_Get_unprotected( the_chain );
    607 }
    608 
     647  return _Chain_Get_unprotected( &the_chain->Chain );
     648}
     649
     650#if !defined( RTEMS_SMP )
    609651/**
    610652 * @brief Insert a node on a chain
     
    623665  _Chain_Insert( after_node, the_node );
    624666}
     667#endif
     668
     669/**
     670 * @brief Insert a node on a chain
     671 *
     672 * @param[in,out] chain The chain containing the after node.
     673 * @param[in,out] after_node Insert the node after this node.
     674 * @param[in,out] node The node to insert.
     675 */
     676#if defined( RTEMS_SMP )
     677void rtems_chain_explicit_insert(
     678  rtems_chain_control *chain,
     679  rtems_chain_node *after_node,
     680  rtems_chain_node *node
     681);
     682#else
     683RTEMS_INLINE_ROUTINE void rtems_chain_explicit_insert(
     684  rtems_chain_control *chain,
     685  rtems_chain_node *after_node,
     686  rtems_chain_node *node
     687)
     688{
     689  ( void ) chain;
     690  rtems_chain_insert( after_node, node );
     691}
     692#endif
    625693
    626694/**
     
    643711 * append operation.
    644712 */
     713#if defined( RTEMS_SMP )
     714void rtems_chain_append(
     715  rtems_chain_control *the_chain,
     716  rtems_chain_node    *the_node
     717);
     718#else
    645719RTEMS_INLINE_ROUTINE void rtems_chain_append(
    646720  rtems_chain_control *the_chain,
     
    648722)
    649723{
    650   _Chain_Append( the_chain, the_node );
    651 }
     724  _Chain_Append( &the_chain->Chain, the_node );
     725}
     726#endif
    652727
    653728/**
     
    664739)
    665740{
    666   _Chain_Append_unprotected( the_chain, the_node );
     741  _Chain_Append_unprotected( &the_chain->Chain, the_node );
    667742}
    668743
     
    678753 *       prepend operation.
    679754 */
     755#if defined( RTEMS_SMP )
     756void rtems_chain_prepend(
     757  rtems_chain_control *the_chain,
     758  rtems_chain_node    *the_node
     759);
     760#else
    680761RTEMS_INLINE_ROUTINE void rtems_chain_prepend(
    681762  rtems_chain_control *the_chain,
     
    683764)
    684765{
    685   _Chain_Prepend( the_chain, the_node );
    686 }
     766  _Chain_Prepend( &the_chain->Chain, the_node );
     767}
     768#endif
    687769
    688770/**
     
    702784)
    703785{
    704   _Chain_Prepend_unprotected( the_chain, the_node );
     786  _Chain_Prepend_unprotected( &the_chain->Chain, the_node );
    705787}
    706788
     
    713795 * @retval false The chain contained at least one node before the append.
    714796 */
     797#if defined( RTEMS_SMP )
     798bool rtems_chain_append_with_empty_check(
     799  rtems_chain_control *chain,
     800  rtems_chain_node *node
     801);
     802#else
    715803RTEMS_INLINE_ROUTINE bool rtems_chain_append_with_empty_check(
    716804  rtems_chain_control *chain,
     
    718806)
    719807{
    720   return _Chain_Append_with_empty_check( chain, node );
    721 }
     808  return _Chain_Append_with_empty_check( &chain->Chain, node );
     809}
     810#endif
    722811
    723812/**
     
    729818 * @retval false The chain contained at least one node before the prepend.
    730819 */
     820#if defined( RTEMS_SMP )
     821bool rtems_chain_prepend_with_empty_check(
     822  rtems_chain_control *chain,
     823  rtems_chain_node *node
     824);
     825#else
    731826RTEMS_INLINE_ROUTINE bool rtems_chain_prepend_with_empty_check(
    732827  rtems_chain_control *chain,
     
    734829)
    735830{
    736   return _Chain_Prepend_with_empty_check( chain, node );
    737 }
     831  return _Chain_Prepend_with_empty_check( &chain->Chain, node );
     832}
     833#endif
    738834
    739835/**
     
    749845 * @retval false The chain contained at least one node after the node removal.
    750846 */
     847#if defined( RTEMS_SMP )
     848bool rtems_chain_get_with_empty_check(
     849  rtems_chain_control *chain,
     850  rtems_chain_node **node
     851);
     852#else
    751853RTEMS_INLINE_ROUTINE bool rtems_chain_get_with_empty_check(
    752854  rtems_chain_control *chain,
     
    754856)
    755857{
    756   return _Chain_Get_with_empty_check( chain, node );
    757 }
     858  return _Chain_Get_with_empty_check( &chain->Chain, node );
     859}
     860#endif
    758861
    759862/**
     
    771874)
    772875{
    773   return _Chain_Node_count_unprotected( chain );
     876  return _Chain_Node_count_unprotected( &chain->Chain );
    774877}
    775878
Note: See TracChangeset for help on using the changeset viewer.