![]() |
|
|||
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 */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |