RTEMS  5.0.0
smplock.h
Go to the documentation of this file.
1 
9 /*
10  * COPYRIGHT (c) 1989-2011.
11  * On-Line Applications Research Corporation (OAR).
12  *
13  * Copyright (c) 2013, 2016 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.org/license/LICENSE.
18  */
19 
20 #ifndef _RTEMS_SCORE_SMPLOCK_H
21 #define _RTEMS_SCORE_SMPLOCK_H
22 
23 #include <rtems/score/cpuopts.h>
24 
43 #if defined(RTEMS_SMP)
44 
47 #include <rtems/score/isrlevel.h>
48 
49 #if defined(RTEMS_DEBUG)
50 #include <rtems/score/assert.h>
51 #include <rtems/score/smp.h>
52 #endif
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif /* __cplusplus */
57 
58 #if defined(RTEMS_DEBUG) || defined(RTEMS_PROFILING)
59 #define RTEMS_SMP_LOCK_DO_NOT_INLINE
60 #endif
61 
65 typedef struct {
66  SMP_ticket_lock_Control Ticket_lock;
67 #if defined(RTEMS_DEBUG)
68 
80  uint32_t owner;
81 #endif
82 #if defined(RTEMS_PROFILING)
83  SMP_lock_Stats Stats;
84 #endif
85 } SMP_lock_Control;
86 
90 typedef struct {
91  ISR_Level isr_level;
92 #if defined(RTEMS_DEBUG)
93  SMP_lock_Control *lock_used_for_acquire;
94 #endif
95 #if defined(RTEMS_PROFILING)
96  SMP_lock_Stats_context Stats_context;
97 #endif
98 } SMP_lock_Context;
99 
100 #if defined(RTEMS_DEBUG)
101 #define SMP_LOCK_NO_OWNER 0
102 #endif
103 
107 #if defined(RTEMS_DEBUG) && defined(RTEMS_PROFILING)
108  #define SMP_LOCK_INITIALIZER( name ) \
109  { \
110  SMP_TICKET_LOCK_INITIALIZER, \
111  SMP_LOCK_NO_OWNER, \
112  SMP_LOCK_STATS_INITIALIZER( name ) \
113  }
114 #elif defined(RTEMS_DEBUG)
115  #define SMP_LOCK_INITIALIZER( name ) \
116  { SMP_TICKET_LOCK_INITIALIZER, SMP_LOCK_NO_OWNER }
117 #elif defined(RTEMS_PROFILING)
118  #define SMP_LOCK_INITIALIZER( name ) \
119  { SMP_TICKET_LOCK_INITIALIZER, SMP_LOCK_STATS_INITIALIZER( name ) }
120 #else
121  #define SMP_LOCK_INITIALIZER( name ) { SMP_TICKET_LOCK_INITIALIZER }
122 #endif
123 
124 static inline void _SMP_lock_Initialize_inline(
125  SMP_lock_Control *lock,
126  const char *name
127 )
128 {
129  _SMP_ticket_lock_Initialize( &lock->Ticket_lock );
130 #if defined(RTEMS_DEBUG)
131  lock->owner = SMP_LOCK_NO_OWNER;
132 #endif
133 #if defined(RTEMS_PROFILING)
134  _SMP_lock_Stats_initialize( &lock->Stats, name );
135 #else
136  (void) name;
137 #endif
138 }
139 
149 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
150 void _SMP_lock_Initialize(
151  SMP_lock_Control *lock,
152  const char * name
153 );
154 #else
155 #define _SMP_lock_Initialize( lock, name ) \
156  _SMP_lock_Initialize_inline( lock, name )
157 #endif
158 
159 static inline void _SMP_lock_Destroy_inline( SMP_lock_Control *lock )
160 {
161  _SMP_ticket_lock_Destroy( &lock->Ticket_lock );
162  _SMP_lock_Stats_destroy( &lock->Stats );
163 }
164 
172 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
173 void _SMP_lock_Destroy( SMP_lock_Control *lock );
174 #else
175 #define _SMP_lock_Destroy( lock ) \
176  _SMP_lock_Destroy_inline( lock )
177 #endif
178 
179 #if defined(RTEMS_DEBUG)
180 static inline uint32_t _SMP_lock_Who_am_I( void )
181 {
182  /*
183  * The CPU index starts with zero. Increment it by one, to allow global SMP
184  * locks to reside in the BSS section.
185  */
186  return _SMP_Get_current_processor() + 1;
187 }
188 #endif
189 
190 static inline void _SMP_lock_Acquire_inline(
191  SMP_lock_Control *lock,
192  SMP_lock_Context *context
193 )
194 {
195 #if defined(RTEMS_DEBUG)
196  context->lock_used_for_acquire = lock;
197 #else
198  (void) context;
199 #endif
200  _SMP_ticket_lock_Acquire(
201  &lock->Ticket_lock,
202  &lock->Stats,
203  &context->Stats_context
204  );
205 #if defined(RTEMS_DEBUG)
206  lock->owner = _SMP_lock_Who_am_I();
207 #endif
208 }
209 
221 void _SMP_lock_Acquire(
222  SMP_lock_Control *lock,
223  SMP_lock_Context *context
224 );
225 
226 static inline void _SMP_lock_Release_inline(
227  SMP_lock_Control *lock,
228  SMP_lock_Context *context
229 )
230 {
231 #if defined(RTEMS_DEBUG)
232  _Assert( context->lock_used_for_acquire == lock );
233  context->lock_used_for_acquire = NULL;
234  _Assert( lock->owner == _SMP_lock_Who_am_I() );
235  lock->owner = SMP_LOCK_NO_OWNER;
236 #else
237  (void) context;
238 #endif
239  _SMP_ticket_lock_Release(
240  &lock->Ticket_lock,
241  &context->Stats_context
242  );
243 }
244 
252 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
253 void _SMP_lock_Release(
254  SMP_lock_Control *lock,
255  SMP_lock_Context *context
256 );
257 #else
258 #define _SMP_lock_Release( lock, context ) \
259  _SMP_lock_Release_inline( lock, context )
260 #endif
261 
262 static inline void _SMP_lock_ISR_disable_and_acquire_inline(
263  SMP_lock_Control *lock,
264  SMP_lock_Context *context
265 )
266 {
267  _ISR_Local_disable( context->isr_level );
268  _SMP_lock_Acquire_inline( lock, context );
269 }
270 
278 void _SMP_lock_ISR_disable_and_acquire(
279  SMP_lock_Control *lock,
280  SMP_lock_Context *context
281 );
282 
283 static inline void _SMP_lock_Release_and_ISR_enable_inline(
284  SMP_lock_Control *lock,
285  SMP_lock_Context *context
286 )
287 {
288  _SMP_lock_Release_inline( lock, context );
289  _ISR_Local_enable( context->isr_level );
290 }
291 
299 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
300 void _SMP_lock_Release_and_ISR_enable(
301  SMP_lock_Control *lock,
302  SMP_lock_Context *context
303 );
304 #else
305 #define _SMP_lock_Release_and_ISR_enable( lock, context ) \
306  _SMP_lock_Release_and_ISR_enable_inline( lock, context )
307 #endif
308 
309 #if defined(RTEMS_DEBUG)
310 
316 bool _SMP_lock_Is_owner( const SMP_lock_Control *lock );
317 #endif
318 
321 #ifdef __cplusplus
322 }
323 #endif /* __cplusplus */
324 
325 #endif /* RTEMS_SMP */
326 
327 #endif /* _RTEMS_SCORE_SMPLOCK_H */
SuperCore SMP Support API.
ISR Level Type.
#define _ISR_Local_disable(_level)
Disables interrupts on this processor.
Definition: isrlevel.h:54
uint32_t ISR_Level
Definition: isrlevel.h:38
SMP Lock API.
#define _ISR_Local_enable(_level)
Enables interrupts on this processor.
Definition: isrlevel.h:71
unsigned context
Definition: tlb.h:108
SMP Lock API.
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77