[a112364] | 1 | /** |
---|
| 2 | * @file rtems/score/threadq.h |
---|
| 3 | * |
---|
| 4 | * Constants and Structures Associated with the Manipulation of Objects |
---|
| 5 | * |
---|
| 6 | * This include file contains all the constants and structures associated |
---|
| 7 | * with the manipulation of objects. |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | /* |
---|
[ed7a028] | 11 | * COPYRIGHT (c) 1989-2014. |
---|
[a112364] | 12 | * On-Line Applications Research Corporation (OAR). |
---|
| 13 | * |
---|
| 14 | * The license and distribution terms for this file may be |
---|
| 15 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 16 | * http://www.rtems.org/license/LICENSE. |
---|
[a112364] | 17 | */ |
---|
| 18 | |
---|
| 19 | #ifndef _RTEMS_SCORE_THREADQIMPL_H |
---|
| 20 | #define _RTEMS_SCORE_THREADQIMPL_H |
---|
| 21 | |
---|
| 22 | #include <rtems/score/threadq.h> |
---|
[d8752860] | 23 | #include <rtems/score/chainimpl.h> |
---|
| 24 | #include <rtems/score/rbtreeimpl.h> |
---|
[a112364] | 25 | #include <rtems/score/thread.h> |
---|
| 26 | |
---|
| 27 | #ifdef __cplusplus |
---|
| 28 | extern "C" { |
---|
| 29 | #endif |
---|
| 30 | |
---|
| 31 | /** |
---|
| 32 | * @addtogroup ScoreThreadQueue |
---|
| 33 | */ |
---|
| 34 | /**@{*/ |
---|
| 35 | |
---|
[12f93fbb] | 36 | /** |
---|
| 37 | * @brief Thread queue with a layout compatible to struct _Thread_queue_Queue |
---|
| 38 | * defined in Newlib <sys/lock.h>. |
---|
| 39 | */ |
---|
| 40 | typedef struct { |
---|
| 41 | Thread_queue_Queue Queue; |
---|
| 42 | |
---|
| 43 | #if !defined(RTEMS_SMP) |
---|
| 44 | /* |
---|
| 45 | * The struct _Thread_queue_Queue definition is independent of the RTEMS |
---|
| 46 | * build configuration. Thus, the storage space for the SMP lock is always |
---|
| 47 | * present. In SMP configurations, the SMP lock is contained in the |
---|
| 48 | * Thread_queue_Queue. |
---|
| 49 | */ |
---|
| 50 | unsigned int reserved[2]; |
---|
| 51 | #endif |
---|
| 52 | } Thread_queue_Syslock_queue; |
---|
| 53 | |
---|
[d7665823] | 54 | RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize( |
---|
| 55 | Thread_queue_Queue *queue |
---|
| 56 | ) |
---|
| 57 | { |
---|
| 58 | queue->heads = NULL; |
---|
[0e3c59d6] | 59 | #if defined(RTEMS_SMP) |
---|
| 60 | _SMP_ticket_lock_Initialize( &queue->Lock ); |
---|
| 61 | #endif |
---|
[d7665823] | 62 | } |
---|
| 63 | |
---|
[0e3c59d6] | 64 | RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_do_acquire_critical( |
---|
[e2735012] | 65 | Thread_queue_Queue *queue, |
---|
[0e3c59d6] | 66 | #if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) |
---|
| 67 | SMP_lock_Stats *lock_stats, |
---|
| 68 | #endif |
---|
[e2735012] | 69 | ISR_lock_Context *lock_context |
---|
| 70 | ) |
---|
| 71 | { |
---|
[0e3c59d6] | 72 | #if defined(RTEMS_SMP) |
---|
| 73 | _SMP_ticket_lock_Acquire( |
---|
| 74 | &queue->Lock, |
---|
| 75 | lock_stats, |
---|
| 76 | &lock_context->Lock_context.Stats_context |
---|
| 77 | ); |
---|
| 78 | #else |
---|
| 79 | (void) queue; |
---|
| 80 | (void) lock_context; |
---|
| 81 | #endif |
---|
[e2735012] | 82 | } |
---|
| 83 | |
---|
[0e3c59d6] | 84 | #if defined(RTEMS_SMP) && defined( RTEMS_PROFILING ) |
---|
| 85 | #define \ |
---|
| 86 | _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \ |
---|
| 87 | _Thread_queue_Queue_do_acquire_critical( queue, lock_stats, lock_context ) |
---|
| 88 | #else |
---|
| 89 | #define \ |
---|
| 90 | _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \ |
---|
| 91 | _Thread_queue_Queue_do_acquire_critical( queue, lock_context ) |
---|
| 92 | #endif |
---|
| 93 | |
---|
[e2735012] | 94 | RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release( |
---|
| 95 | Thread_queue_Queue *queue, |
---|
| 96 | ISR_lock_Context *lock_context |
---|
| 97 | ) |
---|
| 98 | { |
---|
[0e3c59d6] | 99 | #if defined(RTEMS_SMP) |
---|
| 100 | _SMP_ticket_lock_Release( |
---|
| 101 | &queue->Lock, |
---|
| 102 | &lock_context->Lock_context.Stats_context |
---|
| 103 | ); |
---|
| 104 | #endif |
---|
| 105 | _ISR_lock_ISR_enable( lock_context ); |
---|
[e2735012] | 106 | } |
---|
| 107 | |
---|
[02c4c441] | 108 | RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical( |
---|
| 109 | Thread_queue_Control *the_thread_queue, |
---|
| 110 | ISR_lock_Context *lock_context |
---|
| 111 | ) |
---|
| 112 | { |
---|
[e2735012] | 113 | _Thread_queue_Queue_acquire_critical( |
---|
| 114 | &the_thread_queue->Queue, |
---|
[0e3c59d6] | 115 | &the_thread_queue->Lock_stats, |
---|
[e2735012] | 116 | lock_context |
---|
| 117 | ); |
---|
[02c4c441] | 118 | } |
---|
| 119 | |
---|
| 120 | RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire( |
---|
| 121 | Thread_queue_Control *the_thread_queue, |
---|
| 122 | ISR_lock_Context *lock_context |
---|
| 123 | ) |
---|
| 124 | { |
---|
| 125 | _ISR_lock_ISR_disable( lock_context ); |
---|
| 126 | _Thread_queue_Acquire_critical( the_thread_queue, lock_context ); |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | RTEMS_INLINE_ROUTINE void _Thread_queue_Release( |
---|
| 130 | Thread_queue_Control *the_thread_queue, |
---|
| 131 | ISR_lock_Context *lock_context |
---|
| 132 | ) |
---|
| 133 | { |
---|
[0e3c59d6] | 134 | _Thread_queue_Queue_release( |
---|
| 135 | &the_thread_queue->Queue, |
---|
| 136 | lock_context |
---|
| 137 | ); |
---|
[02c4c441] | 138 | } |
---|
| 139 | |
---|
[a112364] | 140 | /** |
---|
| 141 | * The following type defines the callout used when a remote task |
---|
| 142 | * is extracted from a local thread queue. |
---|
| 143 | */ |
---|
| 144 | typedef void ( *Thread_queue_Flush_callout )( |
---|
| 145 | Thread_Control * |
---|
| 146 | ); |
---|
| 147 | |
---|
| 148 | /** |
---|
| 149 | * @brief Gets a pointer to a thread waiting on the_thread_queue. |
---|
| 150 | * |
---|
| 151 | * This function returns a pointer to a thread waiting on |
---|
| 152 | * the_thread_queue. The selection of this thread is based on |
---|
| 153 | * the discipline of the_thread_queue. If no threads are waiting |
---|
| 154 | * on the_thread_queue, then NULL is returned. |
---|
[3250664] | 155 | * |
---|
| 156 | * - INTERRUPT LATENCY: |
---|
| 157 | * + single case |
---|
[a112364] | 158 | */ |
---|
| 159 | Thread_Control *_Thread_queue_Dequeue( |
---|
| 160 | Thread_queue_Control *the_thread_queue |
---|
| 161 | ); |
---|
| 162 | |
---|
| 163 | /** |
---|
[cc366ec] | 164 | * @brief Blocks the thread and places it on the thread queue. |
---|
[a112364] | 165 | * |
---|
[cc366ec] | 166 | * This enqueues the thread on the thread queue, blocks the thread, and |
---|
| 167 | * optionally starts the thread timer in case the timeout interval is not |
---|
| 168 | * WATCHDOG_NO_TIMEOUT. |
---|
[a112364] | 169 | * |
---|
[02c4c441] | 170 | * The caller must be the owner of the thread queue lock. This function will |
---|
| 171 | * release the thread queue lock and register it as the new thread lock. |
---|
[cc366ec] | 172 | * Thread dispatching is disabled before the thread queue lock is released. |
---|
| 173 | * Thread dispatching is enabled once the sequence to block the thread is |
---|
| 174 | * complete. The operation to enqueue the thread on the queue is protected by |
---|
| 175 | * the thread queue lock. This makes it possible to use the thread queue lock |
---|
| 176 | * to protect the state of objects embedding the thread queue and directly |
---|
| 177 | * enter _Thread_queue_Enqueue_critical() in case the thread must block. |
---|
| 178 | * |
---|
| 179 | * @code |
---|
| 180 | * #include <rtems/score/threadqimpl.h> |
---|
| 181 | * #include <rtems/score/statesimpl.h> |
---|
| 182 | * |
---|
| 183 | * typedef struct { |
---|
| 184 | * Thread_queue_Control Queue; |
---|
| 185 | * Thread_Control *owner; |
---|
| 186 | * } Mutex; |
---|
| 187 | * |
---|
| 188 | * void _Mutex_Obtain( Mutex *mutex ) |
---|
| 189 | * { |
---|
| 190 | * ISR_lock_Context lock_context; |
---|
| 191 | * Thread_Control *executing; |
---|
| 192 | * |
---|
| 193 | * _Thread_queue_Acquire( &mutex->Queue, &lock_context ); |
---|
| 194 | * |
---|
| 195 | * executing = _Thread_Executing; |
---|
| 196 | * |
---|
| 197 | * if ( mutex->owner == NULL ) { |
---|
| 198 | * mutex->owner = executing; |
---|
| 199 | * _Thread_queue_Release( &mutex->Queue, &lock_context ); |
---|
| 200 | * } else { |
---|
| 201 | * _Thread_queue_Enqueue_critical( |
---|
[e2735012] | 202 | * &mutex->Queue.Queue, |
---|
| 203 | * mutex->Queue.operations, |
---|
[cc366ec] | 204 | * executing, |
---|
| 205 | * STATES_WAITING_FOR_MUTEX, |
---|
| 206 | * WATCHDOG_NO_TIMEOUT, |
---|
| 207 | * 0, |
---|
| 208 | * &lock_context |
---|
| 209 | * ); |
---|
| 210 | * } |
---|
| 211 | * } |
---|
| 212 | * @endcode |
---|
[a112364] | 213 | * |
---|
[e2735012] | 214 | * @param[in] queue The actual thread queue. |
---|
| 215 | * @param[in] operations The thread queue operations. |
---|
[02c4c441] | 216 | * @param[in] the_thread The thread to enqueue. |
---|
| 217 | * @param[in] state The new state of the thread. |
---|
| 218 | * @param[in] timeout Interval to wait. Use WATCHDOG_NO_TIMEOUT to block |
---|
| 219 | * potentially forever. |
---|
[f5d6c8b] | 220 | * @param[in] timeout_code The return code in case a timeout occurs. |
---|
[02c4c441] | 221 | * @param[in] lock_context The lock context of the lock acquire. |
---|
[a112364] | 222 | */ |
---|
[02c4c441] | 223 | void _Thread_queue_Enqueue_critical( |
---|
[e2735012] | 224 | Thread_queue_Queue *queue, |
---|
| 225 | const Thread_queue_Operations *operations, |
---|
| 226 | Thread_Control *the_thread, |
---|
| 227 | States_Control state, |
---|
| 228 | Watchdog_Interval timeout, |
---|
| 229 | uint32_t timeout_code, |
---|
| 230 | ISR_lock_Context *lock_context |
---|
[a112364] | 231 | ); |
---|
| 232 | |
---|
[cc366ec] | 233 | /** |
---|
| 234 | * @brief Acquires the thread queue lock and calls |
---|
| 235 | * _Thread_queue_Enqueue_critical(). |
---|
| 236 | */ |
---|
[02c4c441] | 237 | RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue( |
---|
| 238 | Thread_queue_Control *the_thread_queue, |
---|
| 239 | Thread_Control *the_thread, |
---|
| 240 | States_Control state, |
---|
[f5d6c8b] | 241 | Watchdog_Interval timeout, |
---|
| 242 | uint32_t timeout_code |
---|
[02c4c441] | 243 | ) |
---|
| 244 | { |
---|
| 245 | ISR_lock_Context lock_context; |
---|
| 246 | |
---|
| 247 | _Thread_queue_Acquire( the_thread_queue, &lock_context ); |
---|
| 248 | _Thread_queue_Enqueue_critical( |
---|
[e2735012] | 249 | &the_thread_queue->Queue, |
---|
| 250 | the_thread_queue->operations, |
---|
[02c4c441] | 251 | the_thread, |
---|
| 252 | state, |
---|
| 253 | timeout, |
---|
[f5d6c8b] | 254 | timeout_code, |
---|
[02c4c441] | 255 | &lock_context |
---|
| 256 | ); |
---|
| 257 | } |
---|
| 258 | |
---|
[a112364] | 259 | /** |
---|
[cc366ec] | 260 | * @brief Extracts the thread from the thread queue, restores the default wait |
---|
| 261 | * operations and restores the default thread lock. |
---|
[a112364] | 262 | * |
---|
[cc366ec] | 263 | * The caller must be the owner of the thread queue lock. The thread queue |
---|
| 264 | * lock is not released. |
---|
[a112364] | 265 | * |
---|
[e2735012] | 266 | * @param[in] queue The actual thread queue. |
---|
| 267 | * @param[in] operations The thread queue operations. |
---|
[cc366ec] | 268 | * @param[in] the_thread The thread to extract. |
---|
[e709aa85] | 269 | * |
---|
| 270 | * @return Returns the unblock indicator for _Thread_queue_Unblock_critical(). |
---|
| 271 | * True indicates, that this thread must be unblocked by the scheduler later in |
---|
| 272 | * _Thread_queue_Unblock_critical(), and false otherwise. In case false is |
---|
| 273 | * returned, then the thread queue enqueue procedure was interrupted. Thus it |
---|
| 274 | * will unblock itself and the thread wait information is no longer accessible, |
---|
| 275 | * since this thread may already block on another resource in an SMP |
---|
| 276 | * configuration. |
---|
[a112364] | 277 | */ |
---|
[e709aa85] | 278 | bool _Thread_queue_Extract_locked( |
---|
[e2735012] | 279 | Thread_queue_Queue *queue, |
---|
| 280 | const Thread_queue_Operations *operations, |
---|
| 281 | Thread_Control *the_thread |
---|
[cc366ec] | 282 | ); |
---|
| 283 | |
---|
| 284 | /** |
---|
| 285 | * @brief Unblocks the thread which was on the thread queue before. |
---|
| 286 | * |
---|
| 287 | * The caller must be the owner of the thread queue lock. This function will |
---|
| 288 | * release the thread queue lock. Thread dispatching is disabled before the |
---|
| 289 | * thread queue lock is released and an unblock is necessary. Thread |
---|
| 290 | * dispatching is enabled once the sequence to unblock the thread is complete. |
---|
| 291 | * |
---|
[e709aa85] | 292 | * @param[in] unblock The unblock indicator returned by |
---|
| 293 | * _Thread_queue_Extract_locked(). |
---|
[e2735012] | 294 | * @param[in] queue The actual thread queue. |
---|
[cc366ec] | 295 | * @param[in] the_thread The thread to extract. |
---|
| 296 | * @param[in] lock_context The lock context of the lock acquire. |
---|
| 297 | */ |
---|
| 298 | void _Thread_queue_Unblock_critical( |
---|
[e709aa85] | 299 | bool unblock, |
---|
[e2735012] | 300 | Thread_queue_Queue *queue, |
---|
| 301 | Thread_Control *the_thread, |
---|
| 302 | ISR_lock_Context *lock_context |
---|
[cc366ec] | 303 | ); |
---|
| 304 | |
---|
| 305 | /** |
---|
| 306 | * @brief Extracts the thread from the thread queue and unblocks it. |
---|
| 307 | * |
---|
| 308 | * The caller must be the owner of the thread queue lock. This function will |
---|
| 309 | * release the thread queue lock and restore the default thread lock. Thread |
---|
| 310 | * dispatching is disabled before the thread queue lock is released and an |
---|
| 311 | * unblock is necessary. Thread dispatching is enabled once the sequence to |
---|
| 312 | * unblock the thread is complete. This makes it possible to use the thread |
---|
| 313 | * queue lock to protect the state of objects embedding the thread queue and |
---|
| 314 | * directly enter _Thread_queue_Extract_critical() to finalize an operation in |
---|
| 315 | * case a waiting thread exists. |
---|
| 316 | * |
---|
| 317 | * @code |
---|
| 318 | * #include <rtems/score/threadqimpl.h> |
---|
| 319 | * |
---|
| 320 | * typedef struct { |
---|
| 321 | * Thread_queue_Control Queue; |
---|
| 322 | * Thread_Control *owner; |
---|
| 323 | * } Mutex; |
---|
| 324 | * |
---|
| 325 | * void _Mutex_Release( Mutex *mutex ) |
---|
| 326 | * { |
---|
| 327 | * ISR_lock_Context lock_context; |
---|
| 328 | * Thread_Control *first; |
---|
| 329 | * |
---|
| 330 | * _Thread_queue_Acquire( &mutex->Queue, &lock_context ); |
---|
| 331 | * |
---|
| 332 | * first = _Thread_queue_First_locked( &mutex->Queue ); |
---|
| 333 | * mutex->owner = first; |
---|
| 334 | * |
---|
| 335 | * if ( first != NULL ) { |
---|
| 336 | * _Thread_queue_Extract_critical( |
---|
[e2735012] | 337 | * &mutex->Queue.Queue, |
---|
| 338 | * mutex->Queue.operations, |
---|
[cc366ec] | 339 | * first, |
---|
| 340 | * &lock_context |
---|
| 341 | * ); |
---|
| 342 | * } |
---|
| 343 | * @endcode |
---|
| 344 | * |
---|
[e2735012] | 345 | * @param[in] queue The actual thread queue. |
---|
| 346 | * @param[in] operations The thread queue operations. |
---|
[cc366ec] | 347 | * @param[in] the_thread The thread to extract. |
---|
| 348 | * @param[in] lock_context The lock context of the lock acquire. |
---|
| 349 | */ |
---|
| 350 | void _Thread_queue_Extract_critical( |
---|
[e2735012] | 351 | Thread_queue_Queue *queue, |
---|
| 352 | const Thread_queue_Operations *operations, |
---|
| 353 | Thread_Control *the_thread, |
---|
| 354 | ISR_lock_Context *lock_context |
---|
[cc366ec] | 355 | ); |
---|
[a112364] | 356 | |
---|
[ed7a028] | 357 | /** |
---|
[cc366ec] | 358 | * @brief Extracts thread from thread queue. |
---|
[ed7a028] | 359 | * |
---|
[22788bc] | 360 | * This routine removes @a the_thread its thread queue |
---|
[ed7a028] | 361 | * and cancels any timeouts associated with this blocking. |
---|
| 362 | * |
---|
| 363 | * @param[in] the_thread is the pointer to a thread control block that |
---|
| 364 | * is to be removed |
---|
| 365 | */ |
---|
[cc366ec] | 366 | void _Thread_queue_Extract( Thread_Control *the_thread ); |
---|
[91e7b0c] | 367 | |
---|
[a112364] | 368 | /** |
---|
| 369 | * @brief Extracts the_thread from the_thread_queue. |
---|
| 370 | * |
---|
| 371 | * This routine extracts the_thread from the_thread_queue |
---|
| 372 | * and ensures that if there is a proxy for this task on |
---|
| 373 | * another node, it is also dealt with. |
---|
| 374 | */ |
---|
[600bb68f] | 375 | void _Thread_queue_Extract_with_proxy( |
---|
[a112364] | 376 | Thread_Control *the_thread |
---|
| 377 | ); |
---|
| 378 | |
---|
| 379 | /** |
---|
[02c4c441] | 380 | * @brief Returns the first thread on the thread queue if it exists, otherwise |
---|
[cc366ec] | 381 | * @c NULL. |
---|
[02c4c441] | 382 | * |
---|
[cc366ec] | 383 | * The caller must be the owner of the thread queue lock. The thread queue |
---|
| 384 | * lock is not released. |
---|
[02c4c441] | 385 | * |
---|
| 386 | * @param[in] the_thread_queue The thread queue. |
---|
[a112364] | 387 | * |
---|
[02c4c441] | 388 | * @retval NULL No thread is present on the thread queue. |
---|
| 389 | * @retval first The first thread on the thread queue according to the enqueue |
---|
| 390 | * order. |
---|
| 391 | */ |
---|
[cc366ec] | 392 | RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked( |
---|
[02c4c441] | 393 | Thread_queue_Control *the_thread_queue |
---|
[cc366ec] | 394 | ) |
---|
| 395 | { |
---|
[d7665823] | 396 | Thread_queue_Heads *heads = the_thread_queue->Queue.heads; |
---|
| 397 | |
---|
| 398 | if ( heads != NULL ) { |
---|
| 399 | return ( *the_thread_queue->operations->first )( heads ); |
---|
| 400 | } else { |
---|
| 401 | return NULL; |
---|
| 402 | } |
---|
[cc366ec] | 403 | } |
---|
[02c4c441] | 404 | |
---|
| 405 | /** |
---|
| 406 | * @brief Returns the first thread on the thread queue if it exists, otherwise |
---|
| 407 | * @c NULL. |
---|
[a112364] | 408 | * |
---|
[02c4c441] | 409 | * @param[in] the_thread_queue The thread queue. |
---|
[a112364] | 410 | * |
---|
[02c4c441] | 411 | * @retval NULL No thread is present on the thread queue. |
---|
| 412 | * @retval first The first thread on the thread queue according to the enqueue |
---|
| 413 | * order. |
---|
[a112364] | 414 | */ |
---|
| 415 | Thread_Control *_Thread_queue_First( |
---|
| 416 | Thread_queue_Control *the_thread_queue |
---|
| 417 | ); |
---|
| 418 | |
---|
| 419 | /** |
---|
| 420 | * @brief Unblocks all threads blocked on the_thread_queue. |
---|
| 421 | * |
---|
| 422 | * This routine unblocks all threads blocked on the_thread_queue |
---|
| 423 | * and cancels any associated timeouts. |
---|
| 424 | * |
---|
| 425 | * @param[in] the_thread_queue is the pointer to a threadq header |
---|
| 426 | * @param[in] remote_extract_callout points to a method to invoke to |
---|
| 427 | * invoke when a remote thread is unblocked |
---|
| 428 | * @param[in] status is the status which will be returned to |
---|
| 429 | * all unblocked threads |
---|
| 430 | */ |
---|
| 431 | void _Thread_queue_Flush( |
---|
| 432 | Thread_queue_Control *the_thread_queue, |
---|
| 433 | Thread_queue_Flush_callout remote_extract_callout, |
---|
| 434 | uint32_t status |
---|
| 435 | ); |
---|
| 436 | |
---|
| 437 | /** |
---|
| 438 | * @brief Initialize the_thread_queue. |
---|
| 439 | * |
---|
| 440 | * This routine initializes the_thread_queue based on the |
---|
| 441 | * discipline indicated in attribute_set. The state set on |
---|
| 442 | * threads which block on the_thread_queue is state. |
---|
| 443 | * |
---|
| 444 | * @param[in] the_thread_queue is the pointer to a threadq header |
---|
| 445 | * @param[in] the_discipline is the queueing discipline |
---|
| 446 | */ |
---|
| 447 | void _Thread_queue_Initialize( |
---|
[f5d6c8b] | 448 | Thread_queue_Control *the_thread_queue, |
---|
| 449 | Thread_queue_Disciplines the_discipline |
---|
[a112364] | 450 | ); |
---|
| 451 | |
---|
[0e3c59d6] | 452 | #if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) |
---|
| 453 | #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ |
---|
| 454 | .Queue = { \ |
---|
| 455 | .heads = NULL, \ |
---|
| 456 | .Lock = SMP_TICKET_LOCK_INITIALIZER, \ |
---|
| 457 | }, \ |
---|
| 458 | .Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \ |
---|
| 459 | .operations = &_Thread_queue_Operations_FIFO \ |
---|
| 460 | } |
---|
| 461 | |
---|
| 462 | #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ |
---|
| 463 | .Queue = { \ |
---|
| 464 | .heads = NULL, \ |
---|
| 465 | .Lock = SMP_TICKET_LOCK_INITIALIZER, \ |
---|
| 466 | }, \ |
---|
| 467 | .Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \ |
---|
| 468 | .operations = &_Thread_queue_Operations_priority \ |
---|
| 469 | } |
---|
| 470 | #elif defined(RTEMS_SMP) |
---|
[d8752860] | 471 | #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ |
---|
[e2735012] | 472 | .Queue = { \ |
---|
[d7665823] | 473 | .heads = NULL, \ |
---|
[0e3c59d6] | 474 | .Lock = SMP_TICKET_LOCK_INITIALIZER, \ |
---|
[d8752860] | 475 | }, \ |
---|
[e2735012] | 476 | .operations = &_Thread_queue_Operations_FIFO \ |
---|
[d8752860] | 477 | } |
---|
| 478 | |
---|
[9341773] | 479 | #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ |
---|
[e2735012] | 480 | .Queue = { \ |
---|
[d7665823] | 481 | .heads = NULL, \ |
---|
[0e3c59d6] | 482 | .Lock = SMP_TICKET_LOCK_INITIALIZER, \ |
---|
[d8752860] | 483 | }, \ |
---|
[e2735012] | 484 | .operations = &_Thread_queue_Operations_priority \ |
---|
[d8752860] | 485 | } |
---|
| 486 | #else |
---|
| 487 | #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ |
---|
[d7665823] | 488 | .Queue = { .heads = NULL }, \ |
---|
[d8752860] | 489 | .operations = &_Thread_queue_Operations_FIFO \ |
---|
| 490 | } |
---|
| 491 | |
---|
[9341773] | 492 | #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ |
---|
[d7665823] | 493 | .Queue = { .heads = NULL }, \ |
---|
[d8752860] | 494 | .operations = &_Thread_queue_Operations_priority \ |
---|
| 495 | } |
---|
| 496 | #endif |
---|
| 497 | |
---|
[02c4c441] | 498 | RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy( |
---|
| 499 | Thread_queue_Control *the_thread_queue |
---|
| 500 | ) |
---|
| 501 | { |
---|
[0e3c59d6] | 502 | #if defined(RTEMS_SMP) |
---|
| 503 | _SMP_ticket_lock_Destroy( &the_thread_queue->Queue.Lock ); |
---|
| 504 | _SMP_lock_Stats_destroy( &the_thread_queue->Lock_stats ); |
---|
| 505 | #endif |
---|
[02c4c441] | 506 | } |
---|
| 507 | |
---|
[a112364] | 508 | /** |
---|
[ed7a028] | 509 | * @brief Compare two thread's priority for RBTree Insertion. |
---|
| 510 | * |
---|
| 511 | * @param[in] left points to the left thread's RBnode |
---|
| 512 | * @param[in] right points to the right thread's RBnode |
---|
| 513 | * |
---|
[e0eb07a] | 514 | * @retval 1 The @a left node is more important than @a right node. |
---|
| 515 | * @retval 0 The @a left node is of equal importance with @a right node. |
---|
| 516 | * @retval 1 The @a left node is less important than @a right node. |
---|
[a112364] | 517 | */ |
---|
[60fe374] | 518 | RBTree_Compare_result _Thread_queue_Compare_priority( |
---|
[ed7a028] | 519 | const RBTree_Node *left, |
---|
| 520 | const RBTree_Node *right |
---|
| 521 | ); |
---|
[a112364] | 522 | |
---|
[568af83] | 523 | extern const Thread_queue_Operations _Thread_queue_Operations_default; |
---|
| 524 | |
---|
| 525 | extern const Thread_queue_Operations _Thread_queue_Operations_FIFO; |
---|
| 526 | |
---|
| 527 | extern const Thread_queue_Operations _Thread_queue_Operations_priority; |
---|
| 528 | |
---|
[a112364] | 529 | /**@}*/ |
---|
| 530 | |
---|
| 531 | #ifdef __cplusplus |
---|
| 532 | } |
---|
| 533 | #endif |
---|
| 534 | |
---|
| 535 | #endif |
---|
| 536 | /* end of include file */ |
---|