source: rtems/cpukit/sapi/src/chainsmp.c @ ae88aa7

4.115
Last change on this file since ae88aa7 was ae88aa7, checked in by Sebastian Huber <sebastian.huber@…>, on 03/10/14 at 07:15:37

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.

  • Property mode set to 100644
File size: 2.6 KB
Line 
1/*
2 * Copyright (c) 2013-2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/chain.h>
20
21#if defined( RTEMS_SMP )
22
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 )
38{
39  ISR_Level level;
40
41  chain_acquire( &level );
42  _Chain_Extract_unprotected( node );
43  chain_release( &level );
44}
45
46rtems_chain_node *rtems_chain_get( rtems_chain_control *chain )
47{
48  rtems_chain_node *node;
49  ISR_Level level;
50
51  chain_acquire( &level );
52  node = _Chain_Get_unprotected( chain );
53  chain_release( &level );
54
55  return node;
56}
57
58void rtems_chain_insert( rtems_chain_node *after_node, rtems_chain_node *node )
59{
60  ISR_Level level;
61
62  chain_acquire( &level );
63  _Chain_Insert_unprotected( after_node, node );
64  chain_release( &level );
65}
66
67void rtems_chain_append(
68  rtems_chain_control *chain,
69  rtems_chain_node *node
70)
71{
72  ISR_Level level;
73
74  chain_acquire( &level );
75  _Chain_Append_unprotected( chain, node );
76  chain_release( &level );
77}
78
79void rtems_chain_prepend(
80  rtems_chain_control *chain,
81  rtems_chain_node *node
82)
83{
84  ISR_Level level;
85
86  chain_acquire( &level );
87  _Chain_Prepend_unprotected( chain, node );
88  chain_release( &level );
89}
90
91bool rtems_chain_append_with_empty_check(
92  rtems_chain_control *chain,
93  rtems_chain_node *node
94)
95{
96  bool was_empty;
97  ISR_Level level;
98
99  chain_acquire( &level );
100  was_empty = _Chain_Append_with_empty_check_unprotected( chain, node );
101  chain_release( &level );
102
103  return was_empty;
104}
105
106bool rtems_chain_prepend_with_empty_check(
107  rtems_chain_control *chain,
108  rtems_chain_node *node
109)
110{
111  bool was_empty;
112  ISR_Level level;
113
114  chain_acquire( &level );
115  was_empty = _Chain_Prepend_with_empty_check_unprotected( chain, node );
116  chain_release( &level );
117
118  return was_empty;
119}
120
121bool rtems_chain_get_with_empty_check(
122  rtems_chain_control *chain,
123  rtems_chain_node **node
124)
125{
126  bool is_empty_now;
127  ISR_Level level;
128
129  chain_acquire( &level );
130  is_empty_now = _Chain_Get_with_empty_check_unprotected( chain, node );
131  chain_release( &level );
132
133  return is_empty_now;
134}
135
136#endif /* defined( RTEMS_SMP ) */
Note: See TracBrowser for help on using the repository browser.