source: rtems/cpukit/include/rtems/score/threadqimpl.h @ 0e49372a

Last change on this file since 0e49372a was 0e49372a, checked in by Sebastian Huber <sebastian.huber@…>, on 04/19/21 at 18:06:27

score: Remove unused _Thread_queue_Dequeue()

Last use was removed by:

commit 54550e048d3a49435912797d2024f80671e93267
Author: Sebastian Huber <sebastian.huber@…>
Date: Fri May 13 08:16:30 2016 +0200

posix: Rework pthread_join()

Rework pthread_join() to use _Thread_Join().

  • Property mode set to 100644
File size: 41.6 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScoreThreadQueue
5 *
6 * @brief This header file provides interfaces of the
7 *   @ref RTEMSScoreThreadQueue which are only used by the implementation.
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/priorityimpl.h>
25#include <rtems/score/scheduler.h>
26#include <rtems/score/smp.h>
27#include <rtems/score/status.h>
28#include <rtems/score/thread.h>
29#include <rtems/score/threaddispatch.h>
30
31#if defined(RTEMS_DEBUG)
32#include <string.h>
33#endif
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39/**
40 *  @addtogroup RTEMSScoreThreadQueue
41 *
42 * @{
43 */
44
45#define THREAD_QUEUE_LINK_OF_PATH_NODE( node ) \
46  RTEMS_CONTAINER_OF( node, Thread_queue_Link, Path_node );
47
48/**
49 * @brief Thread queue with a layout compatible to struct _Thread_queue_Queue
50 * defined in Newlib <sys/lock.h>.
51 */
52typedef struct {
53#if !defined(RTEMS_SMP)
54  /*
55   * The struct _Thread_queue_Queue definition is independent of the RTEMS
56   * build configuration.  Thus, the storage space for the SMP lock is always
57   * present.  In SMP configurations, the SMP lock is contained in the
58   * Thread_queue_Queue.
59   */
60  unsigned int reserved[2];
61#endif
62
63  Thread_queue_Queue Queue;
64} Thread_queue_Syslock_queue;
65
66/**
67 * @brief Does nothing.
68 *
69 * @param queue This parameter is unused.
70 * @param the_thread This parameter is unused.
71 * @param cpu_self This parameter is unused.
72 * @param queue_context This parameter is unused.
73 */
74void _Thread_queue_Enqueue_do_nothing_extra(
75  Thread_queue_Queue   *queue,
76  Thread_Control       *the_thread,
77  Per_CPU_Control      *cpu_self,
78  Thread_queue_Context *queue_context
79);
80
81/**
82 * @brief Adds timeout ticks of the queue to the thread.
83 *
84 * @param queue This parameter is unused.
85 * @param[in, out] the_thread The thread to add timeout ticks to.
86 * @param cpu_self The cpu for the operation.
87 * @param queue_context The thread queue context.
88 */
89void _Thread_queue_Add_timeout_ticks(
90  Thread_queue_Queue   *queue,
91  Thread_Control       *the_thread,
92  Per_CPU_Control      *cpu_self,
93  Thread_queue_Context *queue_context
94);
95
96/**
97 * @brief Adds a monotonic timespec to the thread and sets the watchdog header
98 *      to monotonic.
99 *
100 * @param queue This parameter is unused.
101 * @param[in, out] the_thread The thread to add the timeout and set watchdog header to
102 *      monotonic.
103 * @param cpu_self The cpu to get the monotonic watchdog header from.
104 * @param queue_context The thread queue context.
105 */
106void _Thread_queue_Add_timeout_monotonic_timespec(
107  Thread_queue_Queue   *queue,
108  Thread_Control       *the_thread,
109  Per_CPU_Control      *cpu_self,
110  Thread_queue_Context *queue_context
111);
112
113/**
114 * @brief Adds a monotonic timespec to the thread and sets the watchdog header
115 *      to realtime.
116 *
117 * @param queue This parameter is unused.
118 * @param[in, out] the_thread The thread to add the timeout and set watchdog header to
119 *      realtime.
120 * @param cpu_self The cpu to get the realtime watchdog header from.
121 * @param queue_context The thread queue context.
122 */
123void _Thread_queue_Add_timeout_realtime_timespec(
124  Thread_queue_Queue   *queue,
125  Thread_Control       *the_thread,
126  Per_CPU_Control      *cpu_self,
127  Thread_queue_Context *queue_context
128);
129
130/**
131 * @brief Sets the thread wait return code to STATUS_DEADLOCK.
132 *
133 * @param[out] the_thread The thread to set the wait return code to
134 *      STATUS_DEADLOCK.
135 */
136void _Thread_queue_Deadlock_status( Thread_Control *the_thread );
137
138/**
139 * @brief Results in an INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK fatal error.
140 *
141 * @param the_thread The thread for the operation.
142 */
143void _Thread_queue_Deadlock_fatal( Thread_Control *the_thread );
144
145/**
146 * @brief Initializes a thread queue context.
147 *
148 * @param[out] queue_context The thread queue context to initialize.
149 */
150RTEMS_INLINE_ROUTINE void _Thread_queue_Context_initialize(
151  Thread_queue_Context *queue_context
152)
153{
154#if defined(RTEMS_DEBUG)
155  memset( queue_context, 0x7f, sizeof( *queue_context ) );
156#if defined(RTEMS_SMP)
157  _Chain_Initialize_node( &queue_context->Lock_context.Wait.Gate.Node );
158#endif
159  queue_context->enqueue_callout = NULL;
160  queue_context->deadlock_callout = NULL;
161#else
162  (void) queue_context;
163#endif
164}
165
166/**
167 * @brief Sets the thread state for the thread to enqueue in the thread queue
168 * context.
169 *
170 * @param[out] queue_context The thread queue context.
171 * @param state The thread state.
172 *
173 * @see _Thread_queue_Enqueue().
174 */
175RTEMS_INLINE_ROUTINE void
176_Thread_queue_Context_set_thread_state(
177  Thread_queue_Context *queue_context,
178  States_Control        thread_state
179)
180{
181  queue_context->thread_state = thread_state;
182}
183
184/**
185 * @brief Sets the timeout ticks in the thread queue context.
186 *
187 * @param[out] queue_context The thread queue context.
188 * @param ticks The timeout in ticks.
189 *
190 * @see _Thread_queue_Enqueue().
191 */
192RTEMS_INLINE_ROUTINE void
193_Thread_queue_Context_set_timeout_ticks(
194  Thread_queue_Context *queue_context,
195  Watchdog_Interval     ticks
196)
197{
198  queue_context->Timeout.ticks = ticks;
199}
200
201/**
202 * @brief Sets the timeout argument in the thread queue context.
203 *
204 * @param[out] queue_context The thread queue context.
205 * @param arg The timeout argument.
206 *
207 * @see _Thread_queue_Enqueue().
208 */
209RTEMS_INLINE_ROUTINE void
210_Thread_queue_Context_set_timeout_argument(
211  Thread_queue_Context *queue_context,
212  const void           *arg
213)
214{
215  queue_context->Timeout.arg = arg;
216}
217
218/**
219 * @brief Sets the enqueue callout in the thread queue context.
220 *
221 * @param[out] queue_context The thread queue context.
222 * @param enqueue_callout The enqueue callout.
223 *
224 * @see _Thread_queue_Enqueue().
225 */
226RTEMS_INLINE_ROUTINE void
227_Thread_queue_Context_set_enqueue_callout(
228  Thread_queue_Context         *queue_context,
229  Thread_queue_Enqueue_callout  enqueue_callout
230)
231{
232  queue_context->enqueue_callout = enqueue_callout;
233}
234
235/**
236 * @brief Sets the do nothing enqueue callout in the thread queue context.
237 *
238 * @param[out] queue_context The thread queue context.
239 *
240 * @see _Thread_queue_Enqueue().
241 */
242RTEMS_INLINE_ROUTINE void
243_Thread_queue_Context_set_enqueue_do_nothing_extra(
244  Thread_queue_Context *queue_context
245)
246{
247  queue_context->enqueue_callout = _Thread_queue_Enqueue_do_nothing_extra;
248}
249
250/**
251 * @brief Sets the enqueue callout to add a relative monotonic timeout in
252 * ticks.
253 *
254 * @param[out] queue_context The thread queue context.
255 * @param ticks The timeout in ticks.
256 *
257 * @see _Thread_queue_Enqueue().
258 */
259RTEMS_INLINE_ROUTINE void
260_Thread_queue_Context_set_enqueue_timeout_ticks(
261  Thread_queue_Context *queue_context,
262  Watchdog_Interval     ticks
263)
264{
265  queue_context->Timeout.ticks = ticks;
266  queue_context->enqueue_callout = _Thread_queue_Add_timeout_ticks;
267}
268
269/**
270 * @brief Sets the enqueue callout to add an absolute monotonic timeout in
271 * timespec format.
272 *
273 * @param[out] queue_context The thread queue context.
274 * @param abstime The absolute monotonic timeout.
275 *
276 * @see _Thread_queue_Enqueue().
277 */
278RTEMS_INLINE_ROUTINE void
279_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
280  Thread_queue_Context  *queue_context,
281  const struct timespec *abstime
282)
283{
284  queue_context->Timeout.arg = abstime;
285  queue_context->enqueue_callout =
286    _Thread_queue_Add_timeout_monotonic_timespec;
287}
288
289/**
290 * @brief Sets the enqueue callout to add an absolute realtime timeout in
291 * timespec format.
292 *
293 * @param[out] queue_context The thread queue context.
294 * @param abstime The absolute realtime timeout.
295 *
296 * @see _Thread_queue_Enqueue().
297 */
298RTEMS_INLINE_ROUTINE void
299_Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
300  Thread_queue_Context  *queue_context,
301  const struct timespec *abstime
302)
303{
304  queue_context->Timeout.arg = abstime;
305  queue_context->enqueue_callout = _Thread_queue_Add_timeout_realtime_timespec;
306}
307
308/**
309 * @brief Sets the deadlock callout in the thread queue
310 * context.
311 *
312 * A deadlock callout must be provided for _Thread_queue_Enqueue()
313 * operations that operate on thread queues which may have an owner, e.g. mutex
314 * objects.  Available deadlock callouts are _Thread_queue_Deadlock_status()
315 * and _Thread_queue_Deadlock_fatal().
316 *
317 * @param[out] queue_context The thread queue context.
318 * @param deadlock_callout The deadlock callout.
319 *
320 * @see _Thread_queue_Enqueue().
321 */
322RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_deadlock_callout(
323  Thread_queue_Context          *queue_context,
324  Thread_queue_Deadlock_callout  deadlock_callout
325)
326{
327  queue_context->deadlock_callout = deadlock_callout;
328}
329
330/**
331 * @brief Clears the priority update count of the thread queue context.
332 *
333 * @param[out] queue_context The thread queue context to clear the priority
334 * update count.
335 */
336RTEMS_INLINE_ROUTINE void _Thread_queue_Context_clear_priority_updates(
337  Thread_queue_Context *queue_context
338)
339{
340  queue_context->Priority.update_count = 0;
341}
342
343/**
344 * @brief Returns the priority update count of the thread queue context.
345 *
346 * @param queue_context The thread queue context to get the priority update
347 *      count of.
348 *
349 * @return The priority update count of @a queue_context.
350 */
351RTEMS_INLINE_ROUTINE size_t _Thread_queue_Context_save_priority_updates(
352  Thread_queue_Context *queue_context
353)
354{
355  return queue_context->Priority.update_count;
356}
357
358/**
359 * @brief Sets the priority update count of the thread queue context.
360 *
361 * @param[out] queue_context The thread queue context to set the priority
362 *      update count of.
363 * @param update_count The priority update count.
364 */
365RTEMS_INLINE_ROUTINE void _Thread_queue_Context_restore_priority_updates(
366  Thread_queue_Context *queue_context,
367  size_t                update_count
368)
369{
370  queue_context->Priority.update_count = update_count;
371}
372
373/**
374 * @brief Adds a priority update of the thread to the thread queue context.
375 *
376 * @param[in, out] queue_context The thread queue context to increase the
377 *      priority update count of and set the_thread in its Priority update
378 *      array.
379 * @param the_thread The thread for the priority update.
380 */
381RTEMS_INLINE_ROUTINE void _Thread_queue_Context_add_priority_update(
382  Thread_queue_Context *queue_context,
383  Thread_Control       *the_thread
384)
385{
386  size_t n;
387
388  n = queue_context->Priority.update_count;
389  _Assert( n < RTEMS_ARRAY_SIZE( queue_context->Priority.update ) );
390
391  queue_context->Priority.update_count = n + 1;
392  queue_context->Priority.update[ n ] = the_thread;
393}
394
395#define _Thread_queue_Context_ISR_disable( queue_context, level ) \
396  do { \
397    _ISR_Local_disable( level ); \
398    _ISR_lock_ISR_disable_profile( \
399      &( queue_context )->Lock_context.Lock_context \
400    ) \
401  } while ( 0 )
402
403/**
404 * @brief Sets the thread queue context ISR level.
405 *
406 * @param[out] queue_context The thread queue context to set the ISR level of.
407 * @param level The ISR level to set @a queue_context to.
408 */
409RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_ISR_level(
410  Thread_queue_Context *queue_context,
411  ISR_Level             level
412)
413{
414  _ISR_lock_Context_set_level(
415    &queue_context->Lock_context.Lock_context,
416    level
417  );
418}
419
420/**
421 * @brief Disables dispatching in a critical section.
422 *
423 * @param queue_context The thread queue context to get the lock context from.
424 *
425 * @return The current processor.
426 */
427RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_queue_Dispatch_disable(
428  Thread_queue_Context *queue_context
429)
430{
431  return _Thread_Dispatch_disable_critical(
432    &queue_context->Lock_context.Lock_context
433  );
434}
435
436/**
437 * @brief Sets the MP callout in the thread queue context.
438 *
439 * @param[out] queue_context The thread queue context.
440 * @param mp_callout Callout to unblock the thread in case it is actually a
441 *   thread proxy.  This parameter is only used on multiprocessing
442 *   configurations.  Used by thread queue extract and unblock methods for
443 *   objects with multiprocessing (MP) support.
444 */
445#if defined(RTEMS_MULTIPROCESSING)
446RTEMS_INLINE_ROUTINE void _Thread_queue_Context_set_MP_callout(
447  Thread_queue_Context    *queue_context,
448  Thread_queue_MP_callout  mp_callout
449)
450{
451  queue_context->mp_callout = mp_callout;
452}
453#else
454#define _Thread_queue_Context_set_MP_callout( queue_context, mp_callout ) \
455  do { \
456    (void) queue_context; \
457  } while ( 0 )
458#endif
459
460#if defined(RTEMS_SMP)
461/**
462 * @brief Closes the gate.
463 *
464 * @param[out] gate The gate to close.
465 */
466RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_close(
467  Thread_queue_Gate *gate
468)
469{
470  _Atomic_Store_uint( &gate->go_ahead, 0, ATOMIC_ORDER_RELAXED );
471}
472
473/**
474 * @brief Adds the gate to the chain.
475 *
476 * @param[in, out] chain The chain to add the gate to.
477 * @param gate The gate to add to the chain.
478 */
479RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_add(
480  Chain_Control     *chain,
481  Thread_queue_Gate *gate
482)
483{
484  _Chain_Append_unprotected( chain, &gate->Node );
485}
486
487/**
488 * @brief Opens the gate.
489 *
490 * @param[out] gate The gate to open.
491 */
492RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_open(
493  Thread_queue_Gate *gate
494)
495{
496  _Atomic_Store_uint( &gate->go_ahead, 1, ATOMIC_ORDER_RELAXED );
497}
498
499/**
500 * @brief Waits on a gate to open.
501 *
502 * Performs busy waiting.
503 *
504 * @param gate The gate to wait for.
505 */
506RTEMS_INLINE_ROUTINE void _Thread_queue_Gate_wait(
507  Thread_queue_Gate *gate
508)
509{
510  while ( _Atomic_Load_uint( &gate->go_ahead, ATOMIC_ORDER_RELAXED ) == 0 ) {
511    /* Wait */
512  }
513}
514#endif
515
516/**
517 * @brief Initializes the thread queue heads.
518 *
519 * @param[out] heads The thread queue heads to initialize.
520 */
521RTEMS_INLINE_ROUTINE void _Thread_queue_Heads_initialize(
522  Thread_queue_Heads *heads
523)
524{
525#if defined(RTEMS_SMP)
526  size_t i;
527
528  for ( i = 0; i < _Scheduler_Count; ++i ) {
529    _Chain_Initialize_node( &heads->Priority[ i ].Node );
530    _Priority_Initialize_empty( &heads->Priority[ i ].Queue );
531    heads->Priority[ i ].Queue.scheduler = &_Scheduler_Table[ i ];
532  }
533#endif
534
535  _Chain_Initialize_empty( &heads->Free_chain );
536  _Chain_Initialize_node( &heads->Free_node );
537}
538
539/**
540 * @brief Initializes the thread queue queue with the given name.
541 *
542 * @param[out] queue The thread queue queue to initialize.
543 * @param name The name for the @a queue.
544 */
545RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize(
546  Thread_queue_Queue *queue,
547  const char         *name
548)
549{
550#if defined(RTEMS_SMP)
551  _SMP_ticket_lock_Initialize( &queue->Lock );
552#endif
553  queue->heads = NULL;
554  queue->owner = NULL;
555  queue->name = name;
556}
557
558/**
559 * @brief Acquires the thread queue queue in a critical section.
560 *
561 * @param queue The thread queue queue to acquire in a critical section.
562 * @param lock_stats The lock statistics.
563 * @param[out] lock_context The interrupt lock context.
564 */
565RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_do_acquire_critical(
566  Thread_queue_Queue *queue,
567#if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
568  SMP_lock_Stats     *lock_stats,
569#endif
570  ISR_lock_Context   *lock_context
571)
572{
573#if defined(RTEMS_SMP)
574  _SMP_ticket_lock_Acquire(
575    &queue->Lock,
576    lock_stats,
577    &lock_context->Lock_context.Stats_context
578  );
579#else
580  (void) queue;
581  (void) lock_context;
582#endif
583}
584
585#if defined(RTEMS_SMP) && defined( RTEMS_PROFILING )
586  #define \
587    _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
588    _Thread_queue_Queue_do_acquire_critical( queue, lock_stats, lock_context )
589#else
590  #define \
591    _Thread_queue_Queue_acquire_critical( queue, lock_stats, lock_context ) \
592    _Thread_queue_Queue_do_acquire_critical( queue, lock_context )
593#endif
594
595/**
596 * @brief Releases the thread queue queue in a critical section.
597 *
598 * @param queue The thread queue queue to release in a critical section.
599 * @param[out] lock_context The interrupt lock context.
600 */
601RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release_critical(
602  Thread_queue_Queue *queue,
603  ISR_lock_Context   *lock_context
604)
605{
606#if defined(RTEMS_SMP)
607  _SMP_ticket_lock_Release(
608    &queue->Lock,
609    &lock_context->Lock_context.Stats_context
610  );
611#else
612  (void) queue;
613  (void) lock_context;
614#endif
615}
616
617/**
618 * @brief Releases the thread queue queue and enables interrupts.
619 *
620 * @param queue The thread queue queue to release.
621 * @param[out] lock_context The interrupt lock context to enable interrupts.
622 */
623RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_release(
624  Thread_queue_Queue *queue,
625  ISR_lock_Context   *lock_context
626)
627{
628  _Thread_queue_Queue_release_critical( queue, lock_context );
629  _ISR_lock_ISR_enable( lock_context );
630}
631
632/**
633 * @brief Copies the thread queue name to the specified buffer.
634 *
635 * @param queue The actual thread queue.
636 * @param[out] buffer The buffer for the thread queue name copy.
637 * @param buffer_size The buffer size in characters.
638 * @param id The object identifier in case the thread queue is embedded in
639 *   an object with identifier, otherwise it is set to 0.
640 *
641 * @return The length of the thread queue name.  May be greater than or equal
642 *  to the buffer size if truncation occurred.
643 */
644size_t _Thread_queue_Queue_get_name_and_id(
645  const Thread_queue_Queue *queue,
646  char                     *buffer,
647  size_t                    buffer_size,
648  Objects_Id               *id
649);
650
651/**
652 * @brief Acquires the thread queue control in a critical section.
653 *
654 * @param the_thread_queue The thread queue control to acquire.
655 * @param[out] lock_context The interrupt lock context.
656 */
657#if defined(RTEMS_SMP)
658void _Thread_queue_Do_acquire_critical(
659  Thread_queue_Control *the_thread_queue,
660  ISR_lock_Context     *lock_context
661);
662#else
663RTEMS_INLINE_ROUTINE void _Thread_queue_Do_acquire_critical(
664  Thread_queue_Control *the_thread_queue,
665  ISR_lock_Context     *lock_context
666)
667{
668  (void) the_thread_queue;
669  (void) lock_context;
670}
671#endif
672
673/**
674 * @brief Acquires the thread queue control in a critical section.
675 *
676 * @param the_thread_queue The thread queue control to acquire.
677 * @param[out] lock_context The interrupt lock context.
678 */
679RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire_critical(
680  Thread_queue_Control *the_thread_queue,
681  Thread_queue_Context *queue_context
682)
683{
684  _Thread_queue_Do_acquire_critical(
685    the_thread_queue,
686    &queue_context->Lock_context.Lock_context
687  );
688}
689
690/**
691 * @brief Acquires the thread queue control in a critical section.
692 *
693 * @param the_thread_queue The thread queue control to acquire.
694 * @param[out] queue_context The thread queue context.
695 */
696#if defined(RTEMS_SMP)
697void _Thread_queue_Acquire(
698  Thread_queue_Control *the_thread_queue,
699  Thread_queue_Context *queue_context
700);
701#else
702RTEMS_INLINE_ROUTINE void _Thread_queue_Acquire(
703  Thread_queue_Control *the_thread_queue,
704  Thread_queue_Context *queue_context
705)
706{
707  (void) the_thread_queue;
708  _ISR_lock_ISR_disable( &queue_context->Lock_context.Lock_context );
709}
710#endif
711
712/**
713 * @brief Checks if the thread queue control is the owner of the lock.
714 *
715 * @param the_thread_queue The thread queue control for the verification.
716 *
717 * @retval true The thread queue control is the owner of the lock.
718 * @retval false The thread queue control is not the owner of the lock.
719 */
720#if defined(RTEMS_DEBUG)
721RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_lock_owner(
722  const Thread_queue_Control *the_thread_queue
723)
724{
725#if defined(RTEMS_SMP)
726  return the_thread_queue->owner == _SMP_lock_Who_am_I();
727#else
728  return _ISR_Get_level() != 0;
729#endif
730}
731#endif
732
733/**
734 * @brief Releases the thread queue control in a critical section.
735 *
736 * @param the_thread_queue The thread queue control to release.
737 * @param[out] lock_context The interrupt lock context.
738 */
739#if defined(RTEMS_SMP)
740void _Thread_queue_Do_release_critical(
741  Thread_queue_Control *the_thread_queue,
742  ISR_lock_Context     *lock_context
743);
744#else
745RTEMS_INLINE_ROUTINE void _Thread_queue_Do_release_critical(
746  Thread_queue_Control *the_thread_queue,
747  ISR_lock_Context     *lock_context
748)
749{
750  (void) the_thread_queue;
751  (void) lock_context;
752  _Assert( _Thread_queue_Is_lock_owner( the_thread_queue ) );
753}
754#endif
755
756/**
757 * @brief Releases the thread queue control in a critical section.
758 *
759 * @param the_thread_queue The thread queue control to release.
760 * @param[out] queue_context The thread queue context.
761 */
762RTEMS_INLINE_ROUTINE void _Thread_queue_Release_critical(
763  Thread_queue_Control *the_thread_queue,
764  Thread_queue_Context *queue_context
765)
766{
767  _Thread_queue_Do_release_critical(
768    the_thread_queue,
769    &queue_context->Lock_context.Lock_context
770  );
771}
772
773/**
774 * @brief Releases the thread queue control and enables interrupts.
775 *
776 * @param the_thread_queue The thread queue control to release.
777 * @param[out] queue_context The thread queue context.
778 */
779#if defined(RTEMS_SMP)
780void _Thread_queue_Release(
781  Thread_queue_Control *the_thread_queue,
782  Thread_queue_Context *queue_context
783);
784#else
785RTEMS_INLINE_ROUTINE void _Thread_queue_Release(
786  Thread_queue_Control *the_thread_queue,
787  Thread_queue_Context *queue_context
788)
789{
790  (void) the_thread_queue;
791  _Assert( _Thread_queue_Is_lock_owner( the_thread_queue ) );
792  _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
793}
794#endif
795
796/**
797 * @brief Blocks the thread and places it on the thread queue.
798 *
799 * This enqueues the thread on the thread queue, blocks the thread, and
800 * optionally starts the thread timer in case the timeout discipline is not
801 * WATCHDOG_NO_TIMEOUT. Timeout discipline and value are in the queue_context.
802 *
803 * The caller must be the owner of the thread queue lock.  This function will
804 * release the thread queue lock and register it as the new thread lock.
805 * Thread dispatching is disabled before the thread queue lock is released.
806 * Thread dispatching is enabled once the sequence to block the thread is
807 * complete.  The operation to enqueue the thread on the queue is protected by
808 * the thread queue lock.  This makes it possible to use the thread queue lock
809 * to protect the state of objects embedding the thread queue and directly
810 * enter _Thread_queue_Enqueue() in case the thread must block.
811 *
812 * The thread queue context must be set up with the following functions,
813 * otherwise the behaviour is unpredictable
814 *
815 * - _Thread_queue_Context_set_thread_state(),
816 *
817 * - _Thread_queue_Context_set_enqueue_callout() or
818 *   _Thread_queue_Context_set_enqueue_do_nothing_extra() or
819 *   _Thread_queue_Context_set_enqueue_timeout_ticks() or
820 *   _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec() or
821 *   _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(),
822 *
823 * - _Thread_queue_Context_set_deadlock_callout().
824 *
825 * @code
826 * #include <rtems/score/threadqimpl.h>
827 * #include <rtems/score/statesimpl.h>
828 *
829 * #define MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority
830 *
831 * typedef struct {
832 *   Thread_queue_Control Queue;
833 * } Mutex;
834 *
835 * void _Mutex_Obtain( Mutex *mutex )
836 * {
837 *   Thread_queue_Context  queue_context;
838 *   Thread_Control       *executing;
839 *
840 *   _Thread_queue_Context_initialize( &queue_context );
841 *   _Thread_queue_Acquire( &mutex->Queue, queue_context );
842 *
843 *   executing = _Thread_Executing;
844 *
845 *   if ( mutex->Queue.owner == NULL ) {
846 *     mutex->Queue.owner = executing;
847 *     _Thread_queue_Release( &mutex->Queue, queue_context );
848 *   } else {
849 *     _Thread_queue_Context_set_thread_state(
850 *       &queue_context,
851 *       STATES_WAITING_FOR_MUTEX
852 *     );
853 *     _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context );
854 *     _Thread_queue_Context_set_deadlock_callout(
855 *       queue_context,
856 *       _Thread_queue_Deadlock_fatal
857 *     );
858 *     _Thread_queue_Enqueue(
859 *       &mutex->Queue.Queue,
860 *       MUTEX_TQ_OPERATIONS,
861 *       executing,
862 *       &queue_context
863 *     );
864 *   }
865 * }
866 * @endcode
867 *
868 * @param queue The actual thread queue.
869 * @param operations The thread queue operations.
870 * @param[in, out] the_thread The thread to enqueue.
871 * @param[in, out] queue_context The thread queue context of the lock acquire.
872 */
873void _Thread_queue_Enqueue(
874  Thread_queue_Queue            *queue,
875  const Thread_queue_Operations *operations,
876  Thread_Control                *the_thread,
877  Thread_queue_Context          *queue_context
878);
879
880#if defined(RTEMS_SMP)
881/**
882 * @brief Enqueues the thread on the thread queue and busy waits for dequeue.
883 *
884 * Optionally starts the thread timer in case the timeout discipline is not
885 * WATCHDOG_NO_TIMEOUT. Timeout discipline and value are in the queue_context.
886 *
887 * The caller must be the owner of the thread queue lock.  This function will
888 * release the thread queue lock and register it as the new thread lock.
889 *
890 * The thread priorities of the owner and the are updated with respect to the
891 * scheduler.  The sticky level of the thread is incremented.  A thread
892 * dispatch is performed if necessary.
893 *
894 * Afterwards, the thread busy waits on the thread wait flags until a timeout
895 * occurs or the thread queue is surrendered to this thread.  So, it sticks to
896 * the processor instead of blocking with respect to the scheduler.
897 *
898 * @param queue The actual thread queue.
899 * @param operations The thread queue operations.
900 * @param[in, out] the_thread The thread to enqueue.
901 * @param[in, out] queue_context The thread queue context of the lock acquire.
902 */
903Status_Control _Thread_queue_Enqueue_sticky(
904  Thread_queue_Queue            *queue,
905  const Thread_queue_Operations *operations,
906  Thread_Control                *the_thread,
907  Thread_queue_Context          *queue_context
908);
909#endif
910
911/**
912 * @brief Extracts the thread from the thread queue, restores the default wait
913 * operations and restores the default thread lock.
914 *
915 * The caller must be the owner of the thread queue lock.  The thread queue
916 * lock is not released.
917 *
918 * @param queue The actual thread queue.
919 * @param operations The thread queue operations.
920 * @param[in, out] the_thread The thread to extract.
921 * @param[in, out] queue_context The thread queue context.
922 *
923 * @return Returns the unblock indicator for _Thread_queue_Unblock_critical().
924 * True indicates, that this thread must be unblocked by the scheduler later in
925 * _Thread_queue_Unblock_critical(), and false otherwise.  In case false is
926 * returned, then the thread queue enqueue procedure was interrupted.  Thus it
927 * will unblock itself and the thread wait information is no longer accessible,
928 * since this thread may already block on another resource in an SMP
929 * configuration.
930 */
931bool _Thread_queue_Extract_locked(
932  Thread_queue_Queue            *queue,
933  const Thread_queue_Operations *operations,
934  Thread_Control                *the_thread,
935  Thread_queue_Context          *queue_context
936);
937
938/**
939 * @brief Unblocks the thread which was on the thread queue before.
940 *
941 * The caller must be the owner of the thread queue lock.  This function will
942 * release the thread queue lock.  Thread dispatching is disabled before the
943 * thread queue lock is released and an unblock is necessary.  Thread
944 * dispatching is enabled once the sequence to unblock the thread is complete.
945 *
946 * @param unblock The unblock indicator returned by
947 * _Thread_queue_Extract_locked().
948 * @param queue The actual thread queue.
949 * @param[in, out] the_thread The thread to extract.
950 * @param[in, out] lock_context The lock context of the lock acquire.
951 */
952void _Thread_queue_Unblock_critical(
953  bool                unblock,
954  Thread_queue_Queue *queue,
955  Thread_Control     *the_thread,
956  ISR_lock_Context   *lock_context
957);
958
959/**
960 * @brief Extracts the thread from the thread queue and unblocks it.
961 *
962 * The caller must be the owner of the thread queue lock.  This function will
963 * release the thread queue lock and restore the default thread lock.  Thread
964 * dispatching is disabled before the thread queue lock is released and an
965 * unblock is necessary.  Thread dispatching is enabled once the sequence to
966 * unblock the thread is complete.  This makes it possible to use the thread
967 * queue lock to protect the state of objects embedding the thread queue and
968 * directly enter _Thread_queue_Extract_critical() to finalize an operation in
969 * case a waiting thread exists.
970 *
971 * @code
972 * #include <rtems/score/threadqimpl.h>
973 *
974 * typedef struct {
975 *   Thread_queue_Control  Queue;
976 *   Thread_Control       *owner;
977 * } Mutex;
978 *
979 * void _Mutex_Release( Mutex *mutex )
980 * {
981 *   Thread_queue_Context  queue_context;
982 *   Thread_Control       *first;
983 *
984 *   _Thread_queue_Context_initialize( &queue_context, NULL );
985 *   _Thread_queue_Acquire( &mutex->Queue, queue_context );
986 *
987 *   first = _Thread_queue_First_locked( &mutex->Queue );
988 *   mutex->owner = first;
989 *
990 *   if ( first != NULL ) {
991 *     _Thread_queue_Extract_critical(
992 *       &mutex->Queue.Queue,
993 *       mutex->Queue.operations,
994 *       first,
995 *       &queue_context
996 *   );
997 * }
998 * @endcode
999 *
1000 * @param queue The actual thread queue.
1001 * @param operations The thread queue operations.
1002 * @param[in, out] the_thread The thread to extract.
1003 * @param[in, out] queue_context The thread queue context of the lock acquire.
1004 */
1005void _Thread_queue_Extract_critical(
1006  Thread_queue_Queue            *queue,
1007  const Thread_queue_Operations *operations,
1008  Thread_Control                *the_thread,
1009  Thread_queue_Context          *queue_context
1010);
1011
1012/**
1013 * @brief Extracts thread from thread queue.
1014 *
1015 * This routine removes @a the_thread its thread queue
1016 * and cancels any timeouts associated with this blocking.
1017 *
1018 * @param[in, out] the_thread The pointer to a thread control block that
1019 *     is to be removed
1020 */
1021void _Thread_queue_Extract( Thread_Control *the_thread );
1022
1023/**
1024 * @brief Extracts the_thread from the_thread_queue.
1025 *
1026 * This routine extracts the_thread from the_thread_queue
1027 * and ensures that if there is a proxy for this task on
1028 * another node, it is also dealt with. A proxy is a data
1029 * data that is on the thread queue on the remote node and
1030 * acts as a proxy for the local thread. If the local thread
1031 * was waiting on a remote operation, then the remote side
1032 * of the operation must be cleaned up.
1033 *
1034 * @param[in, out] the_thread The pointer to a thread control block that
1035 *     is to be removed
1036 */
1037void _Thread_queue_Extract_with_proxy(
1038  Thread_Control       *the_thread
1039);
1040
1041/**
1042 * @brief Surrenders the thread queue previously owned by the thread to the
1043 * first enqueued thread.
1044 *
1045 * The owner of the thread queue must be set to NULL by the caller.
1046 *
1047 * This function releases the thread queue lock.  In addition it performs a
1048 * thread dispatch if necessary.
1049 *
1050 * @param[in, out] queue The actual thread queue.
1051 * @param heads The thread queue heads.  It must not be NULL.
1052 * @param previous_owner The previous owner thread surrendering the thread
1053 *   queue.
1054 * @param queue_context The thread queue context of the lock acquire.
1055 * @param operations The thread queue operations.
1056 */
1057void _Thread_queue_Surrender(
1058  Thread_queue_Queue            *queue,
1059  Thread_queue_Heads            *heads,
1060  Thread_Control                *previous_owner,
1061  Thread_queue_Context          *queue_context,
1062  const Thread_queue_Operations *operations
1063);
1064
1065#if defined(RTEMS_SMP)
1066/**
1067 * @brief Surrenders the thread queue previously owned by the thread to the
1068 * first enqueued thread.
1069 *
1070 * The owner of the thread queue must be set to NULL by the caller.
1071 *
1072 * The caller must be the owner of the thread queue lock.  This function will
1073 * release the thread queue.
1074 *
1075 * The thread priorities of the previous owner and the new owner are updated.  The
1076 * sticky level of the previous owner is decremented.  A thread dispatch is
1077 * performed if necessary.
1078 *
1079 * @param[in, out] queue The actual thread queue.
1080 * @param heads The thread queue heads.  It must not be NULL.
1081 * @param[in, out] previous_owner The previous owner thread surrendering the thread
1082 *   queue.
1083 * @param queue_context The thread queue context of the lock acquire.
1084 * @param operations The thread queue operations.
1085 */
1086void _Thread_queue_Surrender_sticky(
1087  Thread_queue_Queue            *queue,
1088  Thread_queue_Heads            *heads,
1089  Thread_Control                *previous_owner,
1090  Thread_queue_Context          *queue_context,
1091  const Thread_queue_Operations *operations
1092);
1093#endif
1094
1095/**
1096 * @brief Checks if the thread queue queue is empty.
1097 *
1098 * @param queue The thread queue for the verification.
1099 *
1100 * @retval true @a queue is empty.
1101 * @retval false @a queue is not empty.
1102 */
1103RTEMS_INLINE_ROUTINE bool _Thread_queue_Is_empty(
1104  const Thread_queue_Queue *queue
1105)
1106{
1107  return queue->heads == NULL;
1108}
1109
1110/**
1111 * @brief Returns the first thread on the thread queue if it exists, otherwise
1112 * @c NULL.
1113 *
1114 * The caller must be the owner of the thread queue lock.  The thread queue
1115 * lock is not released.
1116 *
1117 * @param the_thread_queue The thread queue.
1118 * @param operations The thread queue operations.
1119 *
1120* @retval first The first thread on the thread queue according to the enqueue
1121 * order.
1122 * @retval NULL No thread is present on the thread queue.
1123 */
1124RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked(
1125  Thread_queue_Control          *the_thread_queue,
1126  const Thread_queue_Operations *operations
1127)
1128{
1129  Thread_queue_Heads *heads = the_thread_queue->Queue.heads;
1130
1131  if ( heads != NULL ) {
1132    return ( *operations->first )( heads );
1133  } else {
1134    return NULL;
1135  }
1136}
1137
1138/**
1139 * @brief Returns the first thread on the thread queue if it exists, otherwise
1140 * @c NULL.
1141 *
1142 * @param the_thread_queue The thread queue.
1143 *
1144 * @retval first The first thread on the thread queue according to the enqueue
1145 * order.
1146 * @retval NULL No thread is present on the thread queue.
1147 */
1148Thread_Control *_Thread_queue_First(
1149  Thread_queue_Control          *the_thread_queue,
1150  const Thread_queue_Operations *operations
1151);
1152
1153/**
1154 * @brief Thread queue flush filter function.
1155 *
1156 * Called under protection of the thread queue lock by
1157 * _Thread_queue_Flush_critical() to optionally alter the thread wait
1158 * information and control the iteration.
1159 *
1160 * @param the_thread The thread to extract.  This is the first parameter to
1161 *   optimize for architectures that use the same register for the first
1162 *   parameter and the return value.
1163 * @param queue The actual thread queue.
1164 * @param queue_context The thread queue context of the lock acquire.  May be
1165 *   used to pass additional data to the filter function via an overlay
1166 *   structure.  The filter function should not release or acquire the thread
1167 *   queue lock.
1168 *
1169 * @retval the_thread Extract this thread.
1170 * @retval NULL Do not extract this thread and stop the thread queue flush
1171 *   operation.  Threads that are already extracted will complete the flush
1172 *   operation.
1173 */
1174typedef Thread_Control *( *Thread_queue_Flush_filter )(
1175  Thread_Control       *the_thread,
1176  Thread_queue_Queue   *queue,
1177  Thread_queue_Context *queue_context
1178);
1179
1180/**
1181 * @brief Default thread queue flush filter function.
1182 *
1183 * @param the_thread The thread to extract.
1184 * @param queue This parameter is unused.
1185 * @param queue_context This parameter is unused.
1186 *
1187 * @retval the_thread Extract this thread.
1188 */
1189Thread_Control *_Thread_queue_Flush_default_filter(
1190  Thread_Control       *the_thread,
1191  Thread_queue_Queue   *queue,
1192  Thread_queue_Context *queue_context
1193);
1194
1195/**
1196 * @brief Status unavailable thread queue flush filter function.
1197 *
1198 * Sets the thread wait return code of the thread to STATUS_UNAVAILABLE.
1199 *
1200 * @param[out] the_thread The thread to extract.
1201 * @param queue This parameter is unused.
1202 * @param queue_context This parameter is unused.
1203 *
1204 * @retval the_thread Extract this thread.
1205 */
1206Thread_Control *_Thread_queue_Flush_status_unavailable(
1207  Thread_Control       *the_thread,
1208  Thread_queue_Queue   *queue,
1209  Thread_queue_Context *queue_context
1210);
1211
1212/**
1213 * @brief Status object was deleted thread queue flush filter function.
1214 *
1215 * Sets the thread wait return code of the thread to STATUS_OBJECT_WAS_DELETED
1216 *
1217 * @param[out] the_thread The thread to extract.
1218 * @param queue This parameter is unused.
1219 * @param queue_context This parameter is unused.
1220 *
1221 * @retval the_thread Extract this thread.
1222 */
1223Thread_Control *_Thread_queue_Flush_status_object_was_deleted(
1224  Thread_Control       *the_thread,
1225  Thread_queue_Queue   *queue,
1226  Thread_queue_Context *queue_context
1227);
1228
1229/**
1230 * @brief Unblocks all threads enqueued on the thread queue.
1231 *
1232 * This function iteratively extracts the first enqueued thread of the thread
1233 * queue until the thread queue is empty or the filter function indicates a
1234 * stop.  The thread timers of the extracted threads are cancelled.  The
1235 * extracted threads are unblocked.
1236 *
1237 * @param queue The actual thread queue.
1238 * @param operations The thread queue operations.
1239 * @param filter The filter functions is called for each thread to extract from
1240 *   the thread queue.  It may be used to alter the thread under protection of
1241 *   the thread queue lock, for example to set the thread wait return code.
1242 *   The return value of the filter function controls if the thread queue flush
1243 *   operation should stop or continue.
1244 * @param queue_context The thread queue context of the lock acquire.  May be
1245 *   used to pass additional data to the filter function via an overlay
1246 *   structure.  The filter function should not release or acquire the thread
1247 *   queue lock.
1248 *
1249 * @return The count of extracted threads.
1250 */
1251size_t _Thread_queue_Flush_critical(
1252  Thread_queue_Queue            *queue,
1253  const Thread_queue_Operations *operations,
1254  Thread_queue_Flush_filter      filter,
1255  Thread_queue_Context          *queue_context
1256);
1257
1258/**
1259 * @brief Initializes the thread queue control to the given name.
1260 *
1261 * @param[out] the_thread_queue The thread queue control to initialize.
1262 * @param name The name for @a the_thread_queue.
1263 */
1264void _Thread_queue_Initialize(
1265  Thread_queue_Control *the_thread_queue,
1266  const char           *name
1267);
1268
1269#if defined(RTEMS_SMP) && defined(RTEMS_DEBUG) && defined(RTEMS_PROFILING)
1270  #define THREAD_QUEUE_INITIALIZER( _name ) \
1271    { \
1272      .Lock_stats = SMP_LOCK_STATS_INITIALIZER( _name ), \
1273      .owner = SMP_LOCK_NO_OWNER, \
1274      .Queue = { \
1275        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1276        .heads = NULL, \
1277        .owner = NULL, \
1278        .name = _name \
1279      } \
1280    }
1281#elif defined(RTEMS_SMP) && defined(RTEMS_DEBUG)
1282  #define THREAD_QUEUE_INITIALIZER( _name ) \
1283    { \
1284      .owner = SMP_LOCK_NO_OWNER, \
1285      .Queue = { \
1286        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1287        .heads = NULL, \
1288        .owner = NULL, \
1289        .name = _name \
1290      } \
1291    }
1292#elif defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
1293  #define THREAD_QUEUE_INITIALIZER( _name ) \
1294    { \
1295      .Lock_stats = SMP_LOCK_STATS_INITIALIZER( _name ), \
1296      .Queue = { \
1297        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1298        .heads = NULL, \
1299        .owner = NULL, \
1300        .name = _name \
1301      } \
1302    }
1303#elif defined(RTEMS_SMP)
1304  #define THREAD_QUEUE_INITIALIZER( _name ) \
1305    { \
1306      .Queue = { \
1307        .Lock = SMP_TICKET_LOCK_INITIALIZER, \
1308        .heads = NULL, \
1309        .owner = NULL, \
1310        .name = _name \
1311      } \
1312    }
1313#else
1314  #define THREAD_QUEUE_INITIALIZER( _name ) \
1315    { \
1316      .Queue = { \
1317        .heads = NULL, \
1318        .owner = NULL, \
1319        .name = _name \
1320      } \
1321    }
1322#endif
1323
1324/**
1325 * @brief Destroys the thread queue.
1326 *
1327 * @param[out] the_thread_queue The thread queue to destroy.
1328 */
1329RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
1330  Thread_queue_Control *the_thread_queue
1331)
1332{
1333#if defined(RTEMS_SMP)
1334  _SMP_ticket_lock_Destroy( &the_thread_queue->Queue.Lock );
1335  _SMP_lock_Stats_destroy( &the_thread_queue->Lock_stats );
1336#endif
1337}
1338
1339/**
1340 * @brief Does nothing.
1341 *
1342 * @param the_proxy This parameter is unused.
1343 * @param mp_id This parameter is unused.
1344 */
1345#if defined(RTEMS_MULTIPROCESSING)
1346void _Thread_queue_MP_callout_do_nothing(
1347  Thread_Control *the_proxy,
1348  Objects_Id      mp_id
1349);
1350
1351/**
1352 * @brief Unblocks the proxy of the thread.
1353 *
1354 * @param queue The thread queue queue.
1355 * @param the_threat The thread to unblock proxy (after casting it to Thread_Proxy_control *).
1356 */
1357void _Thread_queue_Unblock_proxy(
1358  Thread_queue_Queue *queue,
1359  Thread_Control     *the_thread
1360);
1361#endif
1362
1363/**
1364 * @brief Acquires the thread queue path in a critical section.
1365 *
1366 * @param queue The thread queue queue.
1367 * @param the_thread The thread for the operation.
1368 * @param queue_context The thread queue context.
1369 *
1370 * @retval true The operation was successful.
1371 * @retval false The operation failed.
1372 */
1373#if defined(RTEMS_SMP)
1374bool _Thread_queue_Path_acquire_critical(
1375  Thread_queue_Queue   *queue,
1376  Thread_Control       *the_thread,
1377  Thread_queue_Context *queue_context
1378);
1379
1380/**
1381 * @brief Releases the thread queue path in a critical section.
1382 *
1383 * @param queue_context The thread queue context.
1384 */
1385void _Thread_queue_Path_release_critical(
1386  Thread_queue_Context *queue_context
1387);
1388#endif
1389
1390/**
1391 * @brief Helper structure to ensure that all objects containing a thread queue
1392 * have the right layout.
1393 *
1394 * @see _Thread_Wait_get_id() and THREAD_QUEUE_OBJECT_ASSERT().
1395 */
1396typedef struct {
1397  Objects_Control      Object;
1398  Thread_queue_Control Wait_queue;
1399} Thread_queue_Object;
1400
1401#define THREAD_QUEUE_OBJECT_ASSERT( object_type, wait_queue_member, msg ) \
1402  RTEMS_STATIC_ASSERT( \
1403    offsetof( object_type, wait_queue_member ) \
1404      == offsetof( Thread_queue_Object, Wait_queue ) \
1405    && RTEMS_HAVE_MEMBER_SAME_TYPE( \
1406      object_type, \
1407      wait_queue_member, \
1408      Thread_queue_Object, \
1409      Wait_queue \
1410    ), \
1411    msg \
1412  )
1413
1414#define THREAD_QUEUE_QUEUE_TO_OBJECT( queue ) \
1415  RTEMS_CONTAINER_OF( \
1416    queue, \
1417    Thread_queue_Object, \
1418    Wait_queue.Queue \
1419  )
1420
1421extern const Thread_queue_Operations _Thread_queue_Operations_default;
1422
1423extern const Thread_queue_Operations _Thread_queue_Operations_FIFO;
1424
1425extern const Thread_queue_Operations _Thread_queue_Operations_priority;
1426
1427extern const Thread_queue_Operations _Thread_queue_Operations_priority_inherit;
1428
1429/**
1430 * @brief The special thread queue name to indicated that the thread queue is
1431 * embedded in an object with identifier.
1432 *
1433 * @see _Thread_queue_Object_initialize().
1434 */
1435extern const char _Thread_queue_Object_name[];
1436
1437/**
1438 * @brief Initializes a thread queue embedded in an object with identifier.
1439 *
1440 * The object must have the layout specified by Thread_queue_Object.  It should
1441 * be ensured with the THREAD_QUEUE_OBJECT_ASSERT() static assertion.
1442 *
1443 * @param[out] the_thread_queue The thread queue.
1444 */
1445void _Thread_queue_Object_initialize(
1446  Thread_queue_Control *the_thread_queue
1447);
1448
1449/** @} */
1450
1451#ifdef __cplusplus
1452}
1453#endif
1454
1455#endif
1456/* end of include file */
Note: See TracBrowser for help on using the repository browser.