source: rtems/cpukit/score/include/rtems/score/threadqimpl.h @ 8a040fe4

5
Last change on this file since 8a040fe4 was 8a040fe4, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/16 at 15:03:31

score: Use _RBTree_Insert_inline()

Use _RBTree_Insert_inline() for priority thread queues.

Update #2556.

  • Property mode set to 100644
File size: 23.1 KB
Line 
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/*
11 *  COPYRIGHT (c) 1989-2014.
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
16 *  http://www.rtems.org/license/LICENSE.
17 */
18
19#ifndef _RTEMS_SCORE_THREADQIMPL_H
20#define _RTEMS_SCORE_THREADQIMPL_H
21
22#include <rtems/score/threadq.h>
23#include <rtems/score/chainimpl.h>
24#include <rtems/score/rbtreeimpl.h>
25#include <rtems/score/scheduler.h>
26#include <rtems/score/smp.h>
27#include <rtems/score/thread.h>
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/**
34 *  @addtogroup ScoreThreadQueue
35 */
36/**@{*/
37
38/**
39 * @brief Thread queue with a layout compatible to struct _Thread_queue_Queue
40 * defined in Newlib <sys/lock.h>.
41 */
42typedef struct {
43  Thread_queue_Queue Queue;
44
45#if !defined(RTEMS_SMP)
46  /*
47   * The struct _Thread_queue_Queue definition is independent of the RTEMS
48   * build configuration.  Thus, the storage space for the SMP lock is always
49   * present.  In SMP configurations, the SMP lock is contained in the
50   * Thread_queue_Queue.
51   */
52  unsigned int reserved[2];
53#endif
54} Thread_queue_Syslock_queue;
55
56RTEMS_INLINE_ROUTINE void _Thread_queue_Heads_initialize(
57  Thread_queue_Heads *heads
58)
59{
60#if defined(RTEMS_SMP)
61  size_t i;
62
63  for ( i = 0; i < _Scheduler_Count; ++i ) {
64    _RBTree_Initialize_empty( &heads->Priority[ i ].Queue );
65  }
66#endif
67
68  _Chain_Initialize_empty( &heads->Free_chain );
69}
70
71RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize(
72  Thread_queue_Queue *queue
73)
74{
75  queue->heads = NULL;
76#if defined(RTEMS_SMP)
77  _SMP_ticket_lock_Initialize( &queue->Lock );
78#endif
79}
80
81RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_do_acquire_critical(
82  Thread_queue_Queue *queue,
83#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
84  SMP_lock_Stats     *lock_stats,
85#endif
86  ISR_lock_Context   *lock_context
87)
88{
89#if defined(RTEMS_SMP)
90  _SMP_ticket_lock_Acquire(
91    &queue->Lock,
92    lock_stats,
93    &lock_context->Lock_context.Stats_context
94  );
95#else
96  (void) queue;
97  (void) lock_context;
98#endif
99}
100
101#if defined(RTEMS_SMP) && defined( RTEMS_PROFILING )
102  #define \
103    _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
104    _Thread_queue_Queue_do_acquire_critical( queue, lock_stats, lock_context )
105#else
106  #define \
107    _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
108    _Thread_queue_Queue_do_acquire_critical( queue, lock_context )
109#endif
110
111RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release_critical(
112  Thread_queue_Queue *queue,
113  ISR_lock_Context   *lock_context
114)
115{
116#if defined(RTEMS_SMP)
117  _SMP_ticket_lock_Release(
118    &queue->Lock,
119    &lock_context->Lock_context.Stats_context
120  );
121#else
122  (void) queue;
123  (void) lock_context;
124#endif
125}
126
127RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
128  Thread_queue_Queue *queue,
129  ISR_lock_Context   *lock_context
130)
131{
132  _Thread_queue_Queue_release_critical( queue, lock_context );
133  _ISR_lock_ISR_enable( lock_context );
134}
135
136RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical(
137  Thread_queue_Control *the_thread_queue,
138  ISR_lock_Context     *lock_context
139)
140{
141  _Thread_queue_Queue_acquire_critical(
142    &the_thread_queue->Queue,
143    &the_thread_queue->Lock_stats,
144    lock_context
145  );
146#if defined(RTEMS_DEBUG) && defined(RTEMS_SMP)
147  the_thread_queue->owner = _SMP_Get_current_processor();
148#endif
149}
150
151RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire(
152  Thread_queue_Control *the_thread_queue,
153  ISR_lock_Context     *lock_context
154)
155{
156  _ISR_lock_ISR_disable( lock_context );
157  _Thread_queue_Acquire_critical( the_thread_queue, lock_context );
158}
159
160#if defined(RTEMS_DEBUG)
161RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_lock_owner(
162  const Thread_queue_Control *the_thread_queue
163)
164{
165#if defined(RTEMS_SMP)
166  return the_thread_queue->owner == _SMP_Get_current_processor();
167#else
168  return _ISR_Get_level() != 0;
169#endif
170}
171#endif
172
173RTEMS_INLINE_ROUTINE void _Thread_queue_Release_critical(
174  Thread_queue_Control *the_thread_queue,
175  ISR_lock_Context     *lock_context
176)
177{
178#if defined(RTEMS_DEBUG)
179  _Assert( _Thread_queue_Is_lock_owner( the_thread_queue ) );
180#if defined(RTEMS_SMP)
181  the_thread_queue->owner = SMP_LOCK_NO_OWNER;
182#endif
183#endif
184  _Thread_queue_Queue_release_critical(
185    &the_thread_queue->Queue,
186    lock_context
187  );
188}
189
190RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
191  Thread_queue_Control *the_thread_queue,
192  ISR_lock_Context     *lock_context
193)
194{
195  _Thread_queue_Release_critical( the_thread_queue, lock_context );
196  _ISR_lock_ISR_enable( lock_context );
197}
198
199Thread_Control *_Thread_queue_Do_dequeue(
200  Thread_queue_Control          *the_thread_queue,
201  const Thread_queue_Operations *operations
202#if defined(RTEMS_MULTIPROCESSING)
203  ,
204  Thread_queue_MP_callout        mp_callout,
205  Objects_Id                     mp_id
206#endif
207);
208
209/**
210 *  @brief Gets a pointer to a thread waiting on the_thread_queue.
211 *
212 *  This function returns a pointer to a thread waiting on
213 *  the_thread_queue.  The selection of this thread is based on
214 *  the discipline of the_thread_queue.  If no threads are waiting
215 *  on the_thread_queue, then NULL is returned.
216 *
217 *  - INTERRUPT LATENCY:
218 *    + single case
219 */
220#if defined(RTEMS_MULTIPROCESSING)
221  #define _Thread_queue_Dequeue( \
222    the_thread_queue, \
223    operations, \
224    mp_callout, \
225    mp_id \
226  ) \
227    _Thread_queue_Do_dequeue( \
228      the_thread_queue, \
229      operations, \
230      mp_callout, \
231      mp_id \
232    )
233#else
234  #define _Thread_queue_Dequeue( \
235    the_thread_queue, \
236    operations, \
237    mp_callout, \
238    mp_id \
239  ) \
240    _Thread_queue_Do_dequeue( \
241      the_thread_queue, \
242      operations \
243    )
244#endif
245
246/**
247 * @brief Blocks the thread and places it on the thread queue.
248 *
249 * This enqueues the thread on the thread queue, blocks the thread, and
250 * optionally starts the thread timer in case the timeout interval is not
251 * WATCHDOG_NO_TIMEOUT.
252 *
253 * The caller must be the owner of the thread queue lock.  This function will
254 * release the thread queue lock and register it as the new thread lock.
255 * Thread dispatching is disabled before the thread queue lock is released.
256 * Thread dispatching is enabled once the sequence to block the thread is
257 * complete.  The operation to enqueue the thread on the queue is protected by
258 * the thread queue lock.  This makes it possible to use the thread queue lock
259 * to protect the state of objects embedding the thread queue and directly
260 * enter _Thread_queue_Enqueue_critical() in case the thread must block.
261 *
262 * @code
263 * #include <rtems/score/threadqimpl.h>
264 * #include <rtems/score/statesimpl.h>
265 *
266 * #define MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
267 *
268 * typedef struct {
269 *   Thread_queue_Control  Queue;
270 *   Thread_Control       *owner;
271 * } Mutex;
272 *
273 * void _Mutex_Obtain( Mutex *mutex )
274 * {
275 *   ISR_lock_Context  lock_context;
276 *   Thread_Control   *executing;
277 *
278 *   _Thread_queue_Acquire( &mutex->Queue, &lock_context );
279 *
280 *   executing = _Thread_Executing;
281 *
282 *   if ( mutex->owner == NULL ) {
283 *     mutex->owner = executing;
284 *     _Thread_queue_Release( &mutex->Queue, &lock_context );
285 *   } else {
286 *     _Thread_queue_Enqueue_critical(
287 *       &mutex->Queue.Queue,
288 *       MUTEX_TQ_OPERATIONS,
289 *       executing,
290 *       STATES_WAITING_FOR_MUTEX,
291 *       WATCHDOG_NO_TIMEOUT,
292 *       0,
293 *       &lock_context
294 *     );
295 *   }
296 * }
297 * @endcode
298 *
299 * @param[in] queue The actual thread queue.
300 * @param[in] operations The thread queue operations.
301 * @param[in] the_thread The thread to enqueue.
302 * @param[in] state The new state of the thread.
303 * @param[in] timeout Interval to wait.  Use WATCHDOG_NO_TIMEOUT to block
304 * potentially forever.
305 * @param[in] timeout_code The return code in case a timeout occurs.
306 * @param[in] lock_context The lock context of the lock acquire.
307 */
308void _Thread_queue_Enqueue_critical(
309  Thread_queue_Queue            *queue,
310  const Thread_queue_Operations *operations,
311  Thread_Control                *the_thread,
312  States_Control                 state,
313  Watchdog_Interval              timeout,
314  uint32_t                       timeout_code,
315  ISR_lock_Context              *lock_context
316);
317
318/**
319 * @brief Acquires the thread queue lock and calls
320 * _Thread_queue_Enqueue_critical().
321 */
322RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
323  Thread_queue_Control          *the_thread_queue,
324  const Thread_queue_Operations *operations,
325  Thread_Control                *the_thread,
326  States_Control                 state,
327  Watchdog_Interval              timeout,
328  uint32_t                       timeout_code
329)
330{
331  ISR_lock_Context lock_context;
332
333  _Thread_queue_Acquire( the_thread_queue, &lock_context );
334  _Thread_queue_Enqueue_critical(
335    &the_thread_queue->Queue,
336    operations,
337    the_thread,
338    state,
339    timeout,
340    timeout_code,
341    &lock_context
342  );
343}
344
345bool _Thread_queue_Do_extract_locked(
346  Thread_queue_Queue            *queue,
347  const Thread_queue_Operations *operations,
348  Thread_Control                *the_thread
349#if defined(RTEMS_MULTIPROCESSING)
350  ,
351  Thread_queue_MP_callout        mp_callout,
352  Objects_Id                     mp_id
353#endif
354);
355
356/**
357 * @brief Extracts the thread from the thread queue, restores the default wait
358 * operations and restores the default thread lock.
359 *
360 * The caller must be the owner of the thread queue lock.  The thread queue
361 * lock is not released.
362 *
363 * @param[in] queue The actual thread queue.
364 * @param[in] operations The thread queue operations.
365 * @param[in] the_thread The thread to extract.
366 * @param[in] mp_callout Callout to unblock the thread in case it is actually a
367 *   thread proxy.  This parameter is only used on multiprocessing
368 *   configurations.
369 * @param[in] mp_id Object identifier of the object containing the thread
370 *   queue.  This parameter is only used on multiprocessing configurations.
371 *
372 * @return Returns the unblock indicator for _Thread_queue_Unblock_critical().
373 * True indicates, that this thread must be unblocked by the scheduler later in
374 * _Thread_queue_Unblock_critical(), and false otherwise.  In case false is
375 * returned, then the thread queue enqueue procedure was interrupted.  Thus it
376 * will unblock itself and the thread wait information is no longer accessible,
377 * since this thread may already block on another resource in an SMP
378 * configuration.
379 */
380#if defined(RTEMS_MULTIPROCESSING)
381  #define _Thread_queue_Extract_locked( \
382    unblock, \
383    queue, \
384    the_thread, \
385    mp_callout, \
386    mp_id \
387  ) \
388    _Thread_queue_Do_extract_locked( \
389      unblock, \
390      queue, \
391      the_thread, \
392      mp_callout, \
393      mp_id \
394    )
395#else
396  #define _Thread_queue_Extract_locked( \
397    unblock, \
398    queue, \
399    the_thread, \
400    mp_callout, \
401    mp_id \
402  ) \
403    _Thread_queue_Do_extract_locked( \
404      unblock, \
405      queue, \
406      the_thread \
407    )
408#endif
409
410void _Thread_queue_Do_unblock_critical(
411  bool                     unblock,
412  Thread_queue_Queue      *queue,
413  Thread_Control          *the_thread,
414#if defined(RTEMS_MULTIPROCESSING)
415  Thread_queue_MP_callout  mp_callout,
416  Objects_Id               mp_id,
417#endif
418  ISR_lock_Context        *lock_context
419);
420
421/**
422 * @brief Unblocks the thread which was on the thread queue before.
423 *
424 * The caller must be the owner of the thread queue lock.  This function will
425 * release the thread queue lock.  Thread dispatching is disabled before the
426 * thread queue lock is released and an unblock is necessary.  Thread
427 * dispatching is enabled once the sequence to unblock the thread is complete.
428 *
429 * @param[in] unblock The unblock indicator returned by
430 * _Thread_queue_Extract_locked().
431 * @param[in] queue The actual thread queue.
432 * @param[in] the_thread The thread to extract.
433 * @param[in] mp_callout Callout to unblock the thread in case it is actually a
434 *   thread proxy.  This parameter is only used on multiprocessing
435 *   configurations.
436 * @param[in] mp_id Object identifier of the object containing the thread
437 *   queue.  This parameter is only used on multiprocessing configurations.
438 * @param[in] lock_context The lock context of the lock acquire.
439 */
440#if defined(RTEMS_MULTIPROCESSING)
441  #define _Thread_queue_Unblock_critical( \
442    unblock, \
443    queue, \
444    the_thread, \
445    mp_callout, \
446    mp_id, \
447    lock_context \
448  ) \
449    _Thread_queue_Do_unblock_critical( \
450      unblock, \
451      queue, \
452      the_thread, \
453      mp_callout, \
454      mp_id, \
455      lock_context \
456    )
457#else
458  #define _Thread_queue_Unblock_critical( \
459    unblock, \
460    queue, \
461    the_thread, \
462    mp_callout, \
463    mp_id, \
464    lock_context \
465  ) \
466    _Thread_queue_Do_unblock_critical( \
467      unblock, \
468      queue, \
469      the_thread, \
470      lock_context \
471    )
472#endif
473
474void _Thread_queue_Do_extract_critical(
475  Thread_queue_Queue            *queue,
476  const Thread_queue_Operations *operations,
477  Thread_Control                *the_thread,
478#if defined(RTEMS_MULTIPROCESSING)
479  Thread_queue_MP_callout        mp_callout,
480  Objects_Id                     mp_id,
481#endif
482  ISR_lock_Context              *lock_context
483);
484
485/**
486 * @brief Extracts the thread from the thread queue and unblocks it.
487 *
488 * The caller must be the owner of the thread queue lock.  This function will
489 * release the thread queue lock and restore the default thread lock.  Thread
490 * dispatching is disabled before the thread queue lock is released and an
491 * unblock is necessary.  Thread dispatching is enabled once the sequence to
492 * unblock the thread is complete.  This makes it possible to use the thread
493 * queue lock to protect the state of objects embedding the thread queue and
494 * directly enter _Thread_queue_Extract_critical() to finalize an operation in
495 * case a waiting thread exists.
496 *
497 * @code
498 * #include <rtems/score/threadqimpl.h>
499 *
500 * typedef struct {
501 *   Thread_queue_Control  Queue;
502 *   Thread_Control       *owner;
503 * } Mutex;
504 *
505 * void _Mutex_Release( Mutex *mutex )
506 * {
507 *   ISR_lock_Context  lock_context;
508 *   Thread_Control   *first;
509 *
510 *   _Thread_queue_Acquire( &mutex->Queue, &lock_context );
511 *
512 *   first = _Thread_queue_First_locked( &mutex->Queue );
513 *   mutex->owner = first;
514 *
515 *   if ( first != NULL ) {
516 *     _Thread_queue_Extract_critical(
517 *       &mutex->Queue.Queue,
518 *       mutex->Queue.operations,
519 *       first,
520 *       NULL,
521 *       0,
522 *       &lock_context
523 *   );
524 * }
525 * @endcode
526 *
527 * @param[in] queue The actual thread queue.
528 * @param[in] operations The thread queue operations.
529 * @param[in] the_thread The thread to extract.
530 * @param[in] mp_callout Callout to unblock the thread in case it is actually a
531 *   thread proxy.  This parameter is only used on multiprocessing
532 *   configurations.
533 * @param[in] mp_id Object identifier of the object containing the thread
534 *   queue.  This parameter is only used on multiprocessing configurations.
535 * @param[in] lock_context The lock context of the lock acquire.
536 */
537#if defined(RTEMS_MULTIPROCESSING)
538  #define _Thread_queue_Extract_critical( \
539    queue, \
540    operations, \
541    the_thread, \
542    mp_callout, \
543    mp_id, \
544    lock_context \
545  ) \
546    _Thread_queue_Do_extract_critical( \
547      queue, \
548      operations, \
549      the_thread, \
550      mp_callout, \
551      mp_id, \
552      lock_context \
553    )
554#else
555  #define _Thread_queue_Extract_critical( \
556    queue, \
557    operations, \
558    the_thread, \
559    mp_callout, \
560    mp_id, \
561    lock_context \
562  ) \
563    _Thread_queue_Do_extract_critical( \
564      queue, \
565      operations, \
566      the_thread, \
567      lock_context \
568    )
569#endif
570
571/**
572 *  @brief Extracts thread from thread queue.
573 *
574 *  This routine removes @a the_thread its thread queue
575 *  and cancels any timeouts associated with this blocking.
576 *
577 *  @param[in] the_thread is the pointer to a thread control block that
578 *      is to be removed
579 */
580void _Thread_queue_Extract( Thread_Control *the_thread );
581
582/**
583 *  @brief Extracts the_thread from the_thread_queue.
584 *
585 *  This routine extracts the_thread from the_thread_queue
586 *  and ensures that if there is a proxy for this task on
587 *  another node, it is also dealt with.
588 */
589void _Thread_queue_Extract_with_proxy(
590  Thread_Control       *the_thread
591);
592
593RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_empty(
594  const Thread_queue_Queue *queue
595)
596{
597  return queue->heads == NULL;
598}
599
600/**
601 * @brief Returns the first thread on the thread queue if it exists, otherwise
602 * @c NULL.
603 *
604 * The caller must be the owner of the thread queue lock.  The thread queue
605 * lock is not released.
606 *
607 * @param[in] the_thread_queue The thread queue.
608 * @param[in] operations The thread queue operations.
609 *
610 * @retval NULL No thread is present on the thread queue.
611 * @retval first The first thread on the thread queue according to the enqueue
612 * order.
613 */
614RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked(
615  Thread_queue_Control          *the_thread_queue,
616  const Thread_queue_Operations *operations
617)
618{
619  Thread_queue_Heads *heads = the_thread_queue->Queue.heads;
620
621  if ( heads != NULL ) {
622    return ( *operations->first )( heads );
623  } else {
624    return NULL;
625  }
626}
627
628/**
629 * @brief Returns the first thread on the thread queue if it exists, otherwise
630 * @c NULL.
631 *
632 * @param[in] the_thread_queue The thread queue.
633 *
634 * @retval NULL No thread is present on the thread queue.
635 * @retval first The first thread on the thread queue according to the enqueue
636 * order.
637 */
638Thread_Control *_Thread_queue_First(
639  Thread_queue_Control          *the_thread_queue,
640  const Thread_queue_Operations *operations
641);
642
643/**
644 * @brief Thread queue flush filter function.
645 *
646 * Called under protection of the thread queue lock by
647 * _Thread_queue_Flush_critical() to optionally alter the thread wait
648 * information and control the iteration.
649 *
650 * @param the_thread The thread to extract.  This is the first parameter to
651 *   optimize for architectures that use the same register for the first
652 *   parameter and the return value.
653 * @param queue The actual thread queue.
654 * @param lock_context The lock context of the lock acquire.  May be used to
655 *   pass additional data to the filter function via an overlay structure.  The
656 *   filter function should not release or acquire the thread queue lock.
657 *
658 * @retval the_thread Extract this thread.
659 * @retval NULL Do not extract this thread and stop the thread queue flush
660 *   operation.  Threads that are already extracted will complete the flush
661 *   operation.
662 */
663typedef Thread_Control *( *Thread_queue_Flush_filter )(
664  Thread_Control     *the_thread,
665  Thread_queue_Queue *queue,
666  ISR_lock_Context   *lock_context
667);
668
669/**
670 * @brief Default thread queue flush filter function.
671 *
672 * @param the_thread The thread to extract.
673 * @param queue Unused.
674 * @param lock_context Unused.
675 *
676 * @retval the_thread Extract this thread.
677 */
678Thread_Control *_Thread_queue_Flush_default_filter(
679  Thread_Control     *the_thread,
680  Thread_queue_Queue *queue,
681  ISR_lock_Context   *lock_context
682);
683
684size_t _Thread_queue_Do_flush_critical(
685  Thread_queue_Queue            *queue,
686  const Thread_queue_Operations *operations,
687  Thread_queue_Flush_filter      filter,
688#if defined(RTEMS_MULTIPROCESSING)
689  Thread_queue_MP_callout        mp_callout,
690  Objects_Id                     mp_id,
691#endif
692  ISR_lock_Context              *lock_context
693);
694
695/**
696 * @brief Unblocks all threads enqueued on the thread queue.
697 *
698 * This function iteratively extracts the first enqueued thread of the thread
699 * queue until the thread queue is empty or the filter function indicates a
700 * stop.  The thread timers of the extracted threads are cancelled.  The
701 * extracted threads are unblocked.
702 *
703 * @param queue The actual thread queue.
704 * @param operations The thread queue operations.
705 * @param filter The filter functions is called for each thread to extract from
706 *   the thread queue.  It may be used to alter the thread under protection of
707 *   the thread queue lock, for example to set the thread wait return code.
708 *   The return value of the filter function controls if the thread queue flush
709 *   operation should stop or continue.
710 * @param mp_callout Callout to extract the proxy of a remote thread.  This
711 *   parameter is only used on multiprocessing configurations.
712 * @param mp_id Object identifier of the object containing the thread queue.
713 *   This parameter is only used on multiprocessing configurations.
714 *
715 * @return The count of extracted threads.
716 */
717#if defined(RTEMS_MULTIPROCESSING)
718  #define _Thread_queue_Flush_critical( \
719    queue, \
720    operations, \
721    filter, \
722    mp_callout, \
723    mp_id, \
724    lock_context \
725  ) \
726    _Thread_queue_Do_flush_critical( \
727      queue, \
728      operations, \
729      filter, \
730      mp_callout, \
731      mp_id, \
732      lock_context \
733    )
734#else
735  #define _Thread_queue_Flush_critical( \
736    queue, \
737    operations, \
738    filter, \
739    mp_callout, \
740    mp_id, \
741    lock_context \
742  ) \
743    _Thread_queue_Do_flush_critical( \
744      queue, \
745      operations, \
746      filter, \
747      lock_context \
748    )
749#endif
750
751void _Thread_queue_Initialize( Thread_queue_Control *the_thread_queue );
752
753#if defined(RTEMS_SMP) && defined(RTEMS_DEBUG) && defined(RTEMS_PROFILING)
754  #define THREAD_QUEUE_INITIALIZER( name ) \
755    { \
756      .Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \
757      .owner = SMP_LOCK_NO_OWNER, \
758      .Queue = { \
759        .heads = NULL, \
760        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
761      } \
762    }
763#elif defined(RTEMS_SMP) && defined(RTEMS_DEBUG)
764  #define THREAD_QUEUE_INITIALIZER( name ) \
765    { \
766      .owner = SMP_LOCK_NO_OWNER, \
767      .Queue = { \
768        .heads = NULL, \
769        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
770      } \
771    }
772#elif defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
773  #define THREAD_QUEUE_INITIALIZER( name ) \
774    { \
775      .Lock_stats = SMP_LOCK_STATS_INITIALIZER( name ), \
776      .Queue = { \
777        .heads = NULL, \
778        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
779      } \
780    }
781#elif defined(RTEMS_SMP)
782  #define THREAD_QUEUE_INITIALIZER( name ) \
783    { \
784      .Queue = { \
785        .heads = NULL, \
786        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
787      } \
788    }
789#else
790  #define THREAD_QUEUE_INITIALIZER( name ) \
791    { .Queue = { .heads = NULL } }
792#endif
793
794RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
795  Thread_queue_Control *the_thread_queue
796)
797{
798#if defined(RTEMS_SMP)
799  _SMP_ticket_lock_Destroy( &the_thread_queue->Queue.Lock );
800  _SMP_lock_Stats_destroy( &the_thread_queue->Lock_stats );
801#endif
802}
803
804/**
805 * @brief Boosts the priority of the thread if threads of another scheduler
806 * instance are enqueued on the thread queue.
807 *
808 * The thread queue must use the priority waiting discipline.
809 *
810 * @param[in] queue The actual thread queue.
811 * @param[in] the_thread The thread to boost the priority if necessary.
812 */
813#if defined(RTEMS_SMP)
814void _Thread_queue_Boost_priority(
815  Thread_queue_Queue *queue,
816  Thread_Control     *the_thread
817);
818#else
819RTEMS_INLINE_ROUTINE void _Thread_queue_Boost_priority(
820  Thread_queue_Queue *queue,
821  Thread_Control     *the_thread
822)
823{
824  (void) queue;
825  (void) the_thread;
826}
827#endif
828
829#if defined(RTEMS_MULTIPROCESSING)
830void _Thread_queue_MP_callout_do_nothing(
831  Thread_Control *the_proxy,
832  Objects_Id      mp_id
833);
834#endif
835
836extern const Thread_queue_Operations _Thread_queue_Operations_default;
837
838extern const Thread_queue_Operations _Thread_queue_Operations_FIFO;
839
840extern const Thread_queue_Operations _Thread_queue_Operations_priority;
841
842/**@}*/
843
844#ifdef __cplusplus
845}
846#endif
847
848#endif
849/* end of include file */
Note: See TracBrowser for help on using the repository browser.