[20f02c6] | 1 | /** |
---|
[5bb6ac9] | 2 | * @file |
---|
[ac7d5ef0] | 3 | * |
---|
[5bb6ac9] | 4 | * @ingroup RTEMSScoreThread |
---|
[319cb20] | 5 | * |
---|
[5bb6ac9] | 6 | * @brief Constants and Structures Related with the Thread Control Block |
---|
| 7 | * |
---|
| 8 | * This include file contains all constants and structures associated |
---|
| 9 | * with the thread control block. |
---|
[baff4da] | 10 | */ |
---|
| 11 | |
---|
| 12 | /* |
---|
[e6c87f7] | 13 | * COPYRIGHT (c) 1989-2014. |
---|
[ac7d5ef0] | 14 | * On-Line Applications Research Corporation (OAR). |
---|
| 15 | * |
---|
[1fcac5ad] | 16 | * Copyright (c) 2014, 2016 embedded brains GmbH. |
---|
[1b1be254] | 17 | * |
---|
[98e4ebf5] | 18 | * The license and distribution terms for this file may be |
---|
| 19 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 20 | * http://www.rtems.org/license/LICENSE. |
---|
[ac7d5ef0] | 21 | */ |
---|
| 22 | |
---|
[092f142a] | 23 | #ifndef _RTEMS_SCORE_THREAD_H |
---|
| 24 | #define _RTEMS_SCORE_THREAD_H |
---|
[ac7d5ef0] | 25 | |
---|
[4c8a0ac] | 26 | #include <rtems/score/atomic.h> |
---|
[5618c37a] | 27 | #include <rtems/score/context.h> |
---|
| 28 | #if defined(RTEMS_MULTIPROCESSING) |
---|
| 29 | #include <rtems/score/mppkt.h> |
---|
| 30 | #endif |
---|
[21275b58] | 31 | #include <rtems/score/freechain.h> |
---|
[d3802bb5] | 32 | #include <rtems/score/isrlock.h> |
---|
[a6e7d5e4] | 33 | #include <rtems/score/objectdata.h> |
---|
[5618c37a] | 34 | #include <rtems/score/priority.h> |
---|
[e27421f] | 35 | #include <rtems/score/schedulernode.h> |
---|
[5618c37a] | 36 | #include <rtems/score/stack.h> |
---|
| 37 | #include <rtems/score/states.h> |
---|
[a112364] | 38 | #include <rtems/score/threadq.h> |
---|
[d297c81d] | 39 | #include <rtems/score/timestamp.h> |
---|
[5618c37a] | 40 | #include <rtems/score/watchdog.h> |
---|
| 41 | |
---|
[c5831a3f] | 42 | #if defined(RTEMS_SMP) |
---|
[7851555] | 43 | #include <rtems/score/processormask.h> |
---|
[9db8705] | 44 | #endif |
---|
| 45 | |
---|
[ba74ebde] | 46 | struct rtems_user_env_t; |
---|
| 47 | |
---|
[cef5675] | 48 | struct _pthread_cleanup_context; |
---|
| 49 | |
---|
[bd67d7d2] | 50 | struct Per_CPU_Control; |
---|
| 51 | |
---|
[e460cd00] | 52 | struct _Scheduler_Control; |
---|
[c5831a3f] | 53 | |
---|
[709f38a] | 54 | struct User_extensions_Iterator; |
---|
| 55 | |
---|
[5618c37a] | 56 | #ifdef __cplusplus |
---|
| 57 | extern "C" { |
---|
| 58 | #endif |
---|
| 59 | |
---|
[baff4da] | 60 | /** |
---|
[5bb6ac9] | 61 | * @defgroup RTEMSScoreThread Thread Handler |
---|
| 62 | * |
---|
| 63 | * @ingroup RTEMSScore |
---|
| 64 | * |
---|
| 65 | * @brief Thread Handler |
---|
[baff4da] | 66 | * |
---|
[5bb6ac9] | 67 | * This handler encapsulates functionality related to the management of |
---|
| 68 | * threads. This includes the creation, deletion, and scheduling of threads. |
---|
[d8cd045c] | 69 | * |
---|
[5bb6ac9] | 70 | * The following variables are maintained as part of the per cpu data |
---|
| 71 | * structure. |
---|
[11e8bc5] | 72 | * |
---|
[5bb6ac9] | 73 | * + Idle thread pointer |
---|
| 74 | * + Executing thread pointer |
---|
| 75 | * + Heir thread pointer |
---|
[11e8bc5] | 76 | * |
---|
[5bb6ac9] | 77 | *@{ |
---|
[baff4da] | 78 | */ |
---|
| 79 | |
---|
[54f35888] | 80 | #define RTEMS_SCORE_THREAD_ENABLE_EXHAUST_TIMESLICE |
---|
[442eac69] | 81 | |
---|
[fdc70e2] | 82 | /* |
---|
| 83 | * With the addition of the Constant Block Scheduler (CBS), |
---|
| 84 | * this feature is needed even when POSIX is disabled. |
---|
| 85 | */ |
---|
| 86 | #define RTEMS_SCORE_THREAD_ENABLE_SCHEDULER_CALLOUT |
---|
[442eac69] | 87 | |
---|
[47d2464] | 88 | #if defined(RTEMS_DEBUG) |
---|
| 89 | #define RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT |
---|
| 90 | #endif |
---|
| 91 | |
---|
[ccd5434] | 92 | /* |
---|
| 93 | * Only provided for backward compatiblity to not break application |
---|
| 94 | * configurations. |
---|
[ac7d5ef0] | 95 | */ |
---|
[ccd5434] | 96 | typedef void *Thread RTEMS_DEPRECATED; |
---|
[ac7d5ef0] | 97 | |
---|
[3b14b7ad] | 98 | /** |
---|
| 99 | * @brief Type of the numeric argument of a thread entry function with at |
---|
[20f02c6] | 100 | * least one numeric argument. |
---|
[3b14b7ad] | 101 | * |
---|
| 102 | * This numeric argument type designates an unsigned integer type with the |
---|
| 103 | * property that any valid pointer to void can be converted to this type and |
---|
| 104 | * then converted back to a pointer to void. The result will compare equal to |
---|
| 105 | * the original pointer. |
---|
| 106 | */ |
---|
[46d3c6d8] | 107 | typedef CPU_Uint32ptr Thread_Entry_numeric_type; |
---|
[3b14b7ad] | 108 | |
---|
[baff4da] | 109 | /** |
---|
[ccd5434] | 110 | * @brief Data for idle thread entry. |
---|
[ac7d5ef0] | 111 | */ |
---|
[ccd5434] | 112 | typedef struct { |
---|
| 113 | void *( *entry )( uintptr_t argument ); |
---|
| 114 | } Thread_Entry_idle; |
---|
[0d051533] | 115 | |
---|
[ccd5434] | 116 | /** |
---|
| 117 | * @brief Data for thread entry with one numeric argument and no return value. |
---|
[6a07436] | 118 | */ |
---|
[ccd5434] | 119 | typedef struct { |
---|
| 120 | void ( *entry )( Thread_Entry_numeric_type argument ); |
---|
| 121 | Thread_Entry_numeric_type argument; |
---|
| 122 | } Thread_Entry_numeric; |
---|
[baff4da] | 123 | |
---|
[ccd5434] | 124 | /** |
---|
| 125 | * @brief Data for thread entry with one pointer argument and a pointer return |
---|
| 126 | * value. |
---|
[baff4da] | 127 | */ |
---|
[ccd5434] | 128 | typedef struct { |
---|
| 129 | void *( *entry )( void *argument ); |
---|
| 130 | void *argument; |
---|
| 131 | } Thread_Entry_pointer; |
---|
[baff4da] | 132 | |
---|
[ccd5434] | 133 | /** |
---|
| 134 | * @brief Thread entry information. |
---|
[baff4da] | 135 | */ |
---|
[ccd5434] | 136 | typedef struct { |
---|
| 137 | /** |
---|
| 138 | * @brief Thread entry adaptor. |
---|
| 139 | * |
---|
| 140 | * Calls the corresponding thread entry with the right parameters. |
---|
| 141 | * |
---|
| 142 | * @param executing The executing thread. |
---|
| 143 | */ |
---|
| 144 | void ( *adaptor )( Thread_Control *executing ); |
---|
[baff4da] | 145 | |
---|
[ccd5434] | 146 | /** |
---|
| 147 | * @brief Thread entry data used by the adaptor to call the thread entry |
---|
| 148 | * function with the right parameters. |
---|
| 149 | */ |
---|
| 150 | union { |
---|
| 151 | Thread_Entry_idle Idle; |
---|
| 152 | Thread_Entry_numeric Numeric; |
---|
| 153 | Thread_Entry_pointer Pointer; |
---|
| 154 | } Kinds; |
---|
| 155 | } Thread_Entry_information; |
---|
[ac7d5ef0] | 156 | |
---|
[baff4da] | 157 | /** |
---|
[2f200c7] | 158 | * The following lists the algorithms used to manage the thread cpu budget. |
---|
| 159 | * |
---|
| 160 | * Reset Timeslice: At each context switch, reset the time quantum. |
---|
| 161 | * Exhaust Timeslice: Only reset the quantum once it is consumed. |
---|
| 162 | * Callout: Execute routine when budget is consumed. |
---|
| 163 | */ |
---|
| 164 | typedef enum { |
---|
| 165 | THREAD_CPU_BUDGET_ALGORITHM_NONE, |
---|
| 166 | THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE, |
---|
[442eac69] | 167 | #if defined(RTEMS_SCORE_THREAD_ENABLE_EXHAUST_TIMESLICE) |
---|
| 168 | THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE, |
---|
| 169 | #endif |
---|
| 170 | #if defined(RTEMS_SCORE_THREAD_ENABLE_SCHEDULER_CALLOUT) |
---|
| 171 | THREAD_CPU_BUDGET_ALGORITHM_CALLOUT |
---|
| 172 | #endif |
---|
[2f200c7] | 173 | } Thread_CPU_budget_algorithms; |
---|
| 174 | |
---|
[6a07436] | 175 | /** This defines thes the entry point for the thread specific timeslice |
---|
| 176 | * budget management algorithm. |
---|
[baff4da] | 177 | */ |
---|
[2f200c7] | 178 | typedef void (*Thread_CPU_budget_algorithm_callout )( Thread_Control * ); |
---|
| 179 | |
---|
[baff4da] | 180 | /** |
---|
[ac7d5ef0] | 181 | * The following structure contains the information which defines |
---|
| 182 | * the starting state of a thread. |
---|
| 183 | */ |
---|
| 184 | typedef struct { |
---|
[ccd5434] | 185 | /** This field contains the thread entry information. */ |
---|
| 186 | Thread_Entry_information Entry; |
---|
[6a07436] | 187 | /*-------------- initial execution modes ----------------- */ |
---|
| 188 | /** This field indicates whether the thread was preemptible when |
---|
| 189 | * it started. |
---|
| 190 | */ |
---|
[484a769] | 191 | bool is_preemptible; |
---|
[6a07436] | 192 | /** This field indicates the CPU budget algorith. */ |
---|
[3b14b7ad] | 193 | Thread_CPU_budget_algorithms budget_algorithm; |
---|
[6a07436] | 194 | /** This field is the routine to invoke when the CPU allotment is |
---|
| 195 | * consumed. |
---|
| 196 | */ |
---|
[3b14b7ad] | 197 | Thread_CPU_budget_algorithm_callout budget_callout; |
---|
[6a07436] | 198 | /** This field is the initial ISR disable level of this thread. */ |
---|
[3b14b7ad] | 199 | uint32_t isr_level; |
---|
[6a07436] | 200 | /** This field is the initial priority. */ |
---|
[3b14b7ad] | 201 | Priority_Control initial_priority; |
---|
[0bde56b] | 202 | /** |
---|
| 203 | * @brief This field is a pointer to the allocated stack area, otherwise it |
---|
| 204 | * is NULL. |
---|
| 205 | */ |
---|
| 206 | void *allocated_stack; |
---|
[6a07436] | 207 | /** This field is the stack information. */ |
---|
[3b14b7ad] | 208 | Stack_Control Initial_stack; |
---|
[bacf79e] | 209 | #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
---|
| 210 | /** This field is the initial FP context area address. */ |
---|
| 211 | Context_Control_fp *fp_context; |
---|
| 212 | #endif |
---|
[022851a] | 213 | /** The thread-local storage (TLS) area */ |
---|
| 214 | void *tls_area; |
---|
[3b14b7ad] | 215 | } Thread_Start_information; |
---|
[ac7d5ef0] | 216 | |
---|
[15b5678d] | 217 | #if defined(RTEMS_SMP) |
---|
| 218 | /** |
---|
| 219 | * @brief The thread state with respect to the scheduler. |
---|
| 220 | */ |
---|
| 221 | typedef enum { |
---|
| 222 | /** |
---|
| 223 | * @brief This thread is blocked with respect to the scheduler. |
---|
| 224 | * |
---|
| 225 | * This thread uses no scheduler nodes. |
---|
| 226 | */ |
---|
| 227 | THREAD_SCHEDULER_BLOCKED, |
---|
| 228 | |
---|
| 229 | /** |
---|
| 230 | * @brief This thread is scheduled with respect to the scheduler. |
---|
| 231 | * |
---|
| 232 | * This thread executes using one of its scheduler nodes. This could be its |
---|
| 233 | * own scheduler node or in case it owns resources taking part in the |
---|
| 234 | * scheduler helping protocol a scheduler node of another thread. |
---|
| 235 | */ |
---|
| 236 | THREAD_SCHEDULER_SCHEDULED, |
---|
| 237 | |
---|
| 238 | /** |
---|
| 239 | * @brief This thread is ready with respect to the scheduler. |
---|
| 240 | * |
---|
| 241 | * None of the scheduler nodes of this thread is scheduled. |
---|
| 242 | */ |
---|
| 243 | THREAD_SCHEDULER_READY |
---|
| 244 | } Thread_Scheduler_state; |
---|
| 245 | #endif |
---|
| 246 | |
---|
| 247 | /** |
---|
| 248 | * @brief Thread scheduler control. |
---|
| 249 | */ |
---|
| 250 | typedef struct { |
---|
| 251 | #if defined(RTEMS_SMP) |
---|
[07a32d19] | 252 | /** |
---|
| 253 | * @brief Lock to protect the scheduler node change requests. |
---|
| 254 | */ |
---|
| 255 | ISR_lock_Control Lock; |
---|
| 256 | |
---|
[15b5678d] | 257 | /** |
---|
| 258 | * @brief The current scheduler state of this thread. |
---|
| 259 | */ |
---|
| 260 | Thread_Scheduler_state state; |
---|
| 261 | |
---|
| 262 | /** |
---|
[7097962] | 263 | * @brief The home scheduler of this thread. |
---|
[15b5678d] | 264 | */ |
---|
[7097962] | 265 | const struct _Scheduler_Control *home_scheduler; |
---|
| 266 | |
---|
| 267 | /** |
---|
| 268 | * @brief The pinned scheduler of this thread. |
---|
| 269 | */ |
---|
| 270 | const struct _Scheduler_Control *pinned_scheduler; |
---|
[15b5678d] | 271 | |
---|
| 272 | /** |
---|
| 273 | * @brief The processor assigned by the current scheduler. |
---|
| 274 | */ |
---|
| 275 | struct Per_CPU_Control *cpu; |
---|
[266d383] | 276 | |
---|
| 277 | /** |
---|
| 278 | * @brief Scheduler nodes immediately available to the thread by its home |
---|
[7097962] | 279 | * scheduler and due to thread queue ownerships. |
---|
[266d383] | 280 | * |
---|
| 281 | * This chain is protected by the thread wait lock. |
---|
[c0f1f52] | 282 | * |
---|
| 283 | * This chain is never empty. The first scheduler node on the chain is the |
---|
[7097962] | 284 | * scheduler node of the home scheduler. |
---|
[266d383] | 285 | */ |
---|
| 286 | Chain_Control Wait_nodes; |
---|
[ebdd2a3] | 287 | |
---|
| 288 | /** |
---|
| 289 | * @brief Scheduler nodes immediately available to the schedulers for this |
---|
| 290 | * thread. |
---|
| 291 | * |
---|
| 292 | * This chain is protected by the thread state lock. |
---|
[c0f1f52] | 293 | * |
---|
[7097962] | 294 | * This chain is never empty for normal threads (the only exception are idle |
---|
| 295 | * threads associated with an online processor which is not used by a |
---|
| 296 | * scheduler). In case a pinned scheduler is set for this thread, then the |
---|
| 297 | * first scheduler node of this chain belongs to the pinned scheduler, |
---|
| 298 | * otherwise the first scheduler node of this chain belongs to the home |
---|
| 299 | * scheduler. |
---|
[ebdd2a3] | 300 | */ |
---|
| 301 | Chain_Control Scheduler_nodes; |
---|
| 302 | |
---|
[351c14d] | 303 | /** |
---|
| 304 | * @brief Node for the Per_CPU_Control::Threads_in_need_for_help chain. |
---|
| 305 | * |
---|
| 306 | * This chain is protected by the Per_CPU_Control::Lock lock of the assigned |
---|
| 307 | * processor. |
---|
| 308 | */ |
---|
| 309 | Chain_Node Help_node; |
---|
| 310 | |
---|
| 311 | /** |
---|
| 312 | * @brief Count of nodes scheduler nodes minus one. |
---|
| 313 | * |
---|
| 314 | * This chain is protected by the thread state lock. |
---|
| 315 | */ |
---|
| 316 | size_t helping_nodes; |
---|
| 317 | |
---|
[ebdd2a3] | 318 | /** |
---|
| 319 | * @brief List of pending scheduler node requests. |
---|
| 320 | * |
---|
| 321 | * This list is protected by the thread scheduler lock. |
---|
| 322 | */ |
---|
| 323 | Scheduler_Node *requests; |
---|
[7851555] | 324 | |
---|
[7097962] | 325 | /** |
---|
| 326 | * @brief The thread pinning to current processor level. |
---|
| 327 | * |
---|
| 328 | * Must be touched only by the executing thread with thread dispatching |
---|
| 329 | * disabled. If non-zero, then the thread is pinned to its current |
---|
| 330 | * processor. The pin level is incremented and decremented by two. The |
---|
| 331 | * least-significant bit indicates that the thread was pre-empted and must |
---|
| 332 | * undo the pinning with respect to the scheduler once the level changes from |
---|
| 333 | * three to one. |
---|
| 334 | * |
---|
| 335 | * The thread pinning may be used to access per-processor data structures in |
---|
| 336 | * critical sections with enabled thread dispatching, e.g. a pinned thread is |
---|
| 337 | * allowed to block. |
---|
| 338 | * |
---|
| 339 | * Thread pinning should be used only for short critical sections and not all |
---|
| 340 | * the time. Thread pinning is a very low overhead operation in case the |
---|
| 341 | * thread is not preempted during the pinning. |
---|
| 342 | * |
---|
| 343 | * @see _Thread_Pin() and _Thread_Unpin(). |
---|
| 344 | */ |
---|
| 345 | int pin_level; |
---|
| 346 | |
---|
[7851555] | 347 | /** |
---|
| 348 | * @brief The thread processor affinity set. |
---|
| 349 | */ |
---|
| 350 | Processor_mask Affinity; |
---|
[15b5678d] | 351 | #endif |
---|
[5d6b211] | 352 | |
---|
| 353 | /** |
---|
| 354 | * @brief The scheduler nodes of this thread. |
---|
| 355 | * |
---|
| 356 | * Each thread has a scheduler node for each scheduler instance. |
---|
| 357 | */ |
---|
| 358 | Scheduler_Node *nodes; |
---|
[15b5678d] | 359 | } Thread_Scheduler_control; |
---|
| 360 | |
---|
[f773c012] | 361 | /** |
---|
| 362 | * @brief Union type to hold a pointer to an immutable or a mutable object. |
---|
| 363 | * |
---|
| 364 | * The main purpose is to enable passing of pointers to read-only send buffers |
---|
| 365 | * in the message passing subsystem. This approach is somewhat fragile since |
---|
| 366 | * it prevents the compiler to check if the operations on objects are valid |
---|
| 367 | * with respect to the constant qualifier. An alternative would be to add a |
---|
| 368 | * third pointer argument for immutable objects, but this would increase the |
---|
| 369 | * structure size. |
---|
| 370 | */ |
---|
| 371 | typedef union { |
---|
| 372 | void *mutable_object; |
---|
| 373 | const void *immutable_object; |
---|
| 374 | } Thread_Wait_information_Object_argument_type; |
---|
| 375 | |
---|
[4c8a0ac] | 376 | /** |
---|
| 377 | * @brief This type is able to contain several flags used to control the wait |
---|
| 378 | * class and state of a thread. |
---|
| 379 | * |
---|
| 380 | * The mutually exclusive wait class flags are |
---|
| 381 | * - @ref THREAD_WAIT_CLASS_EVENT, |
---|
| 382 | * - @ref THREAD_WAIT_CLASS_SYSTEM_EVENT, and |
---|
| 383 | * - @ref THREAD_WAIT_CLASS_OBJECT. |
---|
| 384 | * |
---|
| 385 | * The mutually exclusive wait state flags are |
---|
| 386 | * - @ref THREAD_WAIT_STATE_INTEND_TO_BLOCK, |
---|
[b7cff7fe] | 387 | * - @ref THREAD_WAIT_STATE_BLOCKED, and |
---|
| 388 | * - @ref THREAD_WAIT_STATE_READY_AGAIN. |
---|
[4c8a0ac] | 389 | */ |
---|
| 390 | typedef unsigned int Thread_Wait_flags; |
---|
| 391 | |
---|
[4b72da4] | 392 | /** |
---|
[319cb20] | 393 | * @brief Information required to manage a thread while it is blocked. |
---|
[baff4da] | 394 | * |
---|
| 395 | * This contains the information required to manage a thread while it is |
---|
| 396 | * blocked and to return information to it. |
---|
| 397 | */ |
---|
[ac7d5ef0] | 398 | typedef struct { |
---|
[97312fcc] | 399 | #if defined(RTEMS_MULTIPROCESSING) |
---|
| 400 | /* |
---|
| 401 | * @brief This field is the identifier of the remote object this thread is |
---|
| 402 | * waiting upon. |
---|
| 403 | */ |
---|
| 404 | Objects_Id remote_id; |
---|
| 405 | #endif |
---|
[baff4da] | 406 | /** This field is used to return an integer while when blocked. */ |
---|
| 407 | uint32_t count; |
---|
[f773c012] | 408 | /** This field is for a pointer to a user return argument. */ |
---|
[baff4da] | 409 | void *return_argument; |
---|
[f773c012] | 410 | /** This field is for a pointer to a second user return argument. */ |
---|
| 411 | Thread_Wait_information_Object_argument_type |
---|
| 412 | return_argument_second; |
---|
[baff4da] | 413 | /** This field contains any options in effect on this blocking operation. */ |
---|
[d6154c7] | 414 | uint32_t option; |
---|
[baff4da] | 415 | /** This field will contain the return status from a blocking operation. |
---|
[20f02c6] | 416 | * |
---|
[baff4da] | 417 | * @note The following assumes that all API return codes can be |
---|
| 418 | * treated as an uint32_t. |
---|
[3a4ae6c] | 419 | */ |
---|
[baff4da] | 420 | uint32_t return_code; |
---|
[3a4ae6c] | 421 | |
---|
[4c8a0ac] | 422 | /** |
---|
| 423 | * @brief This field contains several flags used to control the wait class |
---|
| 424 | * and state of a thread in case fine-grained locking is used. |
---|
| 425 | */ |
---|
| 426 | #if defined(RTEMS_SMP) |
---|
| 427 | Atomic_Uint flags; |
---|
| 428 | #else |
---|
| 429 | Thread_Wait_flags flags; |
---|
| 430 | #endif |
---|
[568af83] | 431 | |
---|
[1fcac5ad] | 432 | #if defined(RTEMS_SMP) |
---|
| 433 | /** |
---|
| 434 | * @brief Thread wait lock control block. |
---|
| 435 | * |
---|
| 436 | * Parts of the thread wait information are protected by the thread wait |
---|
| 437 | * default lock and additionally a thread queue lock in case the thread |
---|
| 438 | * is enqueued on a thread queue. |
---|
| 439 | * |
---|
| 440 | * The thread wait lock mechanism protects the following thread variables |
---|
| 441 | * - POSIX_API_Control::Attributes, |
---|
[300f6a48] | 442 | * - Scheduler_Node::Wait, |
---|
[1fcac5ad] | 443 | * - Thread_Control::Wait::Lock::Pending_requests, |
---|
| 444 | * - Thread_Control::Wait::queue, and |
---|
| 445 | * - Thread_Control::Wait::operations. |
---|
| 446 | * |
---|
| 447 | * @see _Thread_Wait_acquire(), _Thread_Wait_release(), _Thread_Wait_claim(), |
---|
| 448 | * _Thread_Wait_restore_default() and _Thread_Wait_tranquilize(). |
---|
| 449 | */ |
---|
| 450 | struct { |
---|
| 451 | /** |
---|
| 452 | * @brief Thread wait default lock. |
---|
| 453 | */ |
---|
| 454 | ISR_lock_Control Default; |
---|
| 455 | |
---|
| 456 | /** |
---|
| 457 | * @brief The pending thread wait lock acquire or tranquilize requests in |
---|
| 458 | * case the thread is enqueued on a thread queue. |
---|
| 459 | */ |
---|
| 460 | Chain_Control Pending_requests; |
---|
[ff2e6c64] | 461 | |
---|
| 462 | /** |
---|
| 463 | * @brief Tranquilizer gate used by _Thread_Wait_tranquilize(). |
---|
| 464 | * |
---|
| 465 | * This gate is closed by _Thread_Wait_claim(). In case there are no |
---|
| 466 | * pending requests during a _Thread_Wait_restore_default(), then this gate |
---|
| 467 | * is opened immediately, otherwise it is placed on the pending request |
---|
| 468 | * chain and opened by _Thread_Wait_remove_request_locked() as the last |
---|
| 469 | * gate on the chain to signal overall request completion. |
---|
| 470 | */ |
---|
| 471 | Thread_queue_Gate Tranquilizer; |
---|
[1fcac5ad] | 472 | } Lock; |
---|
[d79df38] | 473 | |
---|
| 474 | /** |
---|
| 475 | * @brief Thread queue link provided for use by the thread wait lock owner to |
---|
| 476 | * build a thread queue path. |
---|
| 477 | */ |
---|
| 478 | Thread_queue_Link Link; |
---|
[1fcac5ad] | 479 | #endif |
---|
| 480 | |
---|
| 481 | /** |
---|
| 482 | * @brief The current thread queue. |
---|
| 483 | * |
---|
| 484 | * If this field is NULL the thread is not enqueued on a thread queue. This |
---|
| 485 | * field is protected by the thread wait default lock. |
---|
| 486 | * |
---|
| 487 | * @see _Thread_Wait_claim(). |
---|
| 488 | */ |
---|
| 489 | Thread_queue_Queue *queue; |
---|
| 490 | |
---|
[568af83] | 491 | /** |
---|
| 492 | * @brief The current thread queue operations. |
---|
| 493 | * |
---|
[1fcac5ad] | 494 | * This field is protected by the thread lock wait default lock. |
---|
[568af83] | 495 | * |
---|
[1fcac5ad] | 496 | * @see _Thread_Wait_claim(). |
---|
[568af83] | 497 | */ |
---|
| 498 | const Thread_queue_Operations *operations; |
---|
[d7665823] | 499 | |
---|
| 500 | Thread_queue_Heads *spare_heads; |
---|
[ac7d5ef0] | 501 | } Thread_Wait_information; |
---|
| 502 | |
---|
[03b900d] | 503 | /** |
---|
| 504 | * @brief Information required to manage a thread timer. |
---|
| 505 | */ |
---|
| 506 | typedef struct { |
---|
| 507 | ISR_LOCK_MEMBER( Lock ) |
---|
| 508 | Watchdog_Header *header; |
---|
| 509 | Watchdog_Control Watchdog; |
---|
| 510 | } Thread_Timer_information; |
---|
| 511 | |
---|
[baff4da] | 512 | /** |
---|
[ac7d5ef0] | 513 | * The following defines the control block used to manage |
---|
| 514 | * each thread proxy. |
---|
| 515 | * |
---|
[baff4da] | 516 | * @note It is critical that proxies and threads have identical |
---|
[ac7d5ef0] | 517 | * memory images for the shared part. |
---|
| 518 | */ |
---|
| 519 | typedef struct { |
---|
[6a07436] | 520 | /** This field is the object management structure for each proxy. */ |
---|
[ac7d5ef0] | 521 | Objects_Control Object; |
---|
[6e4f929] | 522 | |
---|
| 523 | /** |
---|
| 524 | * @see Thread_Control::Join_queue |
---|
| 525 | */ |
---|
| 526 | Thread_queue_Control Join_queue; |
---|
| 527 | |
---|
[6a07436] | 528 | /** This field is the current execution state of this proxy. */ |
---|
[ac7d5ef0] | 529 | States_Control current_state; |
---|
[900d337f] | 530 | |
---|
| 531 | /** |
---|
[300f6a48] | 532 | * @brief The base priority of this thread in its home scheduler instance. |
---|
[900d337f] | 533 | */ |
---|
[300f6a48] | 534 | Priority_Node Real_priority; |
---|
[900d337f] | 535 | |
---|
[47d2464] | 536 | #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT) |
---|
[6a07436] | 537 | /** This field is the number of mutexes currently held by this proxy. */ |
---|
[d6154c7] | 538 | uint32_t resource_count; |
---|
[47d2464] | 539 | #endif |
---|
[fd84982] | 540 | |
---|
[15b5678d] | 541 | /** |
---|
| 542 | * @brief Scheduler related control. |
---|
| 543 | */ |
---|
| 544 | Thread_Scheduler_control Scheduler; |
---|
| 545 | |
---|
[6a07436] | 546 | /** This field is the blocking information for this proxy. */ |
---|
[ac7d5ef0] | 547 | Thread_Wait_information Wait; |
---|
[6a07436] | 548 | /** This field is the Watchdog used to manage proxy delays and timeouts. */ |
---|
[03b900d] | 549 | Thread_Timer_information Timer; |
---|
[97e2729d] | 550 | #if defined(RTEMS_MULTIPROCESSING) |
---|
[6a07436] | 551 | /** This field is the received response packet in an MP system. */ |
---|
[3a4ae6c] | 552 | MP_packet_Prefix *receive_packet; |
---|
[ac7d5ef0] | 553 | /****************** end of common block ********************/ |
---|
[8f96581] | 554 | |
---|
| 555 | /** |
---|
[a4217c6] | 556 | * @brief Thread queue callout for _Thread_queue_Enqueue(). |
---|
[8f96581] | 557 | */ |
---|
| 558 | Thread_queue_MP_callout thread_queue_callout; |
---|
| 559 | |
---|
[84dc9df] | 560 | /** |
---|
| 561 | * @brief This field is used to manage the set of active proxies in the system. |
---|
| 562 | */ |
---|
| 563 | RBTree_Node Active; |
---|
[16832b0] | 564 | |
---|
[15b5678d] | 565 | /** |
---|
| 566 | * @brief The scheduler node providing the thread wait nodes used to enqueue |
---|
| 567 | * this thread proxy on a thread queue. |
---|
| 568 | */ |
---|
| 569 | Scheduler_Node Scheduler_node; |
---|
| 570 | |
---|
[16832b0] | 571 | /** |
---|
| 572 | * @brief Provide thread queue heads for this thread proxy. |
---|
| 573 | * |
---|
| 574 | * The actual size of the thread queue heads depends on the application |
---|
| 575 | * configuration. Since thread proxies are never destroyed we can use the |
---|
| 576 | * same storage place for the thread queue heads. |
---|
| 577 | */ |
---|
| 578 | Thread_queue_Heads Thread_queue_heads[ RTEMS_ZERO_LENGTH_ARRAY ]; |
---|
[8f96581] | 579 | #endif |
---|
[ac7d5ef0] | 580 | } Thread_Proxy_control; |
---|
| 581 | |
---|
[baff4da] | 582 | /** |
---|
[ac7d5ef0] | 583 | * The following record defines the control block used |
---|
| 584 | * to manage each thread. |
---|
| 585 | * |
---|
[baff4da] | 586 | * @note It is critical that proxies and threads have identical |
---|
[ac7d5ef0] | 587 | * memory images for the shared part. |
---|
| 588 | */ |
---|
[3a4ae6c] | 589 | typedef enum { |
---|
[6a07436] | 590 | /** This value is for the Classic RTEMS API. */ |
---|
[5e9b32b] | 591 | THREAD_API_RTEMS, |
---|
[6a07436] | 592 | /** This value is for the POSIX API. */ |
---|
[f0caa05] | 593 | THREAD_API_POSIX |
---|
[3a4ae6c] | 594 | } Thread_APIs; |
---|
[7f6a24ab] | 595 | |
---|
[6a07436] | 596 | /** This macro defines the first API which has threads. */ |
---|
[3a4ae6c] | 597 | #define THREAD_API_FIRST THREAD_API_RTEMS |
---|
[baff4da] | 598 | |
---|
[6a07436] | 599 | /** This macro defines the last API which has threads. */ |
---|
[f0caa05] | 600 | #define THREAD_API_LAST THREAD_API_POSIX |
---|
[7f6a24ab] | 601 | |
---|
[0dd732d] | 602 | typedef struct Thread_Action Thread_Action; |
---|
| 603 | |
---|
| 604 | /** |
---|
| 605 | * @brief Thread action handler. |
---|
| 606 | * |
---|
[6e4f929] | 607 | * The thread action handler will be called with interrupts disabled and a |
---|
| 608 | * corresponding lock acquired, e.g. _Thread_State_acquire(). The handler must |
---|
| 609 | * release the corresponding lock, e.g. _Thread_State_release(). So, the |
---|
| 610 | * corresponding lock may be used to protect private data used by the |
---|
| 611 | * particular action. |
---|
[0dd732d] | 612 | * |
---|
[6e4f929] | 613 | * Since the action is passed to the handler additional data may be accessed |
---|
| 614 | * via RTEMS_CONTAINER_OF(). |
---|
[0dd732d] | 615 | * |
---|
[6e4f929] | 616 | * @param[in] the_thread The thread performing the action. |
---|
[0dd732d] | 617 | * @param[in] action The thread action. |
---|
[6e4f929] | 618 | * @param[in] lock_context The lock context to use for the lock release. |
---|
[0dd732d] | 619 | */ |
---|
| 620 | typedef void ( *Thread_Action_handler )( |
---|
[6e4f929] | 621 | Thread_Control *the_thread, |
---|
| 622 | Thread_Action *action, |
---|
| 623 | ISR_lock_Context *lock_context |
---|
[0dd732d] | 624 | ); |
---|
| 625 | |
---|
| 626 | /** |
---|
| 627 | * @brief Thread action. |
---|
| 628 | * |
---|
| 629 | * Thread actions can be chained together to trigger a set of actions on |
---|
| 630 | * particular events like for example a thread post-switch. Use |
---|
| 631 | * _Thread_Action_initialize() to initialize this structure. |
---|
| 632 | * |
---|
| 633 | * Thread actions are the building block for efficient implementation of |
---|
| 634 | * - Classic signals delivery, |
---|
[6e4f929] | 635 | * - POSIX signals delivery, and |
---|
| 636 | * - thread life-cycle changes. |
---|
[0dd732d] | 637 | * |
---|
[6e4f929] | 638 | * @see _Thread_Add_post_switch_action() and _Thread_Run_post_switch_actions(). |
---|
[0dd732d] | 639 | */ |
---|
| 640 | struct Thread_Action { |
---|
| 641 | Chain_Node Node; |
---|
| 642 | Thread_Action_handler handler; |
---|
| 643 | }; |
---|
| 644 | |
---|
[5eaf0e7] | 645 | /** |
---|
| 646 | * @brief Per-thread information for POSIX Keys. |
---|
| 647 | */ |
---|
| 648 | typedef struct { |
---|
| 649 | /** |
---|
| 650 | * @brief Key value pairs registered for this thread. |
---|
| 651 | */ |
---|
| 652 | RBTree_Control Key_value_pairs; |
---|
| 653 | |
---|
| 654 | /** |
---|
| 655 | * @brief Lock to protect the tree operations. |
---|
| 656 | */ |
---|
| 657 | ISR_LOCK_MEMBER( Lock ) |
---|
| 658 | } Thread_Keys_information; |
---|
| 659 | |
---|
[0dd732d] | 660 | /** |
---|
| 661 | * @brief Control block to manage thread actions. |
---|
| 662 | * |
---|
| 663 | * Use _Thread_Action_control_initialize() to initialize this structure. |
---|
| 664 | */ |
---|
| 665 | typedef struct { |
---|
| 666 | Chain_Control Chain; |
---|
| 667 | } Thread_Action_control; |
---|
| 668 | |
---|
[1b1be254] | 669 | /** |
---|
| 670 | * @brief Thread life states. |
---|
| 671 | * |
---|
| 672 | * The thread life states are orthogonal to the thread states used for |
---|
| 673 | * synchronization primitives and blocking operations. They reflect the state |
---|
| 674 | * changes triggered with thread restart and delete requests. |
---|
[e753748] | 675 | * |
---|
| 676 | * The individual state values must be a power of two to allow use of bit |
---|
| 677 | * operations to manipulate and evaluate the thread life state. |
---|
[1b1be254] | 678 | */ |
---|
| 679 | typedef enum { |
---|
| 680 | THREAD_LIFE_PROTECTED = 0x1, |
---|
| 681 | THREAD_LIFE_RESTARTING = 0x2, |
---|
[54550e04] | 682 | THREAD_LIFE_TERMINATING = 0x4, |
---|
[da826560] | 683 | THREAD_LIFE_CHANGE_DEFERRED = 0x8, |
---|
[54550e04] | 684 | THREAD_LIFE_DETACHED = 0x10 |
---|
[1b1be254] | 685 | } Thread_Life_state; |
---|
| 686 | |
---|
| 687 | /** |
---|
| 688 | * @brief Thread life control. |
---|
| 689 | */ |
---|
[5c731a83] | 690 | typedef struct { |
---|
[1b1be254] | 691 | /** |
---|
| 692 | * @brief Thread life action used to react upon thread restart and delete |
---|
| 693 | * requests. |
---|
| 694 | */ |
---|
[5c731a83] | 695 | Thread_Action Action; |
---|
[1b1be254] | 696 | |
---|
| 697 | /** |
---|
| 698 | * @brief The current thread life state. |
---|
| 699 | */ |
---|
| 700 | Thread_Life_state state; |
---|
[862a0ee] | 701 | |
---|
| 702 | /** |
---|
| 703 | * @brief The count of pending life change requests. |
---|
| 704 | */ |
---|
| 705 | uint32_t pending_life_change_requests; |
---|
[54550e04] | 706 | |
---|
| 707 | /** |
---|
| 708 | * @brief The thread exit value. |
---|
| 709 | * |
---|
| 710 | * It is, |
---|
| 711 | * - the value passed to pthread_exit(), or |
---|
| 712 | * - PTHREAD_CANCELED in case it is cancelled via pthread_cancel(), or |
---|
| 713 | * - NULL. |
---|
| 714 | */ |
---|
| 715 | void *exit_value; |
---|
[5c731a83] | 716 | } Thread_Life_control; |
---|
| 717 | |
---|
[134a181] | 718 | typedef struct { |
---|
| 719 | uint32_t flags; |
---|
| 720 | void * control; |
---|
| 721 | }Thread_Capture_control; |
---|
| 722 | |
---|
[baff4da] | 723 | /** |
---|
[6a07436] | 724 | * This structure defines the Thread Control Block (TCB). |
---|
[4827470] | 725 | * |
---|
| 726 | * Uses a leading underscore in the structure name to allow forward |
---|
| 727 | * declarations in standard header files provided by Newlib and GCC. |
---|
[70488f56] | 728 | * |
---|
| 729 | * In case the second member changes (currently Join_queue), then the memset() |
---|
| 730 | * in _Thread_Initialize() must be adjusted. |
---|
[baff4da] | 731 | */ |
---|
[4827470] | 732 | struct _Thread_Control { |
---|
[6a07436] | 733 | /** This field is the object management structure for each thread. */ |
---|
| 734 | Objects_Control Object; |
---|
[6e4f929] | 735 | |
---|
| 736 | /** |
---|
| 737 | * @brief Thread queue for thread join operations and multi-purpose lock. |
---|
| 738 | * |
---|
| 739 | * The lock of this thread queue is used for various purposes. It protects |
---|
| 740 | * the following fields |
---|
| 741 | * |
---|
[bd12dda] | 742 | * - RTEMS_API_Control::Signal, |
---|
[8bc6bf28] | 743 | * - Thread_Control::budget_algorithm, |
---|
| 744 | * - Thread_Control::budget_callout, |
---|
| 745 | * - Thread_Control::cpu_time_budget, |
---|
[bd12dda] | 746 | * - Thread_Control::current_state, |
---|
| 747 | * - Thread_Control::Post_switch_actions, |
---|
| 748 | * - Thread_Control::Scheduler::control, and |
---|
| 749 | * - Thread_Control::Scheduler::own_control. |
---|
[6e4f929] | 750 | * |
---|
| 751 | * @see _Thread_State_acquire(). |
---|
| 752 | */ |
---|
| 753 | Thread_queue_Control Join_queue; |
---|
| 754 | |
---|
[6a07436] | 755 | /** This field is the current execution state of this thread. */ |
---|
| 756 | States_Control current_state; |
---|
[900d337f] | 757 | |
---|
| 758 | /** |
---|
[300f6a48] | 759 | * @brief The base priority of this thread in its home scheduler instance. |
---|
[900d337f] | 760 | */ |
---|
[300f6a48] | 761 | Priority_Node Real_priority; |
---|
[900d337f] | 762 | |
---|
[47d2464] | 763 | #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT) |
---|
[6a07436] | 764 | /** This field is the number of mutexes currently held by this thread. */ |
---|
| 765 | uint32_t resource_count; |
---|
[47d2464] | 766 | #endif |
---|
[15b5678d] | 767 | |
---|
| 768 | /** |
---|
| 769 | * @brief Scheduler related control. |
---|
| 770 | */ |
---|
| 771 | Thread_Scheduler_control Scheduler; |
---|
| 772 | |
---|
[6a07436] | 773 | /** This field is the blocking information for this thread. */ |
---|
| 774 | Thread_Wait_information Wait; |
---|
| 775 | /** This field is the Watchdog used to manage thread delays and timeouts. */ |
---|
[03b900d] | 776 | Thread_Timer_information Timer; |
---|
[97e2729d] | 777 | #if defined(RTEMS_MULTIPROCESSING) |
---|
[6a07436] | 778 | /** This field is the received response packet in an MP system. */ |
---|
| 779 | MP_packet_Prefix *receive_packet; |
---|
[fd84982] | 780 | #endif |
---|
[a6502a58] | 781 | /*================= end of common block =================*/ |
---|
| 782 | |
---|
[10e32a26] | 783 | #if defined(RTEMS_SMP) && defined(RTEMS_PROFILING) |
---|
| 784 | /** |
---|
| 785 | * @brief Potpourri lock statistics. |
---|
| 786 | * |
---|
| 787 | * These SMP lock statistics are used for all lock objects that lack a |
---|
| 788 | * storage space for the statistics. Examples are lock objects used in |
---|
| 789 | * external libraries which are independent of the actual RTEMS build |
---|
| 790 | * configuration. |
---|
| 791 | */ |
---|
| 792 | SMP_lock_Stats Potpourri_stats; |
---|
| 793 | #endif |
---|
| 794 | |
---|
[1f5bee3] | 795 | /** This field is true if the thread is an idle thread. */ |
---|
| 796 | bool is_idle; |
---|
[931dd97] | 797 | #if defined(RTEMS_MULTIPROCESSING) |
---|
[6a07436] | 798 | /** This field is true if the thread is offered globally */ |
---|
[484a769] | 799 | bool is_global; |
---|
[931dd97] | 800 | #endif |
---|
[6a07436] | 801 | /** This field is true if the thread is preemptible. */ |
---|
[484a769] | 802 | bool is_preemptible; |
---|
[335e5ca] | 803 | /** This field is true if the thread uses the floating point unit. */ |
---|
| 804 | bool is_fp; |
---|
[2d36931] | 805 | |
---|
[64ba1a96] | 806 | /** |
---|
| 807 | * @brief True, if the thread was created with an inherited scheduler |
---|
| 808 | * (PTHREAD_INHERIT_SCHED), and false otherwise. |
---|
| 809 | */ |
---|
| 810 | bool was_created_with_inherited_scheduler; |
---|
| 811 | |
---|
[6a07436] | 812 | /** This field is the length of the time quantum that this thread is |
---|
| 813 | * allowed to consume. The algorithm used to manage limits on CPU usage |
---|
| 814 | * is specified by budget_algorithm. |
---|
| 815 | */ |
---|
[d6154c7] | 816 | uint32_t cpu_time_budget; |
---|
[6a07436] | 817 | /** This field is the algorithm used to manage this thread's time |
---|
| 818 | * quantum. The algorithm may be specified as none which case, |
---|
| 819 | * no limit is in place. |
---|
| 820 | */ |
---|
[2f200c7] | 821 | Thread_CPU_budget_algorithms budget_algorithm; |
---|
[6a07436] | 822 | /** This field is the method invoked with the budgeted time is consumed. */ |
---|
[2f200c7] | 823 | Thread_CPU_budget_algorithm_callout budget_callout; |
---|
[c3330a8] | 824 | /** This field is the amount of CPU time consumed by this thread |
---|
[6a07436] | 825 | * since it was created. |
---|
| 826 | */ |
---|
[d297c81d] | 827 | Timestamp_Control cpu_time_used; |
---|
[108c4b0] | 828 | |
---|
[6a07436] | 829 | /** This field contains information about the starting state of |
---|
| 830 | * this thread. |
---|
| 831 | */ |
---|
[2f200c7] | 832 | Thread_Start_information Start; |
---|
[0dd732d] | 833 | |
---|
| 834 | Thread_Action_control Post_switch_actions; |
---|
| 835 | |
---|
[6a07436] | 836 | /** This field contains the context of this thread. */ |
---|
[2f200c7] | 837 | Context_Control Registers; |
---|
[499d443] | 838 | #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) |
---|
[6a07436] | 839 | /** This field points to the floating point context for this thread. |
---|
| 840 | * If NULL, the thread is integer only. |
---|
| 841 | */ |
---|
[3c86f88] | 842 | Context_Control_fp *fp_context; |
---|
[17508d02] | 843 | #endif |
---|
[6a07436] | 844 | /** This field points to the newlib reentrancy structure for this thread. */ |
---|
[d36b3152] | 845 | struct _reent *libc_reent; |
---|
[6a07436] | 846 | /** This array contains the API extension area pointers. */ |
---|
[2f200c7] | 847 | void *API_Extensions[ THREAD_API_LAST + 1 ]; |
---|
[e6c87f7] | 848 | |
---|
| 849 | /** |
---|
[5eaf0e7] | 850 | * @brief The POSIX Keys information. |
---|
[e6c87f7] | 851 | */ |
---|
[5eaf0e7] | 852 | Thread_Keys_information Keys; |
---|
[e6c87f7] | 853 | |
---|
[2e06be4] | 854 | /** |
---|
| 855 | * @brief Thread life-cycle control. |
---|
| 856 | * |
---|
| 857 | * Control state changes triggered by thread restart and delete requests. |
---|
| 858 | */ |
---|
[5c731a83] | 859 | Thread_Life_control Life; |
---|
[69aa3349] | 860 | |
---|
[134a181] | 861 | Thread_Capture_control Capture; |
---|
| 862 | |
---|
[ba74ebde] | 863 | /** |
---|
| 864 | * @brief Pointer to an optional thread-specific POSIX user environment. |
---|
| 865 | */ |
---|
| 866 | struct rtems_user_env_t *user_environment; |
---|
| 867 | |
---|
[cef5675] | 868 | /** |
---|
| 869 | * @brief LIFO list of POSIX cleanup contexts. |
---|
| 870 | */ |
---|
| 871 | struct _pthread_cleanup_context *last_cleanup_context; |
---|
| 872 | |
---|
[709f38a] | 873 | /** |
---|
| 874 | * @brief LIFO list of user extensions iterators. |
---|
| 875 | */ |
---|
| 876 | struct User_extensions_Iterator *last_user_extensions_iterator; |
---|
| 877 | |
---|
[69aa3349] | 878 | /** |
---|
| 879 | * @brief Variable length array of user extension pointers. |
---|
| 880 | * |
---|
| 881 | * The length is defined by the application via <rtems/confdefs.h>. |
---|
| 882 | */ |
---|
| 883 | void *extensions[ RTEMS_ZERO_LENGTH_ARRAY ]; |
---|
[2f200c7] | 884 | }; |
---|
[ac7d5ef0] | 885 | |
---|
[17c66867] | 886 | typedef void (*rtems_per_thread_routine)( Thread_Control * ); |
---|
| 887 | |
---|
[5bb6ac9] | 888 | /** |
---|
| 889 | * @brief Deprecated, use rtems_task_iterate() instead. |
---|
| 890 | * |
---|
| 891 | * Use rtems_task_iterate() instead. |
---|
| 892 | */ |
---|
[17c66867] | 893 | void rtems_iterate_over_all_threads( |
---|
| 894 | rtems_per_thread_routine routine |
---|
[d271c3bb] | 895 | ) RTEMS_DEPRECATED; |
---|
[17c66867] | 896 | |
---|
[69aa3349] | 897 | /** |
---|
| 898 | * @brief Thread control add-on. |
---|
| 899 | */ |
---|
| 900 | typedef struct { |
---|
| 901 | /** |
---|
| 902 | * @brief Offset of the pointer field in Thread_Control referencing an |
---|
| 903 | * application configuration dependent memory area in the thread control |
---|
| 904 | * block. |
---|
| 905 | */ |
---|
| 906 | size_t destination_offset; |
---|
| 907 | |
---|
| 908 | /** |
---|
| 909 | * @brief Offset relative to the thread control block begin to an application |
---|
| 910 | * configuration dependent memory area. |
---|
| 911 | */ |
---|
| 912 | size_t source_offset; |
---|
| 913 | } Thread_Control_add_on; |
---|
| 914 | |
---|
| 915 | /** |
---|
| 916 | * @brief Thread control add-ons. |
---|
| 917 | * |
---|
| 918 | * The thread control block contains fields that point to application |
---|
| 919 | * configuration dependent memory areas, like the scheduler information, the |
---|
[d5154d0f] | 920 | * API control blocks, the user extension context table, and the Newlib |
---|
| 921 | * re-entrancy support. Account for these areas in the configuration and |
---|
| 922 | * avoid extra workspace allocations for these areas. |
---|
[69aa3349] | 923 | * |
---|
| 924 | * This array is provided via <rtems/confdefs.h>. |
---|
| 925 | * |
---|
[21275b58] | 926 | * @see _Thread_Control_add_on_count. |
---|
[69aa3349] | 927 | */ |
---|
| 928 | extern const Thread_Control_add_on _Thread_Control_add_ons[]; |
---|
| 929 | |
---|
| 930 | /** |
---|
| 931 | * @brief Thread control add-on count. |
---|
| 932 | * |
---|
| 933 | * Count of entries in _Thread_Control_add_ons. |
---|
| 934 | * |
---|
| 935 | * This value is provided via <rtems/confdefs.h>. |
---|
| 936 | */ |
---|
| 937 | extern const size_t _Thread_Control_add_on_count; |
---|
| 938 | |
---|
| 939 | /** |
---|
[21275b58] | 940 | * @brief Count of configured threads. |
---|
[69aa3349] | 941 | * |
---|
| 942 | * This value is provided via <rtems/confdefs.h>. |
---|
| 943 | */ |
---|
[21275b58] | 944 | extern const size_t _Thread_Initial_thread_count; |
---|
[69aa3349] | 945 | |
---|
[5ee70c5] | 946 | /** |
---|
| 947 | * @brief The default maximum size of a thread name in characters (including |
---|
| 948 | * the terminating '\0' character). |
---|
| 949 | * |
---|
| 950 | * This is the default value for the application configuration option |
---|
| 951 | * CONFIGURE_MAXIMUM_THREAD_NAME_SIZE. |
---|
| 952 | */ |
---|
| 953 | #define THREAD_DEFAULT_MAXIMUM_NAME_SIZE 16 |
---|
| 954 | |
---|
[da6ad56] | 955 | /** |
---|
| 956 | * @brief Maximum size of a thread name in characters (including the |
---|
| 957 | * terminating '\0' character). |
---|
| 958 | * |
---|
| 959 | * This value is provided via <rtems/confdefs.h>. |
---|
| 960 | */ |
---|
| 961 | extern const size_t _Thread_Maximum_name_size; |
---|
| 962 | |
---|
[21275b58] | 963 | /** |
---|
| 964 | * @brief The configured thread control block. |
---|
| 965 | * |
---|
| 966 | * This type is defined in <rtems/confdefs.h> and depends on the application |
---|
| 967 | * configuration. |
---|
| 968 | */ |
---|
| 969 | typedef struct Thread_Configured_control Thread_Configured_control; |
---|
| 970 | |
---|
| 971 | /** |
---|
| 972 | * @brief The configured thread queue heads. |
---|
| 973 | * |
---|
| 974 | * In SMP configurations, this type is defined in <rtems/confdefs.h> and depends |
---|
| 975 | * on the application configuration. |
---|
| 976 | */ |
---|
| 977 | #if defined(RTEMS_SMP) |
---|
| 978 | typedef struct Thread_queue_Configured_heads Thread_queue_Configured_heads; |
---|
| 979 | #else |
---|
| 980 | typedef Thread_queue_Heads Thread_queue_Configured_heads; |
---|
| 981 | #endif |
---|
| 982 | |
---|
| 983 | /** |
---|
| 984 | * @brief Size of the thread queue heads of a particular application. |
---|
| 985 | * |
---|
| 986 | * In SMP configurations, this value is provided via <rtems/confdefs.h>. |
---|
| 987 | */ |
---|
| 988 | #if defined(RTEMS_SMP) |
---|
| 989 | extern const size_t _Thread_queue_Heads_size; |
---|
| 990 | #else |
---|
| 991 | #define _Thread_queue_Heads_size sizeof(Thread_queue_Heads) |
---|
| 992 | #endif |
---|
| 993 | |
---|
| 994 | /** |
---|
| 995 | * @brief The thread object information. |
---|
| 996 | */ |
---|
| 997 | typedef struct { |
---|
| 998 | /** |
---|
| 999 | * @brief The object information. |
---|
| 1000 | */ |
---|
| 1001 | Objects_Information Objects; |
---|
| 1002 | |
---|
| 1003 | /** |
---|
| 1004 | * @brief Thread queue heads maintenance. |
---|
| 1005 | */ |
---|
| 1006 | union { |
---|
| 1007 | /** |
---|
| 1008 | * @brief Contains the initial set of thread queue heads. |
---|
| 1009 | * |
---|
| 1010 | * This is set by <rtems/confdefs.h> via THREAD_INFORMATION_DEFINE(). |
---|
| 1011 | */ |
---|
| 1012 | Thread_queue_Configured_heads *initial; |
---|
| 1013 | |
---|
| 1014 | /** |
---|
| 1015 | * @brief The free thread queue heads. |
---|
| 1016 | * |
---|
| 1017 | * This member is initialized by _Thread_Initialize_information(). |
---|
| 1018 | */ |
---|
| 1019 | Freechain_Control Free; |
---|
| 1020 | } Thread_queue_heads; |
---|
| 1021 | } Thread_Information; |
---|
| 1022 | |
---|
| 1023 | /** |
---|
| 1024 | * @brief The internal thread objects information. |
---|
| 1025 | */ |
---|
| 1026 | extern Thread_Information _Thread_Information; |
---|
| 1027 | |
---|
| 1028 | #define THREAD_INFORMATION_DEFINE_ZERO( name, api, cls ) \ |
---|
| 1029 | Thread_Information name##_Information = { \ |
---|
| 1030 | { \ |
---|
| 1031 | _Objects_Build_id( api, cls, 1, 0 ), \ |
---|
| 1032 | NULL, \ |
---|
[2485156] | 1033 | _Objects_Allocate_none, \ |
---|
[6135747] | 1034 | NULL, \ |
---|
[21275b58] | 1035 | 0, \ |
---|
| 1036 | 0, \ |
---|
| 1037 | 0, \ |
---|
| 1038 | 0, \ |
---|
| 1039 | CHAIN_INITIALIZER_EMPTY( name##_Information.Objects.Inactive ), \ |
---|
| 1040 | NULL, \ |
---|
| 1041 | NULL, \ |
---|
| 1042 | NULL \ |
---|
| 1043 | OBJECTS_INFORMATION_MP( name##_Information.Objects, NULL ), \ |
---|
| 1044 | }, { \ |
---|
| 1045 | NULL \ |
---|
| 1046 | } \ |
---|
| 1047 | } |
---|
| 1048 | |
---|
[d252e20a] | 1049 | /** |
---|
| 1050 | * @brief Return an inactive thread object or NULL. |
---|
| 1051 | * |
---|
| 1052 | * @retval NULL No inactive object is available. |
---|
| 1053 | * @retval object An inactive object. |
---|
| 1054 | */ |
---|
| 1055 | Objects_Control *_Thread_Allocate_unlimited( Objects_Information *information ); |
---|
| 1056 | |
---|
[21275b58] | 1057 | #define THREAD_INFORMATION_DEFINE( name, api, cls, max ) \ |
---|
| 1058 | static Objects_Control * \ |
---|
| 1059 | name##_Local_table[ _Objects_Maximum_per_allocation( max ) ]; \ |
---|
| 1060 | static Thread_Configured_control \ |
---|
| 1061 | name##_Objects[ _Objects_Maximum_per_allocation( max ) ]; \ |
---|
| 1062 | static Thread_queue_Configured_heads \ |
---|
| 1063 | name##_Heads[ _Objects_Maximum_per_allocation( max ) ]; \ |
---|
| 1064 | Thread_Information name##_Information = { \ |
---|
| 1065 | { \ |
---|
| 1066 | _Objects_Build_id( api, cls, 1, _Objects_Maximum_per_allocation( max ) ), \ |
---|
| 1067 | name##_Local_table, \ |
---|
[2485156] | 1068 | _Objects_Is_unlimited( max ) ? \ |
---|
[d252e20a] | 1069 | _Thread_Allocate_unlimited : _Objects_Allocate_static, \ |
---|
[6135747] | 1070 | _Objects_Is_unlimited( max ) ? \ |
---|
| 1071 | _Objects_Free_unlimited : _Objects_Free_static, \ |
---|
[21275b58] | 1072 | 0, \ |
---|
| 1073 | _Objects_Is_unlimited( max ) ? _Objects_Maximum_per_allocation( max ) : 0, \ |
---|
| 1074 | sizeof( Thread_Configured_control ), \ |
---|
| 1075 | OBJECTS_NO_STRING_NAME, \ |
---|
| 1076 | CHAIN_INITIALIZER_EMPTY( name##_Information.Objects.Inactive ), \ |
---|
| 1077 | NULL, \ |
---|
| 1078 | NULL, \ |
---|
| 1079 | &name##_Objects[ 0 ].Control.Object \ |
---|
| 1080 | OBJECTS_INFORMATION_MP( name##_Information.Objects, NULL ) \ |
---|
| 1081 | }, { \ |
---|
| 1082 | &name##_Heads[ 0 ] \ |
---|
| 1083 | } \ |
---|
| 1084 | } |
---|
| 1085 | |
---|
[32991495] | 1086 | /** |
---|
| 1087 | * @brief The idle thread stacks. |
---|
| 1088 | * |
---|
| 1089 | * Provided by the application via <rtems/confdefs.h>. |
---|
| 1090 | */ |
---|
| 1091 | extern char _Thread_Idle_stacks[]; |
---|
| 1092 | |
---|
[1d9f509e] | 1093 | #if defined(RTEMS_MULTIPROCESSING) |
---|
| 1094 | /** |
---|
| 1095 | * @brief The configured thread control block. |
---|
| 1096 | * |
---|
| 1097 | * This type is defined in <rtems/confdefs.h> and depends on the application |
---|
| 1098 | * configuration. |
---|
| 1099 | */ |
---|
| 1100 | typedef struct Thread_Configured_proxy_control Thread_Configured_proxy_control; |
---|
| 1101 | |
---|
| 1102 | /** |
---|
| 1103 | * @brief The configured proxies. |
---|
| 1104 | * |
---|
| 1105 | * Provided by the application via <rtems/confdefs.h>. |
---|
| 1106 | */ |
---|
| 1107 | extern Thread_Configured_proxy_control * const _Thread_MP_Proxies; |
---|
| 1108 | #endif |
---|
| 1109 | |
---|
[5bb6ac9] | 1110 | /** @} */ |
---|
[ac7d5ef0] | 1111 | |
---|
| 1112 | #ifdef __cplusplus |
---|
| 1113 | } |
---|
| 1114 | #endif |
---|
| 1115 | |
---|
| 1116 | #endif |
---|
[b10825c] | 1117 | /* end of include file */ |
---|