RTEMS 7.0-rc1
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,
247 const Thread_Configuration *config
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#else
1150 (void) executing;
1151#endif
1152#else
1153 (void) executing;
1154#endif
1155}
1156
1162static inline void _Thread_Restore_fp( Thread_Control *executing )
1163{
1164#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1165#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
1166 if ( (executing->fp_context != NULL) &&
1167 !_Thread_Is_allocated_fp( executing ) ) {
1168 if ( _Thread_Allocated_fp != NULL )
1170 _Context_Restore_fp( &executing->fp_context );
1171 _Thread_Allocated_fp = executing;
1172 }
1173#else
1174 if ( executing->fp_context != NULL )
1175 _Context_Restore_fp( &executing->fp_context );
1176#endif
1177#else
1178 (void) executing;
1179#endif
1180}
1181
1188#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1189static inline void _Thread_Deallocate_fp( void )
1190{
1191 _Thread_Allocated_fp = NULL;
1192}
1193#endif
1194
1204static inline bool _Thread_Is_context_switch_necessary( void )
1205{
1206 return ( _Thread_Dispatch_necessary );
1207}
1208
1214static inline uint32_t _Thread_Get_maximum_internal_threads(void)
1215{
1216 /* Idle threads */
1217 uint32_t maximum_internal_threads =
1219
1220 /* MPCI thread */
1221#if defined(RTEMS_MULTIPROCESSING)
1222 if ( _System_state_Is_multiprocessing ) {
1223 ++maximum_internal_threads;
1224 }
1225#endif
1226
1227 return maximum_internal_threads;
1228}
1229
1236static inline Thread_Control *_Thread_Internal_allocate( void )
1237{
1238 return (Thread_Control *)
1239 _Objects_Allocate_unprotected( &_Thread_Information.Objects );
1240}
1241
1255static inline Thread_Control *_Thread_Get_heir_and_make_it_executing(
1256 Per_CPU_Control *cpu_self
1257)
1258{
1259 Thread_Control *heir;
1260
1261 heir = cpu_self->heir;
1262 cpu_self->dispatch_necessary = false;
1263 cpu_self->executing = heir;
1264
1265 return heir;
1266}
1267
1275static inline void _Thread_Update_CPU_time_used(
1276 Thread_Control *the_thread,
1277 Per_CPU_Control *cpu
1278)
1279{
1280 Timestamp_Control last;
1282
1283 last = cpu->cpu_usage_timestamp;
1284 _TOD_Get_uptime( &cpu->cpu_usage_timestamp );
1285 _Timestamp_Subtract( &last, &cpu->cpu_usage_timestamp, &ran );
1286 _Timestamp_Add_to( &the_thread->cpu_time_used, &ran );
1287}
1288
1296#if defined( RTEMS_SMP )
1297static inline void _Thread_Dispatch_update_heir(
1298 Per_CPU_Control *cpu_self,
1299 Per_CPU_Control *cpu_for_heir,
1300 Thread_Control *heir
1301)
1302{
1303 _Thread_Update_CPU_time_used( cpu_for_heir->heir, cpu_for_heir );
1304
1305 cpu_for_heir->heir = heir;
1306
1307 _Thread_Dispatch_request( cpu_self, cpu_for_heir );
1308}
1309#endif
1310
1321
1333 Thread_Control *the_thread
1334);
1335
1346 Thread_Control *the_thread
1347);
1348
1354static inline void _Thread_Action_control_initialize(
1355 Thread_Action_control *action_control
1356)
1357{
1358 _Chain_Initialize_empty( &action_control->Chain );
1359}
1360
1366static inline void _Thread_Action_initialize(
1367 Thread_Action *action
1368)
1369{
1370 _Chain_Set_off_chain( &action->Node );
1371}
1372
1385static inline void _Thread_Add_post_switch_action(
1386 Thread_Control *the_thread,
1387 Thread_Action *action,
1388 Thread_Action_handler handler
1389)
1390{
1391 Per_CPU_Control *cpu_of_thread;
1392
1393 _Assert( _Thread_State_is_owner( the_thread ) );
1394
1395 cpu_of_thread = _Thread_Get_CPU( the_thread );
1396
1397 action->handler = handler;
1398
1399 _Thread_Dispatch_request( _Per_CPU_Get(), cpu_of_thread );
1400
1401 _Chain_Append_if_is_off_chain_unprotected(
1402 &the_thread->Post_switch_actions.Chain,
1403 &action->Node
1404 );
1405}
1406
1418static inline void _Thread_Append_post_switch_action(
1419 Thread_Control *the_thread,
1420 Thread_Action *action
1421)
1422{
1423 _Assert( _Thread_State_is_owner( the_thread ) );
1424 _Assert( action->handler != NULL );
1425
1426 _Chain_Append_unprotected(
1427 &the_thread->Post_switch_actions.Chain,
1428 &action->Node
1429 );
1430}
1431
1440static inline bool _Thread_Is_life_restarting(
1441 Thread_Life_state life_state
1442)
1443{
1444 return ( life_state & THREAD_LIFE_RESTARTING ) != 0;
1445}
1446
1455static inline bool _Thread_Is_life_terminating(
1456 Thread_Life_state life_state
1457)
1458{
1459 return ( life_state & THREAD_LIFE_TERMINATING ) != 0;
1460}
1461
1470static inline bool _Thread_Is_life_change_allowed(
1471 Thread_Life_state life_state
1472)
1473{
1474 return ( life_state
1476}
1477
1486static inline bool _Thread_Is_life_changing(
1487 Thread_Life_state life_state
1488)
1489{
1490 return ( life_state
1492}
1493
1502static inline bool _Thread_Is_joinable(
1503 const Thread_Control *the_thread
1504)
1505{
1506 _Assert( _Thread_State_is_owner( the_thread ) );
1507 return ( the_thread->Life.state & THREAD_LIFE_DETACHED ) == 0;
1508}
1509
1515static inline void _Thread_Resource_count_increment(
1516 Thread_Control *the_thread
1517)
1518{
1519#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1520 ++the_thread->resource_count;
1521#else
1522 (void) the_thread;
1523#endif
1524}
1525
1531static inline void _Thread_Resource_count_decrement(
1532 Thread_Control *the_thread
1533)
1534{
1535#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1536 --the_thread->resource_count;
1537#else
1538 (void) the_thread;
1539#endif
1540}
1541
1542#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1554static inline bool _Thread_Owns_resources(
1555 const Thread_Control *the_thread
1556)
1557{
1558 return the_thread->resource_count != 0;
1559}
1560#endif
1561
1569static inline const Scheduler_Control *_Thread_Scheduler_get_home(
1570 const Thread_Control *the_thread
1571)
1572{
1573#if defined(RTEMS_SMP)
1574 return the_thread->Scheduler.home_scheduler;
1575#else
1576 (void) the_thread;
1577 return &_Scheduler_Table[ 0 ];
1578#endif
1579}
1580
1588static inline Scheduler_Node *_Thread_Scheduler_get_home_node(
1589 const Thread_Control *the_thread
1590)
1591{
1592#if defined(RTEMS_SMP)
1593 _Assert( !_Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
1594 return SCHEDULER_NODE_OF_THREAD_WAIT_NODE(
1595 _Chain_First( &the_thread->Scheduler.Wait_nodes )
1596 );
1597#else
1598 return the_thread->Scheduler.nodes;
1599#endif
1600}
1601
1610static inline Scheduler_Node *_Thread_Scheduler_get_node_by_index(
1611 const Thread_Control *the_thread,
1612 size_t scheduler_index
1613)
1614{
1615 _Assert( scheduler_index < _Scheduler_Count );
1616#if defined(RTEMS_SMP)
1617 return (Scheduler_Node *)
1618 ( (uintptr_t) the_thread->Scheduler.nodes
1619 + scheduler_index * _Scheduler_Node_size );
1620#else
1621 (void) scheduler_index;
1622 return the_thread->Scheduler.nodes;
1623#endif
1624}
1625
1626#if defined(RTEMS_SMP)
1633static inline void _Thread_Scheduler_acquire_critical(
1634 Thread_Control *the_thread,
1635 ISR_lock_Context *lock_context
1636)
1637{
1638 _ISR_lock_Acquire( &the_thread->Scheduler.Lock, lock_context );
1639}
1640
1647static inline void _Thread_Scheduler_release_critical(
1648 Thread_Control *the_thread,
1649 ISR_lock_Context *lock_context
1650)
1651{
1652 _ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context );
1653}
1654
1660void _Thread_Scheduler_process_requests( Thread_Control *the_thread );
1661
1669static inline void _Thread_Scheduler_add_request(
1670 Thread_Control *the_thread,
1671 Scheduler_Node *scheduler_node,
1672 Scheduler_Node_request request
1673)
1674{
1675 ISR_lock_Context lock_context;
1676 Scheduler_Node_request current_request;
1677
1678 _Thread_Scheduler_acquire_critical( the_thread, &lock_context );
1679
1680 current_request = scheduler_node->Thread.request;
1681
1682 if ( current_request == SCHEDULER_NODE_REQUEST_NOT_PENDING ) {
1683 _Assert(
1684 request == SCHEDULER_NODE_REQUEST_ADD
1685 || request == SCHEDULER_NODE_REQUEST_REMOVE
1686 );
1687 _Assert( scheduler_node->Thread.next_request == NULL );
1688 scheduler_node->Thread.next_request = the_thread->Scheduler.requests;
1689 the_thread->Scheduler.requests = scheduler_node;
1690 } else if ( current_request != SCHEDULER_NODE_REQUEST_NOTHING ) {
1691 _Assert(
1692 ( current_request == SCHEDULER_NODE_REQUEST_ADD
1693 && request == SCHEDULER_NODE_REQUEST_REMOVE )
1694 || ( current_request == SCHEDULER_NODE_REQUEST_REMOVE
1695 && request == SCHEDULER_NODE_REQUEST_ADD )
1696 );
1697 request = SCHEDULER_NODE_REQUEST_NOTHING;
1698 }
1699
1700 scheduler_node->Thread.request = request;
1701
1702 _Thread_Scheduler_release_critical( the_thread, &lock_context );
1703}
1704
1712static inline void _Thread_Scheduler_add_wait_node(
1713 Thread_Control *the_thread,
1714 Scheduler_Node *scheduler_node
1715)
1716{
1717 _Chain_Append_unprotected(
1718 &the_thread->Scheduler.Wait_nodes,
1719 &scheduler_node->Thread.Wait_node
1720 );
1721 _Thread_Scheduler_add_request(
1722 the_thread,
1723 scheduler_node,
1724 SCHEDULER_NODE_REQUEST_ADD
1725 );
1726}
1727
1735static inline void _Thread_Scheduler_remove_wait_node(
1736 Thread_Control *the_thread,
1737 Scheduler_Node *scheduler_node
1738)
1739{
1740 _Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
1741 _Thread_Scheduler_add_request(
1742 the_thread,
1743 scheduler_node,
1744 SCHEDULER_NODE_REQUEST_REMOVE
1745 );
1746}
1747#endif
1748
1760static inline Priority_Control _Thread_Get_priority(
1761 const Thread_Control *the_thread
1762)
1763{
1764 Scheduler_Node *scheduler_node;
1765
1766 scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
1767 return _Priority_Get_priority( &scheduler_node->Wait.Priority );
1768}
1769
1777static inline Priority_Control _Thread_Get_unmapped_priority(
1778 const Thread_Control *the_thread
1779)
1780{
1781 return SCHEDULER_PRIORITY_UNMAP( _Thread_Get_priority( the_thread ) );
1782}
1783
1791static inline Priority_Control _Thread_Get_unmapped_real_priority(
1792 const Thread_Control *the_thread
1793)
1794{
1795 return SCHEDULER_PRIORITY_UNMAP( the_thread->Real_priority.priority );
1796}
1797
1808static inline void _Thread_Wait_acquire_default_critical(
1809 Thread_Control *the_thread,
1810 ISR_lock_Context *lock_context
1811)
1812{
1813 _ISR_lock_Acquire( &the_thread->Wait.Lock.Default, lock_context );
1814#ifndef RTEMS_SMP
1815 (void) the_thread;
1816#endif
1817}
1818
1830static inline Thread_Control *_Thread_Wait_acquire_default_for_executing(
1831 ISR_lock_Context *lock_context
1832)
1833{
1834 Thread_Control *executing;
1835
1836 _ISR_lock_ISR_disable( lock_context );
1837 executing = _Thread_Executing;
1838 _Thread_Wait_acquire_default_critical( executing, lock_context );
1839
1840 return executing;
1841}
1842
1852static inline void _Thread_Wait_acquire_default(
1853 Thread_Control *the_thread,
1854 ISR_lock_Context *lock_context
1855)
1856{
1857 _ISR_lock_ISR_disable( lock_context );
1858 _Thread_Wait_acquire_default_critical( the_thread, lock_context );
1859}
1860
1871static inline void _Thread_Wait_release_default_critical(
1872 Thread_Control *the_thread,
1873 ISR_lock_Context *lock_context
1874)
1875{
1876 _ISR_lock_Release( &the_thread->Wait.Lock.Default, lock_context );
1877#ifndef RTEMS_SMP
1878 (void) the_thread;
1879#endif
1880}
1881
1890static inline void _Thread_Wait_release_default(
1891 Thread_Control *the_thread,
1892 ISR_lock_Context *lock_context
1893)
1894{
1895 _Thread_Wait_release_default_critical( the_thread, lock_context );
1896 _ISR_lock_ISR_enable( lock_context );
1897}
1898
1899#if defined(RTEMS_SMP)
1900#define THREAD_QUEUE_CONTEXT_OF_REQUEST( node ) \
1901 RTEMS_CONTAINER_OF( node, Thread_queue_Context, Lock_context.Wait.Gate.Node )
1902
1909static inline void _Thread_Wait_remove_request_locked(
1910 Thread_Control *the_thread,
1911 Thread_queue_Lock_context *queue_lock_context
1912)
1913{
1914 Chain_Node *first;
1915
1916 _Chain_Extract_unprotected( &queue_lock_context->Wait.Gate.Node );
1917 first = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
1918
1919 if ( first != _Chain_Tail( &the_thread->Wait.Lock.Pending_requests ) ) {
1920 _Thread_queue_Gate_open( (Thread_queue_Gate *) first );
1921 }
1922}
1923
1930static inline void _Thread_Wait_acquire_queue_critical(
1931 Thread_queue_Queue *queue,
1932 Thread_queue_Lock_context *queue_lock_context
1933)
1934{
1935 _Thread_queue_Queue_acquire_critical(
1936 queue,
1937 &_Thread_Executing->Potpourri_stats,
1938 &queue_lock_context->Lock_context
1939 );
1940}
1941
1948static inline void _Thread_Wait_release_queue_critical(
1949 Thread_queue_Queue *queue,
1950 Thread_queue_Lock_context *queue_lock_context
1951)
1952{
1953 _Thread_queue_Queue_release_critical(
1954 queue,
1955 &queue_lock_context->Lock_context
1956 );
1957}
1958#endif
1959
1968static inline void _Thread_Wait_acquire_critical(
1969 Thread_Control *the_thread,
1970 Thread_queue_Context *queue_context
1971)
1972{
1973#if defined(RTEMS_SMP)
1974 Thread_queue_Queue *queue;
1975
1976 _Thread_Wait_acquire_default_critical(
1977 the_thread,
1978 &queue_context->Lock_context.Lock_context
1979 );
1980
1981 queue = the_thread->Wait.queue;
1982 queue_context->Lock_context.Wait.queue = queue;
1983
1984 if ( queue != NULL ) {
1985 _Thread_queue_Gate_add(
1986 &the_thread->Wait.Lock.Pending_requests,
1987 &queue_context->Lock_context.Wait.Gate
1988 );
1989 _Thread_Wait_release_default_critical(
1990 the_thread,
1991 &queue_context->Lock_context.Lock_context
1992 );
1993 _Thread_Wait_acquire_queue_critical( queue, &queue_context->Lock_context );
1994
1995 if ( queue_context->Lock_context.Wait.queue == NULL ) {
1996 _Thread_Wait_release_queue_critical(
1997 queue,
1998 &queue_context->Lock_context
1999 );
2000 _Thread_Wait_acquire_default_critical(
2001 the_thread,
2002 &queue_context->Lock_context.Lock_context
2003 );
2004 _Thread_Wait_remove_request_locked(
2005 the_thread,
2006 &queue_context->Lock_context
2007 );
2008 _Assert( the_thread->Wait.queue == NULL );
2009 }
2010 }
2011#else
2012 (void) the_thread;
2013 (void) queue_context;
2014#endif
2015}
2016
2024static inline void _Thread_Wait_acquire(
2025 Thread_Control *the_thread,
2026 Thread_queue_Context *queue_context
2027)
2028{
2030 _Thread_Wait_acquire_critical( the_thread, queue_context );
2031}
2032
2043static inline void _Thread_Wait_release_critical(
2044 Thread_Control *the_thread,
2045 Thread_queue_Context *queue_context
2046)
2047{
2048#if defined(RTEMS_SMP)
2049 Thread_queue_Queue *queue;
2050
2051 queue = queue_context->Lock_context.Wait.queue;
2052
2053 if ( queue != NULL ) {
2054 _Thread_Wait_release_queue_critical(
2055 queue, &queue_context->Lock_context
2056 );
2057 _Thread_Wait_acquire_default_critical(
2058 the_thread,
2059 &queue_context->Lock_context.Lock_context
2060 );
2061 _Thread_Wait_remove_request_locked(
2062 the_thread,
2063 &queue_context->Lock_context
2064 );
2065 }
2066
2067 _Thread_Wait_release_default_critical(
2068 the_thread,
2069 &queue_context->Lock_context.Lock_context
2070 );
2071#else
2072 (void) the_thread;
2073 (void) queue_context;
2074#endif
2075}
2076
2085static inline void _Thread_Wait_release(
2086 Thread_Control *the_thread,
2087 Thread_queue_Context *queue_context
2088)
2089{
2090 _Thread_Wait_release_critical( the_thread, queue_context );
2092}
2093
2108static inline void _Thread_Wait_claim(
2109 Thread_Control *the_thread,
2110 Thread_queue_Queue *queue
2111)
2112{
2113 ISR_lock_Context lock_context;
2114
2115 _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
2116
2117 _Assert( the_thread->Wait.queue == NULL );
2118
2119#if defined(RTEMS_SMP)
2120 _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
2121 _Chain_Initialize_node( &the_thread->Wait.Lock.Tranquilizer.Node );
2122 _Thread_queue_Gate_close( &the_thread->Wait.Lock.Tranquilizer );
2123#endif
2124
2125 the_thread->Wait.queue = queue;
2126
2127 _Thread_Wait_release_default_critical( the_thread, &lock_context );
2128}
2129
2137static inline void _Thread_Wait_claim_finalize(
2138 Thread_Control *the_thread,
2139 const Thread_queue_Operations *operations
2140)
2141{
2142 the_thread->Wait.operations = operations;
2143}
2144
2156static inline void _Thread_Wait_remove_request(
2157 Thread_Control *the_thread,
2158 Thread_queue_Lock_context *queue_lock_context
2159)
2160{
2161#if defined(RTEMS_SMP)
2162 ISR_lock_Context lock_context;
2163
2164 _Thread_Wait_acquire_default( the_thread, &lock_context );
2165 _Thread_Wait_remove_request_locked( the_thread, queue_lock_context );
2166 _Thread_Wait_release_default( the_thread, &lock_context );
2167#else
2168 (void) the_thread;
2169 (void) queue_lock_context;
2170#endif
2171}
2172
2185static inline void _Thread_Wait_restore_default(
2186 Thread_Control *the_thread
2187)
2188{
2189#if defined(RTEMS_SMP)
2190 ISR_lock_Context lock_context;
2191 Chain_Node *node;
2192 const Chain_Node *tail;
2193
2194 _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
2195
2196 node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
2197 tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
2198
2199 if ( node != tail ) {
2200 do {
2201 Thread_queue_Context *queue_context;
2202
2203 queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
2204 queue_context->Lock_context.Wait.queue = NULL;
2205
2206 node = _Chain_Next( node );
2207 } while ( node != tail );
2208
2209 _Thread_queue_Gate_add(
2210 &the_thread->Wait.Lock.Pending_requests,
2211 &the_thread->Wait.Lock.Tranquilizer
2212 );
2213 } else {
2214 _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
2215 }
2216#endif
2217
2218 the_thread->Wait.queue = NULL;
2220
2221#if defined(RTEMS_SMP)
2222 _Thread_Wait_release_default_critical( the_thread, &lock_context );
2223#endif
2224}
2225
2244static inline void _Thread_Wait_tranquilize(
2245 Thread_Control *the_thread
2246)
2247{
2248#if defined(RTEMS_SMP)
2249 _Thread_queue_Gate_wait( &the_thread->Wait.Lock.Tranquilizer );
2250#else
2251 (void) the_thread;
2252#endif
2253}
2254
2262static inline void _Thread_Wait_cancel(
2263 Thread_Control *the_thread,
2264 Thread_queue_Context *queue_context
2265)
2266{
2267 Thread_queue_Queue *queue;
2268
2269 queue = the_thread->Wait.queue;
2270
2271 if ( queue != NULL ) {
2272#if defined(RTEMS_SMP)
2273 _Assert( queue_context->Lock_context.Wait.queue == queue );
2274#endif
2275
2276 ( *the_thread->Wait.operations->extract )(
2277 queue,
2278 the_thread,
2279 queue_context
2280 );
2281 _Thread_Wait_restore_default( the_thread );
2282
2283#if defined(RTEMS_SMP)
2284 _Assert( queue_context->Lock_context.Wait.queue == NULL );
2285 queue_context->Lock_context.Wait.queue = queue;
2286#endif
2287 }
2288}
2289
2293#define THREAD_WAIT_STATE_MASK 0xffU
2294
2302#define THREAD_WAIT_STATE_READY 0x0U
2303
2311#define THREAD_WAIT_STATE_INTEND_TO_BLOCK 0x1U
2312
2316#define THREAD_WAIT_STATE_BLOCKED 0x2U
2317
2321#define THREAD_WAIT_CLASS_MASK 0xff00U
2322
2326#define THREAD_WAIT_CLASS_EVENT 0x100U
2327
2331#define THREAD_WAIT_CLASS_SYSTEM_EVENT 0x200U
2332
2336#define THREAD_WAIT_CLASS_OBJECT 0x400U
2337
2341#define THREAD_WAIT_CLASS_PERIOD 0x800U
2342
2349static inline void _Thread_Wait_flags_set(
2350 Thread_Control *the_thread,
2351 Thread_Wait_flags flags
2352)
2353{
2354#if defined(RTEMS_SMP)
2355 _Atomic_Store_uint( &the_thread->Wait.flags, flags, ATOMIC_ORDER_RELAXED );
2356#else
2357 the_thread->Wait.flags = flags;
2358#endif
2359}
2360
2368static inline Thread_Wait_flags _Thread_Wait_flags_get(
2369 const Thread_Control *the_thread
2370)
2371{
2372#if defined(RTEMS_SMP)
2373 return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_RELAXED );
2374#else
2375 return the_thread->Wait.flags;
2376#endif
2377}
2378
2386static inline Thread_Wait_flags _Thread_Wait_flags_get_acquire(
2387 const Thread_Control *the_thread
2388)
2389{
2390#if defined(RTEMS_SMP)
2391 return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_ACQUIRE );
2392#else
2393 return the_thread->Wait.flags;
2394#endif
2395}
2396
2413static inline bool _Thread_Wait_flags_try_change_release(
2414 Thread_Control *the_thread,
2415 Thread_Wait_flags expected_flags,
2416 Thread_Wait_flags desired_flags
2417)
2418{
2419 _Assert( _ISR_Get_level() != 0 );
2420
2421#if defined(RTEMS_SMP)
2422 return _Atomic_Compare_exchange_uint(
2423 &the_thread->Wait.flags,
2424 &expected_flags,
2425 desired_flags,
2426 ATOMIC_ORDER_RELEASE,
2427 ATOMIC_ORDER_RELAXED
2428 );
2429#else
2430 bool success = ( the_thread->Wait.flags == expected_flags );
2431
2432 if ( success ) {
2433 the_thread->Wait.flags = desired_flags;
2434 }
2435
2436 return success;
2437#endif
2438}
2439
2453static inline bool _Thread_Wait_flags_try_change_acquire(
2454 Thread_Control *the_thread,
2455 Thread_Wait_flags expected_flags,
2456 Thread_Wait_flags desired_flags
2457)
2458{
2459#if defined(RTEMS_SMP)
2460 return _Atomic_Compare_exchange_uint(
2461 &the_thread->Wait.flags,
2462 &expected_flags,
2463 desired_flags,
2464 ATOMIC_ORDER_ACQUIRE,
2465 ATOMIC_ORDER_ACQUIRE
2466 );
2467#else
2468 bool success;
2469 ISR_Level level;
2470
2471 _ISR_Local_disable( level );
2472
2473 success = _Thread_Wait_flags_try_change_release(
2474 the_thread,
2475 expected_flags,
2476 desired_flags
2477 );
2478
2479 _ISR_Local_enable( level );
2480 return success;
2481#endif
2482}
2483
2500Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread );
2501
2507static inline Status_Control _Thread_Wait_get_status(
2508 const Thread_Control *the_thread
2509)
2510{
2511 return (Status_Control) the_thread->Wait.return_code;
2512}
2513
2526void _Thread_Continue( Thread_Control *the_thread, Status_Control status );
2527
2533void _Thread_Timeout( Watchdog_Control *the_watchdog );
2534
2541static inline void _Thread_Timer_initialize(
2543 Per_CPU_Control *cpu
2544)
2545{
2546 _ISR_lock_Initialize( &timer->Lock, "Thread Timer" );
2547 timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
2548 _Watchdog_Preinitialize( &timer->Watchdog, cpu );
2549}
2550
2558static inline void _Thread_Add_timeout_ticks(
2559 Thread_Control *the_thread,
2560 Per_CPU_Control *cpu,
2561 Watchdog_Interval ticks
2562)
2563{
2564 ISR_lock_Context lock_context;
2565
2566 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2567
2568 the_thread->Timer.header =
2570 the_thread->Timer.Watchdog.routine = _Thread_Timeout;
2571 _Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks );
2572
2573 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2574}
2575
2584static inline void _Thread_Timer_insert_realtime(
2585 Thread_Control *the_thread,
2586 Per_CPU_Control *cpu,
2588 uint64_t expire
2589)
2590{
2591 ISR_lock_Context lock_context;
2592 Watchdog_Header *header;
2593
2594 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2595
2596 header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
2597 the_thread->Timer.header = header;
2598 the_thread->Timer.Watchdog.routine = routine;
2599 _Watchdog_Per_CPU_insert( &the_thread->Timer.Watchdog, cpu, header, expire );
2600
2601 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2602}
2603
2609static inline void _Thread_Timer_remove( Thread_Control *the_thread )
2610{
2611 ISR_lock_Context lock_context;
2612
2613 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2614
2615 _Watchdog_Per_CPU_remove(
2616 &the_thread->Timer.Watchdog,
2617#if defined(RTEMS_SMP)
2618 the_thread->Timer.Watchdog.cpu,
2619#else
2620 _Per_CPU_Get(),
2621#endif
2622 the_thread->Timer.header
2623 );
2624
2625 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2626}
2627
2635static inline void _Thread_Remove_timer_and_unblock(
2636 Thread_Control *the_thread,
2637 Thread_queue_Queue *queue
2638)
2639{
2640 _Thread_Wait_tranquilize( the_thread );
2641 _Thread_Timer_remove( the_thread );
2642
2643#if defined(RTEMS_MULTIPROCESSING)
2644 if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
2645 _Thread_Unblock( the_thread );
2646 } else {
2647 _Thread_queue_Unblock_proxy( queue, the_thread );
2648 }
2649#else
2650 (void) queue;
2651 _Thread_Unblock( the_thread );
2652#endif
2653}
2654
2665 Thread_Control *the_thread,
2666 const char *name
2667);
2668
2678size_t _Thread_Get_name(
2679 const Thread_Control *the_thread,
2680 char *buffer,
2681 size_t buffer_size
2682);
2683
2684#if defined(RTEMS_SMP)
2685#define THREAD_PIN_STEP 2
2686
2687#define THREAD_PIN_PREEMPTION 1
2688
2695void _Thread_Do_unpin(
2696 Thread_Control *executing,
2697 Per_CPU_Control *cpu_self
2698);
2699#endif
2700
2706static inline void _Thread_Pin( Thread_Control *executing )
2707{
2708#if defined(RTEMS_SMP)
2709 _Assert( executing == _Thread_Get_executing() );
2710
2711 executing->Scheduler.pin_level += THREAD_PIN_STEP;
2712#else
2713 (void) executing;
2714#endif
2715}
2716
2723static inline void _Thread_Unpin(
2724 Thread_Control *executing,
2725 Per_CPU_Control *cpu_self
2726)
2727{
2728#if defined(RTEMS_SMP)
2729 unsigned int pin_level;
2730
2731 _Assert( executing == _Per_CPU_Get_executing( cpu_self ) );
2732
2733 pin_level = executing->Scheduler.pin_level;
2734 _Assert( pin_level > 0 );
2735
2736 if (
2738 pin_level != ( THREAD_PIN_STEP | THREAD_PIN_PREEMPTION )
2739 )
2740 ) {
2741 executing->Scheduler.pin_level = pin_level - THREAD_PIN_STEP;
2742 } else {
2743 _Thread_Do_unpin( executing, cpu_self );
2744 }
2745#else
2746 (void) executing;
2747 (void) cpu_self;
2748#endif
2749}
2750
2753#ifdef __cplusplus
2754}
2755#endif
2756
2757#if defined(RTEMS_MULTIPROCESSING)
2758#include <rtems/score/threadmp.h>
2759#endif
2760
2761#ifdef __cplusplus
2762extern "C" {
2763#endif
2764
2775static inline void _Thread_Timer_remove_and_continue(
2776 Thread_Control *the_thread,
2777 Status_Control status
2778)
2779{
2780 _Thread_Timer_remove( the_thread );
2781#if defined(RTEMS_MULTIPROCESSING)
2782 _Thread_MP_Extract_proxy( the_thread );
2783#endif
2784 _Thread_Continue( the_thread, status );
2785}
2786
2787#ifdef __cplusplus
2788}
2789#endif
2790
2791#endif
2792/* 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:776
#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:1534
Status_Control _Thread_Restart(Thread_Control *the_thread, const Thread_Entry_information *entry, ISR_lock_Context *lock_context)
Restarts the thread.
Definition: threadrestart.c:538
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:503
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:626
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:467
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:99
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:599
@ 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
struct Per_CPU_Control::@4363 Watchdog
Watchdog state for this processor.
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
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::@4366 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:217
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:222
Definition: threadq.h:144
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:149
The thread queue operations are used to manage the threads of a thread queue.
Definition: threadq.h:563
Thread_queue_Extract_operation extract
This operation is used to extract the thread from the thread queue.
Definition: threadq.h:589
Definition: threadq.h:436
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: 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...