RTEMS 6.1-rc6
Loading...
Searching...
No Matches
threadimpl.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
12/*
13 * COPYRIGHT (c) 1989-2008.
14 * On-Line Applications Research Corporation (OAR).
15 *
16 * Copyright (C) 2014, 2017 embedded brains GmbH & Co. KG
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#ifndef _RTEMS_SCORE_THREADIMPL_H
41#define _RTEMS_SCORE_THREADIMPL_H
42
43#include <rtems/score/thread.h>
44#include <rtems/score/assert.h>
46#include <rtems/score/interr.h>
47#include <rtems/score/isr.h>
51#include <rtems/score/status.h>
55#include <rtems/score/todimpl.h>
57#include <rtems/config.h>
58
59#ifdef __cplusplus
60extern "C" {
61#endif
62
73typedef struct {
74#if defined(RTEMS_SMP)
78 ISR_lock_Control Lock;
79#endif
80
86
95
105
110#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
112#endif
113
114#if defined(RTEMS_SMP)
115#define THREAD_OF_SCHEDULER_HELP_NODE( node ) \
116 RTEMS_CONTAINER_OF( node, Thread_Control, Scheduler.Help_node )
117#endif
118
119typedef bool ( *Thread_Visitor )( Thread_Control *the_thread, void *arg );
120
129void _Thread_Iterate(
130 Thread_Visitor visitor,
131 void *arg
132);
133
140
147
155void _Thread_Create_idle(void);
156
165
169typedef struct {
174
179
184
190 void ( *stack_free )( void * );
191
196
201
205 uint32_t name;
206
210 uint32_t isr_level;
211
215 bool is_fp;
216
222
245 Thread_Information *information,
246 Thread_Control *the_thread,
248);
249
260void _Thread_Free(
261 Thread_Information *information,
262 Thread_Control *the_thread
263);
264
299 Thread_Control *the_thread,
301 ISR_lock_Context *lock_context
302);
303
318 Thread_Control *the_thread,
320 ISR_lock_Context *lock_context
321);
322
328void _Thread_Yield( Thread_Control *executing );
329
342 Thread_Life_state life_states_to_clear,
343 Thread_Life_state life_states_to_set,
344 Thread_Life_state ignored_life_states
345);
346
358
368void _Thread_Kill_zombies( void );
369
378 void *exit_value,
379 Thread_Life_state life_states_to_set
380);
381
400 Thread_Control *the_thread,
401 States_Control waiting_for_join,
402 Thread_Control *executing,
403 Thread_queue_Context *queue_context
404);
405
409typedef enum {
414
422
434 Thread_Control *the_thread,
435 Thread_Control *executing,
436 Thread_Life_state life_states_to_clear
437);
438
458 Thread_Control *the_thread,
459 Thread_Control *executing,
460 Thread_queue_Context *queue_context
461);
462
471static inline bool _Thread_Is_ready( const Thread_Control *the_thread )
472{
473 return _States_Is_ready( the_thread->current_state );
474}
475
488 Thread_Control *the_thread,
489 States_Control state
490);
491
504 Thread_Control *the_thread,
505 States_Control state
506);
507
520 Thread_Control *the_thread,
521 States_Control state
522);
523
536 Thread_Control *the_thread,
537 States_Control state
538);
539
549 Thread_Control *the_thread
550);
551
558
565
574
590void _Thread_Handler( void );
591
598static inline void _Thread_State_acquire_critical(
599 Thread_Control *the_thread,
600 ISR_lock_Context *lock_context
601)
602{
603 _Thread_queue_Do_acquire_critical( &the_thread->Join_queue, lock_context );
604}
605
612static inline void _Thread_State_acquire(
613 Thread_Control *the_thread,
614 ISR_lock_Context *lock_context
615)
616{
617 _ISR_lock_ISR_disable( lock_context );
618 _Thread_State_acquire_critical( the_thread, lock_context );
619}
620
629static inline Thread_Control *_Thread_State_acquire_for_executing(
630 ISR_lock_Context *lock_context
631)
632{
633 Thread_Control *executing;
634
635 _ISR_lock_ISR_disable( lock_context );
636 executing = _Thread_Executing;
637 _Thread_State_acquire_critical( executing, lock_context );
638
639 return executing;
640}
641
648static inline void _Thread_State_release_critical(
649 Thread_Control *the_thread,
650 ISR_lock_Context *lock_context
651)
652{
653 _Thread_queue_Do_release_critical( &the_thread->Join_queue, lock_context );
654}
655
662static inline void _Thread_State_release(
663 Thread_Control *the_thread,
664 ISR_lock_Context *lock_context
665)
666{
667 _Thread_State_release_critical( the_thread, lock_context );
668 _ISR_lock_ISR_enable( lock_context );
669}
670
679#if defined(RTEMS_DEBUG)
680static inline bool _Thread_State_is_owner(
681 const Thread_Control *the_thread
682)
683{
684 return _Thread_queue_Is_lock_owner( &the_thread->Join_queue );
685}
686#endif
687
701 Thread_Control *start_of_path,
702 Thread_queue_Context *queue_context
703);
704
721 Thread_Control *the_thread,
722 Priority_Node *priority_node,
723 Thread_queue_Context *queue_context
724);
725
742 Thread_Control *the_thread,
743 Priority_Node *priority_node,
744 Thread_queue_Context *queue_context
745);
746
767 Thread_Control *the_thread,
768 Priority_Node *priority_node,
769 Priority_Group_order priority_group_order,
770 Thread_queue_Context *queue_context
771);
772
794static inline void _Thread_Priority_change(
795 Thread_Control *the_thread,
796 Priority_Node *priority_node,
797 Priority_Control new_priority,
798 Priority_Group_order priority_group_order,
799 Thread_queue_Context *queue_context
800)
801{
802 _Priority_Node_set_priority( priority_node, new_priority );
803
804#if defined(RTEMS_SCORE_THREAD_REAL_PRIORITY_MAY_BE_INACTIVE)
805 if ( !_Priority_Node_is_active( priority_node ) ) {
806 /* The priority change is picked up once the node is added */
807 return;
808 }
809#endif
810
812 the_thread,
813 priority_node,
814 priority_group_order,
815 queue_context
816 );
817}
818
819#if defined(RTEMS_SMP)
832void _Thread_Priority_replace(
833 Thread_Control *the_thread,
834 Priority_Node *victim_node,
835 Priority_Node *replacement_node
836);
837#endif
838
850void _Thread_Priority_update( Thread_queue_Context *queue_context );
851
852#if defined(RTEMS_SMP)
859void _Thread_Priority_update_and_make_sticky( Thread_Control *the_thread );
860
867void _Thread_Priority_update_and_clean_sticky( Thread_Control *the_thread );
868
874void _Thread_Priority_update_ignore_sticky( Thread_Control *the_thread );
875#endif
876
887static inline bool _Thread_Priority_less_than(
888 Priority_Control left,
889 Priority_Control right
890)
891{
892 return left > right;
893}
894
904static inline Priority_Control _Thread_Priority_highest(
905 Priority_Control left,
906 Priority_Control right
907)
908{
909 return _Thread_Priority_less_than( left, right ) ? right : left;
910}
911
924static inline Objects_Information *_Thread_Get_objects_information_by_id(
925 Objects_Id id
926)
927{
928 uint32_t the_api;
929
930 the_api = _Objects_Get_API( id );
931
932 if ( !_Objects_Is_api_valid( the_api ) ) {
933 return NULL;
934 }
935
936 /*
937 * Threads are always first class :)
938 *
939 * There is no need to validate the object class of the object identifier,
940 * since this will be done by the object get methods.
941 */
942 return _Objects_Information_table[ the_api ][ 1 ];
943}
944
952static inline Thread_Information *_Thread_Get_objects_information(
953 Thread_Control *the_thread
954)
955{
956 size_t the_api;
957 Thread_Information *information;
958
959 the_api = (size_t) _Objects_Get_API( the_thread->Object.id );
960 _Assert( _Objects_Is_api_valid( the_api ) );
961
962 information = (Thread_Information *)
963 _Objects_Information_table[ the_api ][ 1 ];
964 _Assert( information != NULL );
965
966 return information;
967}
968
978 Objects_Id id,
979 ISR_lock_Context *lock_context
980);
981
988
996static inline Per_CPU_Control *_Thread_Get_CPU(
997 const Thread_Control *thread
998)
999{
1000#if defined(RTEMS_SMP)
1001 return thread->Scheduler.cpu;
1002#else
1003 (void) thread;
1004
1005 return _Per_CPU_Get();
1006#endif
1007}
1008
1015static inline void _Thread_Set_CPU(
1016 Thread_Control *thread,
1017 Per_CPU_Control *cpu
1018)
1019{
1020#if defined(RTEMS_SMP)
1021 thread->Scheduler.cpu = cpu;
1022#else
1023 (void) thread;
1024 (void) cpu;
1025#endif
1026}
1027
1039static inline bool _Thread_Is_executing (
1040 const Thread_Control *the_thread
1041)
1042{
1043 return ( the_thread == _Thread_Executing );
1044}
1045
1046#if defined(RTEMS_SMP)
1059static inline bool _Thread_Is_executing_on_a_processor(
1060 const Thread_Control *the_thread
1061)
1062{
1063 return _CPU_Context_Get_is_executing( &the_thread->Registers );
1064}
1065#endif
1066
1078static inline bool _Thread_Is_heir (
1079 const Thread_Control *the_thread
1080)
1081{
1082 return ( the_thread == _Thread_Heir );
1083}
1084
1094static inline void _Thread_Unblock (
1095 Thread_Control *the_thread
1096)
1097{
1098 _Thread_Clear_state( the_thread, STATES_BLOCKED );
1099}
1100
1116#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1117static inline bool _Thread_Is_allocated_fp (
1118 const Thread_Control *the_thread
1119)
1120{
1121 return ( the_thread == _Thread_Allocated_fp );
1122}
1123#endif
1124
1125/*
1126 * If the CPU has hardware floating point, then we must address saving
1127 * and restoring it as part of the context switch.
1128 *
1129 * The second conditional compilation section selects the algorithm used
1130 * to context switch between floating point tasks. The deferred algorithm
1131 * can be significantly better in a system with few floating point tasks
1132 * because it reduces the total number of save and restore FP context
1133 * operations. However, this algorithm can not be used on all CPUs due
1134 * to unpredictable use of FP registers by some compilers for integer
1135 * operations.
1136 */
1137
1143static inline void _Thread_Save_fp( Thread_Control *executing )
1144{
1145#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1146#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
1147 if ( executing->fp_context != NULL )
1148 _Context_Save_fp( &executing->fp_context );
1149#endif
1150#endif
1151}
1152
1158static inline void _Thread_Restore_fp( Thread_Control *executing )
1159{
1160#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1161#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
1162 if ( (executing->fp_context != NULL) &&
1163 !_Thread_Is_allocated_fp( executing ) ) {
1164 if ( _Thread_Allocated_fp != NULL )
1166 _Context_Restore_fp( &executing->fp_context );
1167 _Thread_Allocated_fp = executing;
1168 }
1169#else
1170 if ( executing->fp_context != NULL )
1171 _Context_Restore_fp( &executing->fp_context );
1172#endif
1173#endif
1174}
1175
1182#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1183static inline void _Thread_Deallocate_fp( void )
1184{
1185 _Thread_Allocated_fp = NULL;
1186}
1187#endif
1188
1198static inline bool _Thread_Is_context_switch_necessary( void )
1199{
1200 return ( _Thread_Dispatch_necessary );
1201}
1202
1208static inline uint32_t _Thread_Get_maximum_internal_threads(void)
1209{
1210 /* Idle threads */
1211 uint32_t maximum_internal_threads =
1213
1214 /* MPCI thread */
1215#if defined(RTEMS_MULTIPROCESSING)
1216 if ( _System_state_Is_multiprocessing ) {
1217 ++maximum_internal_threads;
1218 }
1219#endif
1220
1221 return maximum_internal_threads;
1222}
1223
1230static inline Thread_Control *_Thread_Internal_allocate( void )
1231{
1232 return (Thread_Control *)
1233 _Objects_Allocate_unprotected( &_Thread_Information.Objects );
1234}
1235
1249static inline Thread_Control *_Thread_Get_heir_and_make_it_executing(
1250 Per_CPU_Control *cpu_self
1251)
1252{
1253 Thread_Control *heir;
1254
1255 heir = cpu_self->heir;
1256 cpu_self->dispatch_necessary = false;
1257 cpu_self->executing = heir;
1258
1259 return heir;
1260}
1261
1269static inline void _Thread_Update_CPU_time_used(
1270 Thread_Control *the_thread,
1271 Per_CPU_Control *cpu
1272)
1273{
1274 Timestamp_Control last;
1276
1277 last = cpu->cpu_usage_timestamp;
1278 _TOD_Get_uptime( &cpu->cpu_usage_timestamp );
1279 _Timestamp_Subtract( &last, &cpu->cpu_usage_timestamp, &ran );
1280 _Timestamp_Add_to( &the_thread->cpu_time_used, &ran );
1281}
1282
1290#if defined( RTEMS_SMP )
1291static inline void _Thread_Dispatch_update_heir(
1292 Per_CPU_Control *cpu_self,
1293 Per_CPU_Control *cpu_for_heir,
1294 Thread_Control *heir
1295)
1296{
1297 _Thread_Update_CPU_time_used( cpu_for_heir->heir, cpu_for_heir );
1298
1299 cpu_for_heir->heir = heir;
1300
1301 _Thread_Dispatch_request( cpu_self, cpu_for_heir );
1302}
1303#endif
1304
1315
1327 Thread_Control *the_thread
1328);
1329
1340 Thread_Control *the_thread
1341);
1342
1348static inline void _Thread_Action_control_initialize(
1349 Thread_Action_control *action_control
1350)
1351{
1352 _Chain_Initialize_empty( &action_control->Chain );
1353}
1354
1360static inline void _Thread_Action_initialize(
1361 Thread_Action *action
1362)
1363{
1364 _Chain_Set_off_chain( &action->Node );
1365}
1366
1379static inline void _Thread_Add_post_switch_action(
1380 Thread_Control *the_thread,
1381 Thread_Action *action,
1382 Thread_Action_handler handler
1383)
1384{
1385 Per_CPU_Control *cpu_of_thread;
1386
1387 _Assert( _Thread_State_is_owner( the_thread ) );
1388
1389 cpu_of_thread = _Thread_Get_CPU( the_thread );
1390
1391 action->handler = handler;
1392
1393 _Thread_Dispatch_request( _Per_CPU_Get(), cpu_of_thread );
1394
1395 _Chain_Append_if_is_off_chain_unprotected(
1396 &the_thread->Post_switch_actions.Chain,
1397 &action->Node
1398 );
1399}
1400
1412static inline void _Thread_Append_post_switch_action(
1413 Thread_Control *the_thread,
1414 Thread_Action *action
1415)
1416{
1417 _Assert( _Thread_State_is_owner( the_thread ) );
1418 _Assert( action->handler != NULL );
1419
1420 _Chain_Append_unprotected(
1421 &the_thread->Post_switch_actions.Chain,
1422 &action->Node
1423 );
1424}
1425
1434static inline bool _Thread_Is_life_restarting(
1435 Thread_Life_state life_state
1436)
1437{
1438 return ( life_state & THREAD_LIFE_RESTARTING ) != 0;
1439}
1440
1449static inline bool _Thread_Is_life_terminating(
1450 Thread_Life_state life_state
1451)
1452{
1453 return ( life_state & THREAD_LIFE_TERMINATING ) != 0;
1454}
1455
1464static inline bool _Thread_Is_life_change_allowed(
1465 Thread_Life_state life_state
1466)
1467{
1468 return ( life_state
1470}
1471
1480static inline bool _Thread_Is_life_changing(
1481 Thread_Life_state life_state
1482)
1483{
1484 return ( life_state
1486}
1487
1496static inline bool _Thread_Is_joinable(
1497 const Thread_Control *the_thread
1498)
1499{
1500 _Assert( _Thread_State_is_owner( the_thread ) );
1501 return ( the_thread->Life.state & THREAD_LIFE_DETACHED ) == 0;
1502}
1503
1509static inline void _Thread_Resource_count_increment(
1510 Thread_Control *the_thread
1511)
1512{
1513#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1514 ++the_thread->resource_count;
1515#else
1516 (void) the_thread;
1517#endif
1518}
1519
1525static inline void _Thread_Resource_count_decrement(
1526 Thread_Control *the_thread
1527)
1528{
1529#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1530 --the_thread->resource_count;
1531#else
1532 (void) the_thread;
1533#endif
1534}
1535
1536#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1548static inline bool _Thread_Owns_resources(
1549 const Thread_Control *the_thread
1550)
1551{
1552 return the_thread->resource_count != 0;
1553}
1554#endif
1555
1563static inline const Scheduler_Control *_Thread_Scheduler_get_home(
1564 const Thread_Control *the_thread
1565)
1566{
1567#if defined(RTEMS_SMP)
1568 return the_thread->Scheduler.home_scheduler;
1569#else
1570 (void) the_thread;
1571 return &_Scheduler_Table[ 0 ];
1572#endif
1573}
1574
1582static inline Scheduler_Node *_Thread_Scheduler_get_home_node(
1583 const Thread_Control *the_thread
1584)
1585{
1586#if defined(RTEMS_SMP)
1587 _Assert( !_Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
1588 return SCHEDULER_NODE_OF_THREAD_WAIT_NODE(
1589 _Chain_First( &the_thread->Scheduler.Wait_nodes )
1590 );
1591#else
1592 return the_thread->Scheduler.nodes;
1593#endif
1594}
1595
1604static inline Scheduler_Node *_Thread_Scheduler_get_node_by_index(
1605 const Thread_Control *the_thread,
1606 size_t scheduler_index
1607)
1608{
1609 _Assert( scheduler_index < _Scheduler_Count );
1610#if defined(RTEMS_SMP)
1611 return (Scheduler_Node *)
1612 ( (uintptr_t) the_thread->Scheduler.nodes
1613 + scheduler_index * _Scheduler_Node_size );
1614#else
1615 (void) scheduler_index;
1616 return the_thread->Scheduler.nodes;
1617#endif
1618}
1619
1620#if defined(RTEMS_SMP)
1627static inline void _Thread_Scheduler_acquire_critical(
1628 Thread_Control *the_thread,
1629 ISR_lock_Context *lock_context
1630)
1631{
1632 _ISR_lock_Acquire( &the_thread->Scheduler.Lock, lock_context );
1633}
1634
1641static inline void _Thread_Scheduler_release_critical(
1642 Thread_Control *the_thread,
1643 ISR_lock_Context *lock_context
1644)
1645{
1646 _ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context );
1647}
1648
1654void _Thread_Scheduler_process_requests( Thread_Control *the_thread );
1655
1663static inline void _Thread_Scheduler_add_request(
1664 Thread_Control *the_thread,
1665 Scheduler_Node *scheduler_node,
1666 Scheduler_Node_request request
1667)
1668{
1669 ISR_lock_Context lock_context;
1670 Scheduler_Node_request current_request;
1671
1672 _Thread_Scheduler_acquire_critical( the_thread, &lock_context );
1673
1674 current_request = scheduler_node->Thread.request;
1675
1676 if ( current_request == SCHEDULER_NODE_REQUEST_NOT_PENDING ) {
1677 _Assert(
1678 request == SCHEDULER_NODE_REQUEST_ADD
1679 || request == SCHEDULER_NODE_REQUEST_REMOVE
1680 );
1681 _Assert( scheduler_node->Thread.next_request == NULL );
1682 scheduler_node->Thread.next_request = the_thread->Scheduler.requests;
1683 the_thread->Scheduler.requests = scheduler_node;
1684 } else if ( current_request != SCHEDULER_NODE_REQUEST_NOTHING ) {
1685 _Assert(
1686 ( current_request == SCHEDULER_NODE_REQUEST_ADD
1687 && request == SCHEDULER_NODE_REQUEST_REMOVE )
1688 || ( current_request == SCHEDULER_NODE_REQUEST_REMOVE
1689 && request == SCHEDULER_NODE_REQUEST_ADD )
1690 );
1691 request = SCHEDULER_NODE_REQUEST_NOTHING;
1692 }
1693
1694 scheduler_node->Thread.request = request;
1695
1696 _Thread_Scheduler_release_critical( the_thread, &lock_context );
1697}
1698
1706static inline void _Thread_Scheduler_add_wait_node(
1707 Thread_Control *the_thread,
1708 Scheduler_Node *scheduler_node
1709)
1710{
1711 _Chain_Append_unprotected(
1712 &the_thread->Scheduler.Wait_nodes,
1713 &scheduler_node->Thread.Wait_node
1714 );
1715 _Thread_Scheduler_add_request(
1716 the_thread,
1717 scheduler_node,
1718 SCHEDULER_NODE_REQUEST_ADD
1719 );
1720}
1721
1729static inline void _Thread_Scheduler_remove_wait_node(
1730 Thread_Control *the_thread,
1731 Scheduler_Node *scheduler_node
1732)
1733{
1734 _Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
1735 _Thread_Scheduler_add_request(
1736 the_thread,
1737 scheduler_node,
1738 SCHEDULER_NODE_REQUEST_REMOVE
1739 );
1740}
1741#endif
1742
1754static inline Priority_Control _Thread_Get_priority(
1755 const Thread_Control *the_thread
1756)
1757{
1758 Scheduler_Node *scheduler_node;
1759
1760 scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
1761 return _Priority_Get_priority( &scheduler_node->Wait.Priority );
1762}
1763
1771static inline Priority_Control _Thread_Get_unmapped_priority(
1772 const Thread_Control *the_thread
1773)
1774{
1775 return SCHEDULER_PRIORITY_UNMAP( _Thread_Get_priority( the_thread ) );
1776}
1777
1785static inline Priority_Control _Thread_Get_unmapped_real_priority(
1786 const Thread_Control *the_thread
1787)
1788{
1789 return SCHEDULER_PRIORITY_UNMAP( the_thread->Real_priority.priority );
1790}
1791
1802static inline void _Thread_Wait_acquire_default_critical(
1803 Thread_Control *the_thread,
1804 ISR_lock_Context *lock_context
1805)
1806{
1807 _ISR_lock_Acquire( &the_thread->Wait.Lock.Default, lock_context );
1808}
1809
1821static inline Thread_Control *_Thread_Wait_acquire_default_for_executing(
1822 ISR_lock_Context *lock_context
1823)
1824{
1825 Thread_Control *executing;
1826
1827 _ISR_lock_ISR_disable( lock_context );
1828 executing = _Thread_Executing;
1829 _Thread_Wait_acquire_default_critical( executing, lock_context );
1830
1831 return executing;
1832}
1833
1843static inline void _Thread_Wait_acquire_default(
1844 Thread_Control *the_thread,
1845 ISR_lock_Context *lock_context
1846)
1847{
1848 _ISR_lock_ISR_disable( lock_context );
1849 _Thread_Wait_acquire_default_critical( the_thread, lock_context );
1850}
1851
1862static inline void _Thread_Wait_release_default_critical(
1863 Thread_Control *the_thread,
1864 ISR_lock_Context *lock_context
1865)
1866{
1867 _ISR_lock_Release( &the_thread->Wait.Lock.Default, lock_context );
1868}
1869
1878static inline void _Thread_Wait_release_default(
1879 Thread_Control *the_thread,
1880 ISR_lock_Context *lock_context
1881)
1882{
1883 _Thread_Wait_release_default_critical( the_thread, lock_context );
1884 _ISR_lock_ISR_enable( lock_context );
1885}
1886
1887#if defined(RTEMS_SMP)
1888#define THREAD_QUEUE_CONTEXT_OF_REQUEST( node ) \
1889 RTEMS_CONTAINER_OF( node, Thread_queue_Context, Lock_context.Wait.Gate.Node )
1890
1897static inline void _Thread_Wait_remove_request_locked(
1898 Thread_Control *the_thread,
1899 Thread_queue_Lock_context *queue_lock_context
1900)
1901{
1902 Chain_Node *first;
1903
1904 _Chain_Extract_unprotected( &queue_lock_context->Wait.Gate.Node );
1905 first = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
1906
1907 if ( first != _Chain_Tail( &the_thread->Wait.Lock.Pending_requests ) ) {
1908 _Thread_queue_Gate_open( (Thread_queue_Gate *) first );
1909 }
1910}
1911
1918static inline void _Thread_Wait_acquire_queue_critical(
1919 Thread_queue_Queue *queue,
1920 Thread_queue_Lock_context *queue_lock_context
1921)
1922{
1923 _Thread_queue_Queue_acquire_critical(
1924 queue,
1925 &_Thread_Executing->Potpourri_stats,
1926 &queue_lock_context->Lock_context
1927 );
1928}
1929
1936static inline void _Thread_Wait_release_queue_critical(
1937 Thread_queue_Queue *queue,
1938 Thread_queue_Lock_context *queue_lock_context
1939)
1940{
1941 _Thread_queue_Queue_release_critical(
1942 queue,
1943 &queue_lock_context->Lock_context
1944 );
1945}
1946#endif
1947
1956static inline void _Thread_Wait_acquire_critical(
1957 Thread_Control *the_thread,
1958 Thread_queue_Context *queue_context
1959)
1960{
1961#if defined(RTEMS_SMP)
1962 Thread_queue_Queue *queue;
1963
1964 _Thread_Wait_acquire_default_critical(
1965 the_thread,
1966 &queue_context->Lock_context.Lock_context
1967 );
1968
1969 queue = the_thread->Wait.queue;
1970 queue_context->Lock_context.Wait.queue = queue;
1971
1972 if ( queue != NULL ) {
1973 _Thread_queue_Gate_add(
1974 &the_thread->Wait.Lock.Pending_requests,
1975 &queue_context->Lock_context.Wait.Gate
1976 );
1977 _Thread_Wait_release_default_critical(
1978 the_thread,
1979 &queue_context->Lock_context.Lock_context
1980 );
1981 _Thread_Wait_acquire_queue_critical( queue, &queue_context->Lock_context );
1982
1983 if ( queue_context->Lock_context.Wait.queue == NULL ) {
1984 _Thread_Wait_release_queue_critical(
1985 queue,
1986 &queue_context->Lock_context
1987 );
1988 _Thread_Wait_acquire_default_critical(
1989 the_thread,
1990 &queue_context->Lock_context.Lock_context
1991 );
1992 _Thread_Wait_remove_request_locked(
1993 the_thread,
1994 &queue_context->Lock_context
1995 );
1996 _Assert( the_thread->Wait.queue == NULL );
1997 }
1998 }
1999#else
2000 (void) the_thread;
2001 (void) queue_context;
2002#endif
2003}
2004
2012static inline void _Thread_Wait_acquire(
2013 Thread_Control *the_thread,
2014 Thread_queue_Context *queue_context
2015)
2016{
2018 _Thread_Wait_acquire_critical( the_thread, queue_context );
2019}
2020
2031static inline void _Thread_Wait_release_critical(
2032 Thread_Control *the_thread,
2033 Thread_queue_Context *queue_context
2034)
2035{
2036#if defined(RTEMS_SMP)
2037 Thread_queue_Queue *queue;
2038
2039 queue = queue_context->Lock_context.Wait.queue;
2040
2041 if ( queue != NULL ) {
2042 _Thread_Wait_release_queue_critical(
2043 queue, &queue_context->Lock_context
2044 );
2045 _Thread_Wait_acquire_default_critical(
2046 the_thread,
2047 &queue_context->Lock_context.Lock_context
2048 );
2049 _Thread_Wait_remove_request_locked(
2050 the_thread,
2051 &queue_context->Lock_context
2052 );
2053 }
2054
2055 _Thread_Wait_release_default_critical(
2056 the_thread,
2057 &queue_context->Lock_context.Lock_context
2058 );
2059#else
2060 (void) the_thread;
2061 (void) queue_context;
2062#endif
2063}
2064
2073static inline void _Thread_Wait_release(
2074 Thread_Control *the_thread,
2075 Thread_queue_Context *queue_context
2076)
2077{
2078 _Thread_Wait_release_critical( the_thread, queue_context );
2080}
2081
2096static inline void _Thread_Wait_claim(
2097 Thread_Control *the_thread,
2098 Thread_queue_Queue *queue
2099)
2100{
2101 ISR_lock_Context lock_context;
2102
2103 _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
2104
2105 _Assert( the_thread->Wait.queue == NULL );
2106
2107#if defined(RTEMS_SMP)
2108 _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
2109 _Chain_Initialize_node( &the_thread->Wait.Lock.Tranquilizer.Node );
2110 _Thread_queue_Gate_close( &the_thread->Wait.Lock.Tranquilizer );
2111#endif
2112
2113 the_thread->Wait.queue = queue;
2114
2115 _Thread_Wait_release_default_critical( the_thread, &lock_context );
2116}
2117
2125static inline void _Thread_Wait_claim_finalize(
2126 Thread_Control *the_thread,
2127 const Thread_queue_Operations *operations
2128)
2129{
2130 the_thread->Wait.operations = operations;
2131}
2132
2144static inline void _Thread_Wait_remove_request(
2145 Thread_Control *the_thread,
2146 Thread_queue_Lock_context *queue_lock_context
2147)
2148{
2149#if defined(RTEMS_SMP)
2150 ISR_lock_Context lock_context;
2151
2152 _Thread_Wait_acquire_default( the_thread, &lock_context );
2153 _Thread_Wait_remove_request_locked( the_thread, queue_lock_context );
2154 _Thread_Wait_release_default( the_thread, &lock_context );
2155#else
2156 (void) the_thread;
2157 (void) queue_lock_context;
2158#endif
2159}
2160
2173static inline void _Thread_Wait_restore_default(
2174 Thread_Control *the_thread
2175)
2176{
2177#if defined(RTEMS_SMP)
2178 ISR_lock_Context lock_context;
2179 Chain_Node *node;
2180 const Chain_Node *tail;
2181
2182 _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
2183
2184 node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
2185 tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
2186
2187 if ( node != tail ) {
2188 do {
2189 Thread_queue_Context *queue_context;
2190
2191 queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
2192 queue_context->Lock_context.Wait.queue = NULL;
2193
2194 node = _Chain_Next( node );
2195 } while ( node != tail );
2196
2197 _Thread_queue_Gate_add(
2198 &the_thread->Wait.Lock.Pending_requests,
2199 &the_thread->Wait.Lock.Tranquilizer
2200 );
2201 } else {
2202 _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
2203 }
2204#endif
2205
2206 the_thread->Wait.queue = NULL;
2208
2209#if defined(RTEMS_SMP)
2210 _Thread_Wait_release_default_critical( the_thread, &lock_context );
2211#endif
2212}
2213
2232static inline void _Thread_Wait_tranquilize(
2233 Thread_Control *the_thread
2234)
2235{
2236#if defined(RTEMS_SMP)
2237 _Thread_queue_Gate_wait( &the_thread->Wait.Lock.Tranquilizer );
2238#else
2239 (void) the_thread;
2240#endif
2241}
2242
2250static inline void _Thread_Wait_cancel(
2251 Thread_Control *the_thread,
2252 Thread_queue_Context *queue_context
2253)
2254{
2255 Thread_queue_Queue *queue;
2256
2257 queue = the_thread->Wait.queue;
2258
2259 if ( queue != NULL ) {
2260#if defined(RTEMS_SMP)
2261 _Assert( queue_context->Lock_context.Wait.queue == queue );
2262#endif
2263
2264 ( *the_thread->Wait.operations->extract )(
2265 queue,
2266 the_thread,
2267 queue_context
2268 );
2269 _Thread_Wait_restore_default( the_thread );
2270
2271#if defined(RTEMS_SMP)
2272 _Assert( queue_context->Lock_context.Wait.queue == NULL );
2273 queue_context->Lock_context.Wait.queue = queue;
2274#endif
2275 }
2276}
2277
2281#define THREAD_WAIT_STATE_MASK 0xffU
2282
2290#define THREAD_WAIT_STATE_READY 0x0U
2291
2299#define THREAD_WAIT_STATE_INTEND_TO_BLOCK 0x1U
2300
2304#define THREAD_WAIT_STATE_BLOCKED 0x2U
2305
2309#define THREAD_WAIT_CLASS_MASK 0xff00U
2310
2314#define THREAD_WAIT_CLASS_EVENT 0x100U
2315
2319#define THREAD_WAIT_CLASS_SYSTEM_EVENT 0x200U
2320
2324#define THREAD_WAIT_CLASS_OBJECT 0x400U
2325
2329#define THREAD_WAIT_CLASS_PERIOD 0x800U
2330
2337static inline void _Thread_Wait_flags_set(
2338 Thread_Control *the_thread,
2339 Thread_Wait_flags flags
2340)
2341{
2342#if defined(RTEMS_SMP)
2343 _Atomic_Store_uint( &the_thread->Wait.flags, flags, ATOMIC_ORDER_RELAXED );
2344#else
2345 the_thread->Wait.flags = flags;
2346#endif
2347}
2348
2356static inline Thread_Wait_flags _Thread_Wait_flags_get(
2357 const Thread_Control *the_thread
2358)
2359{
2360#if defined(RTEMS_SMP)
2361 return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_RELAXED );
2362#else
2363 return the_thread->Wait.flags;
2364#endif
2365}
2366
2374static inline Thread_Wait_flags _Thread_Wait_flags_get_acquire(
2375 const Thread_Control *the_thread
2376)
2377{
2378#if defined(RTEMS_SMP)
2379 return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_ACQUIRE );
2380#else
2381 return the_thread->Wait.flags;
2382#endif
2383}
2384
2401static inline bool _Thread_Wait_flags_try_change_release(
2402 Thread_Control *the_thread,
2403 Thread_Wait_flags expected_flags,
2404 Thread_Wait_flags desired_flags
2405)
2406{
2407 _Assert( _ISR_Get_level() != 0 );
2408
2409#if defined(RTEMS_SMP)
2410 return _Atomic_Compare_exchange_uint(
2411 &the_thread->Wait.flags,
2412 &expected_flags,
2413 desired_flags,
2414 ATOMIC_ORDER_RELEASE,
2415 ATOMIC_ORDER_RELAXED
2416 );
2417#else
2418 bool success = ( the_thread->Wait.flags == expected_flags );
2419
2420 if ( success ) {
2421 the_thread->Wait.flags = desired_flags;
2422 }
2423
2424 return success;
2425#endif
2426}
2427
2441static inline bool _Thread_Wait_flags_try_change_acquire(
2442 Thread_Control *the_thread,
2443 Thread_Wait_flags expected_flags,
2444 Thread_Wait_flags desired_flags
2445)
2446{
2447#if defined(RTEMS_SMP)
2448 return _Atomic_Compare_exchange_uint(
2449 &the_thread->Wait.flags,
2450 &expected_flags,
2451 desired_flags,
2452 ATOMIC_ORDER_ACQUIRE,
2453 ATOMIC_ORDER_ACQUIRE
2454 );
2455#else
2456 bool success;
2457 ISR_Level level;
2458
2459 _ISR_Local_disable( level );
2460
2461 success = _Thread_Wait_flags_try_change_release(
2462 the_thread,
2463 expected_flags,
2464 desired_flags
2465 );
2466
2467 _ISR_Local_enable( level );
2468 return success;
2469#endif
2470}
2471
2488Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread );
2489
2495static inline Status_Control _Thread_Wait_get_status(
2496 const Thread_Control *the_thread
2497)
2498{
2499 return (Status_Control) the_thread->Wait.return_code;
2500}
2501
2514void _Thread_Continue( Thread_Control *the_thread, Status_Control status );
2515
2521void _Thread_Timeout( Watchdog_Control *the_watchdog );
2522
2529static inline void _Thread_Timer_initialize(
2531 Per_CPU_Control *cpu
2532)
2533{
2534 _ISR_lock_Initialize( &timer->Lock, "Thread Timer" );
2535 timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
2536 _Watchdog_Preinitialize( &timer->Watchdog, cpu );
2537}
2538
2546static inline void _Thread_Add_timeout_ticks(
2547 Thread_Control *the_thread,
2548 Per_CPU_Control *cpu,
2549 Watchdog_Interval ticks
2550)
2551{
2552 ISR_lock_Context lock_context;
2553
2554 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2555
2556 the_thread->Timer.header =
2558 the_thread->Timer.Watchdog.routine = _Thread_Timeout;
2559 _Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks );
2560
2561 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2562}
2563
2572static inline void _Thread_Timer_insert_realtime(
2573 Thread_Control *the_thread,
2574 Per_CPU_Control *cpu,
2576 uint64_t expire
2577)
2578{
2579 ISR_lock_Context lock_context;
2580 Watchdog_Header *header;
2581
2582 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2583
2584 header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
2585 the_thread->Timer.header = header;
2586 the_thread->Timer.Watchdog.routine = routine;
2587 _Watchdog_Per_CPU_insert( &the_thread->Timer.Watchdog, cpu, header, expire );
2588
2589 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2590}
2591
2597static inline void _Thread_Timer_remove( Thread_Control *the_thread )
2598{
2599 ISR_lock_Context lock_context;
2600
2601 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2602
2603 _Watchdog_Per_CPU_remove(
2604 &the_thread->Timer.Watchdog,
2605#if defined(RTEMS_SMP)
2606 the_thread->Timer.Watchdog.cpu,
2607#else
2608 _Per_CPU_Get(),
2609#endif
2610 the_thread->Timer.header
2611 );
2612
2613 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2614}
2615
2623static inline void _Thread_Remove_timer_and_unblock(
2624 Thread_Control *the_thread,
2625 Thread_queue_Queue *queue
2626)
2627{
2628 _Thread_Wait_tranquilize( the_thread );
2629 _Thread_Timer_remove( the_thread );
2630
2631#if defined(RTEMS_MULTIPROCESSING)
2632 if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
2633 _Thread_Unblock( the_thread );
2634 } else {
2635 _Thread_queue_Unblock_proxy( queue, the_thread );
2636 }
2637#else
2638 (void) queue;
2639 _Thread_Unblock( the_thread );
2640#endif
2641}
2642
2653 Thread_Control *the_thread,
2654 const char *name
2655);
2656
2666size_t _Thread_Get_name(
2667 const Thread_Control *the_thread,
2668 char *buffer,
2669 size_t buffer_size
2670);
2671
2672#if defined(RTEMS_SMP)
2673#define THREAD_PIN_STEP 2
2674
2675#define THREAD_PIN_PREEMPTION 1
2676
2683void _Thread_Do_unpin(
2684 Thread_Control *executing,
2685 Per_CPU_Control *cpu_self
2686);
2687#endif
2688
2694static inline void _Thread_Pin( Thread_Control *executing )
2695{
2696#if defined(RTEMS_SMP)
2697 _Assert( executing == _Thread_Get_executing() );
2698
2699 executing->Scheduler.pin_level += THREAD_PIN_STEP;
2700#else
2701 (void) executing;
2702#endif
2703}
2704
2711static inline void _Thread_Unpin(
2712 Thread_Control *executing,
2713 Per_CPU_Control *cpu_self
2714)
2715{
2716#if defined(RTEMS_SMP)
2717 unsigned int pin_level;
2718
2719 _Assert( executing == _Per_CPU_Get_executing( cpu_self ) );
2720
2721 pin_level = executing->Scheduler.pin_level;
2722 _Assert( pin_level > 0 );
2723
2724 if (
2726 pin_level != ( THREAD_PIN_STEP | THREAD_PIN_PREEMPTION )
2727 )
2728 ) {
2729 executing->Scheduler.pin_level = pin_level - THREAD_PIN_STEP;
2730 } else {
2731 _Thread_Do_unpin( executing, cpu_self );
2732 }
2733#else
2734 (void) executing;
2735 (void) cpu_self;
2736#endif
2737}
2738
2741#ifdef __cplusplus
2742}
2743#endif
2744
2745#if defined(RTEMS_MULTIPROCESSING)
2746#include <rtems/score/threadmp.h>
2747#endif
2748
2749#ifdef __cplusplus
2750extern "C" {
2751#endif
2752
2763static inline void _Thread_Timer_remove_and_continue(
2764 Thread_Control *the_thread,
2765 Status_Control status
2766)
2767{
2768 _Thread_Timer_remove( the_thread );
2769#if defined(RTEMS_MULTIPROCESSING)
2770 _Thread_MP_Extract_proxy( the_thread );
2771#endif
2772 _Thread_Continue( the_thread, status );
2773}
2774
2775#ifdef __cplusplus
2776}
2777#endif
2778
2779#endif
2780/* end of include file */
This header file provides the interfaces of the Assert Handler.
This header file provides interfaces of the Chain Handler which are only used by the implementation.
#define RTEMS_PREDICT_TRUE(_exp)
Evaluates the integral expression and tells the compiler that the predicted value is true (1).
Definition: basedefs.h:751
#define RTEMS_NO_RETURN
Tells the compiler in a function declaration that this function does not return.
Definition: basedefs.h:386
#define rtems_configuration_get_maximum_processors()
Gets the maximum number of processors configured for this application.
Definition: config.h:500
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG and static analysis runs.
Definition: assert.h:96
#define _Context_Restore_fp(_fp)
Restore floating point context area.
Definition: context.h:159
#define _Context_Save_fp(_fp)
Save floating point context area.
Definition: context.h:170
#define _ISR_lock_ISR_enable(_context)
Restores the saved interrupt state of the ISR lock context.
Definition: isrlock.h:385
#define _ISR_lock_Release(_lock, _context)
Releases an ISR lock inside an ISR disabled section.
Definition: isrlock.h:282
#define _ISR_lock_ISR_disable(_context)
Disables interrupts and saves the previous interrupt state in the ISR lock context.
Definition: isrlock.h:364
#define _ISR_lock_Acquire(_lock, _context)
Acquires an ISR lock inside an ISR disabled section.
Definition: isrlock.h:259
#define _ISR_lock_Release_and_ISR_enable(_lock, _context)
Releases an ISR lock.
Definition: isrlock.h:229
#define _ISR_lock_ISR_disable_and_acquire(_lock, _context)
Acquires an ISR lock.
Definition: isrlock.h:204
#define _ISR_lock_Initialize(_lock, _name)
Initializes an ISR lock.
Definition: isrlock.h:150
#define _ISR_Local_disable(_level)
Disables interrupts on this processor.
Definition: isrlevel.h:76
#define _ISR_Local_enable(_level)
Enables interrupts on this processor.
Definition: isrlevel.h:93
#define _ISR_Get_level()
Return current interrupt level.
Definition: isrlevel.h:147
uint32_t ISR_Level
Definition: isrlevel.h:60
Objects_Information **const _Objects_Information_table[OBJECTS_APIS_LAST+1]
uint32_t Objects_Id
Definition: object.h:101
@ PER_CPU_WATCHDOG_REALTIME
Index for realtime clock per-CPU watchdog header.
Definition: percpu.h:362
@ PER_CPU_WATCHDOG_TICKS
Index for tick clock per-CPU watchdog header.
Definition: percpu.h:353
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:91
Priority_Group_order
The priority group order determines if a priority node is inserted as the first or last node into its...
Definition: priorityimpl.h:62
#define _Scheduler_Count
This constant contains the count of configured schedulers.
Definition: scheduler.h:395
const Scheduler_Control _Scheduler_Table[]
This table contains the configured schedulers.
#define SCHEDULER_PRIORITY_UNMAP(priority)
Returns the plain priority value.
Definition: schedulernodeimpl.h:70
#define STATES_BLOCKED
Definition: statesimpl.h:152
uint32_t States_Control
Definition: states.h:65
Status_Control
Status codes.
Definition: status.h:111
void _Thread_MP_Extract_proxy(Thread_Control *the_thread)
Extracts the proxy of the thread if necessary.
Definition: threadqextractwithproxy.c:46
const Thread_queue_Operations _Thread_queue_Operations_default
The default thread queue operations are used when a thread is not enqueued on a thread queue.
Definition: threadqops.c:1500
Status_Control _Thread_Restart(Thread_Control *the_thread, const Thread_Entry_information *entry, ISR_lock_Context *lock_context)
Restarts the thread.
Definition: threadrestart.c:536
void _Thread_Continue(Thread_Control *the_thread, Status_Control status)
Cancels a blocking operation so that the thread can continue its execution.
Definition: threadtimeout.c:45
RTEMS_NO_RETURN void _Thread_Exit(void *exit_value, Thread_Life_state life_states_to_set)
Exits the currently executing thread.
Definition: threadrestart.c:501
void _Thread_Entry_adaptor_idle(Thread_Control *executing)
Calls the start kinds idle entry of the thread.
Definition: threadentryadaptoridle.c:43
Thread_Information _Thread_Information
The internal thread objects information.
void _Thread_Timeout(Watchdog_Control *the_watchdog)
General purpose thread wait timeout.
Definition: threadtimeout.c:101
Thread_Cancel_state _Thread_Cancel(Thread_Control *the_thread, Thread_Control *executing, Thread_Life_state life_states_to_clear)
Cancels the thread.
Definition: threadrestart.c:434
Thread_Control * _Thread_Get(Objects_Id id, ISR_lock_Context *lock_context)
Gets a thread by its identifier.
Definition: threadget.c:44
Status_Control _Thread_Initialize(Thread_Information *information, Thread_Control *the_thread, const Thread_Configuration *config)
Initializes thread.
Definition: threadinitialize.c:368
void _Thread_Priority_update(Thread_queue_Context *queue_context)
Updates the priority of all threads in the set.
Definition: threadchangepriority.c:396
void _Thread_Handler_initialization(void)
Initializes thread handler.
Definition: thread.c:80
Timestamp_Control _Thread_Get_CPU_time_used_locked(Thread_Control *the_thread)
Gets the used processor time of the thread throughout its entire lifetime if the caller already acqui...
Definition: threadgetcputimeused.c:53
Objects_Id _Thread_Global_constructor
Object identifier of the global constructor thread.
Definition: threadhandler.c:74
void _Thread_Priority_add(Thread_Control *the_thread, Priority_Node *priority_node, Thread_queue_Context *queue_context)
Adds the specified thread priority node to the corresponding thread priority aggregation.
Definition: threadchangepriority.c:332
size_t _Thread_Get_name(const Thread_Control *the_thread, char *buffer, size_t buffer_size)
Gets the name of the thread.
Definition: threadname.c:65
void _Thread_Priority_perform_actions(Thread_Control *start_of_path, Thread_queue_Context *queue_context)
Checks if the thread is owner of the lock of the join queue.
Definition: threadchangepriority.c:223
#define THREAD_LIFE_TERMINATING
Indicates that thread is terminating.
Definition: thread.h:772
Thread_Cancel_state
Indicates the resulting state of _Thread_Cancel().
Definition: threadimpl.h:409
States_Control _Thread_Set_state(Thread_Control *the_thread, States_Control state)
Sets the specified thread state.
Definition: threadsetstate.c:70
#define THREAD_LIFE_PROTECTED
Indicates that the thread life is protected.
Definition: thread.h:756
RTEMS_NO_RETURN void _Thread_Start_multitasking(void)
Starts thread multitasking.
Definition: threadstartmultitasking.c:46
unsigned int Thread_Life_state
This type represents the thread life state.
Definition: thread.h:747
Timestamp_Control _Thread_Get_CPU_time_used(Thread_Control *the_thread)
Updates the used cpu time for the heir and dispatches a new heir.
Definition: threadgetcputimeused.c:71
Timestamp_Control _Thread_Get_CPU_time_used_after_last_reset(Thread_Control *the_thread)
Gets the used processor time of the thread after the last CPU usage reset.
Definition: threadgetcputimeusedafterreset.c:44
#define THREAD_LIFE_RESTARTING
Indicates that thread is restarting.
Definition: thread.h:764
States_Control _Thread_Clear_state(Thread_Control *the_thread, States_Control state)
Clears the specified thread state.
Definition: threadclearstate.c:72
void _Thread_Yield(Thread_Control *executing)
Yields the currently executing thread.
Definition: threadyield.c:44
void _Thread_Create_idle(void)
Creates idle thread.
Definition: threadcreateidle.c:125
Thread_Control * _Thread_Allocated_fp
Definition: threaddispatch.c:56
void _Thread_Free(Thread_Information *information, Thread_Control *the_thread)
Frees the thread.
Definition: threadinitialize.c:50
Status_Control _Thread_Start(Thread_Control *the_thread, const Thread_Entry_information *entry, ISR_lock_Context *lock_context)
Starts the specified thread.
Definition: threadstart.c:46
void _Thread_Priority_remove(Thread_Control *the_thread, Priority_Node *priority_node, Thread_queue_Context *queue_context)
Removes the specified thread priority node from the corresponding thread priority aggregation.
Definition: threadchangepriority.c:347
void _Thread_Entry_adaptor_numeric(Thread_Control *executing)
Calls the start kinds numeric entry of the thread.
Definition: threadentryadaptornumeric.c:43
void _Thread_Kill_zombies(void)
Kills all zombie threads in the system.
Definition: threadrestart.c:168
unsigned int Thread_Wait_flags
This type is able to contain several flags used to control the wait class and state of a thread.
Definition: thread.h:451
void(* Thread_Action_handler)(Thread_Control *the_thread, Thread_Action *action, ISR_lock_Context *lock_context)
This type defines the prototype of thread action handlers.
Definition: thread.h:686
void _Thread_Entry_adaptor_pointer(Thread_Control *executing)
Calls the start kinds pointer entry of the thread.
Definition: threadentryadaptorpointer.c:43
Objects_Id _Thread_Self_id(void)
Gets the identifier of the calling thread.
Definition: threadselfid.c:46
Thread_Zombie_registry _Thread_Zombies
This object is a registry for threads in the STATES_ZOMBIE state.
Definition: threadrestart.c:66
void _Thread_Priority_changed(Thread_Control *the_thread, Priority_Node *priority_node, Priority_Group_order priority_group_order, Thread_queue_Context *queue_context)
Propagates a thread priority value change in the specified thread priority node to the corresponding ...
Definition: threadchangepriority.c:362
void _Thread_Iterate(Thread_Visitor visitor, void *arg)
Calls the visitor with all threads and the given argument until it is done.
Definition: threaditerate.c:43
void _Thread_Initialize_information(Thread_Information *information)
Initializes the thread information.
Definition: thread.c:68
#define THREAD_LIFE_CHANGE_DEFERRED
Indicates that thread life changes are deferred.
Definition: thread.h:781
Thread_Life_state _Thread_Set_life_protection(Thread_Life_state state)
Set the thread to life protected.
Definition: threadrestart.c:624
Objects_Id _Thread_Wait_get_id(const Thread_Control *the_thread)
Returns the object identifier of the object containing the current thread wait queue.
Definition: threadwaitgetid.c:43
States_Control _Thread_Set_state_locked(Thread_Control *the_thread, States_Control state)
Sets the specified thread state without locking the lock context.
Definition: threadsetstate.c:48
#define THREAD_LIFE_DETACHED
Indicates that thread is detached.
Definition: thread.h:790
Status_Control _Thread_Close(Thread_Control *the_thread, Thread_Control *executing, Thread_queue_Context *queue_context)
Closes the thread.
Definition: threadrestart.c:465
void _Thread_Load_environment(Thread_Control *the_thread)
Initializes enviroment for a thread.
Definition: threadloadenv.c:44
Status_Control _Thread_Set_name(Thread_Control *the_thread, const char *name)
Sets the name of the thread.
Definition: threadname.c:45
void _Thread_Handler(void)
Wrapper function for all threads.
Definition: threadhandler.c:97
Status_Control _Thread_Join(Thread_Control *the_thread, States_Control waiting_for_join, Thread_Control *executing, Thread_queue_Context *queue_context)
Joins the currently executing thread with the thread.
Definition: threadrestart.c:380
States_Control _Thread_Clear_state_locked(Thread_Control *the_thread, States_Control state)
Clears the specified thread state without locking the lock context.
Definition: threadclearstate.c:46
Thread_Life_state _Thread_Change_life(Thread_Life_state life_states_to_clear, Thread_Life_state life_states_to_set, Thread_Life_state ignored_life_states)
Changes the life of currently executing thread.
Definition: threadrestart.c:597
@ THREAD_CANCEL_IN_PROGRESS
Indicates that the thread cancel operation is in progress.
Definition: threadimpl.h:420
@ THREAD_CANCEL_DONE
Indicates that the thread cancel operation is done.
Definition: threadimpl.h:413
int64_t Timestamp_Control
Definition: timestamp.h:76
uint32_t Watchdog_Interval
Type is used to specify the length of intervals.
Definition: watchdogticks.h:59
Watchdog_Service_routine(* Watchdog_Service_routine_entry)(Watchdog_Control *)
Pointer to a watchdog service routine.
Definition: watchdog.h:85
This header file provides the interfaces of the Internal Error Handler.
This header file provides the main interfaces of the ISR Handler.
This header file provides interfaces of the Scheduler Handler related to scheduler nodes which are on...
This header file provides interfaces of the Object Handler which are only used by the implementation.
This header file provides the interfaces of the Operation Status Support.
This header file provides interfaces of the Thread Handler which are used by the implementation and t...
This header file provides interfaces of the Thread States which are only used by the implementation.
This structure represents a chain node.
Definition: chain.h:78
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:94
Objects_Id id
Definition: objectdata.h:65
The information structure used to manage each API class of objects.
Definition: objectdata.h:198
Per CPU Core Structure.
Definition: percpu.h:384
struct _Thread_Control * heir
This is the heir thread for this processor.
Definition: percpu.h:473
Watchdog_Header Header[PER_CPU_WATCHDOG_COUNT]
Header for watchdogs.
Definition: percpu.h:513
volatile bool dispatch_necessary
This is set to true when this processor needs to run the thread dispatcher.
Definition: percpu.h:437
Timestamp_Control cpu_usage_timestamp
The CPU usage timestamp contains the time point of the last heir thread change or last CPU usage upda...
Definition: percpu.h:489
struct _Thread_Control * executing
This is the thread executing on this processor.
Definition: percpu.h:457
struct Per_CPU_Control::@4403 Watchdog
Watchdog state for this processor.
The priority node to build up a priority aggregation.
Definition: priority.h:112
Priority_Control priority
The priority value of this node.
Definition: priority.h:124
Scheduler node for per-thread data.
Definition: schedulernode.h:94
struct Scheduler_Node::@4406 Wait
Thread wait support block.
Control block to manage thread actions.
Definition: thread.h:733
Thread action.
Definition: thread.h:706
This structure contains operations which manage the CPU budget of a thread.
Definition: thread.h:188
The configuration of a new thread to initialize.
Definition: threadimpl.h:169
Priority_Control priority
The new thread's priority.
Definition: threadimpl.h:195
const struct _Scheduler_Control * scheduler
The scheduler control instance for the thread.
Definition: threadimpl.h:173
void * stack_area
The starting address of the stack area.
Definition: threadimpl.h:178
size_t stack_size
The size of the stack area in bytes.
Definition: threadimpl.h:183
bool is_preemptible
Indicates whether the new thread is preemptible.
Definition: threadimpl.h:220
const Thread_CPU_budget_operations * cpu_budget_operations
The thread's initial CPU budget operations.
Definition: threadimpl.h:200
uint32_t isr_level
The thread's initial ISR level.
Definition: threadimpl.h:210
uint32_t name
32-bit unsigned integer name of the object for the thread.
Definition: threadimpl.h:205
bool is_fp
Indicates whether the thread needs a floating-point area.
Definition: threadimpl.h:215
Thread entry information.
Definition: thread.h:163
The thread object information.
Definition: thread.h:1133
Objects_Information Objects
The object information.
Definition: thread.h:1137
Thread_Life_state state
The current thread life state.
Definition: thread.h:805
Scheduler_Node * nodes
The scheduler nodes of this thread.
Definition: thread.h:419
Information required to manage a thread timer.
Definition: thread.h:567
Thread_queue_Queue * queue
The current thread queue.
Definition: thread.h:550
Thread_Wait_flags flags
This field contains several flags used to control the wait class and state of a thread in case fine-g...
Definition: thread.h:490
const Thread_queue_Operations * operations
The current thread queue operations.
Definition: thread.h:559
uint32_t return_code
Definition: thread.h:481
The thread zombie registry is used to register threads in the STATES_ZOMBIE state.
Definition: threadimpl.h:73
Chain_Control Chain
This chain contains the registered zombie threads.
Definition: threadimpl.h:84
Thread queue context for the thread queue methods.
Definition: threadq.h:216
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:221
Definition: threadq.h:143
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:148
The thread queue operations are used to manage the threads of a thread queue.
Definition: threadq.h:554
Thread_queue_Extract_operation extract
This operation is used to extract the thread from the thread queue.
Definition: threadq.h:580
Definition: threadq.h:427
The control block used to manage each watchdog timer.
Definition: watchdog.h:109
Watchdog_Service_routine_entry routine
This field is the function to invoke.
Definition: watchdog.h:133
The watchdog header to manage scheduled watchdogs.
Definition: watchdog.h:90
Scheduler control.
Definition: scheduler.h:337
uint32_t name
The scheduler name.
Definition: scheduler.h:359
Definition: thread.h:837
Context_Control Registers
This member contains the context of this thread.
Definition: thread.h:893
Objects_Control Object
Definition: thread.h:839
Timestamp_Control cpu_time_used
This member contains the amount of CPU time consumed by this thread since it was created.
Definition: thread.h:944
Thread_Wait_information Wait
Definition: thread.h:877
Context_Control_fp * fp_context
Definition: thread.h:964
Priority_Node Real_priority
The base priority of this thread in its home scheduler instance.
Definition: thread.h:864
States_Control current_state
Definition: thread.h:859
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:874
Thread_queue_Control Join_queue
Thread queue for thread join operations and multi-purpose lock.
Definition: thread.h:856
Thread_Timer_information Timer
Definition: thread.h:879
Thread_Life_control Life
Thread life-cycle control.
Definition: thread.h:985
Definition: deflate.c:114
Definition: mmu-config.c:53
This header file provides the interfaces of the System State Handler.
This header file provides the interfaces of the Thread Handler Multiprocessing (MP) Support.
This header file provides interfaces of the Thread Queue Handler which are only used by the implement...
This header file provides interfaces of the Timestamp Handler which are only used by the implementati...
This header file provides the interfaces of the Time of Day Handler and the Time of Day Handler Actio...
This union represents a chain control block.
Definition: chain.h:96
This header file provides interfaces of the Watchdog Handler which are only used by the implementatio...