source: rtems/cpukit/score/include/rtems/score/threadq.h @ 2b72162

5
Last change on this file since 2b72162 was 2b72162, checked in by Sebastian Huber <sebastian.huber@…>, on 01/12/17 at 09:15:56

score: Add Thread_queue_Queue::name

Update #2858.

  • Property mode set to 100644
File size: 15.2 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Constants and Structures Needed to Declare a Thread Queue
5 *
6 *  This include file contains all the constants and structures
7 *  needed to declare a thread queue.
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_THREADQ_H
20#define _RTEMS_SCORE_THREADQ_H
21
22#include <rtems/score/chain.h>
23#include <rtems/score/isrlock.h>
24#include <rtems/score/object.h>
25#include <rtems/score/priority.h>
26#include <rtems/score/rbtree.h>
27#include <rtems/score/states.h>
28#include <rtems/score/watchdog.h>
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
34struct Scheduler_Node;
35
36/**
37 *  @defgroup ScoreThreadQueue Thread Queue Handler
38 *
39 *  @ingroup Score
40 *
41 *  This handler provides the capability to have threads block in
42 *  ordered sets. The sets may be ordered using the FIFO or priority
43 *  discipline.
44 */
45/**@{*/
46
47typedef struct _Thread_Control Thread_Control;
48
49typedef struct Thread_queue_Context Thread_queue_Context;
50
51typedef struct Thread_queue_Queue Thread_queue_Queue;
52
53typedef struct Thread_queue_Operations Thread_queue_Operations;
54
55/**
56 * @brief Thread queue enqueue callout.
57 *
58 * @param[in] queue The actual thread queue.
59 * @param[in] the_thread The thread to enqueue.
60 * @param[in] queue_context The thread queue context of the lock acquire.
61 *
62 * @see _Thread_queue_Context_set_enqueue_callout().
63 */
64typedef void ( *Thread_queue_Enqueue_callout )(
65  Thread_queue_Queue   *queue,
66  Thread_Control       *the_thread,
67  Thread_queue_Context *queue_context
68);
69
70/**
71 * @brief Thread queue deadlock callout.
72 *
73 * @param the_thread The thread that detected the deadlock.
74 *
75 * @see _Thread_queue_Context_set_deadlock_callout().
76 */
77typedef void ( *Thread_queue_Deadlock_callout )(
78  Thread_Control *the_thread
79);
80
81#if defined(RTEMS_MULTIPROCESSING)
82/**
83 * @brief Multiprocessing (MP) support callout for thread queue operations.
84 *
85 * @param the_proxy The thread proxy of the thread queue operation.  A thread
86 *   control is actually a thread proxy if and only if
87 *   _Objects_Is_local_id( the_proxy->Object.id ) is false.
88 * @param mp_id Object identifier of the object containing the thread queue.
89 *
90 * @see _Thread_queue_Context_set_MP_callout().
91 */
92typedef void ( *Thread_queue_MP_callout )(
93  Thread_Control *the_proxy,
94  Objects_Id      mp_id
95);
96#endif
97
98#if defined(RTEMS_SMP)
99/**
100 * @brief The thread queue gate is an SMP synchronization means.
101 *
102 * The gates are added to a list of requests.  A busy wait is performed to make
103 * sure that preceding requests are carried out.  Each predecessor notifies its
104 * successor about on request completion.
105 *
106 * @see _Thread_queue_Gate_add(), _Thread_queue_Gate_wait(), and
107 *   _Thread_queue_Gate_open().
108 */
109typedef struct {
110  Chain_Node Node;
111
112  Atomic_Uint go_ahead;
113} Thread_queue_Gate;
114#endif
115
116typedef struct {
117  /**
118   * @brief The lock context for the thread queue acquire and release
119   * operations.
120   */
121  ISR_lock_Context Lock_context;
122
123#if defined(RTEMS_SMP)
124  /**
125   * @brief Data to support thread queue enqueue operations.
126   */
127  struct {
128    /**
129     * @brief Gate to synchronize thread wait lock requests.
130     *
131     * @see _Thread_Wait_acquire_critical() and _Thread_Wait_tranquilize().
132     */
133    Thread_queue_Gate Gate;
134
135    /**
136     * @brief The thread queue in case the thread is blocked on a thread queue.
137     */
138    Thread_queue_Queue *queue;
139  } Wait;
140#endif
141} Thread_queue_Lock_context;
142
143#if defined(RTEMS_SMP)
144/**
145 * @brief A thread queue link from one thread to another specified by the
146 * thread queue owner and thread wait queue relationships.
147 */
148typedef struct {
149  /**
150   * @brief Node to register this link in the global thread queue links lookup
151   * tree.
152   */
153  RBTree_Node Registry_node;
154
155  /**
156   * @brief The source thread queue determined by the thread queue owner.
157   */
158  Thread_queue_Queue *source;
159
160  /**
161   * @brief The target thread queue determined by the thread wait queue of the
162   * source owner.
163   */
164  Thread_queue_Queue *target;
165
166  /**
167   * @brief Node to add this link to a thread queue path.
168   */
169  Chain_Node Path_node;
170
171  /**
172   * @brief The owner of this thread queue link.
173   */
174  Thread_Control *owner;
175
176  /**
177   * @brief The queue lock context used to acquire the thread wait lock of the
178   * owner.
179   */
180  Thread_queue_Lock_context Lock_context;
181} Thread_queue_Link;
182#endif
183
184/**
185 * @brief Thread queue context for the thread queue methods.
186 *
187 * @see _Thread_queue_Context_initialize().
188 */
189struct Thread_queue_Context {
190  /**
191   * @brief The lock context for the thread queue acquire and release
192   * operations.
193   */
194  Thread_queue_Lock_context Lock_context;
195
196  /**
197   * @brief The thread state for _Thread_queue_Enqueue().
198   */
199  States_Control thread_state;
200
201  /**
202   * @brief The enqueue callout for _Thread_queue_Enqueue().
203   *
204   * The callout is invoked after the release of the thread queue lock with
205   * thread dispatching disabled.  Afterwards the thread is blocked.
206   *
207   * @see _Thread_queue_Enqueue_do_nothing().
208   */
209  Thread_queue_Enqueue_callout enqueue_callout;
210
211  /**
212   * @brief The clock discipline for the interval timeout.
213   * Use WATCHDOG_NO_TIMEOUT to block indefinitely.
214   */
215  Watchdog_Discipline timeout_discipline;
216
217  /**
218   * @brief Interval to wait.
219   */
220  uint64_t timeout;
221
222#if defined(RTEMS_SMP)
223  /**
224   * @brief Representation of a thread queue path from a start thread queue to
225   * the terminal thread queue.
226   *
227   * The start thread queue is determined by the object on which a thread intends
228   * to block.  The terminal thread queue is the thread queue reachable via
229   * thread queue links whose owner is not blocked on a thread queue.  The thread
230   * queue links are determined by the thread queue owner and thread wait queue
231   * relationships.
232   */
233  struct {
234    /**
235     * @brief The chain of thread queue links defining the thread queue path.
236     */
237    Chain_Control Links;
238
239    /**
240     * @brief The start of a thread queue path.
241     */
242    Thread_queue_Link Start;
243
244    /**
245     * @brief In case of a deadlock, a link for the first thread on the path
246     * that tries to enqueue on a thread queue.
247     */
248    Thread_queue_Link Deadlock;
249  } Path;
250#endif
251
252  /**
253   * @brief Block to manage thread priority changes due to a thread queue
254   * operation.
255   */
256  struct {
257    /**
258     * @brief A priority action list.
259     */
260    Priority_Actions Actions;
261
262    /**
263     * @brief Count of threads to update the priority via
264     * _Thread_Priority_update().
265     */
266    size_t update_count;
267
268    /**
269     * @brief Threads to update the priority via _Thread_Priority_update().
270     *
271     * Currently, a maximum of two threads need an update in one rush, for
272     * example the thread of the thread queue operation and the owner of the
273     * thread queue.
274     */
275    Thread_Control *update[ 2 ];
276  } Priority;
277
278  /**
279   * @brief Invoked in case of a detected deadlock.
280   *
281   * Must be initialized for _Thread_queue_Enqueue() in case the
282   * thread queue may have an owner, e.g. for mutex objects.
283   *
284   * @see _Thread_queue_Context_set_deadlock_callout().
285   */
286  Thread_queue_Deadlock_callout deadlock_callout;
287
288#if defined(RTEMS_MULTIPROCESSING)
289  /**
290   * @brief Callout to unblock the thread in case it is actually a thread
291   * proxy.
292   *
293   * This field is only used on multiprocessing configurations.  Used by
294   * thread queue extract and unblock methods for objects with multiprocessing
295   * (MP) support.
296   *
297   * @see _Thread_queue_Context_set_MP_callout().
298   */
299  Thread_queue_MP_callout mp_callout;
300#endif
301};
302
303/**
304 * @brief Thread priority queue.
305 */
306typedef struct {
307#if defined(RTEMS_SMP)
308  /**
309   * @brief Node to enqueue this queue in the FIFO chain of the corresponding
310   * heads structure.
311   *
312   * @see Thread_queue_Heads::Heads::Fifo.
313   */
314  Chain_Node Node;
315#endif
316
317  /**
318   * @brief The actual thread priority queue.
319   */
320  Priority_Aggregation Queue;
321
322  /**
323   * @brief This priority queue is added to a scheduler node of the owner in
324   * case of priority inheritance.
325   */
326  struct Scheduler_Node *scheduler_node;
327} Thread_queue_Priority_queue;
328
329/**
330 * @brief Thread queue heads.
331 *
332 * Each thread is equipped with spare thread queue heads in case it is not
333 * enqueued on a thread queue.  The first thread enqueued on a thread queue
334 * will give its spare thread queue heads to that thread queue.  The threads
335 * arriving at the queue will add their thread queue heads to the free chain of
336 * the queue heads provided by the first thread enqueued.  Once a thread is
337 * dequeued it use the free chain to get new spare thread queue heads.
338 *
339 * Uses a leading underscore in the structure name to allow forward
340 * declarations in standard header files provided by Newlib and GCC.
341 */
342typedef struct _Thread_queue_Heads {
343  /** This union contains the data structures used to manage the blocked
344   *  set of tasks which varies based upon the discipline.
345   */
346  union {
347    /**
348     * @brief This is the FIFO discipline list.
349     *
350     * On SMP configurations this FIFO is used to enqueue the per scheduler
351     * instance priority queues of this structure.  This ensures FIFO fairness
352     * among the highest priority thread of each scheduler instance.
353     */
354    Chain_Control Fifo;
355
356#if !defined(RTEMS_SMP)
357    /**
358     * @brief This is the set of threads for priority discipline waiting.
359     */
360    Thread_queue_Priority_queue Priority;
361#endif
362  } Heads;
363
364  /**
365   * @brief A chain with free thread queue heads providing the spare thread
366   * queue heads for a thread once it is dequeued.
367   */
368  Chain_Control Free_chain;
369
370  /**
371   * @brief A chain node to add these thread queue heads to the free chain of
372   * the thread queue heads dedicated to the thread queue of an object.
373   */
374  Chain_Node Free_node;
375
376#if defined(RTEMS_SMP)
377  /**
378   * @brief One priority queue per scheduler instance.
379   */
380  Thread_queue_Priority_queue Priority[ RTEMS_ZERO_LENGTH_ARRAY ];
381#endif
382} Thread_queue_Heads;
383
384#if defined(RTEMS_SMP)
385  #define THREAD_QUEUE_HEADS_SIZE( scheduler_count ) \
386    ( sizeof( Thread_queue_Heads ) \
387      + ( scheduler_count ) * sizeof( Thread_queue_Priority_queue ) )
388#else
389  #define THREAD_QUEUE_HEADS_SIZE( scheduler_count ) \
390    sizeof( Thread_queue_Heads )
391#endif
392
393struct Thread_queue_Queue {
394  /**
395   * @brief Lock to protect this thread queue.
396   *
397   * It may be used to protect additional state of the object embedding this
398   * thread queue.
399   *
400   * Must be the first component of this structure to be able to re-use
401   * implementation parts for structures defined by Newlib <sys/lock.h>.
402   *
403   * @see _Thread_queue_Acquire(), _Thread_queue_Acquire_critical() and
404   * _Thread_queue_Release().
405   */
406#if defined(RTEMS_SMP)
407  SMP_ticket_lock_Control Lock;
408#endif
409
410  /**
411   * @brief The thread queue heads.
412   *
413   * This pointer is NULL, if and only if no threads are enqueued.  The first
414   * thread to enqueue will give its spare thread queue heads to this thread
415   * queue.
416   */
417  Thread_queue_Heads *heads;
418
419  /**
420   * @brief The thread queue owner.
421   */
422  Thread_Control *owner;
423
424  /**
425   * @brief The thread queue name.
426   */
427  const char *name;
428};
429
430/**
431 * @brief Thread queue action operation.
432 *
433 * @param[in] queue The actual thread queue.
434 * @param[in] the_thread The thread.
435 * @param[in] queue_context The thread queue context providing the thread queue
436 *   action set to perform.  Returns the thread queue action set to perform on
437 *   the thread queue owner or the empty set in case there is nothing to do.
438 */
439typedef void ( *Thread_queue_Priority_actions_operation )(
440  Thread_queue_Queue   *queue,
441  Priority_Actions     *priority_actions
442);
443
444/**
445 * @brief Thread queue enqueue operation.
446 *
447 * A potential thread to update the priority due to priority inheritance is
448 * returned via the thread queue context.  This thread is handed over to
449 * _Thread_Priority_update().
450 *
451 * @param[in] queue The actual thread queue.
452 * @param[in] the_thread The thread to enqueue on the queue.
453 */
454typedef void ( *Thread_queue_Enqueue_operation )(
455  Thread_queue_Queue   *queue,
456  Thread_Control       *the_thread,
457  Thread_queue_Context *queue_context
458);
459
460/**
461 * @brief Thread queue extract operation.
462 *
463 * @param[in] queue The actual thread queue.
464 * @param[in] the_thread The thread to extract from the thread queue.
465 */
466typedef void ( *Thread_queue_Extract_operation )(
467  Thread_queue_Queue   *queue,
468  Thread_Control       *the_thread,
469  Thread_queue_Context *queue_context
470);
471
472/**
473 * @brief Thread queue surrender operation.
474 *
475 * This operation must dequeue and return the first thread on the queue.
476 *
477 * @param[in] queue The actual thread queue.
478 * @param[in] heads The thread queue heads.  It must not be NULL.
479 * @param[in] previous_owner The previous owner of the thread queue.
480 *
481 * @return The previous first thread on the queue.
482 */
483typedef Thread_Control *( *Thread_queue_Surrender_operation )(
484  Thread_queue_Queue   *queue,
485  Thread_queue_Heads   *heads,
486  Thread_Control       *previous_owner,
487  Thread_queue_Context *queue_context
488);
489
490/**
491 * @brief Thread queue first operation.
492 *
493 * @param[in] heads The thread queue heads.
494 *
495 * @retval NULL No thread is present on the thread queue.
496 * @retval first The first thread of the thread queue according to the insert
497 * order.  This thread remains on the thread queue.
498 */
499typedef Thread_Control *( *Thread_queue_First_operation )(
500  Thread_queue_Heads *heads
501);
502
503/**
504 * @brief Thread queue operations.
505 *
506 * @see _Thread_wait_Set_operations().
507 */
508struct Thread_queue_Operations {
509  /**
510   * @brief Thread queue priority actions operation.
511   */
512  Thread_queue_Priority_actions_operation priority_actions;
513
514  /**
515   * @brief Thread queue enqueue operation.
516   *
517   * Called by object routines to enqueue the thread.
518   */
519  Thread_queue_Enqueue_operation enqueue;
520
521  /**
522   * @brief Thread queue extract operation.
523   *
524   * Called by object routines to extract a thread from a thread queue.
525   */
526  Thread_queue_Extract_operation extract;
527
528  /**
529   * @brief Thread queue surrender operation.
530   */
531  Thread_queue_Surrender_operation surrender;
532
533  /**
534   * @brief Thread queue first operation.
535   */
536  Thread_queue_First_operation first;
537};
538
539/**
540 *  This is the structure used to manage sets of tasks which are blocked
541 *  waiting to acquire a resource.
542 */
543typedef struct {
544#if defined(RTEMS_SMP)
545#if defined(RTEMS_DEBUG)
546  /**
547   * @brief The index of the owning processor of the thread queue lock.
548   *
549   * The thread queue lock may be acquired via the thread lock also.  This path
550   * is not covered by this field.  In case the lock is not owned directly via
551   * _Thread_queue_Acquire(), then the value of this field is
552   * SMP_LOCK_NO_OWNER.
553   *
554   * Must be before the queue component of this structure to be able to re-use
555   * implementation parts for structures defined by Newlib <sys/lock.h>.
556   */
557  uint32_t owner;
558#endif
559
560#if defined(RTEMS_PROFILING)
561  /**
562   * @brief SMP lock statistics in case SMP and profiling are enabled.
563   *
564   * Must be before the queue component of this structure to be able to re-use
565   * implementation parts for structures defined by Newlib <sys/lock.h>.
566   */
567  SMP_lock_Stats Lock_stats;
568#endif
569#endif
570
571  /**
572   * @brief The actual thread queue.
573   */
574  Thread_queue_Queue Queue;
575} Thread_queue_Control;
576
577/**@}*/
578
579#ifdef __cplusplus
580}
581#endif
582
583#endif
584/* end of include file */
Note: See TracBrowser for help on using the repository browser.