source: rtems/cpukit/include/rtems/score/isrlock.h @ 255fe43

Last change on this file since 255fe43 was 255fe43, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 20:40:44

cpukit/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 12.2 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreISRLocks
7 *
8 * @brief This header file provides the interfaces of the
9 *   @ref RTEMSScoreISRLocks.
10 */
11
12/*
13 * Copyright (c) 2013, 2019 embedded brains GmbH.  All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _RTEMS_SCORE_ISR_LOCK_H
38#define _RTEMS_SCORE_ISR_LOCK_H
39
40#include <rtems/score/isrlevel.h>
41#include <rtems/score/smplock.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/**
48 * @defgroup RTEMSScoreISRLocks ISR Locks
49 *
50 * @ingroup RTEMSScoreISR
51 *
52 * @brief This group contains the ISR locks implementation.
53 *
54 * The ISR locks are low-level locks to protect critical sections accessed by
55 * threads and interrupt service routines.
56 *
57 * In uniprocessor configurations the ISR locks degrade to simple ISR
58 * disable/enable sequences.  No additional storage or objects are required.
59 *
60 * This synchronization primitive is supported in SMP configurations.  Here SMP
61 * locks are used.
62 *
63 * @{
64 */
65
66/**
67 * @brief ISR lock control.
68 *
69 * @warning Empty structures are implementation-defined in C.  GCC gives them a
70 * size of zero.  In C++ empty structures have a non-zero size.
71 */
72typedef struct {
73#if defined( RTEMS_SMP )
74  SMP_lock_Control Lock;
75#endif
76} ISR_lock_Control;
77
78/**
79 * @brief Local ISR lock context for acquire and release pairs.
80 */
81typedef struct {
82#if defined( RTEMS_SMP )
83  SMP_lock_Context Lock_context;
84#else
85  ISR_Level isr_level;
86#endif
87#if defined( RTEMS_PROFILING )
88  /**
89   * @brief The last interrupt disable instant in CPU counter ticks.
90   */
91  CPU_Counter_ticks ISR_disable_instant;
92#endif
93} ISR_lock_Context;
94
95/**
96 * @brief Defines an ISR lock member.
97 *
98 * Do not add a ';' after this macro.
99 *
100 * @param _designator The designator for the interrupt lock.
101 */
102#if defined( RTEMS_SMP )
103  #define ISR_LOCK_MEMBER( _designator ) ISR_lock_Control _designator;
104#else
105  #define ISR_LOCK_MEMBER( _designator )
106#endif
107
108/**
109 * @brief Declares an ISR lock variable.
110 *
111 * Do not add a ';' after this macro.
112 *
113 * @param _qualifier The qualifier for the interrupt lock, e.g. extern.
114 * @param _designator The designator for the interrupt lock.
115 */
116#if defined( RTEMS_SMP )
117  #define ISR_LOCK_DECLARE( _qualifier, _designator ) \
118    _qualifier ISR_lock_Control _designator;
119#else
120  #define ISR_LOCK_DECLARE( _qualifier, _designator )
121#endif
122
123/**
124 * @brief Defines an ISR lock variable.
125 *
126 * Do not add a ';' after this macro.
127 *
128 * @param _qualifier The qualifier for the interrupt lock, e.g. static.
129 * @param _designator The designator for the interrupt lock.
130 * @param _name The name for the interrupt lock.  It must be a string.  The
131 * name is only used if profiling is enabled.
132 */
133#if defined( RTEMS_SMP )
134  #define ISR_LOCK_DEFINE( _qualifier, _designator, _name ) \
135    _qualifier ISR_lock_Control _designator = { SMP_LOCK_INITIALIZER( _name ) };
136#else
137  #define ISR_LOCK_DEFINE( _qualifier, _designator, _name )
138#endif
139
140/**
141 * @brief Defines an ISR lock variable reference.
142 *
143 * Do not add a ';' after this macro.
144 *
145 * @param _designator The designator for the interrupt lock reference.
146 * @param _target The target for the interrupt lock reference.
147 */
148#if defined( RTEMS_SMP )
149  #define ISR_LOCK_REFERENCE( _designator, _target ) \
150    ISR_lock_Control *_designator = _target;
151#else
152  #define ISR_LOCK_REFERENCE( _designator, _target )
153#endif
154
155/**
156 * @brief Initializer for static initialization of ISR locks.
157 *
158 * @param _name The name for the interrupt lock.  It must be a string.  The
159 * name is only used if profiling is enabled.
160 */
161#if defined( RTEMS_SMP )
162  #define ISR_LOCK_INITIALIZER( _name ) \
163    { SMP_LOCK_INITIALIZER( _name ) }
164#else
165  #define ISR_LOCK_INITIALIZER( _name ) \
166    { }
167#endif
168
169/**
170 * @brief Sets the ISR level in the ISR lock context.
171 *
172 * @param[out] context The ISR lock context.
173 * @param level The ISR level.
174 */
175RTEMS_INLINE_ROUTINE void _ISR_lock_Context_set_level(
176  ISR_lock_Context *context,
177  ISR_Level         level
178)
179{
180#if defined( RTEMS_SMP )
181  context->Lock_context.isr_level = level;
182#else
183  context->isr_level = level;
184#endif
185}
186
187/**
188 * @brief Initializes an ISR lock.
189 *
190 * Concurrent initialization leads to unpredictable results.
191 *
192 * @param[in] _lock The ISR lock control.
193 * @param[in] _name The name for the ISR lock.  This name must be a
194 * string persistent throughout the life time of this lock.  The name is only
195 * used if profiling is enabled.
196 */
197#if defined( RTEMS_SMP )
198  #define _ISR_lock_Initialize( _lock, _name ) \
199    _SMP_lock_Initialize( &( _lock )->Lock, _name )
200#else
201  #define _ISR_lock_Initialize( _lock, _name )
202#endif
203
204/**
205 * @brief Destroys an ISR lock.
206 *
207 * Concurrent destruction leads to unpredictable results.
208 *
209 * @param[in] _lock The ISR lock control.
210 */
211#if defined( RTEMS_SMP )
212  #define _ISR_lock_Destroy( _lock ) \
213    _SMP_lock_Destroy( &( _lock )->Lock )
214#else
215  #define _ISR_lock_Destroy( _lock )
216#endif
217
218/**
219 * @brief Sets the name of an ISR lock.
220 *
221 * @param[out] _lock The ISR lock control.
222 * @param _name The name for the ISR lock.  This name must be a string
223 *   persistent throughout the life time of this lock.  The name is only used
224 *   if profiling is enabled.
225 */
226#if defined( RTEMS_SMP )
227  #define _ISR_lock_Set_name( _lock, _name ) \
228    _SMP_lock_Set_name( &( _lock )->Lock, _name )
229#else
230  #define _ISR_lock_Set_name( _lock, _name )
231#endif
232
233/**
234 * @brief Acquires an ISR lock.
235 *
236 * Interrupts will be disabled.  On SMP configurations this function acquires
237 * an SMP lock.
238 *
239 * This function can be used in thread and interrupt context.
240 *
241 * @param[in] _lock The ISR lock control.
242 * @param[in] _context The local ISR lock context for an acquire and release
243 * pair.
244 *
245 * @see _ISR_lock_Release_and_ISR_enable().
246 */
247#if defined( RTEMS_SMP )
248  #define _ISR_lock_ISR_disable_and_acquire( _lock, _context ) \
249    _SMP_lock_ISR_disable_and_acquire( \
250      &( _lock )->Lock, \
251      &( _context )->Lock_context \
252    )
253#else
254  #define _ISR_lock_ISR_disable_and_acquire( _lock, _context ) \
255    _ISR_Local_disable( ( _context )->isr_level )
256#endif
257
258/**
259 * @brief Releases an ISR lock.
260 *
261 * The interrupt status will be restored.  On SMP configurations this function
262 * releases an SMP lock.
263 *
264 * This function can be used in thread and interrupt context.
265 *
266 * @param[in] _lock The ISR lock control.
267 * @param[in] _context The local ISR lock context for an acquire and release
268 * pair.
269 *
270 * @see _ISR_lock_ISR_disable_and_acquire().
271 */
272#if defined( RTEMS_SMP )
273  #define _ISR_lock_Release_and_ISR_enable( _lock, _context ) \
274    _SMP_lock_Release_and_ISR_enable( \
275      &( _lock )->Lock, \
276      &( _context )->Lock_context \
277    )
278#else
279  #define _ISR_lock_Release_and_ISR_enable( _lock, _context ) \
280    _ISR_Local_enable( ( _context )->isr_level )
281#endif
282
283/**
284 * @brief Acquires an ISR lock inside an ISR disabled section.
285 *
286 * The interrupt status will remain unchanged.  On SMP configurations this
287 * function acquires an SMP lock.
288 *
289 * In case the executing context can be interrupted by higher priority
290 * interrupts and these interrupts enter the critical section protected by this
291 * lock, then the result is unpredictable.
292 *
293 * @param[in] _lock The ISR lock control.
294 * @param[in] _context The local ISR lock context for an acquire and release
295 * pair.
296 *
297 * @see _ISR_lock_Release().
298 */
299#if defined( RTEMS_SMP )
300  #define _ISR_lock_Acquire( _lock, _context ) \
301    do { \
302      _Assert( _ISR_Get_level() != 0 ); \
303      _SMP_lock_Acquire( \
304        &( _lock )->Lock, \
305        &( _context )->Lock_context \
306      ); \
307    } while ( 0 )
308#else
309  #define _ISR_lock_Acquire( _lock, _context ) \
310    do { (void) _context; } while ( 0 )
311#endif
312
313/**
314 * @brief Releases an ISR lock inside an ISR disabled section.
315 *
316 * The interrupt status will remain unchanged.  On SMP configurations this
317 * function releases an SMP lock.
318 *
319 * @param[in] _lock The ISR lock control.
320 * @param[in] _context The local ISR lock context for an acquire and release
321 * pair.
322 *
323 * @see _ISR_lock_Acquire().
324 */
325#if defined( RTEMS_SMP )
326  #define _ISR_lock_Release( _lock, _context ) \
327    _SMP_lock_Release( \
328      &( _lock )->Lock, \
329      &( _context )->Lock_context \
330    )
331#else
332  #define _ISR_lock_Release( _lock, _context ) \
333    do { (void) _context; } while ( 0 )
334#endif
335
336/**
337 * @brief Acquires an ISR lock inside an ISR disabled section (inline).
338 *
339 * @see _ISR_lock_Acquire().
340 */
341#if defined( RTEMS_SMP )
342  #define _ISR_lock_Acquire_inline( _lock, _context ) \
343    do { \
344      _Assert( _ISR_Get_level() != 0 ); \
345      _SMP_lock_Acquire_inline( \
346        &( _lock )->Lock, \
347        &( _context )->Lock_context \
348      ); \
349    } while ( 0 )
350#else
351  #define _ISR_lock_Acquire_inline( _lock, _context ) \
352    do { (void) _context; } while ( 0 )
353#endif
354
355/**
356 * @brief Releases an ISR lock inside an ISR disabled section (inline).
357 *
358 * @see _ISR_lock_Release().
359 */
360#if defined( RTEMS_SMP )
361  #define _ISR_lock_Release_inline( _lock, _context ) \
362    _SMP_lock_Release_inline( \
363      &( _lock )->Lock, \
364      &( _context )->Lock_context \
365    )
366#else
367  #define _ISR_lock_Release_inline( _lock, _context ) \
368    do { (void) _context; } while ( 0 )
369#endif
370
371#if defined( RTEMS_DEBUG )
372  /**
373   * @brief Returns true, if the ISR lock is owned by the current processor,
374   * otherwise false.
375   *
376   * On uni-processor configurations, this function returns true, if interrupts
377   * are disabled, otherwise false.
378   *
379   * @param[in] _lock The ISR lock control.
380   */
381  #if defined( RTEMS_SMP )
382    #define _ISR_lock_Is_owner( _lock ) \
383      _SMP_lock_Is_owner( &( _lock )->Lock )
384  #else
385    #define _ISR_lock_Is_owner( _lock ) \
386      ( _ISR_Get_level() != 0 )
387  #endif
388#endif
389
390#if defined( RTEMS_PROFILING )
391  #define _ISR_lock_ISR_disable_profile( _context ) \
392    ( _context )->ISR_disable_instant = _CPU_Counter_read();
393#else
394  #define _ISR_lock_ISR_disable_profile( _context )
395#endif
396
397/**
398 * @brief Disables interrupts and saves the previous interrupt state in the ISR
399 * lock context.
400 *
401 * This function can be used in thread and interrupt context.
402 *
403 * @param[in] _context The local ISR lock context to store the interrupt state.
404 *
405 * @see _ISR_lock_ISR_enable().
406 */
407#if defined( RTEMS_SMP )
408  #define _ISR_lock_ISR_disable( _context ) \
409    do { \
410      _ISR_Local_disable( ( _context )->Lock_context.isr_level ); \
411      _ISR_lock_ISR_disable_profile( _context ) \
412    } while ( 0 )
413#else
414  #define _ISR_lock_ISR_disable( _context ) \
415    do { \
416      _ISR_Local_disable( ( _context )->isr_level ); \
417      _ISR_lock_ISR_disable_profile( _context ) \
418    } while ( 0 )
419#endif
420
421/**
422 * @brief Restores the saved interrupt state of the ISR lock context.
423 *
424 * This function can be used in thread and interrupt context.
425 *
426 * @param[in] _context The local ISR lock context containing the saved
427 * interrupt state.
428 *
429 * @see _ISR_lock_ISR_disable().
430 */
431#if defined( RTEMS_SMP )
432  #define _ISR_lock_ISR_enable( _context ) \
433    _ISR_Local_enable( ( _context )->Lock_context.isr_level )
434#else
435  #define _ISR_lock_ISR_enable( _context ) \
436    _ISR_Local_enable( ( _context )->isr_level )
437#endif
438
439/** @} */
440
441#ifdef __cplusplus
442}
443#endif
444
445#endif /* _RTEMS_SCORE_ISR_LOCK_H */
Note: See TracBrowser for help on using the repository browser.