source: rtems/cpukit/score/include/rtems/score/smplock.h @ 28779c7

4.11
Last change on this file since 28779c7 was 28779c7, checked in by Sebastian Huber <sebastian.huber@…>, on Mar 7, 2014 at 11:53:41 AM

score: Add function to destroy SMP locks

  • Property mode set to 100644
File size: 5.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreSMPLock
5 *
6 * @brief SMP Lock API
7 */
8
9/*
10 * COPYRIGHT (c) 1989-2011.
11 * On-Line Applications Research Corporation (OAR).
12 *
13 * Copyright (c) 2013-2014 embedded brains GmbH
14 *
15 * The license and distribution terms for this file may be
16 * found in the file LICENSE in this distribution or at
17 * http://www.rtems.com/license/LICENSE.
18 */
19
20#ifndef _RTEMS_SCORE_SMPLOCK_H
21#define _RTEMS_SCORE_SMPLOCK_H
22
23#include <rtems/score/cpuopts.h>
24
25#if defined( RTEMS_SMP )
26
27#include <rtems/score/atomic.h>
28#include <rtems/score/isrlevel.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif /* __cplusplus */
33
34/**
35 * @defgroup ScoreSMPLock SMP Locks
36 *
37 * @ingroup Score
38 *
39 * @brief The SMP lock provides mutual exclusion for SMP systems at the lowest
40 * level.
41 *
42 * The SMP lock is implemented as a ticket lock.  This provides fairness in
43 * case of concurrent lock attempts.
44 *
45 * This SMP lock API uses a local context for acquire and release pairs.  Such
46 * a context may be used to implement for example the Mellor-Crummey and Scott
47 * (MCS) locks in the future.
48 *
49 * @{
50 */
51
52/**
53 * @brief SMP ticket lock control.
54 */
55typedef struct {
56  Atomic_Uint next_ticket;
57  Atomic_Uint now_serving;
58} SMP_ticket_lock_Control;
59
60/**
61 * @brief SMP ticket lock control initializer for static initialization.
62 */
63#define SMP_TICKET_LOCK_INITIALIZER \
64  { ATOMIC_INITIALIZER_UINT( 0U ), ATOMIC_INITIALIZER_UINT( 0U ) }
65
66/**
67 * @brief Initializes an SMP ticket lock.
68 *
69 * Concurrent initialization leads to unpredictable results.
70 *
71 * @param[in,out] lock The SMP ticket lock control.
72 */
73static inline void _SMP_ticket_lock_Initialize( SMP_ticket_lock_Control *lock )
74{
75  _Atomic_Init_uint( &lock->next_ticket, 0U );
76  _Atomic_Init_uint( &lock->now_serving, 0U );
77}
78
79/**
80 * @brief Destroys an SMP ticket lock.
81 *
82 * Concurrent destruction leads to unpredictable results.
83 *
84 * @param[in,out] lock The SMP ticket lock control.
85 */
86static inline void _SMP_ticket_lock_Destroy( SMP_ticket_lock_Control *lock )
87{
88  (void) lock;
89}
90
91/**
92 * @brief Acquires an SMP ticket lock.
93 *
94 * This function will not disable interrupts.  The caller must ensure that the
95 * current thread of execution is not interrupted indefinite once it obtained
96 * the SMP ticket lock.
97 *
98 * @param[in,out] lock The SMP ticket lock control.
99 */
100static inline void _SMP_ticket_lock_Acquire( SMP_ticket_lock_Control *lock )
101{
102  unsigned int my_ticket =
103    _Atomic_Fetch_add_uint( &lock->next_ticket, 1U, ATOMIC_ORDER_RELAXED );
104  unsigned int now_serving;
105
106  do {
107    now_serving =
108      _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_ACQUIRE );
109  } while ( now_serving != my_ticket );
110}
111
112/**
113 * @brief Releases an SMP ticket lock.
114 *
115 * @param[in,out] lock The SMP ticket lock control.
116 */
117static inline void _SMP_ticket_lock_Release( SMP_ticket_lock_Control *lock )
118{
119  unsigned int current_ticket =
120    _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
121  unsigned int next_ticket = current_ticket + 1U;
122
123  _Atomic_Store_uint( &lock->now_serving, next_ticket, ATOMIC_ORDER_RELEASE );
124}
125
126/**
127 * @brief SMP lock control.
128 */
129typedef struct {
130  SMP_ticket_lock_Control ticket_lock;
131} SMP_lock_Control;
132
133/**
134 * @brief Local SMP lock context for acquire and release pairs.
135 */
136typedef struct {
137  ISR_Level isr_level;
138} SMP_lock_Context;
139
140/**
141 * @brief SMP lock control initializer for static initialization.
142 */
143#define SMP_LOCK_INITIALIZER { SMP_TICKET_LOCK_INITIALIZER }
144
145/**
146 * @brief Initializes an SMP lock.
147 *
148 * Concurrent initialization leads to unpredictable results.
149 *
150 * @param[in,out] lock The SMP lock control.
151 */
152static inline void _SMP_lock_Initialize( SMP_lock_Control *lock )
153{
154  _SMP_ticket_lock_Initialize( &lock->ticket_lock );
155}
156
157/**
158 * @brief Destroys an SMP lock.
159 *
160 * Concurrent destruction leads to unpredictable results.
161 *
162 * @param[in,out] lock The SMP lock control.
163 */
164static inline void _SMP_lock_Destroy( SMP_lock_Control *lock )
165{
166  _SMP_ticket_lock_Destroy( &lock->ticket_lock );
167}
168
169/**
170 * @brief Acquires an SMP lock.
171 *
172 * This function will not disable interrupts.  The caller must ensure that the
173 * current thread of execution is not interrupted indefinite once it obtained
174 * the SMP lock.
175 *
176 * @param[in,out] lock The SMP lock control.
177 * @param[in,out] context The local SMP lock context for an acquire and release
178 * pair.
179 */
180static inline void _SMP_lock_Acquire(
181  SMP_lock_Control *lock,
182  SMP_lock_Context *context
183)
184{
185  (void) context;
186  _SMP_ticket_lock_Acquire( &lock->ticket_lock );
187}
188
189/**
190 * @brief Releases an SMP lock.
191 *
192 * @param[in,out] lock The SMP lock control.
193 * @param[in,out] context The local SMP lock context for an acquire and release
194 * pair.
195 */
196static inline void _SMP_lock_Release(
197  SMP_lock_Control *lock,
198  SMP_lock_Context *context
199)
200{
201  (void) context;
202  _SMP_ticket_lock_Release( &lock->ticket_lock );
203}
204
205/**
206 * @brief Disables interrupts and acquires the SMP lock.
207 *
208 * @param[in,out] lock The SMP lock control.
209 * @param[in,out] context The local SMP lock context for an acquire and release
210 * pair.
211 */
212static inline void _SMP_lock_ISR_disable_and_acquire(
213  SMP_lock_Control *lock,
214  SMP_lock_Context *context
215)
216{
217  _ISR_Disable_without_giant( context->isr_level );
218  _SMP_lock_Acquire( lock, context );
219}
220
221/**
222 * @brief Releases the SMP lock and enables interrupts.
223 *
224 * @param[in,out] lock The SMP lock control.
225 * @param[in,out] context The local SMP lock context for an acquire and release
226 * pair.
227 */
228static inline void _SMP_lock_Release_and_ISR_enable(
229  SMP_lock_Control *lock,
230  SMP_lock_Context *context
231)
232{
233  _SMP_lock_Release( lock, context );
234  _ISR_Enable_without_giant( context->isr_level );
235}
236
237/**@}*/
238
239#ifdef __cplusplus
240}
241#endif /* __cplusplus */
242
243#endif /* defined( RTEMS_SMP ) */
244
245#endif /* _RTEMS_SCORE_SMPLOCK_H */
Note: See TracBrowser for help on using the repository browser.