[d8134178] | 1 | /** |
---|
| 2 | * @file |
---|
| 3 | * |
---|
| 4 | * @brief Inlined Routines Associated with the CORE Mutexes |
---|
[3a4ae6c] | 5 | * |
---|
[d8134178] | 6 | * This include file contains all of the inlined routines associated |
---|
| 7 | * with the CORE mutexes. |
---|
[baff4da] | 8 | */ |
---|
| 9 | |
---|
| 10 | /* |
---|
[7c8d65e] | 11 | * COPYRIGHT (c) 1989-2009. |
---|
[3a4ae6c] | 12 | * On-Line Applications Research Corporation (OAR). |
---|
| 13 | * |
---|
[98e4ebf5] | 14 | * The license and distribution terms for this file may be |
---|
| 15 | * found in the file LICENSE in this distribution or at |
---|
[dd687d97] | 16 | * http://www.rtems.com/license/LICENSE. |
---|
[3a4ae6c] | 17 | */ |
---|
| 18 | |
---|
[ef49476] | 19 | #ifndef _RTEMS_SCORE_COREMUTEX_H |
---|
| 20 | # error "Never use <rtems/score/coremutex.inl> directly; include <rtems/score/coremutex.h> instead." |
---|
| 21 | #endif |
---|
| 22 | |
---|
[61d330f5] | 23 | #ifndef _RTEMS_SCORE_COREMUTEX_INL |
---|
| 24 | #define _RTEMS_SCORE_COREMUTEX_INL |
---|
[3a4ae6c] | 25 | |
---|
[4fc370e] | 26 | #include <rtems/score/threaddispatch.h> |
---|
| 27 | |
---|
[baff4da] | 28 | /** |
---|
[d8134178] | 29 | * @addtogroup ScoreMutex |
---|
[baff4da] | 30 | */ |
---|
[b697bc6] | 31 | /**@{**/ |
---|
[baff4da] | 32 | |
---|
| 33 | /** |
---|
[d8134178] | 34 | * @brief Is mutex locked. |
---|
[6a07436] | 35 | * |
---|
[d8134178] | 36 | * This routine returns true if the mutex specified is locked and false |
---|
| 37 | * otherwise. |
---|
[6a07436] | 38 | * |
---|
[d8134178] | 39 | * @param[in] the_mutex is the mutex to check. |
---|
[6a07436] | 40 | * |
---|
[d8134178] | 41 | * @retval true The mutex is locked. |
---|
| 42 | * @retval false The mutex is not locked. |
---|
[3a4ae6c] | 43 | */ |
---|
[484a769] | 44 | RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_locked( |
---|
[3a4ae6c] | 45 | CORE_mutex_Control *the_mutex |
---|
| 46 | ) |
---|
| 47 | { |
---|
| 48 | return the_mutex->lock == CORE_MUTEX_LOCKED; |
---|
| 49 | } |
---|
[d8134178] | 50 | |
---|
[baff4da] | 51 | /** |
---|
[d8134178] | 52 | * @brief Does core mutex use FIFO blocking. |
---|
[6a07436] | 53 | * |
---|
[d8134178] | 54 | * This routine returns true if the mutex's wait discipline is FIFO and false |
---|
| 55 | * otherwise. |
---|
[6a07436] | 56 | * |
---|
[d8134178] | 57 | * @param[in] the_attribute is the attribute set of the mutex. |
---|
[6a07436] | 58 | * |
---|
[d8134178] | 59 | * @retval true The mutex is using FIFO blocking order. |
---|
| 60 | * @retval false The mutex is not using FIFO blocking order. |
---|
[3a4ae6c] | 61 | */ |
---|
[484a769] | 62 | RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_fifo( |
---|
[3a4ae6c] | 63 | CORE_mutex_Attributes *the_attribute |
---|
| 64 | ) |
---|
| 65 | { |
---|
| 66 | return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_FIFO; |
---|
| 67 | } |
---|
[d8134178] | 68 | |
---|
[baff4da] | 69 | /** |
---|
[d8134178] | 70 | * @brief Doex core mutex use priority blocking. |
---|
[6a07436] | 71 | * |
---|
[d8134178] | 72 | * This routine returns true if the mutex's wait discipline is PRIORITY and |
---|
| 73 | * false otherwise. |
---|
[6a07436] | 74 | * |
---|
[d8134178] | 75 | * @param[in] the_attribute is the attribute set of the mutex. |
---|
| 76 | * |
---|
| 77 | * @retval true The mutex is using priority blocking order. |
---|
| 78 | * @retval false The mutex is not using priority blocking order. |
---|
[6a07436] | 79 | * |
---|
[3a4ae6c] | 80 | */ |
---|
[484a769] | 81 | RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority( |
---|
[3a4ae6c] | 82 | CORE_mutex_Attributes *the_attribute |
---|
| 83 | ) |
---|
| 84 | { |
---|
| 85 | return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY; |
---|
| 86 | } |
---|
[d8134178] | 87 | |
---|
[baff4da] | 88 | /** |
---|
[d8134178] | 89 | * @brief Does mutex use priority inheritance. |
---|
[6a07436] | 90 | * |
---|
[d8134178] | 91 | * This routine returns true if the mutex's wait discipline is |
---|
| 92 | * INHERIT_PRIORITY and false otherwise. |
---|
[6a07436] | 93 | * |
---|
[d8134178] | 94 | * @param[in] the_attribute is the attribute set of the mutex. |
---|
[6a07436] | 95 | * |
---|
[d8134178] | 96 | * @retval true The mutex is using priority inheritance. |
---|
| 97 | * @retval false The mutex is not using priority inheritance. |
---|
[3a4ae6c] | 98 | */ |
---|
[484a769] | 99 | RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_inherit_priority( |
---|
[3a4ae6c] | 100 | CORE_mutex_Attributes *the_attribute |
---|
| 101 | ) |
---|
| 102 | { |
---|
| 103 | return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT; |
---|
| 104 | } |
---|
[d8134178] | 105 | |
---|
[baff4da] | 106 | /** |
---|
[d8134178] | 107 | * @brief Does mutex use priority ceiling. |
---|
[6a07436] | 108 | * |
---|
[d8134178] | 109 | * This routine returns true if the mutex's wait discipline is |
---|
| 110 | * PRIORITY_CEILING and false otherwise. |
---|
[6a07436] | 111 | * |
---|
[d8134178] | 112 | * @param[in] the_attribute is the attribute set of the mutex. |
---|
| 113 | * |
---|
| 114 | * @retval true The mutex is using priority ceiling. |
---|
| 115 | * @retval false The mutex is not using priority ceiling. |
---|
[3a4ae6c] | 116 | */ |
---|
[484a769] | 117 | RTEMS_INLINE_ROUTINE bool _CORE_mutex_Is_priority_ceiling( |
---|
[3a4ae6c] | 118 | CORE_mutex_Attributes *the_attribute |
---|
| 119 | ) |
---|
| 120 | { |
---|
| 121 | return the_attribute->discipline == CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING; |
---|
| 122 | } |
---|
[d8134178] | 123 | |
---|
[baff4da] | 124 | /* |
---|
[6a07436] | 125 | * Seize Mutex with Quick Success Path |
---|
| 126 | * |
---|
| 127 | * NOTE: There is no MACRO version of this routine. A body is in |
---|
| 128 | * coremutexseize.c that is duplicated from the .inl by hand. |
---|
[baff4da] | 129 | * |
---|
| 130 | * NOTE: The Doxygen for this routine is in the .h file. |
---|
[21e2b2b] | 131 | */ |
---|
[fd84982] | 132 | |
---|
| 133 | RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock_body( |
---|
[21e2b2b] | 134 | CORE_mutex_Control *the_mutex, |
---|
[4f5baff] | 135 | ISR_Level level |
---|
[21e2b2b] | 136 | ) |
---|
| 137 | { |
---|
| 138 | Thread_Control *executing; |
---|
| 139 | |
---|
| 140 | /* disabled when you get here */ |
---|
| 141 | |
---|
| 142 | executing = _Thread_Executing; |
---|
| 143 | executing->Wait.return_code = CORE_MUTEX_STATUS_SUCCESSFUL; |
---|
| 144 | if ( !_CORE_mutex_Is_locked( the_mutex ) ) { |
---|
| 145 | the_mutex->lock = CORE_MUTEX_LOCKED; |
---|
| 146 | the_mutex->holder = executing; |
---|
| 147 | the_mutex->holder_id = executing->Object.id; |
---|
| 148 | the_mutex->nest_count = 1; |
---|
[fb1d8f81] | 149 | if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || |
---|
[fd84982] | 150 | _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ){ |
---|
| 151 | |
---|
[66a9239a] | 152 | #ifdef __RTEMS_STRICT_ORDER_MUTEX__ |
---|
[1ff9922] | 153 | _Chain_Prepend_unprotected( &executing->lock_mutex, |
---|
| 154 | &the_mutex->queue.lock_queue ); |
---|
[fd84982] | 155 | the_mutex->queue.priority_before = executing->current_priority; |
---|
| 156 | #endif |
---|
| 157 | |
---|
[fb1d8f81] | 158 | executing->resource_count++; |
---|
[fd84982] | 159 | } |
---|
| 160 | |
---|
[fb1d8f81] | 161 | if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { |
---|
[4f5baff] | 162 | _ISR_Enable( level ); |
---|
[86436f44] | 163 | return 0; |
---|
[96d0b64] | 164 | } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING |
---|
| 165 | * |
---|
| 166 | * we possibly bump the priority of the current holder -- which |
---|
| 167 | * happens to be _Thread_Executing. |
---|
| 168 | */ |
---|
[21e2b2b] | 169 | { |
---|
[96d0b64] | 170 | Priority_Control ceiling; |
---|
| 171 | Priority_Control current; |
---|
| 172 | |
---|
| 173 | ceiling = the_mutex->Attributes.priority_ceiling; |
---|
| 174 | current = executing->current_priority; |
---|
| 175 | if ( current == ceiling ) { |
---|
[4f5baff] | 176 | _ISR_Enable( level ); |
---|
[96d0b64] | 177 | return 0; |
---|
| 178 | } |
---|
[21e2b2b] | 179 | |
---|
[96d0b64] | 180 | if ( current > ceiling ) { |
---|
[21e2b2b] | 181 | _Thread_Disable_dispatch(); |
---|
[4f5baff] | 182 | _ISR_Enable( level ); |
---|
[21e2b2b] | 183 | _Thread_Change_priority( |
---|
| 184 | the_mutex->holder, |
---|
| 185 | the_mutex->Attributes.priority_ceiling, |
---|
[6390256] | 186 | false |
---|
[21e2b2b] | 187 | ); |
---|
| 188 | _Thread_Enable_dispatch(); |
---|
| 189 | return 0; |
---|
| 190 | } |
---|
| 191 | /* if ( current < ceiling ) */ { |
---|
| 192 | executing->Wait.return_code = CORE_MUTEX_STATUS_CEILING_VIOLATED; |
---|
[7c8d65e] | 193 | the_mutex->lock = CORE_MUTEX_UNLOCKED; |
---|
[21e2b2b] | 194 | the_mutex->nest_count = 0; /* undo locking above */ |
---|
| 195 | executing->resource_count--; /* undo locking above */ |
---|
[4f5baff] | 196 | _ISR_Enable( level ); |
---|
[21e2b2b] | 197 | return 0; |
---|
| 198 | } |
---|
| 199 | } |
---|
| 200 | return 0; |
---|
| 201 | } |
---|
| 202 | |
---|
[96d0b64] | 203 | /* |
---|
| 204 | * At this point, we know the mutex was not available. If this thread |
---|
| 205 | * is the thread that has locked the mutex, let's see if we are allowed |
---|
| 206 | * to nest access. |
---|
| 207 | */ |
---|
[21e2b2b] | 208 | if ( _Thread_Is_executing( the_mutex->holder ) ) { |
---|
| 209 | switch ( the_mutex->Attributes.lock_nesting_behavior ) { |
---|
| 210 | case CORE_MUTEX_NESTING_ACQUIRES: |
---|
| 211 | the_mutex->nest_count++; |
---|
[4f5baff] | 212 | _ISR_Enable( level ); |
---|
[21e2b2b] | 213 | return 0; |
---|
[7ce892d] | 214 | #if defined(RTEMS_POSIX_API) |
---|
| 215 | case CORE_MUTEX_NESTING_IS_ERROR: |
---|
| 216 | executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED; |
---|
[4f5baff] | 217 | _ISR_Enable( level ); |
---|
[7ce892d] | 218 | return 0; |
---|
| 219 | #endif |
---|
[21e2b2b] | 220 | case CORE_MUTEX_NESTING_BLOCKS: |
---|
| 221 | break; |
---|
| 222 | } |
---|
| 223 | } |
---|
| 224 | |
---|
[96d0b64] | 225 | /* |
---|
| 226 | * The mutex is not available and the caller must deal with the possibility |
---|
| 227 | * of blocking. |
---|
| 228 | */ |
---|
[21e2b2b] | 229 | return 1; |
---|
| 230 | } |
---|
| 231 | |
---|
[d8134178] | 232 | /** @} */ |
---|
[baff4da] | 233 | |
---|
[3a4ae6c] | 234 | #endif |
---|
| 235 | /* end of include file */ |
---|