![]() |
|
|||
File indexing completed on 2025-05-11 08:24:13
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSScoreISRLocks 0007 * 0008 * @brief This header file provides the interfaces of the 0009 * @ref RTEMSScoreISRLocks. 0010 */ 0011 0012 /* 0013 * Copyright (C) 2013, 2024 embedded brains GmbH & Co. KG 0014 * 0015 * Redistribution and use in source and binary forms, with or without 0016 * modification, are permitted provided that the following conditions 0017 * are met: 0018 * 1. Redistributions of source code must retain the above copyright 0019 * notice, this list of conditions and the following disclaimer. 0020 * 2. Redistributions in binary form must reproduce the above copyright 0021 * notice, this list of conditions and the following disclaimer in the 0022 * documentation and/or other materials provided with the distribution. 0023 * 0024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0027 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0028 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0029 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0030 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0031 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0032 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0033 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0034 * POSSIBILITY OF SUCH DAMAGE. 0035 */ 0036 0037 #ifndef _RTEMS_SCORE_ISR_LOCK_H 0038 #define _RTEMS_SCORE_ISR_LOCK_H 0039 0040 #include <rtems/score/isrlevel.h> 0041 #include <rtems/score/smplock.h> 0042 0043 #ifdef __cplusplus 0044 extern "C" { 0045 #endif 0046 0047 /** 0048 * @defgroup RTEMSScoreISRLocks ISR Locks 0049 * 0050 * @ingroup RTEMSScoreISR 0051 * 0052 * @brief This group contains the ISR locks implementation. 0053 * 0054 * The ISR locks are low-level locks to protect critical sections accessed by 0055 * threads and interrupt service routines. 0056 * 0057 * In uniprocessor configurations the ISR locks degrade to simple ISR 0058 * disable/enable sequences. No additional storage or objects are required. 0059 * 0060 * This synchronization primitive is supported in SMP configurations. Here SMP 0061 * locks are used. 0062 * 0063 * @{ 0064 */ 0065 0066 /** 0067 * @brief If this define has a non-zero value, then the interrupt lock 0068 * operations require an object of type ::ISR_lock_Control, otherwise no 0069 * lock object is required. 0070 * 0071 * @par Notes 0072 * This indication can be used to avoid the space overhead for lock objects 0073 * when they are not needed. In this case, the lock operations will not use a 0074 * lock objects parameter. 0075 */ 0076 #if defined( RTEMS_SMP ) 0077 #define ISR_LOCK_NEEDS_OBJECT 1 0078 #else 0079 #define ISR_LOCK_NEEDS_OBJECT 0 0080 #endif 0081 0082 #if ISR_LOCK_NEEDS_OBJECT 0083 /** 0084 * @brief ISR lock control. 0085 */ 0086 typedef struct { 0087 SMP_lock_Control Lock; 0088 } ISR_lock_Control; 0089 #endif 0090 0091 /** 0092 * @brief Local ISR lock context for acquire and release pairs. 0093 */ 0094 typedef struct { 0095 #if defined( RTEMS_SMP ) 0096 SMP_lock_Context Lock_context; 0097 #else 0098 ISR_Level isr_level; 0099 #endif 0100 #if defined( RTEMS_PROFILING ) 0101 /** 0102 * @brief The last interrupt disable instant in CPU counter ticks. 0103 */ 0104 CPU_Counter_ticks ISR_disable_instant; 0105 #endif 0106 } ISR_lock_Context; 0107 0108 #if ISR_LOCK_NEEDS_OBJECT 0109 /** 0110 * @brief Initializer for static initialization of ISR locks. 0111 * 0112 * @param _name The name for the interrupt lock. It must be a string. The 0113 * name is only used if profiling is enabled. 0114 */ 0115 #define ISR_LOCK_INITIALIZER( _name ) { SMP_LOCK_INITIALIZER( _name ) } 0116 #endif 0117 0118 /** 0119 * @brief Sets the ISR level in the ISR lock context. 0120 * 0121 * @param[out] context The ISR lock context. 0122 * @param level The ISR level. 0123 */ 0124 static inline void _ISR_lock_Context_set_level( 0125 ISR_lock_Context *context, 0126 ISR_Level level 0127 ) 0128 { 0129 #if defined( RTEMS_SMP ) 0130 context->Lock_context.isr_level = level; 0131 #else 0132 context->isr_level = level; 0133 #endif 0134 } 0135 0136 /** 0137 * @brief Initializes an ISR lock. 0138 * 0139 * Concurrent initialization leads to unpredictable results. 0140 * 0141 * @param[in] _lock The ISR lock control. 0142 * @param[in] _name The name for the ISR lock. This name must be a 0143 * string persistent throughout the life time of this lock. The name is only 0144 * used if profiling is enabled. 0145 */ 0146 #if defined( RTEMS_SMP ) 0147 #define _ISR_lock_Initialize( _lock, _name ) \ 0148 _SMP_lock_Initialize( &( _lock )->Lock, _name ) 0149 #else 0150 #define _ISR_lock_Initialize( _lock, _name ) \ 0151 do { (void) _name; } while (0) 0152 #endif 0153 0154 /** 0155 * @brief Destroys an ISR lock. 0156 * 0157 * Concurrent destruction leads to unpredictable results. 0158 * 0159 * @param[in] _lock The ISR lock control. 0160 */ 0161 #if defined( RTEMS_SMP ) 0162 #define _ISR_lock_Destroy( _lock ) \ 0163 _SMP_lock_Destroy( &( _lock )->Lock ) 0164 #else 0165 #define _ISR_lock_Destroy( _lock ) 0166 #endif 0167 0168 /** 0169 * @brief Sets the name of an ISR lock. 0170 * 0171 * @param[out] _lock The ISR lock control. 0172 * @param _name The name for the ISR lock. This name must be a string 0173 * persistent throughout the life time of this lock. The name is only used 0174 * if profiling is enabled. 0175 */ 0176 #if defined( RTEMS_SMP ) 0177 #define _ISR_lock_Set_name( _lock, _name ) \ 0178 _SMP_lock_Set_name( &( _lock )->Lock, _name ) 0179 #else 0180 #define _ISR_lock_Set_name( _lock, _name ) 0181 #endif 0182 0183 /** 0184 * @brief Acquires an ISR lock. 0185 * 0186 * Interrupts will be disabled. On SMP configurations this function acquires 0187 * an SMP lock. 0188 * 0189 * This function can be used in thread and interrupt context. 0190 * 0191 * @param[in] _lock The ISR lock control. 0192 * @param[in] _context The local ISR lock context for an acquire and release 0193 * pair. 0194 * 0195 * @see _ISR_lock_Release_and_ISR_enable(). 0196 */ 0197 #if defined( RTEMS_SMP ) 0198 #define _ISR_lock_ISR_disable_and_acquire( _lock, _context ) \ 0199 _SMP_lock_ISR_disable_and_acquire( \ 0200 &( _lock )->Lock, \ 0201 &( _context )->Lock_context \ 0202 ) 0203 #else 0204 #define _ISR_lock_ISR_disable_and_acquire( _lock, _context ) \ 0205 _ISR_Local_disable( ( _context )->isr_level ) 0206 #endif 0207 0208 /** 0209 * @brief Releases an ISR lock. 0210 * 0211 * The interrupt status will be restored. On SMP configurations this function 0212 * releases an SMP lock. 0213 * 0214 * This function can be used in thread and interrupt context. 0215 * 0216 * @param[in] _lock The ISR lock control. 0217 * @param[in] _context The local ISR lock context for an acquire and release 0218 * pair. 0219 * 0220 * @see _ISR_lock_ISR_disable_and_acquire(). 0221 */ 0222 #if defined( RTEMS_SMP ) 0223 #define _ISR_lock_Release_and_ISR_enable( _lock, _context ) \ 0224 _SMP_lock_Release_and_ISR_enable( \ 0225 &( _lock )->Lock, \ 0226 &( _context )->Lock_context \ 0227 ) 0228 #else 0229 #define _ISR_lock_Release_and_ISR_enable( _lock, _context ) \ 0230 _ISR_Local_enable( ( _context )->isr_level ) 0231 #endif 0232 0233 /** 0234 * @brief Acquires an ISR lock inside an ISR disabled section. 0235 * 0236 * The interrupt status will remain unchanged. On SMP configurations this 0237 * function acquires an SMP lock. 0238 * 0239 * In case the executing context can be interrupted by higher priority 0240 * interrupts and these interrupts enter the critical section protected by this 0241 * lock, then the result is unpredictable. 0242 * 0243 * @param[in] _lock The ISR lock control. 0244 * @param[in] _context The local ISR lock context for an acquire and release 0245 * pair. 0246 * 0247 * @see _ISR_lock_Release(). 0248 */ 0249 #if defined( RTEMS_SMP ) 0250 #define _ISR_lock_Acquire( _lock, _context ) \ 0251 do { \ 0252 _Assert( _ISR_Get_level() != 0 ); \ 0253 _SMP_lock_Acquire( \ 0254 &( _lock )->Lock, \ 0255 &( _context )->Lock_context \ 0256 ); \ 0257 } while ( 0 ) 0258 #else 0259 #define _ISR_lock_Acquire( _lock, _context ) \ 0260 do { (void) _context; } while ( 0 ) 0261 #endif 0262 0263 /** 0264 * @brief Releases an ISR lock inside an ISR disabled section. 0265 * 0266 * The interrupt status will remain unchanged. On SMP configurations this 0267 * function releases an SMP lock. 0268 * 0269 * @param[in] _lock The ISR lock control. 0270 * @param[in] _context The local ISR lock context for an acquire and release 0271 * pair. 0272 * 0273 * @see _ISR_lock_Acquire(). 0274 */ 0275 #if defined( RTEMS_SMP ) 0276 #define _ISR_lock_Release( _lock, _context ) \ 0277 _SMP_lock_Release( \ 0278 &( _lock )->Lock, \ 0279 &( _context )->Lock_context \ 0280 ) 0281 #else 0282 #define _ISR_lock_Release( _lock, _context ) \ 0283 do { (void) _context; } while ( 0 ) 0284 #endif 0285 0286 /** 0287 * @brief Acquires an ISR lock inside an ISR disabled section (inline). 0288 * 0289 * @see _ISR_lock_Acquire(). 0290 */ 0291 #if defined( RTEMS_SMP ) 0292 #define _ISR_lock_Acquire_inline( _lock, _context ) \ 0293 do { \ 0294 _Assert( _ISR_Get_level() != 0 ); \ 0295 _SMP_lock_Acquire_inline( \ 0296 &( _lock )->Lock, \ 0297 &( _context )->Lock_context \ 0298 ); \ 0299 } while ( 0 ) 0300 #else 0301 #define _ISR_lock_Acquire_inline( _lock, _context ) \ 0302 do { (void) _context; } while ( 0 ) 0303 #endif 0304 0305 /** 0306 * @brief Releases an ISR lock inside an ISR disabled section (inline). 0307 * 0308 * @see _ISR_lock_Release(). 0309 */ 0310 #if defined( RTEMS_SMP ) 0311 #define _ISR_lock_Release_inline( _lock, _context ) \ 0312 _SMP_lock_Release_inline( \ 0313 &( _lock )->Lock, \ 0314 &( _context )->Lock_context \ 0315 ) 0316 #else 0317 #define _ISR_lock_Release_inline( _lock, _context ) \ 0318 do { (void) _context; } while ( 0 ) 0319 #endif 0320 0321 #if defined( RTEMS_DEBUG ) 0322 /** 0323 * @brief Returns true, if the ISR lock is owned by the current processor, 0324 * otherwise false. 0325 * 0326 * On uni-processor configurations, this function returns true, if interrupts 0327 * are disabled, otherwise false. 0328 * 0329 * @param[in] _lock The ISR lock control. 0330 */ 0331 #if defined( RTEMS_SMP ) 0332 #define _ISR_lock_Is_owner( _lock ) \ 0333 _SMP_lock_Is_owner( &( _lock )->Lock ) 0334 #else 0335 #define _ISR_lock_Is_owner( _lock ) \ 0336 ( _ISR_Get_level() != 0 ) 0337 #endif 0338 #endif 0339 0340 #if defined( RTEMS_PROFILING ) 0341 #define _ISR_lock_ISR_disable_profile( _context ) \ 0342 ( _context )->ISR_disable_instant = _CPU_Counter_read(); 0343 #else 0344 #define _ISR_lock_ISR_disable_profile( _context ) 0345 #endif 0346 0347 /** 0348 * @brief Disables interrupts and saves the previous interrupt state in the ISR 0349 * lock context. 0350 * 0351 * This function can be used in thread and interrupt context. 0352 * 0353 * @param[in] _context The local ISR lock context to store the interrupt state. 0354 * 0355 * @see _ISR_lock_ISR_enable(). 0356 */ 0357 #if defined( RTEMS_SMP ) 0358 #define _ISR_lock_ISR_disable( _context ) \ 0359 do { \ 0360 _ISR_Local_disable( ( _context )->Lock_context.isr_level ); \ 0361 _ISR_lock_ISR_disable_profile( _context ) \ 0362 } while ( 0 ) 0363 #else 0364 #define _ISR_lock_ISR_disable( _context ) \ 0365 do { \ 0366 _ISR_Local_disable( ( _context )->isr_level ); \ 0367 _ISR_lock_ISR_disable_profile( _context ) \ 0368 } while ( 0 ) 0369 #endif 0370 0371 /** 0372 * @brief Restores the saved interrupt state of the ISR lock context. 0373 * 0374 * This function can be used in thread and interrupt context. 0375 * 0376 * @param[in] _context The local ISR lock context containing the saved 0377 * interrupt state. 0378 * 0379 * @see _ISR_lock_ISR_disable(). 0380 */ 0381 #if defined( RTEMS_SMP ) 0382 #define _ISR_lock_ISR_enable( _context ) \ 0383 _ISR_Local_enable( ( _context )->Lock_context.isr_level ) 0384 #else 0385 #define _ISR_lock_ISR_enable( _context ) \ 0386 _ISR_Local_enable( ( _context )->isr_level ) 0387 #endif 0388 0389 /** @} */ 0390 0391 #ifdef __cplusplus 0392 } 0393 #endif 0394 0395 #endif /* _RTEMS_SCORE_ISR_LOCK_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |