Changeset ae88aa7 in rtems


Ignore:
Timestamp:
Mar 10, 2014, 7:15:37 AM (6 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
d50acdbb
Parents:
b1196e3
git-author:
Sebastian Huber <sebastian.huber@…> (03/10/14 07:15:37)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/11/14 09:58:09)
Message:

sapi: Use one SMP lock for all chains

This partially reverts commit 1215fd4d9426a59d568560e9a485628560363133.

In order to support profiling of SMP locks and provide a future
compatible SMP locks API it is necessary to add an SMP lock destroy
function. Since the commit above adds an SMP lock to each chain control
we would have to add a rtems_chain_destroy() function as well. This
complicates the chain usage dramatically. Thus revert the patch above.
A global SMP lock for all chains is used to implement the protected
chain operations.

Advantages:

  • The SAPI chain API is now identical on SMP and non-SMP configurations.
  • The size of the chain control is reduced and is then equal to the Score chains.
  • The protected chain operations work correctly on SMP.

Disadvantage:

  • Applications using many different chains and the protected operations may notice lock contention.

The chain control size drop is a huge benefit (SAPI chain controls are
66% larger than the Score chain controls). The only disadvantage is not
really a problem since these applications can use specific interrupt
locks and unprotected chain operations to avoid this issue.

Files:
8 edited

Legend:

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

    rb1196e3 rae88aa7  
    277277
    278278  mpc55xx_edma_release_channel_by_tcd(ctx->edma_tcd);
    279   rtems_chain_explicit_extract(&edma_channel_chain, &ctx->node);
     279  rtems_chain_extract(&ctx->node);
    280280
    281281  sc = rtems_interrupt_handler_remove(
  • c/src/libchip/ide/ata.c

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

    rb1196e3 rae88aa7  
    5656        AIO_printf ("Request chain on [IQ]\n");
    5757
    58         rtems_chain_explicit_extract (idle_req_chain, &r_chain->next_fd);
     58        rtems_chain_extract (&r_chain->next_fd);
    5959        rtems_aio_remove_fd (r_chain);
    6060        pthread_mutex_destroy (&r_chain->mutex);
     
    7373
    7474    pthread_mutex_lock (&r_chain->mutex);
    75     rtems_chain_explicit_extract (work_req_chain, &r_chain->next_fd);
     75    rtems_chain_extract (&r_chain->next_fd);
    7676    rtems_aio_remove_fd (r_chain);
    7777    pthread_mutex_unlock (&r_chain->mutex);
  • cpukit/posix/src/aio_misc.c

    rb1196e3 rae88aa7  
    121121        rtems_chain_prepend (chain, &r_chain->next_fd);
    122122      else
    123         rtems_chain_explicit_insert (chain,
    124                                      rtems_chain_previous (node),
    125                                      &r_chain->next_fd);
     123        rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd);
    126124
    127125      r_chain->new_fd = 1;
     
    160158  }
    161159
    162   rtems_chain_explicit_insert (work_req_chain,
    163                                rtems_chain_previous (node),
    164                                &r_chain->next_fd);
     160  rtems_chain_insert (rtems_chain_previous (node), &r_chain->next_fd);
    165161}
    166162 
     
    201197    }
    202198
    203     rtems_chain_explicit_insert (chain, node->previous, &req->next_prio);
     199    rtems_chain_insert (node->previous, &req->next_prio);
    204200
    205201  }
     
    227223  while (!rtems_chain_is_tail (chain, node))
    228224    {
    229       rtems_chain_explicit_extract (chain, node);
     225      rtems_chain_extract (node);
    230226      rtems_aio_request *req = (rtems_aio_request *) node;
    231227      node = rtems_chain_next (node);
     
    271267  else
    272268    {
    273       rtems_chain_explicit_extract (chain, node);
     269      rtems_chain_extract (node);
    274270      current->aiocbp->error_code = ECANCELED;
    275271      current->aiocbp->return_value = -1;
     
    446442      pthread_setschedparam (pthread_self(), req->policy, &param);
    447443
    448       rtems_chain_explicit_extract (chain, node);
     444      rtems_chain_extract (node);
    449445
    450446      pthread_mutex_unlock (&r_chain->mutex);
     
    512508             the queue and start working with idle fd chains */
    513509          if (result == ETIMEDOUT) {
    514             rtems_chain_explicit_extract (&aio_request_queue.work_req,
    515                                     &r_chain->next_fd);
     510            rtems_chain_extract (&r_chain->next_fd);
    516511            pthread_mutex_destroy (&r_chain->mutex);
    517512            pthread_cond_destroy (&r_chain->cond);
     
    549544
    550545            node = rtems_chain_first (&aio_request_queue.idle_req);
    551             rtems_chain_explicit_extract (&aio_request_queue.idle_req, node);
     546            rtems_chain_extract (node);
    552547
    553548            r_chain = (rtems_aio_request_chain *) node;
  • cpukit/sapi/include/rtems/chain.h

    rb1196e3 rae88aa7  
    66
    77/*
    8  *  Copyright (c) 2010 embedded brains GmbH.
     8 *  Copyright (c) 2010-2014 embedded brains GmbH.
    99 *
    1010 *  COPYRIGHT (c) 1989-2008.
     
    2020
    2121#include <rtems/score/chainimpl.h>
    22 #include <rtems/score/isrlock.h>
    2322#include <rtems/rtems/event.h>
    2423
     
    3837typedef Chain_Node rtems_chain_node;
    3938
    40 typedef struct {
    41   Chain_Control Chain;
    42   ISR_lock_Control Lock;
    43 } rtems_chain_control;
     39typedef Chain_Control rtems_chain_control;
    4440
    4541/**
     
    4743 */
    4844#define RTEMS_CHAIN_INITIALIZER_EMPTY( name ) \
    49   { CHAIN_INITIALIZER_EMPTY( name.Chain ), ISR_LOCK_INITIALIZER }
     45  CHAIN_INITIALIZER_EMPTY( name )
    5046
    5147/**
     
    5551 */
    5652#define RTEMS_CHAIN_INITIALIZER_ONE_NODE( node ) \
    57   { CHAIN_INITIALIZER_ONE_NODE( node ), ISR_LOCK_INITIALIZER }
     53  CHAIN_INITIALIZER_ONE_NODE( node )
    5854
    5955/**
     
    6359 */
    6460#define RTEMS_CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain ) \
    65   CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( &( chain )->Chain )
     61  CHAIN_NODE_INITIALIZER_ONE_NODE_CHAIN( chain )
    6662
    6763/**
     
    155151)
    156152{
    157   _ISR_lock_Initialize( &the_chain->Lock );
    158153  _Chain_Initialize(
    159     &the_chain->Chain,
     154    the_chain,
    160155    starting_address,
    161156    number_nodes,
     
    175170)
    176171{
    177   _ISR_lock_Initialize( &the_chain->Lock );
    178   _Chain_Initialize_empty( &the_chain->Chain );
     172  _Chain_Initialize_empty( the_chain );
    179173}
    180174
     
    242236)
    243237{
    244   return _Chain_Head( &the_chain->Chain );
     238  return _Chain_Head( the_chain );
    245239}
    246240
     
    258252)
    259253{
    260   return _Chain_Immutable_head( &the_chain->Chain );
     254  return _Chain_Immutable_head( the_chain );
    261255}
    262256
     
    274268)
    275269{
    276   return _Chain_Tail( &the_chain->Chain );
     270  return _Chain_Tail( the_chain );
    277271}
    278272
     
    290284)
    291285{
    292   return _Chain_Immutable_tail( &the_chain->Chain );
     286  return _Chain_Immutable_tail( the_chain );
    293287}
    294288
     
    307301)
    308302{
    309   return _Chain_First( &the_chain->Chain );
     303  return _Chain_First( the_chain );
    310304}
    311305
     
    324318)
    325319{
    326   return _Chain_Immutable_first( &the_chain->Chain );
     320  return _Chain_Immutable_first( the_chain );
    327321}
    328322
     
    341335)
    342336{
    343   return _Chain_Last( &the_chain->Chain );
     337  return _Chain_Last( the_chain );
    344338}
    345339
     
    358352)
    359353{
    360   return _Chain_Immutable_last( &the_chain->Chain );
     354  return _Chain_Immutable_last( the_chain );
    361355}
    362356
     
    460454)
    461455{
    462   return _Chain_Is_empty( &the_chain->Chain );
     456  return _Chain_Is_empty( the_chain );
    463457}
    464458
     
    515509)
    516510{
    517   return _Chain_Has_only_one_node( &the_chain->Chain );
     511  return _Chain_Has_only_one_node( the_chain );
    518512}
    519513
     
    535529)
    536530{
    537   return _Chain_Is_head( &the_chain->Chain, the_node );
     531  return _Chain_Is_head( the_chain, the_node );
    538532}
    539533
     
    555549)
    556550{
    557   return _Chain_Is_tail( &the_chain->Chain, the_node );
    558 }
    559 
    560 #if !defined( RTEMS_SMP )
     551  return _Chain_Is_tail( the_chain, the_node );
     552}
     553
    561554/**
    562555 * @brief Extract the specified node from a chain.
     
    568561 * @arg the_node specifies the node to extract
    569562 */
     563#if defined( RTEMS_SMP )
     564void rtems_chain_extract(
     565  rtems_chain_node *the_node
     566);
     567#else
    570568RTEMS_INLINE_ROUTINE void rtems_chain_extract(
    571569  rtems_chain_node *the_node
     
    573571{
    574572  _Chain_Extract( the_node );
    575 }
    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  */
    585 void rtems_chain_explicit_extract(
    586   rtems_chain_control *chain,
    587   rtems_chain_node *node
    588 );
    589 #else
    590 RTEMS_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 );
    597573}
    598574#endif
     
    634610)
    635611{
    636   return _Chain_Get( &the_chain->Chain );
     612  return _Chain_Get( the_chain );
    637613}
    638614#endif
     
    645621)
    646622{
    647   return _Chain_Get_unprotected( &the_chain->Chain );
    648 }
    649 
    650 #if !defined( RTEMS_SMP )
     623  return _Chain_Get_unprotected( the_chain );
     624}
     625
    651626/**
    652627 * @brief Insert a node on a chain
     
    658633 * of the extract operation.
    659634 */
     635#if defined( RTEMS_SMP )
     636void rtems_chain_insert(
     637  rtems_chain_node *after_node,
     638  rtems_chain_node *the_node
     639);
     640#else
    660641RTEMS_INLINE_ROUTINE void rtems_chain_insert(
    661642  rtems_chain_node *after_node,
     
    664645{
    665646  _Chain_Insert( after_node, the_node );
    666 }
    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 )
    677 void rtems_chain_explicit_insert(
    678   rtems_chain_control *chain,
    679   rtems_chain_node *after_node,
    680   rtems_chain_node *node
    681 );
    682 #else
    683 RTEMS_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 );
    691647}
    692648#endif
     
    722678)
    723679{
    724   _Chain_Append( &the_chain->Chain, the_node );
     680  _Chain_Append( the_chain, the_node );
    725681}
    726682#endif
     
    739695)
    740696{
    741   _Chain_Append_unprotected( &the_chain->Chain, the_node );
     697  _Chain_Append_unprotected( the_chain, the_node );
    742698}
    743699
     
    764720)
    765721{
    766   _Chain_Prepend( &the_chain->Chain, the_node );
     722  _Chain_Prepend( the_chain, the_node );
    767723}
    768724#endif
     
    784740)
    785741{
    786   _Chain_Prepend_unprotected( &the_chain->Chain, the_node );
     742  _Chain_Prepend_unprotected( the_chain, the_node );
    787743}
    788744
     
    806762)
    807763{
    808   return _Chain_Append_with_empty_check( &chain->Chain, node );
     764  return _Chain_Append_with_empty_check( chain, node );
    809765}
    810766#endif
     
    829785)
    830786{
    831   return _Chain_Prepend_with_empty_check( &chain->Chain, node );
     787  return _Chain_Prepend_with_empty_check( chain, node );
    832788}
    833789#endif
     
    856812)
    857813{
    858   return _Chain_Get_with_empty_check( &chain->Chain, node );
     814  return _Chain_Get_with_empty_check( chain, node );
    859815}
    860816#endif
     
    874830)
    875831{
    876   return _Chain_Node_count_unprotected( &chain->Chain );
     832  return _Chain_Node_count_unprotected( chain );
    877833}
    878834
  • cpukit/sapi/src/chainsmp.c

    rb1196e3 rae88aa7  
    11/*
    2  * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
     2 * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
    33 *
    44 *  embedded brains GmbH
     
    2121#if defined( RTEMS_SMP )
    2222
    23 void rtems_chain_explicit_extract(
    24   rtems_chain_control *chain,
    25   rtems_chain_node *node
    26 )
     23#include <rtems/score/smplock.h>
     24
     25static SMP_lock_Control chain_lock = SMP_LOCK_INITIALIZER;
     26
     27static void chain_acquire( ISR_Level *level )
     28{
     29  _SMP_lock_ISR_disable_and_acquire( &chain_lock, *level );
     30}
     31
     32static void chain_release( ISR_Level *level )
     33{
     34  _SMP_lock_Release_and_ISR_enable( &chain_lock, *level );
     35}
     36
     37void rtems_chain_extract( rtems_chain_node *node )
    2738{
    2839  ISR_Level level;
    2940
    30   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
     41  chain_acquire( &level );
    3142  _Chain_Extract_unprotected( node );
    32   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     43  chain_release( &level );
    3344}
    3445
     
    3849  ISR_Level level;
    3950
    40   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    41   node = _Chain_Get_unprotected( &chain->Chain );
    42   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     51  chain_acquire( &level );
     52  node = _Chain_Get_unprotected( chain );
     53  chain_release( &level );
    4354
    4455  return node;
    4556}
    4657
    47 void rtems_chain_explicit_insert(
    48   rtems_chain_control *chain,
    49   rtems_chain_node *after_node,
    50   rtems_chain_node *node
    51 )
     58void rtems_chain_insert( rtems_chain_node *after_node, rtems_chain_node *node )
    5259{
    5360  ISR_Level level;
    5461
    55   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
     62  chain_acquire( &level );
    5663  _Chain_Insert_unprotected( after_node, node );
    57   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     64  chain_release( &level );
    5865}
    5966
     
    6572  ISR_Level level;
    6673
    67   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    68   _Chain_Append_unprotected( &chain->Chain, node );
    69   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     74  chain_acquire( &level );
     75  _Chain_Append_unprotected( chain, node );
     76  chain_release( &level );
    7077}
    7178
     
    7784  ISR_Level level;
    7885
    79   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    80   _Chain_Prepend_unprotected( &chain->Chain, node );
    81   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     86  chain_acquire( &level );
     87  _Chain_Prepend_unprotected( chain, node );
     88  chain_release( &level );
    8289}
    8390
     
    9097  ISR_Level level;
    9198
    92   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    93   was_empty = _Chain_Append_with_empty_check_unprotected(
    94     &chain->Chain,
    95     node
    96   );
    97   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     99  chain_acquire( &level );
     100  was_empty = _Chain_Append_with_empty_check_unprotected( chain, node );
     101  chain_release( &level );
    98102
    99103  return was_empty;
     
    108112  ISR_Level level;
    109113
    110   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    111   was_empty = _Chain_Prepend_with_empty_check_unprotected(
    112     &chain->Chain,
    113     node
    114   );
    115   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     114  chain_acquire( &level );
     115  was_empty = _Chain_Prepend_with_empty_check_unprotected( chain, node );
     116  chain_release( &level );
    116117
    117118  return was_empty;
     
    126127  ISR_Level level;
    127128
    128   _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    129   is_empty_now = _Chain_Get_with_empty_check_unprotected(
    130     &chain->Chain,
    131     node
    132   );
    133   _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
     129  chain_acquire( &level );
     130  is_empty_now = _Chain_Get_with_empty_check_unprotected( chain, node );
     131  chain_release( &level );
    134132
    135133  return is_empty_now;
  • testsuites/libtests/block06/init.c

    rb1196e3 rae88aa7  
    11311131  bd = (rtems_bdbuf_buffer*) node;
    11321132  pnode = node->previous;
    1133   rtems_chain_explicit_extract (&buffers, node);
     1133  rtems_chain_extract (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_explicit_extract (&buffers, node);
     1140  rtems_chain_extract (node);
    11411141  node = pnode;
    11421142  bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name);
  • testsuites/sptests/spchain/init.c

    rb1196e3 rae88aa7  
    107107  rtems_chain_initialize_empty( &chain );
    108108  rtems_chain_append( &chain, &node1 );
    109   rtems_chain_explicit_insert( &chain, &node1, &node2 );
     109  rtems_chain_insert( &node1, &node2 );
    110110
    111111  puts( "INIT - Verify rtems_chain_is_first" );
     
    309309  node2.id = 2;
    310310  rtems_chain_append( &chain1, &node1.Node );
    311   rtems_chain_explicit_insert( &chain1, &node1.Node, &node2.Node );
     311  rtems_chain_insert( &node1.Node, &node2.Node );
    312312
    313313  for ( p = rtems_chain_first(&chain1), id = 1 ;
Note: See TracChangeset for help on using the changeset viewer.