Changeset 1215fd4 in rtems


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.

Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libcpu/powerpc/mpc55xx/edma/edma.c

    re127c4c r1215fd4  
    276276
    277277  mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
    278   rtems_chain_extract(&ctx->node);
     278  rtems_chain_explicit_extract(&edma_channel_chain, &ctx->node);
    279279
    280280  sc = rtems_interrupt_handler_remove(
  • c/src/libchip/ide/ata.c

    re127c4c r1215fd4  
    492492
    493493    ATA_EXEC_CALLBACK(areq, status);
    494     rtems_chain_extract(&areq->link);
     494    rtems_chain_explicit_extract(&ata_ide_ctrls[ctrl_minor].reqs, &areq->link);
    495495
    496496    if (!rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
  • cpukit/posix/src/aio_cancel.c

    re127c4c r1215fd4  
    2727int aio_cancel(int fildes, struct aiocb  *aiocbp)
    2828{
     29  rtems_chain_control *idle_req_chain = &aio_request_queue.idle_req;
     30  rtems_chain_control *work_req_chain = &aio_request_queue.work_req;
    2931  rtems_aio_request_chain *r_chain;
    3032  int result;
     
    4143    AIO_printf ("Cancel all requests\n");       
    4244         
    43     r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0);
     45    r_chain = rtems_aio_search_fd (work_req_chain, fildes, 0);
    4446    if (r_chain == NULL) {
    4547      AIO_printf ("Request chain not on [WQ]\n");
    4648
    47       if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) {
    48         r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0);
     49      if (!rtems_chain_is_empty (idle_req_chain)) {
     50        r_chain = rtems_aio_search_fd (idle_req_chain, fildes, 0);
    4951        if (r_chain == NULL) {
    5052          pthread_mutex_unlock(&aio_request_queue.mutex);
     
    5456        AIO_printf ("Request chain on [IQ]\n");
    5557
    56         rtems_chain_extract (&r_chain->next_fd);       
     58        rtems_chain_explicit_extract (idle_req_chain, &r_chain->next_fd);
    5759        rtems_aio_remove_fd (r_chain);
    5860        pthread_mutex_destroy (&r_chain->mutex);
     
    7173
    7274    pthread_mutex_lock (&r_chain->mutex);
    73     rtems_chain_extract (&r_chain->next_fd);
     75    rtems_chain_explicit_extract (work_req_chain, &r_chain->next_fd);
    7476    rtems_aio_remove_fd (r_chain);
    7577    pthread_mutex_unlock (&r_chain->mutex);
     
    8486    }
    8587     
    86     r_chain = rtems_aio_search_fd (&aio_request_queue.work_req, fildes, 0);
     88    r_chain = rtems_aio_search_fd (work_req_chain, fildes, 0);
    8789    if (r_chain == NULL) {
    88       if (!rtems_chain_is_empty (&aio_request_queue.idle_req)) {
    89         r_chain = rtems_aio_search_fd (&aio_request_queue.idle_req, fildes, 0);
     90      if (!rtems_chain_is_empty (idle_req_chain)) {
     91        r_chain = rtems_aio_search_fd (idle_req_chain, fildes, 0);
    9092        if (r_chain == NULL) {
    9193          pthread_mutex_unlock (&aio_request_queue.mutex);
  • cpukit/posix/src/aio_misc.c

    re127c4c r1215fd4  
    121121        rtems_chain_prepend (chain, &r_chain->next_fd);
    122122      else
    123         rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd);
     123        rtems_chain_explicit_insert (chain,
     124                                     rtems_chain_previous (node),
     125                                     &r_chain->next_fd);
    124126
    125127      r_chain->new_fd = 1;
     
    145147rtems_aio_move_to_work (rtems_aio_request_chain *r_chain)
    146148{
     149  rtems_chain_control *work_req_chain = &aio_request_queue.work_req;
    147150  rtems_aio_request_chain *temp;
    148151  rtems_chain_node *node;
    149  
    150   node = rtems_chain_first (&aio_request_queue.work_req);
     152
     153  node = rtems_chain_first (work_req_chain);
    151154  temp = (rtems_aio_request_chain *) node;
    152155
    153   while (temp->fildes < r_chain->fildes && 
    154          !rtems_chain_is_tail (&aio_request_queue.work_req, node)) {
     156  while (temp->fildes < r_chain->fildes &&
     157         !rtems_chain_is_tail (work_req_chain, node)) {
    155158    node = rtems_chain_next (node);
    156159    temp = (rtems_aio_request_chain *) node;
    157160  }
    158  
    159   rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd);
     161
     162  rtems_chain_explicit_insert (work_req_chain,
     163                               rtems_chain_previous (node),
     164                               &r_chain->next_fd);
    160165}
    161166 
     
    196201    }
    197202
    198     rtems_chain_insert (node->previous, &req->next_prio);
     203    rtems_chain_explicit_insert (chain, node->previous, &req->next_prio);
    199204
    200205  }
     
    222227  while (!rtems_chain_is_tail (chain, node))
    223228    {
    224       rtems_chain_extract (node);
     229      rtems_chain_explicit_extract (chain, node);
    225230      rtems_aio_request *req = (rtems_aio_request *) node;
    226231      node = rtems_chain_next (node);
     
    266271  else
    267272    {
    268       rtems_chain_extract (node);
     273      rtems_chain_explicit_extract (chain, node);
    269274      current->aiocbp->error_code = ECANCELED;
    270275      current->aiocbp->return_value = -1;
     
    441446      pthread_setschedparam (pthread_self(), req->policy, &param);
    442447
    443       rtems_chain_extract (node);
     448      rtems_chain_explicit_extract (chain, node);
    444449
    445450      pthread_mutex_unlock (&r_chain->mutex);
     
    507512             the queue and start working with idle fd chains */
    508513          if (result == ETIMEDOUT) {
    509             rtems_chain_extract (&r_chain->next_fd);
     514            rtems_chain_explicit_extract (&aio_request_queue.work_req,
     515                                    &r_chain->next_fd);
    510516            pthread_mutex_destroy (&r_chain->mutex);
    511517            pthread_cond_destroy (&r_chain->cond);
     
    543549
    544550            node = rtems_chain_first (&aio_request_queue.idle_req);
    545             rtems_chain_extract (node);
     551            rtems_chain_explicit_extract (&aio_request_queue.idle_req, node);
    546552
    547553            r_chain = (rtems_aio_request_chain *) node;
  • 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
  • testsuites/libtests/block06/init.c

    re127c4c r1215fd4  
    11311131  bd = (rtems_bdbuf_buffer*) node;
    11321132  pnode = node->previous;
    1133   rtems_chain_extract (node);
     1133  rtems_chain_explicit_extract (&buffers, node);
    11341134  node = pnode;
    11351135  bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[4]: ", tc->name);
     
    11381138  bd = (rtems_bdbuf_buffer*) node;
    11391139  pnode = node->previous;
    1140   rtems_chain_extract (node);
     1140  rtems_chain_explicit_extract (&buffers, node);
    11411141  node = pnode;
    11421142  bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name);
  • testsuites/sptests/spchain/init.c

    re127c4c r1215fd4  
    6161static void test_chain_control_layout(void)
    6262{
    63   rtems_chain_control chain;
     63  Chain_Control chain;
     64
    6465  puts( "INIT - Verify rtems_chain_control layout" );
    65   rtems_test_assert(
    66     sizeof(rtems_chain_control)
    67       == sizeof(rtems_chain_node) + sizeof(rtems_chain_node *)
    68   );
    69   rtems_test_assert(
    70     sizeof(rtems_chain_control)
    71       == 3 * sizeof(rtems_chain_node *)
    72   );
    73   rtems_test_assert( &chain.Head.Node.previous == &chain.Tail.Node.next );
     66
     67  rtems_test_assert(
     68    sizeof(Chain_Control)
     69      == sizeof(Chain_Node) + sizeof(Chain_Node *)
     70  );
     71  rtems_test_assert(
     72    sizeof(Chain_Control)
     73      == 3 * sizeof(Chain_Node *)
     74  );
     75  rtems_test_assert(
     76    _Chain_Previous( _Chain_Head( &chain ) )
     77      == _Chain_Next( _Chain_Tail( &chain ) )
     78  );
     79
     80#if !defined( RTEMS_SMP )
     81  rtems_test_assert(
     82    sizeof(Chain_Control)
     83      == sizeof(rtems_chain_control)
     84  );
     85#endif
    7486}
    7587
     
    95107  rtems_chain_initialize_empty( &chain );
    96108  rtems_chain_append( &chain, &node1 );
    97   rtems_chain_insert( &node1, &node2 );
     109  rtems_chain_explicit_insert( &chain, &node1, &node2 );
    98110
    99111  puts( "INIT - Verify rtems_chain_is_first" );
     
    297309  node2.id = 2;
    298310  rtems_chain_append( &chain1, &node1.Node );
    299   rtems_chain_insert( &node1.Node, &node2.Node );
     311  rtems_chain_explicit_insert( &chain1, &node1.Node, &node2.Node );
    300312
    301313  for ( p = rtems_chain_first(&chain1), id = 1 ;
Note: See TracChangeset for help on using the changeset viewer.