source: rtems/cpukit/include/rtems/score/threadq.h @ 21275b58

Last change on this file since 21275b58 was 21275b58, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 22, 2018 at 6:14:51 PM

score: Static Objects_Information initialization

Statically allocate the objects information together with the initial
set of objects either via <rtems/confdefs.h>. Provide default object
informations with zero objects via librtemscpu.a. This greatly
simplifies the workspace size estimate. RTEMS applications which do not
use the unlimited objects option are easier to debug since all objects
reside now in statically allocated objects of the right types.

Close #3621.

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