RTEMS
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
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
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 
129 static inline void _SMP_lock_Initialize_inline(
130  SMP_lock_Control *lock,
131  const char *name
132 )
133 {
134  _SMP_ticket_lock_Initialize( &lock->Ticket_lock );
135 #if defined(RTEMS_DEBUG)
136  lock->owner = SMP_LOCK_NO_OWNER;
137 #endif
138 #if defined(RTEMS_PROFILING)
139  _SMP_lock_Stats_initialize( &lock->Stats, name );
140 #else
141  (void) name;
142 #endif
143 }
144 
154 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
156  SMP_lock_Control *lock,
157  const char *name
158 );
159 #else
160 #define _SMP_lock_Initialize( lock, name ) \
161  _SMP_lock_Initialize_inline( lock, name )
162 #endif
163 
169 static inline void _SMP_lock_Destroy_inline( SMP_lock_Control *lock )
170 {
171  _SMP_ticket_lock_Destroy( &lock->Ticket_lock );
172  _SMP_lock_Stats_destroy( &lock->Stats );
173 }
174 
182 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
183 void _SMP_lock_Destroy( SMP_lock_Control *lock );
184 #else
185 #define _SMP_lock_Destroy( lock ) \
186  _SMP_lock_Destroy_inline( lock )
187 #endif
188 
196 static inline void _SMP_lock_Set_name(
197  SMP_lock_Control *lock,
198  const char *name
199 )
200 {
201 #if defined(RTEMS_PROFILING)
202  lock->Stats.name = name;
203 #else
204  (void) name;
205 #endif
206 }
207 
213 #if defined(RTEMS_DEBUG)
214 static inline uint32_t _SMP_lock_Who_am_I( void )
215 {
216  /*
217  * The CPU index starts with zero. Increment it by one, to allow global SMP
218  * locks to reside in the BSS section.
219  */
220  return _SMP_Get_current_processor() + 1;
221 }
222 #endif
223 
230 static inline void _SMP_lock_Acquire_inline(
231  SMP_lock_Control *lock,
232  SMP_lock_Context *context
233 )
234 {
235 #if defined(RTEMS_DEBUG)
236  context->lock_used_for_acquire = lock;
237 #else
238  (void) context;
239 #endif
241  &lock->Ticket_lock,
242  &lock->Stats,
243  &context->Stats_context
244  );
245 #if defined(RTEMS_DEBUG)
246  lock->owner = _SMP_lock_Who_am_I();
247 #endif
248 }
249 
261 void _SMP_lock_Acquire(
262  SMP_lock_Control *lock,
263  SMP_lock_Context *context
264 );
265 
272 static inline void _SMP_lock_Release_inline(
273  SMP_lock_Control *lock,
274  SMP_lock_Context *context
275 )
276 {
277 #if defined(RTEMS_DEBUG)
278  _Assert( context->lock_used_for_acquire == lock );
279  context->lock_used_for_acquire = NULL;
280  _Assert( lock->owner == _SMP_lock_Who_am_I() );
281  lock->owner = SMP_LOCK_NO_OWNER;
282 #else
283  (void) context;
284 #endif
286  &lock->Ticket_lock,
287  &context->Stats_context
288  );
289 }
290 
298 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
299 void _SMP_lock_Release(
300  SMP_lock_Control *lock,
301  SMP_lock_Context *context
302 );
303 #else
304 #define _SMP_lock_Release( lock, context ) \
305  _SMP_lock_Release_inline( lock, context )
306 #endif
307 
315  SMP_lock_Control *lock,
316  SMP_lock_Context *context
317 )
318 {
319  _ISR_Local_disable( context->isr_level );
320  _SMP_lock_Acquire_inline( lock, context );
321 }
322 
331  SMP_lock_Control *lock,
332  SMP_lock_Context *context
333 );
334 
342  SMP_lock_Control *lock,
343  SMP_lock_Context *context
344 )
345 {
346  _SMP_lock_Release_inline( lock, context );
347  _ISR_Local_enable( context->isr_level );
348 }
349 
357 #if defined(RTEMS_SMP_LOCK_DO_NOT_INLINE)
359  SMP_lock_Control *lock,
360  SMP_lock_Context *context
361 );
362 #else
363 #define _SMP_lock_Release_and_ISR_enable( lock, context ) \
364  _SMP_lock_Release_and_ISR_enable_inline( lock, context )
365 #endif
366 
367 #if defined(RTEMS_DEBUG)
368 
376 bool _SMP_lock_Is_owner( const SMP_lock_Control *lock );
377 #endif
378 
381 #ifdef __cplusplus
382 }
383 #endif /* __cplusplus */
384 
385 #endif /* RTEMS_SMP */
386 
387 #endif /* _RTEMS_SCORE_SMPLOCK_H */
#define _SMP_ticket_lock_Acquire(lock, stats, stats_context)
Acquires an SMP ticket lock.
#define _ISR_Local_disable(_level)
Disables interrupts on this processor.
Definition: isrlevel.h:57
SMP lock control.
Definition: smplock.h:65
Local SMP lock context for acquire and release pairs.
Definition: smplock.h:90
ISR Level Type.
static void _SMP_lock_Initialize_inline(SMP_lock_Control *lock, const char *name)
Initializes the SMP lock with the given name.
Definition: smplock.h:129
static void _SMP_ticket_lock_Initialize(SMP_ticket_lock_Control *lock)
Initializes the SMP ticket lock.
Definition: smplockticket.h:61
static void _SMP_lock_Release_and_ISR_enable_inline(SMP_lock_Control *lock, SMP_lock_Context *context)
Releases the SMP lock and enables interrupts.
Definition: smplock.h:341
static void _SMP_lock_Destroy_inline(SMP_lock_Control *lock)
Destroys the SMP lock.
Definition: smplock.h:169
SuperCore SMP Support API.
void _SMP_lock_Acquire(SMP_lock_Control *lock, SMP_lock_Context *context)
Acquires an SMP lock.
Definition: smplock.c:36
Information for the Assert Handler.
#define _SMP_lock_Release_and_ISR_enable(lock, context)
Releases the SMP lock and enables interrupts.
Definition: smplock.h:363
#define _SMP_ticket_lock_Release(lock, stats_context)
Releases an SMP ticket lock.
SMP Lock API.
uint32_t ISR_Level
Definition: isrlevel.h:41
static void _SMP_lock_Release_inline(SMP_lock_Control *lock, SMP_lock_Context *context)
Releases an SMP lock.
Definition: smplock.h:272
#define _ISR_Local_enable(_level)
Enables interrupts on this processor.
Definition: isrlevel.h:74
static void _SMP_lock_ISR_disable_and_acquire_inline(SMP_lock_Control *lock, SMP_lock_Context *context)
Disables interrupts and acquires the SMP lock.
Definition: smplock.h:314
void _SMP_lock_ISR_disable_and_acquire(SMP_lock_Control *lock, SMP_lock_Context *context)
Disables interrupts and acquires the SMP lock.
Definition: smplock.c:54
static void _SMP_ticket_lock_Destroy(SMP_ticket_lock_Control *lock)
Destroys the SMP ticket lock.
Definition: smplockticket.h:76
SMP ticket lock control.
Definition: smplockticket.h:40
#define _SMP_lock_Release(lock, context)
Releases an SMP lock.
Definition: smplock.h:304
#define _SMP_lock_Destroy(lock)
Destroys an SMP lock.
Definition: smplock.h:185
#define _SMP_lock_Initialize(lock, name)
Initializes an SMP lock.
Definition: smplock.h:160
static void _SMP_lock_Acquire_inline(SMP_lock_Control *lock, SMP_lock_Context *context)
Gets my index.
Definition: smplock.h:230
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100
SMP Lock API.
static void _SMP_lock_Set_name(SMP_lock_Control *lock, const char *name)
Sets the name of an SMP lock.
Definition: smplock.h:196