source: rtems/cpukit/include/rtems/score/threadq.h @ d8de6b9

5
Last change on this file since d8de6b9 was 2afb22b, checked in by Chris Johns <chrisj@…>, on 12/23/17 at 07:18:56

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

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