RTEMS 6.1-rc1
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)
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 );
804 the_thread,
805 priority_node,
806 priority_group_order,
807 queue_context
808 );
809}
810
811#if defined(RTEMS_SMP)
824void _Thread_Priority_replace(
825 Thread_Control *the_thread,
826 Priority_Node *victim_node,
827 Priority_Node *replacement_node
828);
829#endif
830
842void _Thread_Priority_update( Thread_queue_Context *queue_context );
843
844#if defined(RTEMS_SMP)
851void _Thread_Priority_update_and_make_sticky( Thread_Control *the_thread );
852
859void _Thread_Priority_update_and_clean_sticky( Thread_Control *the_thread );
860
866void _Thread_Priority_update_ignore_sticky( Thread_Control *the_thread );
867#endif
868
879static inline bool _Thread_Priority_less_than(
880 Priority_Control left,
881 Priority_Control right
882)
883{
884 return left > right;
885}
886
896static inline Priority_Control _Thread_Priority_highest(
897 Priority_Control left,
898 Priority_Control right
899)
900{
901 return _Thread_Priority_less_than( left, right ) ? right : left;
902}
903
916static inline Objects_Information *_Thread_Get_objects_information_by_id(
917 Objects_Id id
918)
919{
920 uint32_t the_api;
921
922 the_api = _Objects_Get_API( id );
923
924 if ( !_Objects_Is_api_valid( the_api ) ) {
925 return NULL;
926 }
927
928 /*
929 * Threads are always first class :)
930 *
931 * There is no need to validate the object class of the object identifier,
932 * since this will be done by the object get methods.
933 */
934 return _Objects_Information_table[ the_api ][ 1 ];
935}
936
944static inline Thread_Information *_Thread_Get_objects_information(
945 Thread_Control *the_thread
946)
947{
948 size_t the_api;
949 Thread_Information *information;
950
951 the_api = (size_t) _Objects_Get_API( the_thread->Object.id );
952 _Assert( _Objects_Is_api_valid( the_api ) );
953
954 information = (Thread_Information *)
955 _Objects_Information_table[ the_api ][ 1 ];
956 _Assert( information != NULL );
957
958 return information;
959}
960
970 Objects_Id id,
971 ISR_lock_Context *lock_context
972);
973
980
988static inline Per_CPU_Control *_Thread_Get_CPU(
989 const Thread_Control *thread
990)
991{
992#if defined(RTEMS_SMP)
993 return thread->Scheduler.cpu;
994#else
995 (void) thread;
996
997 return _Per_CPU_Get();
998#endif
999}
1000
1007static inline void _Thread_Set_CPU(
1008 Thread_Control *thread,
1009 Per_CPU_Control *cpu
1010)
1011{
1012#if defined(RTEMS_SMP)
1013 thread->Scheduler.cpu = cpu;
1014#else
1015 (void) thread;
1016 (void) cpu;
1017#endif
1018}
1019
1031static inline bool _Thread_Is_executing (
1032 const Thread_Control *the_thread
1033)
1034{
1035 return ( the_thread == _Thread_Executing );
1036}
1037
1038#if defined(RTEMS_SMP)
1051static inline bool _Thread_Is_executing_on_a_processor(
1052 const Thread_Control *the_thread
1053)
1054{
1055 return _CPU_Context_Get_is_executing( &the_thread->Registers );
1056}
1057#endif
1058
1070static inline bool _Thread_Is_heir (
1071 const Thread_Control *the_thread
1072)
1073{
1074 return ( the_thread == _Thread_Heir );
1075}
1076
1086static inline void _Thread_Unblock (
1087 Thread_Control *the_thread
1088)
1089{
1090 _Thread_Clear_state( the_thread, STATES_BLOCKED );
1091}
1092
1108#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1109static inline bool _Thread_Is_allocated_fp (
1110 const Thread_Control *the_thread
1111)
1112{
1113 return ( the_thread == _Thread_Allocated_fp );
1114}
1115#endif
1116
1117/*
1118 * If the CPU has hardware floating point, then we must address saving
1119 * and restoring it as part of the context switch.
1120 *
1121 * The second conditional compilation section selects the algorithm used
1122 * to context switch between floating point tasks. The deferred algorithm
1123 * can be significantly better in a system with few floating point tasks
1124 * because it reduces the total number of save and restore FP context
1125 * operations. However, this algorithm can not be used on all CPUs due
1126 * to unpredictable use of FP registers by some compilers for integer
1127 * operations.
1128 */
1129
1135static inline void _Thread_Save_fp( Thread_Control *executing )
1136{
1137#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1138#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
1139 if ( executing->fp_context != NULL )
1140 _Context_Save_fp( &executing->fp_context );
1141#endif
1142#endif
1143}
1144
1150static inline void _Thread_Restore_fp( Thread_Control *executing )
1151{
1152#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1153#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
1154 if ( (executing->fp_context != NULL) &&
1155 !_Thread_Is_allocated_fp( executing ) ) {
1156 if ( _Thread_Allocated_fp != NULL )
1158 _Context_Restore_fp( &executing->fp_context );
1159 _Thread_Allocated_fp = executing;
1160 }
1161#else
1162 if ( executing->fp_context != NULL )
1163 _Context_Restore_fp( &executing->fp_context );
1164#endif
1165#endif
1166}
1167
1174#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
1175static inline void _Thread_Deallocate_fp( void )
1176{
1178}
1179#endif
1180
1190static inline bool _Thread_Is_context_switch_necessary( void )
1191{
1192 return ( _Thread_Dispatch_necessary );
1193}
1194
1200static inline uint32_t _Thread_Get_maximum_internal_threads(void)
1201{
1202 /* Idle threads */
1203 uint32_t maximum_internal_threads =
1205
1206 /* MPCI thread */
1207#if defined(RTEMS_MULTIPROCESSING)
1208 if ( _System_state_Is_multiprocessing ) {
1209 ++maximum_internal_threads;
1210 }
1211#endif
1212
1213 return maximum_internal_threads;
1214}
1215
1222static inline Thread_Control *_Thread_Internal_allocate( void )
1223{
1224 return (Thread_Control *)
1225 _Objects_Allocate_unprotected( &_Thread_Information.Objects );
1226}
1227
1241static inline Thread_Control *_Thread_Get_heir_and_make_it_executing(
1242 Per_CPU_Control *cpu_self
1243)
1244{
1245 Thread_Control *heir;
1246
1247 heir = cpu_self->heir;
1248 cpu_self->dispatch_necessary = false;
1249 cpu_self->executing = heir;
1250
1251 return heir;
1252}
1253
1261static inline void _Thread_Update_CPU_time_used(
1262 Thread_Control *the_thread,
1263 Per_CPU_Control *cpu
1264)
1265{
1266 Timestamp_Control last;
1268
1269 last = cpu->cpu_usage_timestamp;
1270 _TOD_Get_uptime( &cpu->cpu_usage_timestamp );
1271 _Timestamp_Subtract( &last, &cpu->cpu_usage_timestamp, &ran );
1272 _Timestamp_Add_to( &the_thread->cpu_time_used, &ran );
1273}
1274
1282#if defined( RTEMS_SMP )
1283static inline void _Thread_Dispatch_update_heir(
1284 Per_CPU_Control *cpu_self,
1285 Per_CPU_Control *cpu_for_heir,
1286 Thread_Control *heir
1287)
1288{
1289 _Thread_Update_CPU_time_used( cpu_for_heir->heir, cpu_for_heir );
1290
1291 cpu_for_heir->heir = heir;
1292
1293 _Thread_Dispatch_request( cpu_self, cpu_for_heir );
1294}
1295#endif
1296
1307
1319 Thread_Control *the_thread
1320);
1321
1332 Thread_Control *the_thread
1333);
1334
1340static inline void _Thread_Action_control_initialize(
1341 Thread_Action_control *action_control
1342)
1343{
1344 _Chain_Initialize_empty( &action_control->Chain );
1345}
1346
1352static inline void _Thread_Action_initialize(
1353 Thread_Action *action
1354)
1355{
1356 _Chain_Set_off_chain( &action->Node );
1357}
1358
1371static inline void _Thread_Add_post_switch_action(
1372 Thread_Control *the_thread,
1373 Thread_Action *action,
1374 Thread_Action_handler handler
1375)
1376{
1377 Per_CPU_Control *cpu_of_thread;
1378
1379 _Assert( _Thread_State_is_owner( the_thread ) );
1380
1381 cpu_of_thread = _Thread_Get_CPU( the_thread );
1382
1383 action->handler = handler;
1384
1385 _Thread_Dispatch_request( _Per_CPU_Get(), cpu_of_thread );
1386
1387 _Chain_Append_if_is_off_chain_unprotected(
1388 &the_thread->Post_switch_actions.Chain,
1389 &action->Node
1390 );
1391}
1392
1404static inline void _Thread_Append_post_switch_action(
1405 Thread_Control *the_thread,
1406 Thread_Action *action
1407)
1408{
1409 _Assert( _Thread_State_is_owner( the_thread ) );
1410 _Assert( action->handler != NULL );
1411
1412 _Chain_Append_unprotected(
1413 &the_thread->Post_switch_actions.Chain,
1414 &action->Node
1415 );
1416}
1417
1426static inline bool _Thread_Is_life_restarting(
1427 Thread_Life_state life_state
1428)
1429{
1430 return ( life_state & THREAD_LIFE_RESTARTING ) != 0;
1431}
1432
1441static inline bool _Thread_Is_life_terminating(
1442 Thread_Life_state life_state
1443)
1444{
1445 return ( life_state & THREAD_LIFE_TERMINATING ) != 0;
1446}
1447
1456static inline bool _Thread_Is_life_change_allowed(
1457 Thread_Life_state life_state
1458)
1459{
1460 return ( life_state
1462}
1463
1472static inline bool _Thread_Is_life_changing(
1473 Thread_Life_state life_state
1474)
1475{
1476 return ( life_state
1478}
1479
1488static inline bool _Thread_Is_joinable(
1489 const Thread_Control *the_thread
1490)
1491{
1492 _Assert( _Thread_State_is_owner( the_thread ) );
1493 return ( the_thread->Life.state & THREAD_LIFE_DETACHED ) == 0;
1494}
1495
1501static inline void _Thread_Resource_count_increment(
1502 Thread_Control *the_thread
1503)
1504{
1505#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1506 ++the_thread->resource_count;
1507#else
1508 (void) the_thread;
1509#endif
1510}
1511
1517static inline void _Thread_Resource_count_decrement(
1518 Thread_Control *the_thread
1519)
1520{
1521#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1522 --the_thread->resource_count;
1523#else
1524 (void) the_thread;
1525#endif
1526}
1527
1528#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
1540static inline bool _Thread_Owns_resources(
1541 const Thread_Control *the_thread
1542)
1543{
1544 return the_thread->resource_count != 0;
1545}
1546#endif
1547
1555static inline const Scheduler_Control *_Thread_Scheduler_get_home(
1556 const Thread_Control *the_thread
1557)
1558{
1559#if defined(RTEMS_SMP)
1560 return the_thread->Scheduler.home_scheduler;
1561#else
1562 (void) the_thread;
1563 return &_Scheduler_Table[ 0 ];
1564#endif
1565}
1566
1574static inline Scheduler_Node *_Thread_Scheduler_get_home_node(
1575 const Thread_Control *the_thread
1576)
1577{
1578#if defined(RTEMS_SMP)
1579 _Assert( !_Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
1580 return SCHEDULER_NODE_OF_THREAD_WAIT_NODE(
1581 _Chain_First( &the_thread->Scheduler.Wait_nodes )
1582 );
1583#else
1584 return the_thread->Scheduler.nodes;
1585#endif
1586}
1587
1596static inline Scheduler_Node *_Thread_Scheduler_get_node_by_index(
1597 const Thread_Control *the_thread,
1598 size_t scheduler_index
1599)
1600{
1601 _Assert( scheduler_index < _Scheduler_Count );
1602#if defined(RTEMS_SMP)
1603 return (Scheduler_Node *)
1604 ( (uintptr_t) the_thread->Scheduler.nodes
1605 + scheduler_index * _Scheduler_Node_size );
1606#else
1607 (void) scheduler_index;
1608 return the_thread->Scheduler.nodes;
1609#endif
1610}
1611
1612#if defined(RTEMS_SMP)
1619static inline void _Thread_Scheduler_acquire_critical(
1620 Thread_Control *the_thread,
1621 ISR_lock_Context *lock_context
1622)
1623{
1624 _ISR_lock_Acquire( &the_thread->Scheduler.Lock, lock_context );
1625}
1626
1633static inline void _Thread_Scheduler_release_critical(
1634 Thread_Control *the_thread,
1635 ISR_lock_Context *lock_context
1636)
1637{
1638 _ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context );
1639}
1640
1646void _Thread_Scheduler_process_requests( Thread_Control *the_thread );
1647
1655static inline void _Thread_Scheduler_add_request(
1656 Thread_Control *the_thread,
1657 Scheduler_Node *scheduler_node,
1658 Scheduler_Node_request request
1659)
1660{
1661 ISR_lock_Context lock_context;
1662 Scheduler_Node_request current_request;
1663
1664 _Thread_Scheduler_acquire_critical( the_thread, &lock_context );
1665
1666 current_request = scheduler_node->Thread.request;
1667
1668 if ( current_request == SCHEDULER_NODE_REQUEST_NOT_PENDING ) {
1669 _Assert(
1670 request == SCHEDULER_NODE_REQUEST_ADD
1671 || request == SCHEDULER_NODE_REQUEST_REMOVE
1672 );
1673 _Assert( scheduler_node->Thread.next_request == NULL );
1674 scheduler_node->Thread.next_request = the_thread->Scheduler.requests;
1675 the_thread->Scheduler.requests = scheduler_node;
1676 } else if ( current_request != SCHEDULER_NODE_REQUEST_NOTHING ) {
1677 _Assert(
1678 ( current_request == SCHEDULER_NODE_REQUEST_ADD
1679 && request == SCHEDULER_NODE_REQUEST_REMOVE )
1680 || ( current_request == SCHEDULER_NODE_REQUEST_REMOVE
1681 && request == SCHEDULER_NODE_REQUEST_ADD )
1682 );
1683 request = SCHEDULER_NODE_REQUEST_NOTHING;
1684 }
1685
1686 scheduler_node->Thread.request = request;
1687
1688 _Thread_Scheduler_release_critical( the_thread, &lock_context );
1689}
1690
1698static inline void _Thread_Scheduler_add_wait_node(
1699 Thread_Control *the_thread,
1700 Scheduler_Node *scheduler_node
1701)
1702{
1703 _Chain_Append_unprotected(
1704 &the_thread->Scheduler.Wait_nodes,
1705 &scheduler_node->Thread.Wait_node
1706 );
1707 _Thread_Scheduler_add_request(
1708 the_thread,
1709 scheduler_node,
1710 SCHEDULER_NODE_REQUEST_ADD
1711 );
1712}
1713
1721static inline void _Thread_Scheduler_remove_wait_node(
1722 Thread_Control *the_thread,
1723 Scheduler_Node *scheduler_node
1724)
1725{
1726 _Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
1727 _Thread_Scheduler_add_request(
1728 the_thread,
1729 scheduler_node,
1730 SCHEDULER_NODE_REQUEST_REMOVE
1731 );
1732}
1733#endif
1734
1746static inline Priority_Control _Thread_Get_priority(
1747 const Thread_Control *the_thread
1748)
1749{
1750 Scheduler_Node *scheduler_node;
1751
1752 scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
1753 return _Priority_Get_priority( &scheduler_node->Wait.Priority );
1754}
1755
1763static inline Priority_Control _Thread_Get_unmapped_priority(
1764 const Thread_Control *the_thread
1765)
1766{
1767 return SCHEDULER_PRIORITY_UNMAP( _Thread_Get_priority( the_thread ) );
1768}
1769
1777static inline Priority_Control _Thread_Get_unmapped_real_priority(
1778 const Thread_Control *the_thread
1779)
1780{
1781 return SCHEDULER_PRIORITY_UNMAP( the_thread->Real_priority.priority );
1782}
1783
1794static inline void _Thread_Wait_acquire_default_critical(
1795 Thread_Control *the_thread,
1796 ISR_lock_Context *lock_context
1797)
1798{
1799 _ISR_lock_Acquire( &the_thread->Wait.Lock.Default, lock_context );
1800}
1801
1813static inline Thread_Control *_Thread_Wait_acquire_default_for_executing(
1814 ISR_lock_Context *lock_context
1815)
1816{
1817 Thread_Control *executing;
1818
1819 _ISR_lock_ISR_disable( lock_context );
1820 executing = _Thread_Executing;
1821 _Thread_Wait_acquire_default_critical( executing, lock_context );
1822
1823 return executing;
1824}
1825
1835static inline void _Thread_Wait_acquire_default(
1836 Thread_Control *the_thread,
1837 ISR_lock_Context *lock_context
1838)
1839{
1840 _ISR_lock_ISR_disable( lock_context );
1841 _Thread_Wait_acquire_default_critical( the_thread, lock_context );
1842}
1843
1854static inline void _Thread_Wait_release_default_critical(
1855 Thread_Control *the_thread,
1856 ISR_lock_Context *lock_context
1857)
1858{
1859 _ISR_lock_Release( &the_thread->Wait.Lock.Default, lock_context );
1860}
1861
1870static inline void _Thread_Wait_release_default(
1871 Thread_Control *the_thread,
1872 ISR_lock_Context *lock_context
1873)
1874{
1875 _Thread_Wait_release_default_critical( the_thread, lock_context );
1876 _ISR_lock_ISR_enable( lock_context );
1877}
1878
1879#if defined(RTEMS_SMP)
1880#define THREAD_QUEUE_CONTEXT_OF_REQUEST( node ) \
1881 RTEMS_CONTAINER_OF( node, Thread_queue_Context, Lock_context.Wait.Gate.Node )
1882
1889static inline void _Thread_Wait_remove_request_locked(
1890 Thread_Control *the_thread,
1891 Thread_queue_Lock_context *queue_lock_context
1892)
1893{
1894 Chain_Node *first;
1895
1896 _Chain_Extract_unprotected( &queue_lock_context->Wait.Gate.Node );
1897 first = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
1898
1899 if ( first != _Chain_Tail( &the_thread->Wait.Lock.Pending_requests ) ) {
1900 _Thread_queue_Gate_open( (Thread_queue_Gate *) first );
1901 }
1902}
1903
1910static inline void _Thread_Wait_acquire_queue_critical(
1911 Thread_queue_Queue *queue,
1912 Thread_queue_Lock_context *queue_lock_context
1913)
1914{
1915 _Thread_queue_Queue_acquire_critical(
1916 queue,
1917 &_Thread_Executing->Potpourri_stats,
1918 &queue_lock_context->Lock_context
1919 );
1920}
1921
1928static inline void _Thread_Wait_release_queue_critical(
1929 Thread_queue_Queue *queue,
1930 Thread_queue_Lock_context *queue_lock_context
1931)
1932{
1933 _Thread_queue_Queue_release_critical(
1934 queue,
1935 &queue_lock_context->Lock_context
1936 );
1937}
1938#endif
1939
1948static inline void _Thread_Wait_acquire_critical(
1949 Thread_Control *the_thread,
1950 Thread_queue_Context *queue_context
1951)
1952{
1953#if defined(RTEMS_SMP)
1954 Thread_queue_Queue *queue;
1955
1956 _Thread_Wait_acquire_default_critical(
1957 the_thread,
1958 &queue_context->Lock_context.Lock_context
1959 );
1960
1961 queue = the_thread->Wait.queue;
1962 queue_context->Lock_context.Wait.queue = queue;
1963
1964 if ( queue != NULL ) {
1965 _Thread_queue_Gate_add(
1966 &the_thread->Wait.Lock.Pending_requests,
1967 &queue_context->Lock_context.Wait.Gate
1968 );
1969 _Thread_Wait_release_default_critical(
1970 the_thread,
1971 &queue_context->Lock_context.Lock_context
1972 );
1973 _Thread_Wait_acquire_queue_critical( queue, &queue_context->Lock_context );
1974
1975 if ( queue_context->Lock_context.Wait.queue == NULL ) {
1976 _Thread_Wait_release_queue_critical(
1977 queue,
1978 &queue_context->Lock_context
1979 );
1980 _Thread_Wait_acquire_default_critical(
1981 the_thread,
1982 &queue_context->Lock_context.Lock_context
1983 );
1984 _Thread_Wait_remove_request_locked(
1985 the_thread,
1986 &queue_context->Lock_context
1987 );
1988 _Assert( the_thread->Wait.queue == NULL );
1989 }
1990 }
1991#else
1992 (void) the_thread;
1993 (void) queue_context;
1994#endif
1995}
1996
2004static inline void _Thread_Wait_acquire(
2005 Thread_Control *the_thread,
2006 Thread_queue_Context *queue_context
2007)
2008{
2010 _Thread_Wait_acquire_critical( the_thread, queue_context );
2011}
2012
2023static inline void _Thread_Wait_release_critical(
2024 Thread_Control *the_thread,
2025 Thread_queue_Context *queue_context
2026)
2027{
2028#if defined(RTEMS_SMP)
2029 Thread_queue_Queue *queue;
2030
2031 queue = queue_context->Lock_context.Wait.queue;
2032
2033 if ( queue != NULL ) {
2034 _Thread_Wait_release_queue_critical(
2035 queue, &queue_context->Lock_context
2036 );
2037 _Thread_Wait_acquire_default_critical(
2038 the_thread,
2039 &queue_context->Lock_context.Lock_context
2040 );
2041 _Thread_Wait_remove_request_locked(
2042 the_thread,
2043 &queue_context->Lock_context
2044 );
2045 }
2046
2047 _Thread_Wait_release_default_critical(
2048 the_thread,
2049 &queue_context->Lock_context.Lock_context
2050 );
2051#else
2052 (void) the_thread;
2053 (void) queue_context;
2054#endif
2055}
2056
2065static inline void _Thread_Wait_release(
2066 Thread_Control *the_thread,
2067 Thread_queue_Context *queue_context
2068)
2069{
2070 _Thread_Wait_release_critical( the_thread, queue_context );
2072}
2073
2088static inline void _Thread_Wait_claim(
2089 Thread_Control *the_thread,
2090 Thread_queue_Queue *queue
2091)
2092{
2093 ISR_lock_Context lock_context;
2094
2095 _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
2096
2097 _Assert( the_thread->Wait.queue == NULL );
2098
2099#if defined(RTEMS_SMP)
2100 _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
2101 _Chain_Initialize_node( &the_thread->Wait.Lock.Tranquilizer.Node );
2102 _Thread_queue_Gate_close( &the_thread->Wait.Lock.Tranquilizer );
2103#endif
2104
2105 the_thread->Wait.queue = queue;
2106
2107 _Thread_Wait_release_default_critical( the_thread, &lock_context );
2108}
2109
2117static inline void _Thread_Wait_claim_finalize(
2118 Thread_Control *the_thread,
2119 const Thread_queue_Operations *operations
2120)
2121{
2122 the_thread->Wait.operations = operations;
2123}
2124
2136static inline void _Thread_Wait_remove_request(
2137 Thread_Control *the_thread,
2138 Thread_queue_Lock_context *queue_lock_context
2139)
2140{
2141#if defined(RTEMS_SMP)
2142 ISR_lock_Context lock_context;
2143
2144 _Thread_Wait_acquire_default( the_thread, &lock_context );
2145 _Thread_Wait_remove_request_locked( the_thread, queue_lock_context );
2146 _Thread_Wait_release_default( the_thread, &lock_context );
2147#else
2148 (void) the_thread;
2149 (void) queue_lock_context;
2150#endif
2151}
2152
2165static inline void _Thread_Wait_restore_default(
2166 Thread_Control *the_thread
2167)
2168{
2169#if defined(RTEMS_SMP)
2170 ISR_lock_Context lock_context;
2171 Chain_Node *node;
2172 const Chain_Node *tail;
2173
2174 _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
2175
2176 node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
2177 tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
2178
2179 if ( node != tail ) {
2180 do {
2181 Thread_queue_Context *queue_context;
2182
2183 queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
2184 queue_context->Lock_context.Wait.queue = NULL;
2185
2186 node = _Chain_Next( node );
2187 } while ( node != tail );
2188
2189 _Thread_queue_Gate_add(
2190 &the_thread->Wait.Lock.Pending_requests,
2191 &the_thread->Wait.Lock.Tranquilizer
2192 );
2193 } else {
2194 _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
2195 }
2196#endif
2197
2198 the_thread->Wait.queue = NULL;
2200
2201#if defined(RTEMS_SMP)
2202 _Thread_Wait_release_default_critical( the_thread, &lock_context );
2203#endif
2204}
2205
2224static inline void _Thread_Wait_tranquilize(
2225 Thread_Control *the_thread
2226)
2227{
2228#if defined(RTEMS_SMP)
2229 _Thread_queue_Gate_wait( &the_thread->Wait.Lock.Tranquilizer );
2230#else
2231 (void) the_thread;
2232#endif
2233}
2234
2242static inline void _Thread_Wait_cancel(
2243 Thread_Control *the_thread,
2244 Thread_queue_Context *queue_context
2245)
2246{
2247 Thread_queue_Queue *queue;
2248
2249 queue = the_thread->Wait.queue;
2250
2251 if ( queue != NULL ) {
2252#if defined(RTEMS_SMP)
2253 _Assert( queue_context->Lock_context.Wait.queue == queue );
2254#endif
2255
2256 ( *the_thread->Wait.operations->extract )(
2257 queue,
2258 the_thread,
2259 queue_context
2260 );
2261 _Thread_Wait_restore_default( the_thread );
2262
2263#if defined(RTEMS_SMP)
2264 _Assert( queue_context->Lock_context.Wait.queue == NULL );
2265 queue_context->Lock_context.Wait.queue = queue;
2266#endif
2267 }
2268}
2269
2273#define THREAD_WAIT_STATE_MASK 0xffU
2274
2282#define THREAD_WAIT_STATE_READY 0x0U
2283
2291#define THREAD_WAIT_STATE_INTEND_TO_BLOCK 0x1U
2292
2296#define THREAD_WAIT_STATE_BLOCKED 0x2U
2297
2301#define THREAD_WAIT_CLASS_MASK 0xff00U
2302
2306#define THREAD_WAIT_CLASS_EVENT 0x100U
2307
2311#define THREAD_WAIT_CLASS_SYSTEM_EVENT 0x200U
2312
2316#define THREAD_WAIT_CLASS_OBJECT 0x400U
2317
2321#define THREAD_WAIT_CLASS_PERIOD 0x800U
2322
2329static inline void _Thread_Wait_flags_set(
2330 Thread_Control *the_thread,
2331 Thread_Wait_flags flags
2332)
2333{
2334#if defined(RTEMS_SMP)
2335 _Atomic_Store_uint( &the_thread->Wait.flags, flags, ATOMIC_ORDER_RELAXED );
2336#else
2337 the_thread->Wait.flags = flags;
2338#endif
2339}
2340
2348static inline Thread_Wait_flags _Thread_Wait_flags_get(
2349 const Thread_Control *the_thread
2350)
2351{
2352#if defined(RTEMS_SMP)
2353 return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_RELAXED );
2354#else
2355 return the_thread->Wait.flags;
2356#endif
2357}
2358
2366static inline Thread_Wait_flags _Thread_Wait_flags_get_acquire(
2367 const Thread_Control *the_thread
2368)
2369{
2370#if defined(RTEMS_SMP)
2371 return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_ACQUIRE );
2372#else
2373 return the_thread->Wait.flags;
2374#endif
2375}
2376
2393static inline bool _Thread_Wait_flags_try_change_release(
2394 Thread_Control *the_thread,
2395 Thread_Wait_flags expected_flags,
2396 Thread_Wait_flags desired_flags
2397)
2398{
2399 _Assert( _ISR_Get_level() != 0 );
2400
2401#if defined(RTEMS_SMP)
2402 return _Atomic_Compare_exchange_uint(
2403 &the_thread->Wait.flags,
2404 &expected_flags,
2405 desired_flags,
2406 ATOMIC_ORDER_RELEASE,
2407 ATOMIC_ORDER_RELAXED
2408 );
2409#else
2410 bool success = ( the_thread->Wait.flags == expected_flags );
2411
2412 if ( success ) {
2413 the_thread->Wait.flags = desired_flags;
2414 }
2415
2416 return success;
2417#endif
2418}
2419
2433static inline bool _Thread_Wait_flags_try_change_acquire(
2434 Thread_Control *the_thread,
2435 Thread_Wait_flags expected_flags,
2436 Thread_Wait_flags desired_flags
2437)
2438{
2439#if defined(RTEMS_SMP)
2440 return _Atomic_Compare_exchange_uint(
2441 &the_thread->Wait.flags,
2442 &expected_flags,
2443 desired_flags,
2444 ATOMIC_ORDER_ACQUIRE,
2445 ATOMIC_ORDER_ACQUIRE
2446 );
2447#else
2448 bool success;
2449 ISR_Level level;
2450
2451 _ISR_Local_disable( level );
2452
2453 success = _Thread_Wait_flags_try_change_release(
2454 the_thread,
2455 expected_flags,
2456 desired_flags
2457 );
2458
2459 _ISR_Local_enable( level );
2460 return success;
2461#endif
2462}
2463
2480Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread );
2481
2487static inline Status_Control _Thread_Wait_get_status(
2488 const Thread_Control *the_thread
2489)
2490{
2491 return (Status_Control) the_thread->Wait.return_code;
2492}
2493
2506void _Thread_Continue( Thread_Control *the_thread, Status_Control status );
2507
2513void _Thread_Timeout( Watchdog_Control *the_watchdog );
2514
2521static inline void _Thread_Timer_initialize(
2523 Per_CPU_Control *cpu
2524)
2525{
2526 _ISR_lock_Initialize( &timer->Lock, "Thread Timer" );
2527 timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
2528 _Watchdog_Preinitialize( &timer->Watchdog, cpu );
2529}
2530
2538static inline void _Thread_Add_timeout_ticks(
2539 Thread_Control *the_thread,
2540 Per_CPU_Control *cpu,
2541 Watchdog_Interval ticks
2542)
2543{
2544 ISR_lock_Context lock_context;
2545
2546 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2547
2548 the_thread->Timer.header =
2550 the_thread->Timer.Watchdog.routine = _Thread_Timeout;
2551 _Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks );
2552
2553 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2554}
2555
2564static inline void _Thread_Timer_insert_realtime(
2565 Thread_Control *the_thread,
2566 Per_CPU_Control *cpu,
2568 uint64_t expire
2569)
2570{
2571 ISR_lock_Context lock_context;
2572 Watchdog_Header *header;
2573
2574 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2575
2576 header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
2577 the_thread->Timer.header = header;
2578 the_thread->Timer.Watchdog.routine = routine;
2579 _Watchdog_Per_CPU_insert( &the_thread->Timer.Watchdog, cpu, header, expire );
2580
2581 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2582}
2583
2589static inline void _Thread_Timer_remove( Thread_Control *the_thread )
2590{
2591 ISR_lock_Context lock_context;
2592
2593 _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
2594
2595 _Watchdog_Per_CPU_remove(
2596 &the_thread->Timer.Watchdog,
2597#if defined(RTEMS_SMP)
2598 the_thread->Timer.Watchdog.cpu,
2599#else
2600 _Per_CPU_Get(),
2601#endif
2602 the_thread->Timer.header
2603 );
2604
2605 _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
2606}
2607
2615static inline void _Thread_Remove_timer_and_unblock(
2616 Thread_Control *the_thread,
2617 Thread_queue_Queue *queue
2618)
2619{
2620 _Thread_Wait_tranquilize( the_thread );
2621 _Thread_Timer_remove( the_thread );
2622
2623#if defined(RTEMS_MULTIPROCESSING)
2624 if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
2625 _Thread_Unblock( the_thread );
2626 } else {
2627 _Thread_queue_Unblock_proxy( queue, the_thread );
2628 }
2629#else
2630 (void) queue;
2631 _Thread_Unblock( the_thread );
2632#endif
2633}
2634
2645 Thread_Control *the_thread,
2646 const char *name
2647);
2648
2658size_t _Thread_Get_name(
2659 const Thread_Control *the_thread,
2660 char *buffer,
2661 size_t buffer_size
2662);
2663
2664#if defined(RTEMS_SMP)
2665#define THREAD_PIN_STEP 2
2666
2667#define THREAD_PIN_PREEMPTION 1
2668
2675void _Thread_Do_unpin(
2676 Thread_Control *executing,
2677 Per_CPU_Control *cpu_self
2678);
2679#endif
2680
2686static inline void _Thread_Pin( Thread_Control *executing )
2687{
2688#if defined(RTEMS_SMP)
2689 _Assert( executing == _Thread_Get_executing() );
2690
2691 executing->Scheduler.pin_level += THREAD_PIN_STEP;
2692#else
2693 (void) executing;
2694#endif
2695}
2696
2703static inline void _Thread_Unpin(
2704 Thread_Control *executing,
2705 Per_CPU_Control *cpu_self
2706)
2707{
2708#if defined(RTEMS_SMP)
2709 unsigned int pin_level;
2710
2711 _Assert( executing == _Per_CPU_Get_executing( cpu_self ) );
2712
2713 pin_level = executing->Scheduler.pin_level;
2714 _Assert( pin_level > 0 );
2715
2716 if (
2718 pin_level != ( THREAD_PIN_STEP | THREAD_PIN_PREEMPTION )
2719 )
2720 ) {
2721 executing->Scheduler.pin_level = pin_level - THREAD_PIN_STEP;
2722 } else {
2723 _Thread_Do_unpin( executing, cpu_self );
2724 }
2725#else
2726 (void) executing;
2727 (void) cpu_self;
2728#endif
2729}
2730
2733#ifdef __cplusplus
2734}
2735#endif
2736
2737#if defined(RTEMS_MULTIPROCESSING)
2738#include <rtems/score/threadmp.h>
2739#endif
2740
2741#ifdef __cplusplus
2742extern "C" {
2743#endif
2744
2755static inline void _Thread_Timer_remove_and_continue(
2756 Thread_Control *the_thread,
2757 Status_Control status
2758)
2759{
2760 _Thread_Timer_remove( the_thread );
2761#if defined(RTEMS_MULTIPROCESSING)
2762 _Thread_MP_Extract_proxy( the_thread );
2763#endif
2764 _Thread_Continue( the_thread, status );
2765}
2766
2767#ifdef __cplusplus
2768}
2769#endif
2770
2771#endif
2772/* 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:435
#define _ISR_lock_Release(_lock, _context)
Releases an ISR lock inside an ISR disabled section.
Definition: isrlock.h:332
#define _ISR_lock_ISR_disable(_context)
Disables interrupts and saves the previous interrupt state in the ISR lock context.
Definition: isrlock.h:414
#define _ISR_lock_Acquire(_lock, _context)
Acquires an ISR lock inside an ISR disabled section.
Definition: isrlock.h:309
#define _ISR_lock_Release_and_ISR_enable(_lock, _context)
Releases an ISR lock.
Definition: isrlock.h:279
#define _ISR_lock_ISR_disable_and_acquire(_lock, _context)
Acquires an ISR lock.
Definition: isrlock.h:254
#define _ISR_lock_Initialize(_lock, _name)
Initializes an ISR lock.
Definition: isrlock.h:201
#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:393
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:1478
Status_Control _Thread_Restart(Thread_Control *the_thread, const Thread_Entry_information *entry, ISR_lock_Context *lock_context)
Restarts the thread.
Definition: threadrestart.c:535
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:500
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:433
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:381
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:317
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:222
#define THREAD_LIFE_TERMINATING
Indicates that thread is terminating.
Definition: thread.h:747
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:731
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:722
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:739
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:332
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:167
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:428
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:661
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:347
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:756
Thread_Life_state _Thread_Set_life_protection(Thread_Life_state state)
Set the thread to life protected.
Definition: threadrestart.c:623
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:765
Status_Control _Thread_Close(Thread_Control *the_thread, Thread_Control *executing, Thread_queue_Context *queue_context)
Closes the thread.
Definition: threadrestart.c:464
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:379
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:596
@ 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
#define NULL
Requests a GPIO pin group configuration.
Definition: xil_types.h:54
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:81
ISR lock control.
Definition: isrlock.h:72
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 Per_CPU_Control::@4380 Watchdog
Watchdog state for this processor.
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
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::@4383 Wait
Thread wait support block.
Control block to manage thread actions.
Definition: thread.h:708
Thread action.
Definition: thread.h:681
This structure contains operations which manage the CPU budget of a thread.
Definition: thread.h:165
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:140
The thread object information.
Definition: thread.h:1098
Objects_Information Objects
The object information.
Definition: thread.h:1102
Thread_Life_state state
The current thread life state.
Definition: thread.h:780
Scheduler_Node * nodes
The scheduler nodes of this thread.
Definition: thread.h:396
Information required to manage a thread timer.
Definition: thread.h:544
Thread_queue_Queue * queue
The current thread queue.
Definition: thread.h:527
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:467
const Thread_queue_Operations * operations
The current thread queue operations.
Definition: thread.h:536
uint32_t return_code
Definition: thread.h:458
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:335
uint32_t name
The scheduler name.
Definition: scheduler.h:357
Definition: thread.h:812
Context_Control Registers
This member contains the context of this thread.
Definition: thread.h:868
Objects_Control Object
Definition: thread.h:814
Timestamp_Control cpu_time_used
This member contains the amount of CPU time consumed by this thread since it was created.
Definition: thread.h:909
Thread_Wait_information Wait
Definition: thread.h:852
Context_Control_fp * fp_context
Definition: thread.h:929
Priority_Node Real_priority
The base priority of this thread in its home scheduler instance.
Definition: thread.h:839
States_Control current_state
Definition: thread.h:834
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:849
Thread_queue_Control Join_queue
Thread queue for thread join operations and multi-purpose lock.
Definition: thread.h:831
Thread_Timer_information Timer
Definition: thread.h:854
Thread_Life_control Life
Thread life-cycle control.
Definition: thread.h:950
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...