Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreThread
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScoreThread which are used by the implementation and the
0010  *   @ref RTEMSImplApplConfig.
0011  */
0012 
0013 /*
0014  *  COPYRIGHT (c) 1989-2014.
0015  *  On-Line Applications Research Corporation (OAR).
0016  *
0017  *  Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG
0018  *
0019  * Redistribution and use in source and binary forms, with or without
0020  * modification, are permitted provided that the following conditions
0021  * are met:
0022  * 1. Redistributions of source code must retain the above copyright
0023  *    notice, this list of conditions and the following disclaimer.
0024  * 2. Redistributions in binary form must reproduce the above copyright
0025  *    notice, this list of conditions and the following disclaimer in the
0026  *    documentation and/or other materials provided with the distribution.
0027  *
0028  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0029  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0030  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0031  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0032  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0033  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0034  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0035  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0036  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0037  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0038  * POSSIBILITY OF SUCH DAMAGE.
0039  */
0040 
0041 #ifndef _RTEMS_SCORE_THREAD_H
0042 #define _RTEMS_SCORE_THREAD_H
0043 
0044 #include <rtems/score/atomic.h>
0045 #include <rtems/score/context.h>
0046 #if defined(RTEMS_MULTIPROCESSING)
0047 #include <rtems/score/mppkt.h>
0048 #endif
0049 #include <rtems/score/freechain.h>
0050 #include <rtems/score/isrlock.h>
0051 #include <rtems/score/objectdata.h>
0052 #include <rtems/score/priority.h>
0053 #include <rtems/score/schedulernode.h>
0054 #include <rtems/score/stack.h>
0055 #include <rtems/score/states.h>
0056 #include <rtems/score/threadq.h>
0057 #include <rtems/score/timestamp.h>
0058 #include <rtems/score/watchdog.h>
0059 
0060 #if defined(RTEMS_SMP)
0061 #include <rtems/score/processormask.h>
0062 #endif
0063 
0064 struct rtems_user_env_t;
0065 
0066 struct _pthread_cleanup_context;
0067 
0068 struct Per_CPU_Control;
0069 
0070 struct _Scheduler_Control;
0071 
0072 struct User_extensions_Iterator;
0073 
0074 #ifdef __cplusplus
0075 extern "C" {
0076 #endif
0077 
0078 /**
0079  * @defgroup RTEMSScoreThread Thread Handler
0080  *
0081  * @ingroup RTEMSScore
0082  *
0083  * @brief This group contains the Thread Handler implementation.
0084  *
0085  * This handler encapsulates functionality related to the management of
0086  * threads.  This includes the creation, deletion, and scheduling of threads.
0087  *
0088  * The following variables are maintained as part of the per cpu data
0089  * structure.
0090  *
0091  * + Idle thread pointer
0092  * + Executing thread pointer
0093  * + Heir thread pointer
0094  *
0095  *@{
0096  */
0097 
0098 #if defined(RTEMS_DEBUG)
0099 /**
0100  * @brief This define enables the thread resource count support.
0101  */
0102 #define RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT
0103 #endif
0104 
0105 #if defined(RTEMS_POSIX_API)
0106 /**
0107  * @brief This define enables support for an inactive real thread priority.
0108  *
0109  * For example, the POSIX sporadic server may temporarily remove the real
0110  * priority of a thread while it is in low priority mode.
0111  */
0112 #define RTEMS_SCORE_THREAD_REAL_PRIORITY_MAY_BE_INACTIVE
0113 #endif
0114 
0115 #if defined(RTEMS_POSIX_API) && defined(RTEMS_SMP)
0116 /**
0117  * @brief This define enables support to inhibit scheduler changes.
0118  *
0119  * For example, the POSIX sporadic server adds a second priority to a thread.
0120  * We cannot account for this priority in a scheduler change.
0121  */
0122 #define RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS
0123 #endif
0124 
0125 /**
0126  *  @brief Type of the numeric argument of a thread entry function with at
0127  *  least one numeric argument.
0128  *
0129  *  This numeric argument type designates an unsigned integer type with the
0130  *  property that any valid pointer to void can be converted to this type and
0131  *  then converted back to a pointer to void.  The result will compare equal to
0132  *  the original pointer.
0133  */
0134 typedef CPU_Uint32ptr Thread_Entry_numeric_type;
0135 
0136 /**
0137  * @brief Data for idle thread entry.
0138  */
0139 typedef struct {
0140   void *( *entry )( uintptr_t argument );
0141 } Thread_Entry_idle;
0142 
0143 /**
0144  * @brief Data for thread entry with one numeric argument and no return value.
0145  */
0146 typedef struct {
0147   void ( *entry )( Thread_Entry_numeric_type argument );
0148   Thread_Entry_numeric_type argument;
0149 } Thread_Entry_numeric;
0150 
0151 /**
0152  * @brief Data for thread entry with one pointer argument and a pointer return
0153  * value.
0154  */
0155 typedef struct {
0156   void *( *entry )( void *argument  );
0157   void *argument;
0158 } Thread_Entry_pointer;
0159 
0160 /**
0161  * @brief Thread entry information.
0162  */
0163 typedef struct {
0164   /**
0165    * @brief Thread entry adaptor.
0166    *
0167    * Calls the corresponding thread entry with the right parameters.
0168    *
0169    * @param executing The executing thread.
0170    */
0171   void ( *adaptor )( Thread_Control *executing );
0172 
0173   /**
0174    * @brief Thread entry data used by the adaptor to call the thread entry
0175    * function with the right parameters.
0176    */
0177   union {
0178     Thread_Entry_idle Idle;
0179     Thread_Entry_numeric Numeric;
0180     Thread_Entry_pointer Pointer;
0181   } Kinds;
0182 } Thread_Entry_information;
0183 
0184 /**
0185  * @brief This structure contains operations which manage the CPU budget of a
0186  *   thread.
0187  */
0188 typedef struct {
0189   /**
0190    * @brief This operation is called at each clock tick for the executing
0191    *   thread.
0192    */
0193   void ( *at_tick )( Thread_Control * );
0194 
0195   /**
0196    * @brief This operation is called right before a context switch to the
0197    *   thread is performed.
0198    */
0199   void ( *at_context_switch )( Thread_Control * );
0200 
0201   /**
0202    * @brief This operation is called to initialize the CPU budget of the
0203    *   thread.
0204    */
0205   void ( *initialize )( Thread_Control * );
0206 } Thread_CPU_budget_operations;
0207 
0208 /**
0209  * @brief This structure is used to control the CPU budget of a thread.
0210  */
0211 typedef struct {
0212   /**
0213    * @brief If this member is not NULL, then it references the CPU budget
0214    *   operations used to manage the CPU budget of the thread, otherwise it is
0215    *   NULL.
0216    */
0217   const Thread_CPU_budget_operations *operations;
0218 
0219   /**
0220    * @brief This member contains the count of the time quantum that this thread
0221    *   is allowed to consume until an action takes place defined by the CPU
0222    *   budget operations.
0223    */
0224   uint32_t available;
0225 } Thread_CPU_budget_control;
0226 
0227 /**
0228  *  The following structure contains the information which defines
0229  *  the starting state of a thread.
0230  */
0231 typedef struct {
0232   /** This field contains the thread entry information. */
0233   Thread_Entry_information             Entry;
0234   /*-------------- initial execution modes ----------------- */
0235   /** This field indicates whether the thread was preemptible when
0236     * it started.
0237     */
0238   bool                                 is_preemptible;
0239 
0240   /**
0241    * @brief This member may provide the CPU budget operations activated when a
0242    *   thread is initialized before it is started or restarted.
0243    */
0244   const Thread_CPU_budget_operations *cpu_budget_operations;
0245 
0246   /** This field is the initial ISR disable level of this thread. */
0247   uint32_t                             isr_level;
0248   /** This field is the initial priority. */
0249   Priority_Control                     initial_priority;
0250   /**
0251    * @brief This field points to the handler which should free the stack.
0252    */
0253   void                              ( *stack_free )( void * );
0254   /** This field is the stack information. */
0255   Stack_Control                        Initial_stack;
0256   #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
0257     /** This field is the initial FP context area address. */
0258     Context_Control_fp                  *fp_context;
0259   #endif
0260   /** The thread-local storage (TLS) area */
0261   void                                *tls_area;
0262 } Thread_Start_information;
0263 
0264 #if defined(RTEMS_SMP)
0265 /**
0266  * @brief The thread state with respect to the scheduler.
0267  */
0268 typedef enum {
0269   /**
0270    * @brief This thread is blocked with respect to the scheduler.
0271    *
0272    * This thread uses no scheduler nodes.
0273    */
0274   THREAD_SCHEDULER_BLOCKED,
0275 
0276   /**
0277    * @brief This thread is scheduled with respect to the scheduler.
0278    *
0279    * This thread executes using one of its scheduler nodes.  This could be its
0280    * own scheduler node or in case it owns resources taking part in the
0281    * scheduler helping protocol a scheduler node of another thread.
0282    */
0283   THREAD_SCHEDULER_SCHEDULED,
0284 
0285   /**
0286    * @brief This thread is ready with respect to the scheduler.
0287    *
0288    * None of the scheduler nodes of this thread is scheduled.
0289    */
0290   THREAD_SCHEDULER_READY
0291 } Thread_Scheduler_state;
0292 #endif
0293 
0294 /**
0295  * @brief Thread scheduler control.
0296  */
0297 typedef struct {
0298 #if defined(RTEMS_SMP)
0299   /**
0300    * @brief Lock to protect the scheduler node change requests.
0301    */
0302   ISR_lock_Control Lock;
0303 
0304   /**
0305    * @brief The current scheduler state of this thread.
0306    */
0307   Thread_Scheduler_state state;
0308 
0309   /**
0310    * @brief The home scheduler of this thread.
0311    */
0312   const struct _Scheduler_Control *home_scheduler;
0313 
0314   /**
0315    * @brief The pinned scheduler of this thread.
0316    */
0317   const struct _Scheduler_Control *pinned_scheduler;
0318 
0319   /**
0320    * @brief The processor assigned by the current scheduler.
0321    */
0322   struct Per_CPU_Control *cpu;
0323 
0324   /**
0325    * @brief Scheduler nodes immediately available to the thread by its home
0326    * scheduler and due to thread queue ownerships.
0327    *
0328    * This chain is protected by the thread wait lock.
0329    *
0330    * This chain is never empty.  The first scheduler node on the chain is the
0331    * scheduler node of the home scheduler.
0332    */
0333   Chain_Control Wait_nodes;
0334 
0335   /**
0336    * @brief Scheduler nodes immediately available to the schedulers for this
0337    * thread.
0338    *
0339    * This chain is protected by the thread state lock.
0340    *
0341    * This chain is never empty for normal threads (the only exception are idle
0342    * threads associated with an online processor which is not used by a
0343    * scheduler).  In case a pinned scheduler is set for this thread, then the
0344    * first scheduler node of this chain belongs to the pinned scheduler,
0345    * otherwise the first scheduler node of this chain belongs to the home
0346    * scheduler.
0347    */
0348   Chain_Control Scheduler_nodes;
0349 
0350   /**
0351    * @brief If an ask for help request for the thread is pending, then this
0352    *   member references the processor on which the ask for help request is
0353    *   registered, otherwise it is NULL.
0354    *
0355    * Depending on the state of the thread and usage context, this member is
0356    * protected by the Per_CPU_Control::Lock lock of the referenced processor,
0357    * the scheduler lock of the thread (Thread_Scheduler_control::Lock), or the
0358    * thread state lock.
0359    */
0360   struct Per_CPU_Control *ask_for_help_cpu;
0361 
0362   /**
0363    * @brief This member is the node for the
0364    *   Per_CPU_Control::Threads_in_need_for_help chain.
0365    *
0366    * This chain is protected by the Per_CPU_Control::Lock lock of the processor
0367    * on which the ask for help request is registered
0368    * (Thread_Scheduler_control::ask_for_help_cpu).
0369    */
0370   Chain_Node Help_node;
0371 
0372   /**
0373    * @brief Count of nodes scheduler nodes minus one.
0374    *
0375    * This chain is protected by the thread state lock.
0376    */
0377   size_t helping_nodes;
0378 
0379   /**
0380    * @brief List of pending scheduler node requests.
0381    *
0382    * This list is protected by the thread scheduler lock.
0383    */
0384   Scheduler_Node *requests;
0385 
0386   /**
0387    * @brief The thread pinning to current processor level.
0388    *
0389    * Must be touched only by the executing thread with thread dispatching
0390    * disabled.  If non-zero, then the thread is pinned to its current
0391    * processor.  The pin level is incremented and decremented by two.  The
0392    * least-significant bit indicates that the thread was pre-empted and must
0393    * undo the pinning with respect to the scheduler once the level changes from
0394    * three to one.
0395    *
0396    * The thread pinning may be used to access per-processor data structures in
0397    * critical sections with enabled thread dispatching, e.g. a pinned thread is
0398    * allowed to block.
0399    *
0400    * Thread pinning should be used only for short critical sections and not all
0401    * the time.  Thread pinning is a very low overhead operation in case the
0402    * thread is not preempted during the pinning.
0403    *
0404    * @see _Thread_Pin() and _Thread_Unpin().
0405    */
0406   int pin_level;
0407 
0408   /**
0409    * @brief The thread processor affinity set.
0410    */
0411   Processor_mask Affinity;
0412 #endif
0413 
0414   /**
0415    * @brief The scheduler nodes of this thread.
0416    *
0417    * Each thread has a scheduler node for each scheduler instance.
0418    */
0419   Scheduler_Node *nodes;
0420 } Thread_Scheduler_control;
0421 
0422 /**
0423  *  @brief Union type to hold a pointer to an immutable or a mutable object.
0424  *
0425  *  The main purpose is to enable passing of pointers to read-only send buffers
0426  *  in the message passing subsystem.  This approach is somewhat fragile since
0427  *  it prevents the compiler to check if the operations on objects are valid
0428  *  with respect to the constant qualifier.  An alternative would be to add a
0429  *  third pointer argument for immutable objects, but this would increase the
0430  *  structure size.
0431  */
0432 typedef union {
0433   void       *mutable_object;
0434   const void *immutable_object;
0435 } Thread_Wait_information_Object_argument_type;
0436 
0437 /**
0438  * @brief This type is able to contain several flags used to control the wait
0439  * class and state of a thread.
0440  *
0441  * The mutually exclusive wait class flags are
0442  * - @ref THREAD_WAIT_CLASS_EVENT,
0443  * - @ref THREAD_WAIT_CLASS_SYSTEM_EVENT, and
0444  * - @ref THREAD_WAIT_CLASS_OBJECT.
0445  *
0446  * The mutually exclusive wait state flags are
0447  * - @ref THREAD_WAIT_STATE_INTEND_TO_BLOCK,
0448  * - @ref THREAD_WAIT_STATE_BLOCKED, and
0449  * - @ref THREAD_WAIT_STATE_READY.
0450  */
0451 typedef unsigned int Thread_Wait_flags;
0452 
0453 /**
0454  *  @brief Information required to manage a thread while it is blocked.
0455  *
0456  *  This contains the information required to manage a thread while it is
0457  *  blocked and to return information to it.
0458  */
0459 typedef struct {
0460 #if defined(RTEMS_MULTIPROCESSING)
0461   /*
0462    * @brief This field is the identifier of the remote object this thread is
0463    * waiting upon.
0464    */
0465   Objects_Id            remote_id;
0466 #endif
0467   /** This field is used to return an integer while when blocked. */
0468   uint32_t              count;
0469   /** This field is for a pointer to a user return argument. */
0470   void                 *return_argument;
0471   /** This field is for a pointer to a second user return argument. */
0472   Thread_Wait_information_Object_argument_type
0473                         return_argument_second;
0474   /** This field contains any options in effect on this blocking operation. */
0475   uint32_t              option;
0476   /** This field will contain the return status from a blocking operation.
0477    *
0478    *  @note The following assumes that all API return codes can be
0479    *        treated as an uint32_t.
0480    */
0481   uint32_t              return_code;
0482 
0483   /**
0484    * @brief This field contains several flags used to control the wait class
0485    * and state of a thread in case fine-grained locking is used.
0486    */
0487 #if defined(RTEMS_SMP)
0488   Atomic_Uint           flags;
0489 #else
0490   Thread_Wait_flags     flags;
0491 #endif
0492 
0493 #if defined(RTEMS_SMP)
0494   /**
0495    * @brief Thread wait lock control block.
0496    *
0497    * Parts of the thread wait information are protected by the thread wait
0498    * default lock and additionally a thread queue lock in case the thread
0499    * is enqueued on a thread queue.
0500    *
0501    * The thread wait lock mechanism protects the following thread variables
0502    *  - POSIX_API_Control::Attributes,
0503    *  - Scheduler_Node::Wait,
0504    *  - Thread_Control::Wait::Lock::Pending_requests,
0505    *  - Thread_Control::Wait::queue, and
0506    *  - Thread_Control::Wait::operations.
0507    *
0508    * @see _Thread_Wait_acquire(), _Thread_Wait_release(), _Thread_Wait_claim(),
0509    *   _Thread_Wait_restore_default() and _Thread_Wait_tranquilize().
0510    */
0511   struct {
0512     /**
0513      * @brief Thread wait default lock.
0514      */
0515     ISR_lock_Control Default;
0516 
0517     /**
0518      * @brief The pending thread wait lock acquire or tranquilize requests in
0519      * case the thread is enqueued on a thread queue.
0520      */
0521     Chain_Control Pending_requests;
0522 
0523     /**
0524      * @brief Tranquilizer gate used by _Thread_Wait_tranquilize().
0525      *
0526      * This gate is closed by _Thread_Wait_claim().  In case there are no
0527      * pending requests during a _Thread_Wait_restore_default(), then this gate
0528      * is opened immediately, otherwise it is placed on the pending request
0529      * chain and opened by _Thread_Wait_remove_request_locked() as the last
0530      * gate on the chain to signal overall request completion.
0531      */
0532     Thread_queue_Gate Tranquilizer;
0533   } Lock;
0534 
0535   /**
0536    * @brief Thread queue link provided for use by the thread wait lock owner to
0537    * build a thread queue path.
0538    */
0539   Thread_queue_Link Link;
0540 #endif
0541 
0542   /**
0543    * @brief The current thread queue.
0544    *
0545    * If this field is NULL the thread is not enqueued on a thread queue.  This
0546    * field is protected by the thread wait default lock.
0547    *
0548    * @see _Thread_Wait_claim().
0549    */
0550   Thread_queue_Queue *queue;
0551 
0552   /**
0553    * @brief The current thread queue operations.
0554    *
0555    * This field is protected by the thread lock wait default lock.
0556    *
0557    * @see _Thread_Wait_claim().
0558    */
0559   const Thread_queue_Operations *operations;
0560 
0561   Thread_queue_Heads *spare_heads;
0562 }   Thread_Wait_information;
0563 
0564 /**
0565  * @brief Information required to manage a thread timer.
0566  */
0567 typedef struct {
0568 #if ISR_LOCK_NEEDS_OBJECT
0569   ISR_lock_Control Lock;
0570 #endif
0571   Watchdog_Header *header;
0572   Watchdog_Control Watchdog;
0573 } Thread_Timer_information;
0574 
0575 /**
0576  *  The following defines the control block used to manage
0577  *  each thread proxy.
0578  *
0579  *  @note It is critical that proxies and threads have identical
0580  *        memory images for the shared part.
0581  */
0582 typedef struct {
0583   /** This field is the object management structure for each proxy. */
0584   Objects_Control          Object;
0585 
0586   /**
0587    * @see Thread_Control::Join_queue
0588    */
0589   Thread_queue_Control     Join_queue;
0590 
0591   /** This field is the current execution state of this proxy. */
0592   States_Control           current_state;
0593 
0594   /**
0595    * @brief The base priority of this thread in its home scheduler instance.
0596    */
0597   Priority_Node            Real_priority;
0598 
0599 #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
0600   /** This field is the number of mutexes currently held by this proxy. */
0601   uint32_t                 resource_count;
0602 #endif
0603 
0604   /**
0605    * @brief Scheduler related control.
0606    */
0607   Thread_Scheduler_control Scheduler;
0608 
0609   /** This field is the blocking information for this proxy. */
0610   Thread_Wait_information  Wait;
0611   /** This field is the Watchdog used to manage proxy delays and timeouts. */
0612   Thread_Timer_information Timer;
0613 #if defined(RTEMS_MULTIPROCESSING)
0614   /** This field is the received response packet in an MP system. */
0615   MP_packet_Prefix        *receive_packet;
0616      /****************** end of common block ********************/
0617 
0618   /**
0619    * @brief Thread queue callout for _Thread_queue_Enqueue().
0620    */
0621   Thread_queue_MP_callout  thread_queue_callout;
0622 
0623   /**
0624    * @brief This field is used to manage the set of active proxies in the system.
0625    */
0626   RBTree_Node              Active;
0627 
0628   /**
0629    * @brief The scheduler node providing the thread wait nodes used to enqueue
0630    * this thread proxy on a thread queue.
0631    */
0632   Scheduler_Node           Scheduler_node;
0633 
0634   /**
0635    * @brief Provide thread queue heads for this thread proxy.
0636    *
0637    * The actual size of the thread queue heads depends on the application
0638    * configuration.  Since thread proxies are never destroyed we can use the
0639    * same storage place for the thread queue heads.
0640    */
0641   Thread_queue_Heads       Thread_queue_heads[ RTEMS_ZERO_LENGTH_ARRAY ];
0642 #endif
0643 }   Thread_Proxy_control;
0644 
0645 /**
0646  *  The following record defines the control block used
0647  *  to manage each thread.
0648  *
0649  *  @note It is critical that proxies and threads have identical
0650  *        memory images for the shared part.
0651  */
0652 typedef enum {
0653   /** This value is for the Classic RTEMS API. */
0654   THREAD_API_RTEMS,
0655   /** This value is for the POSIX API. */
0656   THREAD_API_POSIX
0657 }  Thread_APIs;
0658 
0659 /** This macro defines the first API which has threads. */
0660 #define THREAD_API_FIRST THREAD_API_RTEMS
0661 
0662 /** This macro defines the last API which has threads. */
0663 #define THREAD_API_LAST  THREAD_API_POSIX
0664 
0665 typedef struct Thread_Action Thread_Action;
0666 
0667 /**
0668  * @brief This type defines the prototype of thread action handlers.
0669  *
0670  * The thread action handler will be called with interrupts disabled and a
0671  * corresponding lock acquired, e.g. _Thread_State_acquire().  The handler may
0672  * release the corresponding lock, e.g. _Thread_State_release().  If the lock
0673  * is released, it shall be acquired before the handler returns using the lock
0674  * context.  The lock may be used to protect private data used by the action.
0675  *
0676  * Since the action is passed to the handler additional data may be accessed
0677  * via RTEMS_CONTAINER_OF().
0678  *
0679  * @param[in, out] the_thread is the thread performing the action.
0680  *
0681  * @param[in, out] action is the thread action.
0682  *
0683  * @param[in, out] lock_context is the lock context to use for the optional
0684  *   lock release and acquire.
0685  */
0686 typedef void ( *Thread_Action_handler )(
0687   Thread_Control   *the_thread,
0688   Thread_Action    *action,
0689   ISR_lock_Context *lock_context
0690 );
0691 
0692 /**
0693  * @brief Thread action.
0694  *
0695  * Thread actions can be chained together to trigger a set of actions on
0696  * particular events like for example a thread post-switch.  Use
0697  * _Thread_Action_initialize() to initialize this structure.
0698  *
0699  * Thread actions are the building block for efficient implementation of
0700  * - Classic signals delivery,
0701  * - POSIX signals delivery, and
0702  * - thread life-cycle changes.
0703  *
0704  * @see _Thread_Add_post_switch_action() and _Thread_Run_post_switch_actions().
0705  */
0706 struct Thread_Action {
0707   Chain_Node            Node;
0708   Thread_Action_handler handler;
0709 };
0710 
0711 /**
0712  * @brief Per-thread information for POSIX Keys.
0713  */
0714 typedef struct {
0715   /**
0716    * @brief Key value pairs registered for this thread.
0717    */
0718   RBTree_Control Key_value_pairs;
0719 
0720 #if defined(RTEMS_SMP)
0721   /**
0722    * @brief Lock to protect the tree operations.
0723    */
0724   ISR_lock_Control Lock;
0725 #endif
0726 } Thread_Keys_information;
0727 
0728 /**
0729  * @brief Control block to manage thread actions.
0730  *
0731  * Use _Thread_Action_control_initialize() to initialize this structure.
0732  */
0733 typedef struct {
0734   Chain_Control Chain;
0735 } Thread_Action_control;
0736 
0737 /**
0738  * @brief This type represents the thread life state.
0739  *
0740  * The thread life state is orthogonal to the thread state used for
0741  * synchronization primitives and blocking operations.  The thread life state
0742  * reflects changes triggered by thread restart and delete requests.
0743  *
0744  * The individual state flags must be a power of two to allow use of bit
0745  * operations to manipulate and evaluate the thread life state.
0746  */
0747 typedef unsigned int Thread_Life_state;
0748 
0749 /**
0750  * @brief Indicates that the thread life is protected.
0751  *
0752  * If this flag is set, then the thread restart or delete requests are deferred
0753  * until the protection and deferred change flags are cleared.  It is used by
0754  * _Thread_Set_life_protection().
0755  */
0756 #define THREAD_LIFE_PROTECTED 0x1U
0757 
0758 /**
0759  * @brief Indicates that thread is restarting.
0760  *
0761  * If this flag is set, then a thread restart request is in pending. See
0762  * _Thread_Restart_self() and _Thread_Restart_other().
0763  */
0764 #define THREAD_LIFE_RESTARTING 0x2U
0765 
0766 /**
0767  * @brief Indicates that thread is terminating.
0768  *
0769  * If this flag is set, then a thread termination request is in pending.  See
0770  * _Thread_Exit() and _Thread_Cancel().
0771  */
0772 #define THREAD_LIFE_TERMINATING 0x4U
0773 
0774 /**
0775  * @brief Indicates that thread life changes are deferred.
0776  *
0777  * If this flag is set, then the thread restart or delete requests are deferred
0778  * until the protection and deferred change flags are cleared.  It is used by
0779  * pthread_setcanceltype().
0780  */
0781 #define THREAD_LIFE_CHANGE_DEFERRED 0x8U
0782 
0783 /**
0784  * @brief Indicates that thread is detached.
0785  *
0786  * If this flag is set, then the thread is detached.  Detached threads do not
0787  * wait during termination for other threads to join.  See rtems_task_delete(),
0788  * rtems_task_exit(), and pthread_detach().
0789  */
0790 #define THREAD_LIFE_DETACHED 0x10U
0791 
0792 /**
0793  * @brief Thread life control.
0794  */
0795 typedef struct {
0796   /**
0797    * @brief Thread life action used to react upon thread restart and delete
0798    * requests.
0799    */
0800   Thread_Action      Action;
0801 
0802   /**
0803    * @brief The current thread life state.
0804    */
0805   Thread_Life_state  state;
0806 
0807   /**
0808    * @brief The count of pending life change requests.
0809    */
0810   uint32_t pending_life_change_requests;
0811 
0812   /**
0813    * @brief The thread exit value.
0814    *
0815    * It is,
0816    * - the value passed to pthread_exit(), or
0817    * - PTHREAD_CANCELED in case it is cancelled via pthread_cancel(), or
0818    * - NULL.
0819    */
0820   void *exit_value;
0821 } Thread_Life_control;
0822 
0823 typedef struct  {
0824   uint32_t      flags;
0825   void *        control;
0826 }Thread_Capture_control;
0827 
0828 /**
0829  *  This structure defines the Thread Control Block (TCB).
0830  *
0831  *  Uses a leading underscore in the structure name to allow forward
0832  *  declarations in standard header files provided by Newlib and GCC.
0833  *
0834  *  In case the second member changes (currently Join_queue), then the memset()
0835  *  in _Thread_Initialize() must be adjusted.
0836  */
0837 struct _Thread_Control {
0838   /** This field is the object management structure for each thread. */
0839   Objects_Control          Object;
0840 
0841   /**
0842    * @brief Thread queue for thread join operations and multi-purpose lock.
0843    *
0844    * The lock of this thread queue is used for various purposes.  It protects
0845    * the following fields
0846    *
0847    * - RTEMS_API_Control::Signal,
0848    * - Thread_Control::CPU_budget,
0849    * - Thread_Control::current_state,
0850    * - Thread_Control::Post_switch_actions,
0851    * - Thread_Control::Scheduler::control, and
0852    * - Thread_Control::Scheduler::own_control.
0853    *
0854    * @see _Thread_State_acquire().
0855    */
0856   Thread_queue_Control     Join_queue;
0857 
0858   /** This field is the current execution state of this thread. */
0859   States_Control           current_state;
0860 
0861   /**
0862    * @brief The base priority of this thread in its home scheduler instance.
0863    */
0864   Priority_Node            Real_priority;
0865 
0866 #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
0867   /** This field is the number of mutexes currently held by this thread. */
0868   uint32_t                 resource_count;
0869 #endif
0870 
0871   /**
0872    * @brief Scheduler related control.
0873    */
0874   Thread_Scheduler_control Scheduler;
0875 
0876   /** This field is the blocking information for this thread. */
0877   Thread_Wait_information  Wait;
0878   /** This field is the Watchdog used to manage thread delays and timeouts. */
0879   Thread_Timer_information Timer;
0880 #if defined(RTEMS_MULTIPROCESSING)
0881   /** This field is the received response packet in an MP system. */
0882   MP_packet_Prefix        *receive_packet;
0883 #endif
0884      /*================= end of common block =================*/
0885 
0886   /**
0887    * @brief This member contains the context of this thread.
0888    *
0889    * This member is placed directly after the end of the common block so that
0890    * the structure offsets are as small as possible.  This helps on instruction
0891    * set architectures with a very limited range for intermediate values.
0892    */
0893   Context_Control Registers;
0894 
0895 #if defined(RTEMS_SMP) && defined(RTEMS_PROFILING)
0896   /**
0897    * @brief Potpourri lock statistics.
0898    *
0899    * These SMP lock statistics are used for all lock objects that lack a
0900    * storage space for the statistics.  Examples are lock objects used in
0901    * external libraries which are independent of the actual RTEMS build
0902    * configuration.
0903    */
0904   SMP_lock_Stats Potpourri_stats;
0905 #endif
0906 
0907   /** This field is true if the thread is an idle thread. */
0908   bool                                  is_idle;
0909 #if defined(RTEMS_MULTIPROCESSING)
0910   /** This field is true if the thread is offered globally */
0911   bool                                  is_global;
0912 #endif
0913   /** This field is true if the thread is preemptible. */
0914   bool                                  is_preemptible;
0915   /** This field is true if the thread uses the floating point unit. */
0916   bool                                  is_fp;
0917 
0918   /**
0919    * @brief True, if the thread was created with an inherited scheduler
0920    * (PTHREAD_INHERIT_SCHED), and false otherwise.
0921    */
0922   bool was_created_with_inherited_scheduler;
0923 
0924 #if defined(RTEMS_SCORE_THREAD_HAS_SCHEDULER_CHANGE_INHIBITORS)
0925   /**
0926    * @brief This field is true, if scheduler changes are inhibited.
0927    *
0928    * Currently, the POSIX sporadic server is the only inhibitor.  If more are
0929    * added, then this needs to be changed to a counter or a bit field.
0930    */
0931   bool is_scheduler_change_inhibited;
0932 #endif
0933 
0934   /**
0935    * @brief This member contains the CPU budget control used to manage the CPU
0936    *   budget of the thread.
0937    */
0938   Thread_CPU_budget_control CPU_budget;
0939 
0940   /**
0941    * @brief This member contains the amount of CPU time consumed by this thread
0942    *   since it was created.
0943    */
0944   Timestamp_Control cpu_time_used;
0945 
0946   /**
0947    * @brief This member contains the amount of CPU time consumed by this thread
0948    *   at the time of the last reset of the CPU usage by
0949    *   rtems_cpu_usage_reset().
0950    */
0951   Timestamp_Control cpu_time_used_at_last_reset;
0952 
0953   /** This field contains information about the starting state of
0954    *  this thread.
0955    */
0956   Thread_Start_information              Start;
0957 
0958   Thread_Action_control                 Post_switch_actions;
0959 
0960 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
0961   /** This field points to the floating point context for this thread.
0962    *  If NULL, the thread is integer only.
0963    */
0964   Context_Control_fp                   *fp_context;
0965 #endif
0966 
0967 #ifndef _REENT_THREAD_LOCAL
0968   /** This field points to the newlib reentrancy structure for this thread. */
0969   struct _reent                        *libc_reent;
0970 #endif
0971 
0972   /** This array contains the API extension area pointers. */
0973   void                                 *API_Extensions[ THREAD_API_LAST + 1 ];
0974 
0975   /**
0976    * @brief The POSIX Keys information.
0977    */
0978   Thread_Keys_information               Keys;
0979 
0980   /**
0981    * @brief Thread life-cycle control.
0982    *
0983    * Control state changes triggered by thread restart and delete requests.
0984    */
0985   Thread_Life_control                   Life;
0986 
0987   Thread_Capture_control                Capture;
0988 
0989   /**
0990    * @brief Pointer to an optional thread-specific POSIX user environment.
0991    */
0992   struct rtems_user_env_t *user_environment;
0993 
0994   /**
0995    * @brief LIFO list of POSIX cleanup contexts.
0996    */
0997   struct _pthread_cleanup_context *last_cleanup_context;
0998 
0999   /**
1000    * @brief LIFO list of user extensions iterators.
1001    */
1002   struct User_extensions_Iterator *last_user_extensions_iterator;
1003 
1004   /**
1005    * @brief Variable length array of user extension pointers.
1006    *
1007    * The length is defined by the application via <rtems/confdefs.h>.
1008    */
1009   void                                 *extensions[ RTEMS_ZERO_LENGTH_ARRAY ];
1010 };
1011 
1012 typedef void (*rtems_per_thread_routine)( Thread_Control * );
1013 
1014 /**
1015  * @brief Deprecated, use rtems_task_iterate() instead.
1016  *
1017  * Use rtems_task_iterate() instead.
1018  */
1019 void rtems_iterate_over_all_threads(
1020   rtems_per_thread_routine routine
1021 ) RTEMS_DEPRECATED;
1022 
1023 /**
1024  * @brief Thread control add-on.
1025  */
1026 typedef struct {
1027   /**
1028    * @brief Offset of the pointer field in Thread_Control referencing an
1029    * application configuration dependent memory area in the thread control
1030    * block.
1031    */
1032   size_t destination_offset;
1033 
1034   /**
1035    * @brief Offset relative to the thread control block begin to an application
1036    * configuration dependent memory area.
1037    */
1038   size_t source_offset;
1039 } Thread_Control_add_on;
1040 
1041 /**
1042  * @brief Thread control add-ons.
1043  *
1044  * The thread control block contains fields that point to application
1045  * configuration dependent memory areas, like the scheduler information, the
1046  * API control blocks, the user extension context table, and the Newlib
1047  * re-entrancy support.  Account for these areas in the configuration and
1048  * avoid extra workspace allocations for these areas.
1049  *
1050  * This array is provided via <rtems/confdefs.h>.
1051  *
1052  * @see _Thread_Control_add_on_count.
1053  */
1054 extern const Thread_Control_add_on _Thread_Control_add_ons[];
1055 
1056 /**
1057  * @brief Thread control add-on count.
1058  *
1059  * Count of entries in _Thread_Control_add_ons.
1060  *
1061  * This value is provided via <rtems/confdefs.h>.
1062  */
1063 extern const size_t _Thread_Control_add_on_count;
1064 
1065 /**
1066  * @brief Count of configured threads.
1067  *
1068  * This value is provided via <rtems/confdefs.h>.
1069  */
1070 extern const size_t _Thread_Initial_thread_count;
1071 
1072 /**
1073  * @brief The default maximum size of a thread name in characters (including
1074  * the terminating '\0' character).
1075  *
1076  * This is the default value for the application configuration option
1077  * CONFIGURE_MAXIMUM_THREAD_NAME_SIZE.
1078  */
1079 #define THREAD_DEFAULT_MAXIMUM_NAME_SIZE 16
1080 
1081 /**
1082  * @brief Maximum size of a thread name in characters (including the
1083  * terminating '\0' character).
1084  *
1085  * This value is provided via <rtems/confdefs.h>.
1086  */
1087 extern const size_t _Thread_Maximum_name_size;
1088 
1089 /**
1090  * @brief If this constant is greater than zero, then it defines the maximum
1091  * thread-local storage size, otherwise the thread-local storage size is defined
1092  * by the linker depending on the thread-local storage objects used by the
1093  * application in the statically-linked executable.
1094  *
1095  * This value is provided via <rtems/confdefs.h>.
1096  */
1097 extern const size_t _Thread_Maximum_TLS_size;
1098 
1099 /**
1100  * @brief The configured thread control block.
1101  *
1102  * This type is defined in <rtems/confdefs.h> and depends on the application
1103  * configuration.
1104  */
1105 typedef struct Thread_Configured_control Thread_Configured_control;
1106 
1107 /**
1108  * @brief The configured thread queue heads.
1109  *
1110  * In SMP configurations, this type is defined in <rtems/confdefs.h> and depends
1111  * on the application configuration.
1112  */
1113 #if defined(RTEMS_SMP)
1114 typedef struct Thread_queue_Configured_heads Thread_queue_Configured_heads;
1115 #else
1116 typedef Thread_queue_Heads Thread_queue_Configured_heads;
1117 #endif
1118 
1119 /**
1120  * @brief Size of the thread queue heads of a particular application.
1121  *
1122  * In SMP configurations, this value is provided via <rtems/confdefs.h>.
1123  */
1124 #if defined(RTEMS_SMP)
1125 extern const size_t _Thread_queue_Heads_size;
1126 #else
1127 #define _Thread_queue_Heads_size sizeof(Thread_queue_Heads)
1128 #endif
1129 
1130 /**
1131  * @brief The thread object information.
1132  */
1133 typedef struct {
1134   /**
1135    * @brief The object information.
1136    */
1137   Objects_Information Objects;
1138 
1139   /**
1140    * @brief Thread queue heads maintenance.
1141    */
1142   union {
1143     /**
1144      * @brief Contains the initial set of thread queue heads.
1145      *
1146      * This is set by <rtems/confdefs.h> via THREAD_INFORMATION_DEFINE().
1147      */
1148     Thread_queue_Configured_heads *initial;
1149 
1150     /**
1151      * @brief The free thread queue heads.
1152      *
1153      * This member is initialized by _Thread_Initialize_information().
1154      */
1155     Freechain_Control Free;
1156   } Thread_queue_heads;
1157 } Thread_Information;
1158 
1159 /**
1160  * @brief The internal thread  objects information.
1161  */
1162 extern Thread_Information _Thread_Information;
1163 
1164 #define THREAD_INFORMATION_DEFINE_ZERO( name, api, cls ) \
1165 Thread_Information name##_Information = { \
1166   { \
1167     _Objects_Build_id( api, cls, 1, 0 ), \
1168     NULL, \
1169     _Objects_Allocate_none, \
1170     NULL, \
1171     0, \
1172     0, \
1173     0, \
1174     0, \
1175     CHAIN_INITIALIZER_EMPTY( name##_Information.Objects.Inactive ), \
1176     NULL, \
1177     NULL, \
1178     NULL \
1179     OBJECTS_INFORMATION_MP( name##_Information.Objects, NULL ), \
1180   }, { \
1181     NULL \
1182   } \
1183 }
1184 
1185 /**
1186  * @brief Return an inactive thread object or NULL.
1187  *
1188  * @retval NULL No inactive object is available.
1189  * @retval object An inactive object.
1190  */
1191 Objects_Control *_Thread_Allocate_unlimited( Objects_Information *information );
1192 
1193 #define THREAD_INFORMATION_DEFINE( name, api, cls, max ) \
1194 static Objects_Control * \
1195 name##_Local_table[ _Objects_Maximum_per_allocation( max ) ]; \
1196 static RTEMS_SECTION( ".noinit.rtems.content.objects." #name ) \
1197 Thread_Configured_control \
1198 name##_Objects[ _Objects_Maximum_per_allocation( max ) ]; \
1199 static RTEMS_SECTION( ".noinit.rtems.content.objects." #name ) \
1200 Thread_queue_Configured_heads \
1201 name##_Heads[ _Objects_Maximum_per_allocation( max ) ]; \
1202 Thread_Information name##_Information = { \
1203   { \
1204     _Objects_Build_id( api, cls, 1, _Objects_Maximum_per_allocation( max ) ), \
1205     name##_Local_table, \
1206     _Objects_Is_unlimited( max ) ? \
1207       _Thread_Allocate_unlimited : _Objects_Allocate_static, \
1208     _Objects_Is_unlimited( max ) ? \
1209       _Objects_Free_unlimited : _Objects_Free_static, \
1210     0, \
1211     _Objects_Is_unlimited( max ) ? _Objects_Maximum_per_allocation( max ) : 0, \
1212     sizeof( Thread_Configured_control ), \
1213     OBJECTS_NO_STRING_NAME, \
1214     CHAIN_INITIALIZER_EMPTY( name##_Information.Objects.Inactive ), \
1215     NULL, \
1216     NULL, \
1217     &name##_Objects[ 0 ].Control.Object \
1218     OBJECTS_INFORMATION_MP( name##_Information.Objects, NULL ) \
1219   }, { \
1220     &name##_Heads[ 0 ] \
1221   } \
1222 }
1223 
1224 #if defined(RTEMS_MULTIPROCESSING)
1225 /**
1226  * @brief The configured thread control block.
1227  *
1228  * This type is defined in <rtems/confdefs.h> and depends on the application
1229  * configuration.
1230  */
1231 typedef struct Thread_Configured_proxy_control Thread_Configured_proxy_control;
1232 
1233 /**
1234  * @brief The configured proxies.
1235  *
1236  * Provided by the application via <rtems/confdefs.h>.
1237  */
1238 extern Thread_Configured_proxy_control * const _Thread_MP_Proxies;
1239 #endif
1240 
1241 /** @} */
1242 
1243 #ifdef __cplusplus
1244 }
1245 #endif
1246 
1247 #endif
1248 /* end of include file */