RTEMS  5.0.0
threadimpl.h
Go to the documentation of this file.
1 
10 /*
11  * COPYRIGHT (c) 1989-2008.
12  * On-Line Applications Research Corporation (OAR).
13  *
14  * Copyright (c) 2014, 2017 embedded brains GmbH.
15  *
16  * The license and distribution terms for this file may be
17  * found in the file LICENSE in this distribution or at
18  * http://www.rtems.org/license/LICENSE.
19  */
20 
21 #ifndef _RTEMS_SCORE_THREADIMPL_H
22 #define _RTEMS_SCORE_THREADIMPL_H
23 
24 #include <rtems/score/thread.h>
25 #include <rtems/score/assert.h>
26 #include <rtems/score/chainimpl.h>
27 #include <rtems/score/interr.h>
28 #include <rtems/score/isr.h>
29 #include <rtems/score/objectimpl.h>
30 #include <rtems/score/schedulernodeimpl.h>
31 #include <rtems/score/statesimpl.h>
32 #include <rtems/score/status.h>
33 #include <rtems/score/sysstate.h>
36 #include <rtems/score/todimpl.h>
38 #include <rtems/config.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
53 #define THREAD_STATUS_PROXY_BLOCKING 0x1111111
54 
58 extern void *rtems_ada_self;
59 
69 
74 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
76 #endif
77 
78 #if defined(RTEMS_SMP)
79 #define THREAD_OF_SCHEDULER_HELP_NODE( node ) \
80  RTEMS_CONTAINER_OF( node, Thread_Control, Scheduler.Help_node )
81 #endif
82 
83 typedef bool ( *Thread_Visitor )( Thread_Control *the_thread, void *arg );
84 
85 void _Thread_Iterate(
86  Thread_Visitor visitor,
87  void *arg
88 );
89 
90 void _Thread_Initialize_information( Thread_Information *information );
91 
98 
106 void _Thread_Create_idle(void);
107 
116 
130  Thread_Control *the_thread,
131  size_t stack_size
132 );
133 
139 void _Thread_Stack_Free(
140  Thread_Control *the_thread
141 );
142 
156 bool _Thread_Initialize(
157  Thread_Information *information,
158  Thread_Control *the_thread,
159  const struct _Scheduler_Control *scheduler,
160  void *stack_area,
161  size_t stack_size,
162  bool is_fp,
163  Priority_Control priority,
164  bool is_preemptible,
165  Thread_CPU_budget_algorithms budget_algorithm,
167  uint32_t isr_level,
168  Objects_Name name
169 );
170 
181 bool _Thread_Start(
182  Thread_Control *the_thread,
184  ISR_lock_Context *lock_context
185 );
186 
187 void _Thread_Restart_self(
188  Thread_Control *executing,
190  ISR_lock_Context *lock_context
192 
193 bool _Thread_Restart_other(
194  Thread_Control *the_thread,
196  ISR_lock_Context *lock_context
197 );
198 
199 void _Thread_Yield( Thread_Control *executing );
200 
201 Thread_Life_state _Thread_Change_life(
202  Thread_Life_state clear,
203  Thread_Life_state set,
204  Thread_Life_state ignore
205 );
206 
207 Thread_Life_state _Thread_Set_life_protection( Thread_Life_state state );
208 
218 void _Thread_Kill_zombies( void );
219 
220 void _Thread_Exit(
221  Thread_Control *executing,
222  Thread_Life_state set,
223  void *exit_value
224 );
225 
226 void _Thread_Join(
227  Thread_Control *the_thread,
228  States_Control waiting_for_join,
229  Thread_Control *executing,
230  Thread_queue_Context *queue_context
231 );
232 
233 void _Thread_Cancel(
234  Thread_Control *the_thread,
235  Thread_Control *executing,
236  void *exit_value
237 );
238 
239 typedef struct {
241  Thread_Control *cancel;
243 
251 void _Thread_Close(
252  Thread_Control *the_thread,
253  Thread_Control *executing,
255 );
256 
257 RTEMS_INLINE_ROUTINE bool _Thread_Is_ready( const Thread_Control *the_thread )
258 {
259  return _States_Is_ready( the_thread->current_state );
260 }
261 
262 States_Control _Thread_Clear_state_locked(
263  Thread_Control *the_thread,
264  States_Control state
265 );
266 
279  Thread_Control *the_thread,
280  States_Control state
281 );
282 
283 States_Control _Thread_Set_state_locked(
284  Thread_Control *the_thread,
285  States_Control state
286 );
287 
300  Thread_Control *the_thread,
301  States_Control state
302 );
303 
313  Thread_Control *the_thread
314 );
315 
316 void _Thread_Entry_adaptor_idle( Thread_Control *executing );
317 
318 void _Thread_Entry_adaptor_numeric( Thread_Control *executing );
319 
320 void _Thread_Entry_adaptor_pointer( Thread_Control *executing );
321 
337 void _Thread_Handler( void );
338 
339 RTEMS_INLINE_ROUTINE void _Thread_State_acquire_critical(
340  Thread_Control *the_thread,
341  ISR_lock_Context *lock_context
342 )
343 {
344  _Thread_queue_Do_acquire_critical( &the_thread->Join_queue, lock_context );
345 }
346 
347 RTEMS_INLINE_ROUTINE void _Thread_State_acquire(
348  Thread_Control *the_thread,
349  ISR_lock_Context *lock_context
350 )
351 {
352  _ISR_lock_ISR_disable( lock_context );
353  _Thread_State_acquire_critical( the_thread, lock_context );
354 }
355 
356 RTEMS_INLINE_ROUTINE Thread_Control *_Thread_State_acquire_for_executing(
357  ISR_lock_Context *lock_context
358 )
359 {
360  Thread_Control *executing;
361 
362  _ISR_lock_ISR_disable( lock_context );
363  executing = _Thread_Executing;
364  _Thread_State_acquire_critical( executing, lock_context );
365 
366  return executing;
367 }
368 
369 RTEMS_INLINE_ROUTINE void _Thread_State_release_critical(
370  Thread_Control *the_thread,
371  ISR_lock_Context *lock_context
372 )
373 {
374  _Thread_queue_Do_release_critical( &the_thread->Join_queue, lock_context );
375 }
376 
377 RTEMS_INLINE_ROUTINE void _Thread_State_release(
378  Thread_Control *the_thread,
379  ISR_lock_Context *lock_context
380 )
381 {
382  _Thread_State_release_critical( the_thread, lock_context );
383  _ISR_lock_ISR_enable( lock_context );
384 }
385 
386 #if defined(RTEMS_DEBUG)
387 RTEMS_INLINE_ROUTINE bool _Thread_State_is_owner(
388  const Thread_Control *the_thread
389 )
390 {
391  return _Thread_queue_Is_lock_owner( &the_thread->Join_queue );
392 }
393 #endif
394 
408  Thread_Control *start_of_path,
409  Thread_queue_Context *queue_context
410 );
411 
428  Thread_Control *the_thread,
429  Priority_Node *priority_node,
430  Thread_queue_Context *queue_context
431 );
432 
449  Thread_Control *the_thread,
450  Priority_Node *priority_node,
451  Thread_queue_Context *queue_context
452 );
453 
473  Thread_Control *the_thread,
474  Priority_Node *priority_node,
475  bool prepend_it,
476  Thread_queue_Context *queue_context
477 );
478 
500  Thread_Control *the_thread,
501  Priority_Node *priority_node,
502  Priority_Control new_priority,
503  bool prepend_it,
504  Thread_queue_Context *queue_context
505 )
506 {
507  _Priority_Node_set_priority( priority_node, new_priority );
509  the_thread,
510  priority_node,
511  prepend_it,
512  queue_context
513  );
514 }
515 
529  Thread_Control *the_thread,
530  Priority_Node *victim_node,
531  Priority_Node *replacement_node
532 );
533 
550 void _Thread_Priority_update( Thread_queue_Context *queue_context );
551 
552 #if defined(RTEMS_SMP)
553 void _Thread_Priority_and_sticky_update(
554  Thread_Control *the_thread,
555  int sticky_level_change
556 );
557 #endif
558 
564  Priority_Control left,
565  Priority_Control right
566 )
567 {
568  return left > right;
569 }
570 
576  Priority_Control left,
577  Priority_Control right
578 )
579 {
580  return _Thread_Priority_less_than( left, right ) ? right : left;
581 }
582 
583 RTEMS_INLINE_ROUTINE Objects_Information *_Thread_Get_objects_information(
584  Objects_Id id
585 )
586 {
587  uint32_t the_api;
588 
589  the_api = _Objects_Get_API( id );
590 
591  if ( !_Objects_Is_api_valid( the_api ) ) {
592  return NULL;
593  }
594 
595  /*
596  * Threads are always first class :)
597  *
598  * There is no need to validate the object class of the object identifier,
599  * since this will be done by the object get methods.
600  */
601  return _Objects_Information_table[ the_api ][ 1 ];
602 }
603 
610  Objects_Id id,
611  ISR_lock_Context *lock_context
612 );
613 
614 RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Get_CPU(
615  const Thread_Control *thread
616 )
617 {
618 #if defined(RTEMS_SMP)
619  return thread->Scheduler.cpu;
620 #else
621  (void) thread;
622 
623  return _Per_CPU_Get();
624 #endif
625 }
626 
627 RTEMS_INLINE_ROUTINE void _Thread_Set_CPU(
628  Thread_Control *thread,
629  Per_CPU_Control *cpu
630 )
631 {
632 #if defined(RTEMS_SMP)
633  thread->Scheduler.cpu = cpu;
634 #else
635  (void) thread;
636  (void) cpu;
637 #endif
638 }
639 
646  const Thread_Control *the_thread
647 )
648 {
649  return ( the_thread == _Thread_Executing );
650 }
651 
652 #if defined(RTEMS_SMP)
653 
660 RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_on_a_processor(
661  const Thread_Control *the_thread
662 )
663 {
664  return _CPU_Context_Get_is_executing( &the_thread->Registers );
665 }
666 #endif
667 
674  const Thread_Control *the_thread
675 )
676 {
677  return ( the_thread == _Thread_Heir );
678 }
679 
687  Thread_Control *the_thread
688 )
689 {
690  _Thread_Clear_state( the_thread, STATES_BLOCKED );
691 }
692 
699 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
701  const Thread_Control *the_thread
702 )
703 {
704  return ( the_thread == _Thread_Allocated_fp );
705 }
706 #endif
707 
708 /*
709  * If the CPU has hardware floating point, then we must address saving
710  * and restoring it as part of the context switch.
711  *
712  * The second conditional compilation section selects the algorithm used
713  * to context switch between floating point tasks. The deferred algorithm
714  * can be significantly better in a system with few floating point tasks
715  * because it reduces the total number of save and restore FP context
716  * operations. However, this algorithm can not be used on all CPUs due
717  * to unpredictable use of FP registers by some compilers for integer
718  * operations.
719  */
720 
721 RTEMS_INLINE_ROUTINE void _Thread_Save_fp( Thread_Control *executing )
722 {
723 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
724 #if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
725  if ( executing->fp_context != NULL )
726  _Context_Save_fp( &executing->fp_context );
727 #endif
728 #endif
729 }
730 
731 RTEMS_INLINE_ROUTINE void _Thread_Restore_fp( Thread_Control *executing )
732 {
733 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
734 #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
735  if ( (executing->fp_context != NULL) &&
736  !_Thread_Is_allocated_fp( executing ) ) {
737  if ( _Thread_Allocated_fp != NULL )
738  _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
739  _Context_Restore_fp( &executing->fp_context );
740  _Thread_Allocated_fp = executing;
741  }
742 #else
743  if ( executing->fp_context != NULL )
744  _Context_Restore_fp( &executing->fp_context );
745 #endif
746 #endif
747 }
748 
754 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
756 {
757  _Thread_Allocated_fp = NULL;
758 }
759 #endif
760 
767 {
768  return ( _Thread_Dispatch_necessary );
769 }
770 
776  const Thread_Control *the_thread
777 )
778 {
779  return ( the_thread == NULL );
780 }
781 
788  uint32_t code
789 )
790 {
791  return (code == THREAD_STATUS_PROXY_BLOCKING);
792 }
793 
794 RTEMS_INLINE_ROUTINE uint32_t _Thread_Get_maximum_internal_threads(void)
795 {
796  /* Idle threads */
797  uint32_t maximum_internal_threads =
799 
800  /* MPCI thread */
801 #if defined(RTEMS_MULTIPROCESSING)
802  if ( _System_state_Is_multiprocessing ) {
803  ++maximum_internal_threads;
804  }
805 #endif
806 
807  return maximum_internal_threads;
808 }
809 
810 RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
811 {
812  return (Thread_Control *)
814 }
815 
828  Per_CPU_Control *cpu_self
829 )
830 {
831  Thread_Control *heir;
832 
833  heir = cpu_self->heir;
834  cpu_self->dispatch_necessary = false;
835  cpu_self->executing = heir;
836 
837  return heir;
838 }
839 
840 RTEMS_INLINE_ROUTINE void _Thread_Update_CPU_time_used(
841  Thread_Control *the_thread,
842  Per_CPU_Control *cpu
843 )
844 {
845  Timestamp_Control last;
846  Timestamp_Control ran;
847 
848  last = cpu->cpu_usage_timestamp;
849  _TOD_Get_uptime( &cpu->cpu_usage_timestamp );
850  _Timestamp_Subtract( &last, &cpu->cpu_usage_timestamp, &ran );
851  _Timestamp_Add_to( &the_thread->cpu_time_used, &ran );
852 }
853 
854 #if defined( RTEMS_SMP )
855 RTEMS_INLINE_ROUTINE void _Thread_Dispatch_update_heir(
856  Per_CPU_Control *cpu_self,
857  Per_CPU_Control *cpu_for_heir,
858  Thread_Control *heir
859 )
860 {
861  _Thread_Update_CPU_time_used( cpu_for_heir->heir, cpu_for_heir );
862 
863  cpu_for_heir->heir = heir;
864 
865  _Thread_Dispatch_request( cpu_self, cpu_for_heir );
866 }
867 #endif
868 
869 void _Thread_Get_CPU_time_used(
870  Thread_Control *the_thread,
871  Timestamp_Control *cpu_time_used
872 );
873 
874 RTEMS_INLINE_ROUTINE void _Thread_Action_control_initialize(
875  Thread_Action_control *action_control
876 )
877 {
878  _Chain_Initialize_empty( &action_control->Chain );
879 }
880 
881 RTEMS_INLINE_ROUTINE void _Thread_Action_initialize(
882  Thread_Action *action
883 )
884 {
885  _Chain_Set_off_chain( &action->Node );
886 }
887 
888 RTEMS_INLINE_ROUTINE void _Thread_Add_post_switch_action(
889  Thread_Control *the_thread,
890  Thread_Action *action,
891  Thread_Action_handler handler
892 )
893 {
894  Per_CPU_Control *cpu_of_thread;
895 
896  _Assert( _Thread_State_is_owner( the_thread ) );
897 
898  cpu_of_thread = _Thread_Get_CPU( the_thread );
899 
900  action->handler = handler;
901 
902  _Thread_Dispatch_request( _Per_CPU_Get(), cpu_of_thread );
903 
905  &the_thread->Post_switch_actions.Chain,
906  &action->Node
907  );
908 }
909 
910 RTEMS_INLINE_ROUTINE bool _Thread_Is_life_restarting(
911  Thread_Life_state life_state
912 )
913 {
914  return ( life_state & THREAD_LIFE_RESTARTING ) != 0;
915 }
916 
917 RTEMS_INLINE_ROUTINE bool _Thread_Is_life_terminating(
918  Thread_Life_state life_state
919 )
920 {
921  return ( life_state & THREAD_LIFE_TERMINATING ) != 0;
922 }
923 
924 RTEMS_INLINE_ROUTINE bool _Thread_Is_life_change_allowed(
925  Thread_Life_state life_state
926 )
927 {
928  return ( life_state
929  & ( THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED ) ) == 0;
930 }
931 
932 RTEMS_INLINE_ROUTINE bool _Thread_Is_life_changing(
933  Thread_Life_state life_state
934 )
935 {
936  return ( life_state
937  & ( THREAD_LIFE_RESTARTING | THREAD_LIFE_TERMINATING ) ) != 0;
938 }
939 
940 RTEMS_INLINE_ROUTINE bool _Thread_Is_joinable(
941  const Thread_Control *the_thread
942 )
943 {
944  _Assert( _Thread_State_is_owner( the_thread ) );
945  return ( the_thread->Life.state & THREAD_LIFE_DETACHED ) == 0;
946 }
947 
948 RTEMS_INLINE_ROUTINE void _Thread_Resource_count_increment(
949  Thread_Control *the_thread
950 )
951 {
952 #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
953  ++the_thread->resource_count;
954 #else
955  (void) the_thread;
956 #endif
957 }
958 
959 RTEMS_INLINE_ROUTINE void _Thread_Resource_count_decrement(
960  Thread_Control *the_thread
961 )
962 {
963 #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
964  --the_thread->resource_count;
965 #else
966  (void) the_thread;
967 #endif
968 }
969 
970 #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
971 
979 RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources(
980  const Thread_Control *the_thread
981 )
982 {
983  return the_thread->resource_count != 0;
984 }
985 #endif
986 
987 #if defined(RTEMS_SMP)
988 RTEMS_INLINE_ROUTINE void _Thread_Scheduler_cancel_need_for_help(
989  Thread_Control *the_thread,
990  Per_CPU_Control *cpu
991 )
992 {
993  _Per_CPU_Acquire( cpu );
994 
995  if ( !_Chain_Is_node_off_chain( &the_thread->Scheduler.Help_node ) ) {
996  _Chain_Extract_unprotected( &the_thread->Scheduler.Help_node );
997  _Chain_Set_off_chain( &the_thread->Scheduler.Help_node );
998  }
999 
1000  _Per_CPU_Release( cpu );
1001 }
1002 #endif
1003 
1004 RTEMS_INLINE_ROUTINE const Scheduler_Control *_Thread_Scheduler_get_home(
1005  const Thread_Control *the_thread
1006 )
1007 {
1008 #if defined(RTEMS_SMP)
1009  return the_thread->Scheduler.home_scheduler;
1010 #else
1011  (void) the_thread;
1012  return &_Scheduler_Table[ 0 ];
1013 #endif
1014 }
1015 
1016 RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_home_node(
1017  const Thread_Control *the_thread
1018 )
1019 {
1020 #if defined(RTEMS_SMP)
1021  _Assert( !_Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
1022  return SCHEDULER_NODE_OF_THREAD_WAIT_NODE(
1023  _Chain_First( &the_thread->Scheduler.Wait_nodes )
1024  );
1025 #else
1026  return the_thread->Scheduler.nodes;
1027 #endif
1028 }
1029 
1030 RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_node_by_index(
1031  const Thread_Control *the_thread,
1032  size_t scheduler_index
1033 )
1034 {
1035 #if defined(RTEMS_SMP)
1036  return (Scheduler_Node *)
1037  ( (uintptr_t) the_thread->Scheduler.nodes
1038  + scheduler_index * _Scheduler_Node_size );
1039 #else
1040  _Assert( scheduler_index == 0 );
1041  (void) scheduler_index;
1042  return the_thread->Scheduler.nodes;
1043 #endif
1044 }
1045 
1046 #if defined(RTEMS_SMP)
1047 RTEMS_INLINE_ROUTINE void _Thread_Scheduler_acquire_critical(
1048  Thread_Control *the_thread,
1049  ISR_lock_Context *lock_context
1050 )
1051 {
1052  _ISR_lock_Acquire( &the_thread->Scheduler.Lock, lock_context );
1053 }
1054 
1055 RTEMS_INLINE_ROUTINE void _Thread_Scheduler_release_critical(
1056  Thread_Control *the_thread,
1057  ISR_lock_Context *lock_context
1058 )
1059 {
1060  _ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context );
1061 }
1062 
1063 void _Thread_Scheduler_process_requests( Thread_Control *the_thread );
1064 
1065 RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_request(
1066  Thread_Control *the_thread,
1067  Scheduler_Node *scheduler_node,
1068  Scheduler_Node_request request
1069 )
1070 {
1071  ISR_lock_Context lock_context;
1072  Scheduler_Node_request current_request;
1073 
1074  _Thread_Scheduler_acquire_critical( the_thread, &lock_context );
1075 
1076  current_request = scheduler_node->Thread.request;
1077 
1078  if ( current_request == SCHEDULER_NODE_REQUEST_NOT_PENDING ) {
1079  _Assert(
1080  request == SCHEDULER_NODE_REQUEST_ADD
1081  || request == SCHEDULER_NODE_REQUEST_REMOVE
1082  );
1083  _Assert( scheduler_node->Thread.next_request == NULL );
1084  scheduler_node->Thread.next_request = the_thread->Scheduler.requests;
1085  the_thread->Scheduler.requests = scheduler_node;
1086  } else if ( current_request != SCHEDULER_NODE_REQUEST_NOTHING ) {
1087  _Assert(
1088  ( current_request == SCHEDULER_NODE_REQUEST_ADD
1089  && request == SCHEDULER_NODE_REQUEST_REMOVE )
1090  || ( current_request == SCHEDULER_NODE_REQUEST_REMOVE
1091  && request == SCHEDULER_NODE_REQUEST_ADD )
1092  );
1093  request = SCHEDULER_NODE_REQUEST_NOTHING;
1094  }
1095 
1096  scheduler_node->Thread.request = request;
1097 
1098  _Thread_Scheduler_release_critical( the_thread, &lock_context );
1099 }
1100 
1101 RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_wait_node(
1102  Thread_Control *the_thread,
1103  Scheduler_Node *scheduler_node
1104 )
1105 {
1107  &the_thread->Scheduler.Wait_nodes,
1108  &scheduler_node->Thread.Wait_node
1109  );
1110  _Thread_Scheduler_add_request(
1111  the_thread,
1112  scheduler_node,
1113  SCHEDULER_NODE_REQUEST_ADD
1114  );
1115 }
1116 
1117 RTEMS_INLINE_ROUTINE void _Thread_Scheduler_remove_wait_node(
1118  Thread_Control *the_thread,
1119  Scheduler_Node *scheduler_node
1120 )
1121 {
1122  _Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
1123  _Thread_Scheduler_add_request(
1124  the_thread,
1125  scheduler_node,
1126  SCHEDULER_NODE_REQUEST_REMOVE
1127  );
1128 }
1129 #endif
1130 
1141  const Thread_Control *the_thread
1142 )
1143 {
1144  Scheduler_Node *scheduler_node;
1145 
1146  scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
1147  return _Priority_Get_priority( &scheduler_node->Wait.Priority );
1148 }
1149 
1161  Thread_Control *the_thread,
1162  ISR_lock_Context *lock_context
1163 )
1164 {
1165  _ISR_lock_Acquire( &the_thread->Wait.Lock.Default, lock_context );
1166 }
1167 
1180  ISR_lock_Context *lock_context
1181 )
1182 {
1183  Thread_Control *executing;
1184 
1185  _ISR_lock_ISR_disable( lock_context );
1186  executing = _Thread_Executing;
1187  _Thread_Wait_acquire_default_critical( executing, lock_context );
1188 
1189  return executing;
1190 }
1191 
1202  Thread_Control *the_thread,
1203  ISR_lock_Context *lock_context
1204 )
1205 {
1206  _ISR_lock_ISR_disable( lock_context );
1207  _Thread_Wait_acquire_default_critical( the_thread, lock_context );
1208 }
1209 
1221  Thread_Control *the_thread,
1222  ISR_lock_Context *lock_context
1223 )
1224 {
1225  _ISR_lock_Release( &the_thread->Wait.Lock.Default, lock_context );
1226 }
1227 
1237  Thread_Control *the_thread,
1238  ISR_lock_Context *lock_context
1239 )
1240 {
1241  _Thread_Wait_release_default_critical( the_thread, lock_context );
1242  _ISR_lock_ISR_enable( lock_context );
1243 }
1244 
1245 #if defined(RTEMS_SMP)
1246 #define THREAD_QUEUE_CONTEXT_OF_REQUEST( node ) \
1247  RTEMS_CONTAINER_OF( node, Thread_queue_Context, Lock_context.Wait.Gate.Node )
1248 
1249 RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request_locked(
1250  Thread_Control *the_thread,
1251  Thread_queue_Lock_context *queue_lock_context
1252 )
1253 {
1254  Chain_Node *first;
1255 
1256  _Chain_Extract_unprotected( &queue_lock_context->Wait.Gate.Node );
1257  first = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
1258 
1259  if ( first != _Chain_Tail( &the_thread->Wait.Lock.Pending_requests ) ) {
1260  _Thread_queue_Gate_open( (Thread_queue_Gate *) first );
1261  }
1262 }
1263 
1264 RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_queue_critical(
1265  Thread_queue_Queue *queue,
1266  Thread_queue_Lock_context *queue_lock_context
1267 )
1268 {
1269  _Thread_queue_Queue_acquire_critical(
1270  queue,
1271  &_Thread_Executing->Potpourri_stats,
1272  &queue_lock_context->Lock_context
1273  );
1274 }
1275 
1276 RTEMS_INLINE_ROUTINE void _Thread_Wait_release_queue_critical(
1277  Thread_queue_Queue *queue,
1278  Thread_queue_Lock_context *queue_lock_context
1279 )
1280 {
1281  _Thread_queue_Queue_release_critical(
1282  queue,
1283  &queue_lock_context->Lock_context
1284  );
1285 }
1286 #endif
1287 
1297  Thread_Control *the_thread,
1298  Thread_queue_Context *queue_context
1299 )
1300 {
1301 #if defined(RTEMS_SMP)
1302  Thread_queue_Queue *queue;
1303 
1305  the_thread,
1306  &queue_context->Lock_context.Lock_context
1307  );
1308 
1309  queue = the_thread->Wait.queue;
1310  queue_context->Lock_context.Wait.queue = queue;
1311 
1312  if ( queue != NULL ) {
1313  _Thread_queue_Gate_add(
1314  &the_thread->Wait.Lock.Pending_requests,
1315  &queue_context->Lock_context.Wait.Gate
1316  );
1318  the_thread,
1319  &queue_context->Lock_context.Lock_context
1320  );
1321  _Thread_Wait_acquire_queue_critical( queue, &queue_context->Lock_context );
1322 
1323  if ( queue_context->Lock_context.Wait.queue == NULL ) {
1324  _Thread_Wait_release_queue_critical(
1325  queue,
1326  &queue_context->Lock_context
1327  );
1329  the_thread,
1330  &queue_context->Lock_context.Lock_context
1331  );
1332  _Thread_Wait_remove_request_locked(
1333  the_thread,
1334  &queue_context->Lock_context
1335  );
1336  _Assert( the_thread->Wait.queue == NULL );
1337  }
1338  }
1339 #else
1340  (void) the_thread;
1341  (void) queue_context;
1342 #endif
1343 }
1344 
1353  Thread_Control *the_thread,
1354  Thread_queue_Context *queue_context
1355 )
1356 {
1357  _ISR_lock_ISR_disable( &queue_context->Lock_context.Lock_context );
1358  _Thread_Wait_acquire_critical( the_thread, queue_context );
1359 }
1360 
1372  Thread_Control *the_thread,
1373  Thread_queue_Context *queue_context
1374 )
1375 {
1376 #if defined(RTEMS_SMP)
1377  Thread_queue_Queue *queue;
1378 
1379  queue = queue_context->Lock_context.Wait.queue;
1380 
1381  if ( queue != NULL ) {
1382  _Thread_Wait_release_queue_critical(
1383  queue, &queue_context->Lock_context
1384  );
1386  the_thread,
1387  &queue_context->Lock_context.Lock_context
1388  );
1389  _Thread_Wait_remove_request_locked(
1390  the_thread,
1391  &queue_context->Lock_context
1392  );
1393  }
1394 
1396  the_thread,
1397  &queue_context->Lock_context.Lock_context
1398  );
1399 #else
1400  (void) the_thread;
1401  (void) queue_context;
1402 #endif
1403 }
1404 
1414  Thread_Control *the_thread,
1415  Thread_queue_Context *queue_context
1416 )
1417 {
1418  _Thread_Wait_release_critical( the_thread, queue_context );
1419  _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
1420 }
1421 
1437  Thread_Control *the_thread,
1438  Thread_queue_Queue *queue
1439 )
1440 {
1441  ISR_lock_Context lock_context;
1442 
1443  _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
1444 
1445  _Assert( the_thread->Wait.queue == NULL );
1446 
1447 #if defined(RTEMS_SMP)
1448  _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
1449  _Chain_Initialize_node( &the_thread->Wait.Lock.Tranquilizer.Node );
1450  _Thread_queue_Gate_close( &the_thread->Wait.Lock.Tranquilizer );
1451 #endif
1452 
1453  the_thread->Wait.queue = queue;
1454 
1455  _Thread_Wait_release_default_critical( the_thread, &lock_context );
1456 }
1457 
1466  Thread_Control *the_thread,
1467  const Thread_queue_Operations *operations
1468 )
1469 {
1470  the_thread->Wait.operations = operations;
1471 }
1472 
1485  Thread_Control *the_thread,
1486  Thread_queue_Lock_context *queue_lock_context
1487 )
1488 {
1489 #if defined(RTEMS_SMP)
1490  ISR_lock_Context lock_context;
1491 
1492  _Thread_Wait_acquire_default( the_thread, &lock_context );
1493  _Thread_Wait_remove_request_locked( the_thread, queue_lock_context );
1494  _Thread_Wait_release_default( the_thread, &lock_context );
1495 #else
1496  (void) the_thread;
1497  (void) queue_lock_context;
1498 #endif
1499 }
1500 
1514  Thread_Control *the_thread
1515 )
1516 {
1517 #if defined(RTEMS_SMP)
1518  ISR_lock_Context lock_context;
1519  Chain_Node *node;
1520  const Chain_Node *tail;
1521 
1522  _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
1523 
1524  node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
1525  tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
1526 
1527  if ( node != tail ) {
1528  do {
1529  Thread_queue_Context *queue_context;
1530 
1531  queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
1532  queue_context->Lock_context.Wait.queue = NULL;
1533 
1534  node = _Chain_Next( node );
1535  } while ( node != tail );
1536 
1537  _Thread_queue_Gate_add(
1538  &the_thread->Wait.Lock.Pending_requests,
1539  &the_thread->Wait.Lock.Tranquilizer
1540  );
1541  } else {
1542  _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
1543  }
1544 #endif
1545 
1546  the_thread->Wait.queue = NULL;
1547  the_thread->Wait.operations = &_Thread_queue_Operations_default;
1548 
1549 #if defined(RTEMS_SMP)
1550  _Thread_Wait_release_default_critical( the_thread, &lock_context );
1551 #endif
1552 }
1553 
1573  Thread_Control *the_thread
1574 )
1575 {
1576 #if defined(RTEMS_SMP)
1577  _Thread_queue_Gate_wait( &the_thread->Wait.Lock.Tranquilizer );
1578 #else
1579  (void) the_thread;
1580 #endif
1581 }
1582 
1591  Thread_Control *the_thread,
1592  Thread_queue_Context *queue_context
1593 )
1594 {
1595  Thread_queue_Queue *queue;
1596 
1597  queue = the_thread->Wait.queue;
1598 
1599 #if defined(RTEMS_SMP)
1600  if ( queue != NULL ) {
1601  _Assert( queue_context->Lock_context.Wait.queue == queue );
1602 #endif
1603 
1604  ( *the_thread->Wait.operations->extract )(
1605  queue,
1606  the_thread,
1607  queue_context
1608  );
1609  _Thread_Wait_restore_default( the_thread );
1610 
1611 #if defined(RTEMS_SMP)
1612  _Assert( queue_context->Lock_context.Wait.queue == NULL );
1613  queue_context->Lock_context.Wait.queue = queue;
1614  }
1615 #endif
1616 }
1617 
1621 #define THREAD_WAIT_FLAGS_INITIAL 0x0U
1622 
1626 #define THREAD_WAIT_STATE_MASK 0xffU
1627 
1635 #define THREAD_WAIT_STATE_INTEND_TO_BLOCK 0x1U
1636 
1640 #define THREAD_WAIT_STATE_BLOCKED 0x2U
1641 
1647 #define THREAD_WAIT_STATE_READY_AGAIN 0x4U
1648 
1652 #define THREAD_WAIT_CLASS_MASK 0xff00U
1653 
1657 #define THREAD_WAIT_CLASS_EVENT 0x100U
1658 
1662 #define THREAD_WAIT_CLASS_SYSTEM_EVENT 0x200U
1663 
1667 #define THREAD_WAIT_CLASS_OBJECT 0x400U
1668 
1672 #define THREAD_WAIT_CLASS_PERIOD 0x800U
1673 
1674 RTEMS_INLINE_ROUTINE void _Thread_Wait_flags_set(
1675  Thread_Control *the_thread,
1676  Thread_Wait_flags flags
1677 )
1678 {
1679 #if defined(RTEMS_SMP)
1680  _Atomic_Store_uint( &the_thread->Wait.flags, flags, ATOMIC_ORDER_RELAXED );
1681 #else
1682  the_thread->Wait.flags = flags;
1683 #endif
1684 }
1685 
1686 RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get(
1687  const Thread_Control *the_thread
1688 )
1689 {
1690 #if defined(RTEMS_SMP)
1691  return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_RELAXED );
1692 #else
1693  return the_thread->Wait.flags;
1694 #endif
1695 }
1696 
1697 RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get_acquire(
1698  const Thread_Control *the_thread
1699 )
1700 {
1701 #if defined(RTEMS_SMP)
1702  return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_ACQUIRE );
1703 #else
1704  return the_thread->Wait.flags;
1705 #endif
1706 }
1707 
1725  Thread_Control *the_thread,
1726  Thread_Wait_flags expected_flags,
1727  Thread_Wait_flags desired_flags
1728 )
1729 {
1730  _Assert( _ISR_Get_level() != 0 );
1731 
1732 #if defined(RTEMS_SMP)
1733  return _Atomic_Compare_exchange_uint(
1734  &the_thread->Wait.flags,
1735  &expected_flags,
1736  desired_flags,
1737  ATOMIC_ORDER_RELEASE,
1738  ATOMIC_ORDER_RELAXED
1739  );
1740 #else
1741  bool success = ( the_thread->Wait.flags == expected_flags );
1742 
1743  if ( success ) {
1744  the_thread->Wait.flags = desired_flags;
1745  }
1746 
1747  return success;
1748 #endif
1749 }
1750 
1765  Thread_Control *the_thread,
1766  Thread_Wait_flags expected_flags,
1767  Thread_Wait_flags desired_flags
1768 )
1769 {
1770 #if defined(RTEMS_SMP)
1771  return _Atomic_Compare_exchange_uint(
1772  &the_thread->Wait.flags,
1773  &expected_flags,
1774  desired_flags,
1775  ATOMIC_ORDER_ACQUIRE,
1776  ATOMIC_ORDER_ACQUIRE
1777  );
1778 #else
1779  bool success;
1780  ISR_Level level;
1781 
1782  _ISR_Local_disable( level );
1783 
1785  the_thread,
1786  expected_flags,
1787  desired_flags
1788  );
1789 
1790  _ISR_Local_enable( level );
1791  return success;
1792 #endif
1793 }
1794 
1809 Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread );
1810 
1811 RTEMS_INLINE_ROUTINE Status_Control _Thread_Wait_get_status(
1812  const Thread_Control *the_thread
1813 )
1814 {
1815  return (Status_Control) the_thread->Wait.return_code;
1816 }
1817 
1830 void _Thread_Continue( Thread_Control *the_thread, Status_Control status );
1831 
1837 void _Thread_Timeout( Watchdog_Control *the_watchdog );
1838 
1839 RTEMS_INLINE_ROUTINE void _Thread_Timer_initialize(
1840  Thread_Timer_information *timer,
1841  Per_CPU_Control *cpu
1842 )
1843 {
1844  _ISR_lock_Initialize( &timer->Lock, "Thread Timer" );
1845  timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
1846  _Watchdog_Preinitialize( &timer->Watchdog, cpu );
1847 }
1848 
1849 RTEMS_INLINE_ROUTINE void _Thread_Add_timeout_ticks(
1850  Thread_Control *the_thread,
1851  Per_CPU_Control *cpu,
1852  Watchdog_Interval ticks
1853 )
1854 {
1855  ISR_lock_Context lock_context;
1856 
1857  _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
1858 
1859  the_thread->Timer.header =
1861  the_thread->Timer.Watchdog.routine = _Thread_Timeout;
1862  _Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks );
1863 
1864  _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
1865 }
1866 
1867 RTEMS_INLINE_ROUTINE void _Thread_Timer_insert_realtime(
1868  Thread_Control *the_thread,
1869  Per_CPU_Control *cpu,
1871  uint64_t expire
1872 )
1873 {
1874  ISR_lock_Context lock_context;
1875  Watchdog_Header *header;
1876 
1877  _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
1878 
1879  header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
1880  the_thread->Timer.header = header;
1881  the_thread->Timer.Watchdog.routine = routine;
1882  _Watchdog_Per_CPU_insert( &the_thread->Timer.Watchdog, cpu, header, expire );
1883 
1884  _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
1885 }
1886 
1887 RTEMS_INLINE_ROUTINE void _Thread_Timer_remove( Thread_Control *the_thread )
1888 {
1889  ISR_lock_Context lock_context;
1890 
1891  _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
1892 
1893  _Watchdog_Per_CPU_remove(
1894  &the_thread->Timer.Watchdog,
1895 #if defined(RTEMS_SMP)
1896  the_thread->Timer.Watchdog.cpu,
1897 #else
1898  _Per_CPU_Get(),
1899 #endif
1900  the_thread->Timer.header
1901  );
1902 
1903  _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
1904 }
1905 
1906 RTEMS_INLINE_ROUTINE void _Thread_Remove_timer_and_unblock(
1907  Thread_Control *the_thread,
1908  Thread_queue_Queue *queue
1909 )
1910 {
1911  _Thread_Wait_tranquilize( the_thread );
1912  _Thread_Timer_remove( the_thread );
1913 
1914 #if defined(RTEMS_MULTIPROCESSING)
1915  if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
1916  _Thread_Unblock( the_thread );
1917  } else {
1918  _Thread_queue_Unblock_proxy( queue, the_thread );
1919  }
1920 #else
1921  (void) queue;
1922  _Thread_Unblock( the_thread );
1923 #endif
1924 }
1925 
1926 Status_Control _Thread_Set_name(
1927  Thread_Control *the_thread,
1928  const char *name
1929 );
1930 
1931 size_t _Thread_Get_name(
1932  const Thread_Control *the_thread,
1933  char *buffer,
1934  size_t buffer_size
1935 );
1936 
1937 #if defined(RTEMS_SMP)
1938 #define THREAD_PIN_STEP 2
1939 
1940 #define THREAD_PIN_PREEMPTION 1
1941 
1942 void _Thread_Do_unpin(
1943  Thread_Control *executing,
1944  Per_CPU_Control *cpu_self
1945 );
1946 #endif
1947 
1948 RTEMS_INLINE_ROUTINE void _Thread_Pin( Thread_Control *executing )
1949 {
1950 #if defined(RTEMS_SMP)
1951  _Assert( executing == _Thread_Executing );
1952 
1953  executing->Scheduler.pin_level += THREAD_PIN_STEP;
1954 #else
1955  (void) executing;
1956 #endif
1957 }
1958 
1959 RTEMS_INLINE_ROUTINE void _Thread_Unpin(
1960  Thread_Control *executing,
1961  Per_CPU_Control *cpu_self
1962 )
1963 {
1964 #if defined(RTEMS_SMP)
1965  unsigned int pin_level;
1966 
1967  _Assert( executing == _Thread_Executing );
1968 
1969  pin_level = executing->Scheduler.pin_level;
1970  _Assert( pin_level > 0 );
1971 
1972  if (
1974  pin_level != ( THREAD_PIN_STEP | THREAD_PIN_PREEMPTION )
1975  )
1976  ) {
1977  executing->Scheduler.pin_level = pin_level - THREAD_PIN_STEP;
1978  } else {
1979  _Thread_Do_unpin( executing, cpu_self );
1980  }
1981 #else
1982  (void) executing;
1983  (void) cpu_self;
1984 #endif
1985 }
1986 
1989 #ifdef __cplusplus
1990 }
1991 #endif
1992 
1993 #if defined(RTEMS_MULTIPROCESSING)
1994 #include <rtems/score/threadmp.h>
1995 #endif
1996 
1997 #endif
1998 /* end of include file */
Constants and Prototypes Related to the Internal Error Handler.
RTEMS_INLINE_ROUTINE Priority_Control _Thread_Priority_highest(Priority_Control left, Priority_Control right)
Returns the highest priority of the left and right thread priorities in the intuitive sense of priori...
Definition: threadimpl.h:575
void _Thread_Stack_Free(Thread_Control *the_thread)
Deallocate thread stack.
Definition: threadstackfree.c:24
RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Append a node (unprotected).
Definition: chainimpl.h:679
Definition: chain.h:65
Index for realtime clock per-CPU watchdog header.
Definition: percpu.h:268
Timestamp_Control cpu_time_used
Definition: thread.h:823
Thread_Life_state state
The current thread life state.
Definition: thread.h:696
const Thread_queue_Operations * operations
The current thread queue operations.
Definition: thread.h:494
bool _Thread_Start(Thread_Control *the_thread, const Thread_Entry_information *entry, ISR_lock_Context *lock_context)
Initializes thread and executes it.
Definition: threadstart.c:26
int64_t Timestamp_Control
Definition: timestamp.h:52
RTEMS_INLINE_ROUTINE bool _Thread_Is_proxy_blocking(uint32_t code)
Is proxy blocking.
Definition: threadimpl.h:787
RTEMS_INLINE_ROUTINE void _Thread_Wait_claim_finalize(Thread_Control *the_thread, const Thread_queue_Operations *operations)
Finalizes the thread wait queue claim via registration of the corresponding thread queue operations...
Definition: threadimpl.h:1465
Definition: threadq.h:120
RTEMS_INLINE_ROUTINE Objects_APIs _Objects_Get_API(Objects_Id id)
Definition: object.h:250
RTEMS_INLINE_ROUTINE void _Thread_Priority_change(Thread_Control *the_thread, Priority_Node *priority_node, Priority_Control new_priority, bool prepend_it, Thread_queue_Context *queue_context)
Changes the thread priority value of the specified thread priority node in the corresponding thread p...
Definition: threadimpl.h:499
bool _Thread_Initialize(Thread_Information *information, Thread_Control *the_thread, const struct _Scheduler_Control *scheduler, void *stack_area, size_t stack_size, bool is_fp, Priority_Control priority, bool is_preemptible, Thread_CPU_budget_algorithms budget_algorithm, Thread_CPU_budget_algorithm_callout budget_callout, uint32_t isr_level, Objects_Name name)
Initialize thread.
Objects_Control * _Objects_Allocate_unprotected(Objects_Information *information)
Allocates an object without locking the allocator mutex.
Definition: objectallocate.c:33
RTEMS_INLINE_ROUTINE void _Thread_Unblock(Thread_Control *the_thread)
Definition: threadimpl.h:686
#define THREAD_STATUS_PROXY_BLOCKING
Definition: threadimpl.h:53
void _Thread_Priority_update(Thread_queue_Context *queue_context)
Adds a priority node to the corresponding thread priority aggregation.
Definition: threadchangepriority.c:339
Watchdog_Header Header[PER_CPU_WATCHDOG_COUNT]
Header for watchdogs.
Definition: percpu.h:416
RTEMS_INLINE_ROUTINE void _Thread_Wait_claim(Thread_Control *the_thread, Thread_queue_Queue *queue)
Claims the thread wait queue.
Definition: threadimpl.h:1436
void _Thread_Start_multitasking(void) RTEMS_NO_RETURN
Start thread multitasking.
Definition: threadstartmultitasking.c:24
Thread_Wait_information Wait
Definition: thread.h:770
void(* Thread_Action_handler)(Thread_Control *the_thread, Thread_Action *action, ISR_lock_Context *lock_context)
Thread action handler.
Definition: thread.h:616
Thread queue context for the thread queue methods.
Definition: threadq.h:193
The priority node to build up a priority aggregation.
Definition: priority.h:94
#define _ISR_lock_ISR_disable_and_acquire(_lock, _context)
Acquires an ISR lock.
Definition: isrlock.h:223
struct _Thread_Control * executing
This is the thread executing on this processor.
Definition: percpu.h:362
RTEMS_INLINE_ROUTINE bool _Objects_Is_api_valid(uint32_t the_api)
Definition: objectimpl.h:586
Thread entry information.
Definition: thread.h:131
RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_release(Thread_Control *the_thread, Thread_Wait_flags expected_flags, Thread_Wait_flags desired_flags)
Tries to change the thread wait flags with release semantics in case of success.
Definition: threadimpl.h:1724
void _Thread_Handler(void)
Wrapper function for all threads.
Definition: threadhandler.c:72
RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Cancels a thread wait on a thread queue.
Definition: threadimpl.h:1590
#define _ISR_lock_Acquire(_lock, _context)
Acquires an ISR lock inside an ISR disabled section.
Definition: isrlock.h:278
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:277
Data Related to the Management of Processor Interrupt Levels.
Inlined Routines in the Watchdog Handler.
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:65
void _Thread_Priority_replace(Thread_Control *the_thread, Priority_Node *victim_node, Priority_Node *replacement_node)
Replaces the victim priority node with the replacement priority node in the corresponding thread prio...
Definition: threadchangepriority.c:323
RTEMS_INLINE_ROUTINE bool _Thread_Is_executing(const Thread_Control *the_thread)
Definition: threadimpl.h:645
#define _Context_Save_fp(_fp)
Save floating point context area.
Definition: context.h:146
The control block used to manage each watchdog timer.
Definition: watchdog.h:87
#define STATES_BLOCKED
Definition: statesimpl.h:132
RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Releases the thread wait default lock and restores the previous interrupt status. ...
Definition: threadimpl.h:1236
#define _ISR_lock_Initialize(_lock, _name)
Initializes an ISR lock.
Definition: isrlock.h:185
void _Thread_Priority_perform_actions(Thread_Control *start_of_path, Thread_queue_Context *queue_context)
Performs the priority actions specified by the thread queue context along the thread queue path...
Definition: threadchangepriority.c:182
uint32_t return_code
Definition: thread.h:416
RTEMS_INLINE_ROUTINE Priority_Control _Thread_Get_priority(const Thread_Control *the_thread)
Returns the priority of the thread.
Definition: threadimpl.h:1140
void _Thread_Create_idle(void)
Create idle thread.
Definition: threadcreateidle.c:86
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:767
Information required to manage a thread timer.
Definition: thread.h:502
#define _Context_Restore_fp(_fp)
Restore floating point context area.
Definition: context.h:135
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_Next(const Chain_Node *the_node)
Return pointer the next node from this node.
Definition: chainimpl.h:324
Thread_queue_Queue * queue
The current thread queue.
Definition: thread.h:485
RTEMS_INLINE_ROUTINE bool _Chain_Is_node_off_chain(const Chain_Node *node)
Is the node off chain.
Definition: chainimpl.h:139
RTEMS_INLINE_ROUTINE void _Chain_Extract_unprotected(Chain_Node *the_node)
Extract this node (unprotected).
Definition: chainimpl.h:557
void _Thread_Handler_initialization(void)
Initialize thread handler.
Definition: thread.c:59
Objects_Information Objects
The object information.
Definition: thread.h:979
#define _ISR_Get_level()
Return current interrupt level.
Definition: isrlevel.h:125
RTEMS_INLINE_ROUTINE void _Chain_Initialize_empty(Chain_Control *the_chain)
Initialize this chain as empty.
Definition: chainimpl.h:504
void _Thread_Priority_changed(Thread_Control *the_thread, Priority_Node *priority_node, bool prepend_it, Thread_queue_Context *queue_context)
Propagates a thread priority value change in the specified thread priority node to the corresponding ...
Definition: threadchangepriority.c:307
Context_Control_fp * fp_context
Definition: thread.h:838
Helpers for Manipulating Timestamps.
Definition: threadq.h:397
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:394
RTEMS_INLINE_ROUTINE void _Timestamp_Add_to(Timestamp_Control *_time, const Timestamp_Control *_add)
Adds two timestamps.
Definition: timestampimpl.h:145
Watchdog_Service_routine_entry routine
This field is the function to invoke.
Definition: watchdog.h:111
Thread queue operations.
Definition: threadq.h:512
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:66
RTEMS_INLINE_ROUTINE bool _Chain_Is_empty(const Chain_Control *the_chain)
Is the chain empty.
Definition: chainimpl.h:390
Thread_Information _Thread_Information
The internal thread objects information.
#define RTEMS_PREDICT_TRUE(_exp)
Returns the value of the specified integral expression and tells the compiler that the predicted valu...
Definition: basedefs.h:345
States_Control _Thread_Set_state(Thread_Control *the_thread, States_Control state)
Sets the specified thread state.
Definition: threadsetstate.c:50
#define _ISR_Local_disable(_level)
Disables interrupts on this processor.
Definition: isrlevel.h:54
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:292
#define _ISR_lock_ISR_disable(_context)
Disables interrupts and saves the previous interrupt state in the ISR lock context.
Definition: isrlock.h:383
RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Acquires the thread wait default lock inside a critical section (interrupts disabled).
Definition: threadimpl.h:1160
void(* Thread_CPU_budget_algorithm_callout)(Thread_Control *)
Definition: thread.h:173
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_First(const Chain_Control *the_chain)
Return pointer to chain&#39;s first node.
Definition: chainimpl.h:257
uint32_t ISR_Level
Definition: isrlevel.h:38
Definition: thread.h:728
RTEMS_INLINE_ROUTINE bool _Thread_Is_heir(const Thread_Control *the_thread)
Definition: threadimpl.h:673
Thread_Control * _Thread_Allocated_fp
Definition: threaddispatch.c:34
Control block to manage thread actions.
Definition: thread.h:661
#define _ISR_lock_ISR_enable(_context)
Restores the saved interrupt state of the ISR lock context.
Definition: isrlock.h:404
Per CPU Core Structure.
Definition: percpu.h:290
RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Acquires the thread wait default lock and disables interrupts.
Definition: threadimpl.h:1201
RTEMS_INLINE_ROUTINE void _Thread_Wait_restore_default(Thread_Control *the_thread)
Restores the default thread wait queue and operations.
Definition: threadimpl.h:1513
void _Thread_Load_environment(Thread_Control *the_thread)
Initializes enviroment for a thread.
Definition: threadloadenv.c:24
#define _ISR_lock_Release(_lock, _context)
Releases an ISR lock inside an ISR disabled section.
Definition: isrlock.h:301
RTEMS_INLINE_ROUTINE void _Thread_Wait_release_critical(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Releases the thread wait lock inside a critical section (interrupts disabled).
Definition: threadimpl.h:1371
The thread object information.
Definition: thread.h:975
RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_acquire(Thread_Control *the_thread, Thread_Wait_flags expected_flags, Thread_Wait_flags desired_flags)
Tries to change the thread wait flags with acquire semantics.
Definition: threadimpl.h:1764
Thread action.
Definition: thread.h:636
RTEMS_INLINE_ROUTINE bool _Thread_Is_allocated_fp(const Thread_Control *the_thread)
Definition: threadimpl.h:700
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:198
Objects_Control Object
Definition: thread.h:730
Thread_Life_state
Thread life states.
Definition: thread.h:675
Thread_queue_Extract_operation extract
Thread queue extract operation.
Definition: threadq.h:530
RTEMS_INLINE_ROUTINE bool _Objects_Is_local_id(Objects_Id id RTEMS_UNUSED)
Definition: objectimpl.h:623
RTEMS_INLINE_ROUTINE void _Thread_Dispatch_request(Per_CPU_Control *cpu_self, Per_CPU_Control *cpu_target)
Requests a thread dispatch on the target processor.
Definition: threaddispatch.h:231
#define _ISR_lock_Release_and_ISR_enable(_lock, _context)
Releases an ISR lock.
Definition: isrlock.h:248
States_Control current_state
Definition: thread.h:752
The information structure used to manage each API class of objects.
Definition: objectdata.h:160
Objects_Information **const _Objects_Information_table[OBJECTS_APIS_LAST+1]
Definition: exinit.c:53
#define _ISR_Local_enable(_level)
Enables interrupts on this processor.
Definition: isrlevel.h:71
RTEMS_INLINE_ROUTINE void _Watchdog_Preinitialize(Watchdog_Control *the_watchdog, Per_CPU_Control *cpu)
Pre-initializes a watchdog.
Definition: watchdogimpl.h:168
RTEMS_INLINE_ROUTINE Chain_Node * _Chain_Tail(Chain_Control *the_chain)
Return pointer to chain tail.
Definition: chainimpl.h:224
Chain Handler API.
RTEMS_INLINE_ROUTINE void _Chain_Initialize_node(Chain_Node *the_node)
Initializes a chain node.
Definition: chainimpl.h:119
RTEMS_INLINE_ROUTINE bool _Thread_Priority_less_than(Priority_Control left, Priority_Control right)
Returns true if the left thread priority is less than the right thread priority in the intuitive sens...
Definition: threadimpl.h:563
Time of Day Handler API.
Inlined Routines Associated with Thread State Information.
#define RTEMS_NO_RETURN
Definition: basedefs.h:101
struct Scheduler_Node::@3976 Wait
Thread wait support block.
volatile bool dispatch_necessary
This is set to true when this processor needs to run the thread dispatcher.
Definition: percpu.h:343
void _Thread_Kill_zombies(void)
Kills all zombie threads in the system.
Definition: threadrestart.c:218
Definition: inftrees.h:24
RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request(Thread_Control *the_thread, Thread_queue_Lock_context *queue_lock_context)
Removes a thread wait lock request.
Definition: threadimpl.h:1484
struct _Thread_Control * heir
This is the heir thread for this processor.
Definition: percpu.h:378
RTEMS_INLINE_ROUTINE void _Timestamp_Subtract(const Timestamp_Control *_start, const Timestamp_Control *_end, Timestamp_Control *_result)
Subtracts two timestamps.
Definition: timestampimpl.h:166
uint32_t States_Control
Definition: states.h:41
uint32_t Watchdog_Interval
Type is used to specify the length of intervals.
Definition: watchdogticks.h:36
The watchdog header to manage scheduled watchdogs.
Definition: watchdog.h:68
unsigned context
Definition: tlb.h:108
System State Handler API.
size_t _Thread_Stack_Allocate(Thread_Control *the_thread, size_t stack_size)
Allocate the requested stack space for the thread.
Definition: threadstackallocate.c:26
Thread_queue_Control Join_queue
Thread queue for thread join operations and multi-purpose lock.
Definition: thread.h:749
void * rtems_ada_self
Scheduler control.
Definition: scheduler.h:266
Scheduler node for per-thread data.
Definition: schedulernode.h:65
const Scheduler_Control _Scheduler_Table[]
Registered schedulers.
RTEMS_INLINE_ROUTINE Thread_Control * _Thread_Wait_acquire_default_for_executing(ISR_lock_Context *lock_context)
Acquires the thread wait default lock and returns the executing thread.
Definition: threadimpl.h:1179
Definition: threadimpl.h:239
RTEMS_INLINE_ROUTINE void _Thread_Wait_release(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Releases the thread wait lock and restores the previous interrupt status.
Definition: threadimpl.h:1413
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:425
RTEMS_INLINE_ROUTINE bool _States_Is_ready(States_Control the_states)
Definition: statesimpl.h:185
RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp(void)
Definition: threadimpl.h:755
struct Per_CPU_Control::@3973 Watchdog
Watchdog state for this processor.
Scheduler_Node * nodes
The scheduler nodes of this thread.
Definition: thread.h:354
RTEMS_INLINE_ROUTINE void _Chain_Set_off_chain(Chain_Node *node)
Set off chain.
Definition: chainimpl.h:101
States_Control _Thread_Clear_state(Thread_Control *the_thread, States_Control state)
Clears the specified thread state.
Definition: threadclearstate.c:51
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:125
Index for tick clock per-CPU watchdog header.
Definition: percpu.h:259
Definition: mmu-config.c:39
RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_critical(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Acquires the thread wait lock inside a critical section (interrupts disabled).
Definition: threadimpl.h:1296
Inlined Routines in the Object Handler.
RTEMS_INLINE_ROUTINE void _Thread_Wait_tranquilize(Thread_Control *the_thread)
Tranquilizes the thread after a wait on a thread queue.
Definition: threadimpl.h:1572
RTEMS_INLINE_ROUTINE const Chain_Node * _Chain_Immutable_tail(const Chain_Control *the_chain)
Return pointer to immutable chain tail.
Definition: chainimpl.h:240
RTEMS_INLINE_ROUTINE bool _Thread_Is_context_switch_necessary(void)
Definition: threadimpl.h:766
Multiprocessing Portion of the Thread Package.
Objects_Id _Thread_Global_constructor
Object identifier of the global constructor thread.
Definition: threadhandler.c:49
uint32_t Objects_Id
Definition: object.h:75
Context_Control Registers
Definition: thread.h:833
Definition: object.h:59
Thread_Life_control Life
Thread life-cycle control.
Definition: thread.h:855
Constants and Structures Related with the Thread Control Block.
RTEMS_INLINE_ROUTINE void _Chain_Append_if_is_off_chain_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Append a node on the end of a chain if the node is in the off chain state (unprotected).
Definition: chainimpl.h:707
RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Acquires the thread wait default lock and disables interrupts.
Definition: threadimpl.h:1352
#define rtems_configuration_get_maximum_processors()
Returns the configured maximum count of processors.
Definition: config.h:351
Thread_Control * _Thread_Get(Objects_Id id, ISR_lock_Context *lock_context)
Gets a thread by its identifier.
Definition: threadget.c:24
void _Thread_Timeout(Watchdog_Control *the_watchdog)
General purpose thread wait timeout.
Definition: threadtimeout.c:83
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:25
RTEMS_INLINE_ROUTINE Thread_Control * _Thread_Get_heir_and_make_it_executing(Per_CPU_Control *cpu_self)
Gets the heir of the processor and makes it executing.
Definition: threadimpl.h:827
Watchdog_Service_routine(* Watchdog_Service_routine_entry)(Watchdog_Control *)
Pointer to a watchdog service routine.
Definition: watchdog.h:63
RTEMS_INLINE_ROUTINE bool _Thread_Is_null(const Thread_Control *the_thread)
Definition: threadimpl.h:775
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:21
RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Releases the thread wait default lock inside a critical section (interrupts disabled).
Definition: threadimpl.h:1220
Thread_CPU_budget_algorithms
Definition: thread.h:159
Thread_Timer_information Timer
Definition: thread.h:772
#define NULL
Requests a GPIO pin group configuration.
Definition: bestcomm_api.h:77
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:386
void _Thread_Close(Thread_Control *the_thread, Thread_Control *executing, Thread_Close_context *context)
Closes the thread.
Definition: threadrestart.c:511
Objects_Id id
Definition: objectdata.h:43