RTEMS
threadrestart.c
Go to the documentation of this file.
1 
9 /*
10  * COPYRIGHT (c) 1989-1999.
11  * On-Line Applications Research Corporation (OAR).
12  *
13  * Copyright (c) 2014, 2016 embedded brains GmbH.
14  *
15  * The license and distribution terms for this file may be
16  * found in the file LICENSE in this distribution or at
17  * http://www.rtems.org/license/LICENSE.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <rtems/score/threadimpl.h>
25 #include <rtems/score/apimutex.h>
26 #include <rtems/score/assert.h>
27 #include <rtems/score/chainimpl.h>
29 #include <rtems/score/isrlock.h>
31 #include <rtems/score/stackimpl.h>
32 #include <rtems/score/sysstate.h>
36 #include <rtems/score/wkspace.h>
37 
38 #define THREAD_JOIN_TQ_OPERATIONS &_Thread_queue_Operations_priority
39 
40 static void _Thread_Life_action_handler(
41  Thread_Control *executing,
42  Thread_Action *action,
43  ISR_lock_Context *lock_context
44 );
45 
46 typedef struct {
47  Chain_Control Chain;
48  ISR_lock_Control Lock;
50 
51 static Thread_Zombie_control _Thread_Zombies = {
52  .Chain = CHAIN_INITIALIZER_EMPTY( _Thread_Zombies.Chain ),
53  .Lock = ISR_LOCK_INITIALIZER( "thread zombies" )
54 };
55 
56 static void _Thread_Raise_real_priority(
57  Thread_Control *the_thread,
58  Priority_Control priority
59 )
60 {
61  Thread_queue_Context queue_context;
62 
63  _Thread_queue_Context_initialize( &queue_context );
65  _Thread_Wait_acquire( the_thread, &queue_context );
66 
67  if ( priority < the_thread->Real_priority.priority ) {
69  the_thread,
70  &the_thread->Real_priority,
71  priority,
72  false,
73  &queue_context
74  );
75  }
76 
77  _Thread_Wait_release( the_thread, &queue_context );
78  _Thread_Priority_update( &queue_context );
79 }
80 
81 typedef struct {
83  void *exit_value;
85 
86 static Thread_Control *_Thread_Join_flush_filter(
87  Thread_Control *the_thread,
88  Thread_queue_Queue *queue,
89  Thread_queue_Context *queue_context
90 )
91 {
92  Thread_Join_context *join_context;
93 
94  join_context = (Thread_Join_context *) queue_context;
95 
96  the_thread->Wait.return_argument = join_context->exit_value;
97 
98  return the_thread;
99 }
100 
101 static void _Thread_Wake_up_joining_threads( Thread_Control *the_thread )
102 {
103  Thread_Join_context join_context;
104 
105  join_context.exit_value = the_thread->Life.exit_value;
106 
107  _Thread_queue_Context_initialize( &join_context.Base );
108  _Thread_queue_Acquire( &the_thread->Join_queue, &join_context.Base );
110  &the_thread->Join_queue.Queue,
111  THREAD_JOIN_TQ_OPERATIONS,
112  _Thread_Join_flush_filter,
113  &join_context.Base
114  );
115 }
116 
117 static void _Thread_Add_to_zombie_chain( Thread_Control *the_thread )
118 {
119  ISR_lock_Context lock_context;
120  Thread_Zombie_control *zombies;
121 
122  zombies = &_Thread_Zombies;
123  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
124  _Chain_Append_unprotected( &zombies->Chain, &the_thread->Object.Node );
125  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
126 }
127 
128 static void _Thread_Make_zombie( Thread_Control *the_thread )
129 {
130 #if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
131  if ( _Thread_Owns_resources( the_thread ) ) {
132  _Internal_error( INTERNAL_ERROR_RESOURCE_IN_USE );
133  }
134 #endif
135 
137  _Objects_Get_information_id( the_thread->Object.id ),
138  &the_thread->Object
139  );
140 
141  _Thread_Set_state( the_thread, STATES_ZOMBIE );
142  _Thread_queue_Extract_with_proxy( the_thread );
143  _Thread_Timer_remove( the_thread );
144 
145  /*
146  * Add the thread to the thread zombie chain before we wake up joining
147  * threads, so that they are able to clean up the thread immediately. This
148  * matters for SMP configurations.
149  */
150  _Thread_Add_to_zombie_chain( the_thread );
151 
152  _Thread_Wake_up_joining_threads( the_thread );
153 }
154 
155 static void _Thread_Free( Thread_Control *the_thread )
156 {
157  Thread_Information *information = (Thread_Information *)
158  _Objects_Get_information_id( the_thread->Object.id );
159 
160  _User_extensions_Thread_delete( the_thread );
162  _ISR_lock_Destroy( &the_thread->Keys.Lock );
164  _Thread_Scheduler_get_home( the_thread ),
165  _Thread_Scheduler_get_home_node( the_thread )
166  );
167  _ISR_lock_Destroy( &the_thread->Timer.Lock );
168 
169  /*
170  * The thread might have been FP. So deal with that.
171  */
172 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
173 #if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
174  if ( _Thread_Is_allocated_fp( the_thread ) )
175  _Thread_Deallocate_fp();
176 #endif
177 #endif
178 
180  &information->Thread_queue_heads.Free,
181  the_thread->Wait.spare_heads
182  );
183 
184  /*
185  * Free the rest of the memory associated with this task
186  * and set the associated pointers to NULL for safety.
187  */
188  ( *the_thread->Start.stack_free )( the_thread->Start.Initial_stack.area );
189 
190 #if defined(RTEMS_SMP)
191  _ISR_lock_Destroy( &the_thread->Scheduler.Lock );
192  _ISR_lock_Destroy( &the_thread->Wait.Lock.Default );
193  _SMP_lock_Stats_destroy( &the_thread->Potpourri_stats );
194 #endif
195 
196  _Thread_queue_Destroy( &the_thread->Join_queue );
197  _Context_Destroy( the_thread, &the_thread->Registers );
198  _Objects_Free( &information->Objects, &the_thread->Object );
199 }
200 
201 static void _Thread_Wait_for_execution_stop( Thread_Control *the_thread )
202 {
203 #if defined(RTEMS_SMP)
204  /*
205  * It is very unlikely that we see an executing thread here. It can happen
206  * in case the thread termination sequence is interrupted by a slow interrupt
207  * service on a remote processor.
208  */
209  while ( _Thread_Is_executing_on_a_processor( the_thread ) ) {
210  /* Wait */
211  }
212 #else
213  (void) the_thread;
214 #endif
215 }
216 
218 {
219  ISR_lock_Context lock_context;
220  Thread_Zombie_control *zombies = &_Thread_Zombies;
221  Thread_Control *the_thread;
222 
223  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
224 
225  the_thread = (Thread_Control *) _Chain_Get_unprotected( &zombies->Chain );
226  while ( the_thread != NULL ) {
227  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
228 
229  _Thread_Wait_for_execution_stop( the_thread );
230  _Thread_Free( the_thread );
231 
232  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
233 
234  the_thread = (Thread_Control *) _Chain_Get_unprotected( &zombies->Chain );
235  }
236 
237  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
238 }
239 
240 static Thread_Life_state _Thread_Change_life_locked(
241  Thread_Control *the_thread,
242  Thread_Life_state clear,
243  Thread_Life_state set,
244  Thread_Life_state ignore
245 )
246 {
247  Thread_Life_state previous;
248  Thread_Life_state state;
249 
250  previous = the_thread->Life.state;
251  state = previous;
252  state &= ~clear;
253  state |= set;
254  the_thread->Life.state = state;
255 
256  state &= ~ignore;
257 
258  if (
260  && _Thread_Is_life_changing( state )
261  ) {
262  the_thread->is_preemptible = the_thread->Start.is_preemptible;
263  the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
264  the_thread->budget_callout = the_thread->Start.budget_callout;
265 
267  the_thread,
268  &the_thread->Life.Action,
269  _Thread_Life_action_handler
270  );
271  }
272 
273  return previous;
274 }
275 
276 static Per_CPU_Control *_Thread_Wait_for_join(
277  Thread_Control *executing,
278  Per_CPU_Control *cpu_self
279 )
280 {
281  ISR_lock_Context lock_context;
282 
283  _Thread_State_acquire( executing, &lock_context );
284 
285  if (
286  _Thread_Is_joinable( executing )
287  && _Thread_queue_Is_empty( &executing->Join_queue.Queue )
288  ) {
290  _Thread_State_release( executing, &lock_context );
291  _Thread_Dispatch_direct( cpu_self );
292 
293  /* Let other threads run */
294 
295  cpu_self = _Thread_Dispatch_disable();
296  } else {
297  _Thread_State_release( executing, &lock_context );
298  }
299 
300  return cpu_self;
301 }
302 
303 void _Thread_Life_action_handler(
304  Thread_Control *executing,
305  Thread_Action *action,
306  ISR_lock_Context *lock_context
307 )
308 {
309  Thread_Life_state previous_life_state;
310  Per_CPU_Control *cpu_self;
311 
312  (void) action;
313 
314  previous_life_state = executing->Life.state;
315  executing->Life.state = previous_life_state | THREAD_LIFE_PROTECTED;
316 
317  _Thread_State_release( executing, lock_context );
318 
319  if ( _Thread_Is_life_terminating( previous_life_state ) ) {
321  } else {
322  _Assert( _Thread_Is_life_restarting( previous_life_state ) );
323 
324  _User_extensions_Thread_restart( executing );
325  }
326 
327  cpu_self = _Thread_Dispatch_disable();
328 
329  if ( _Thread_Is_life_terminating( previous_life_state ) ) {
330  cpu_self = _Thread_Wait_for_join( executing, cpu_self );
331  _Thread_Make_zombie( executing );
332  _Thread_Dispatch_direct( cpu_self );
334  }
335 
336  _Assert( _Thread_Is_life_restarting( previous_life_state ) );
337 
338  _Thread_State_acquire( executing, lock_context );
339 
340  /*
341  * The executing thread runs with thread dispatching disabled right now.
342  * Other threads may have suspended the executing thread. The thread life
343  * handler may run in parallel with _Thread_Add_life_change_request() which
344  * may have set STATES_LIFE_IS_CHANGING.
345  */
346  _Assert(
347  executing->current_state == STATES_READY
348  || executing->current_state == STATES_SUSPENDED
349  || executing->current_state == STATES_LIFE_IS_CHANGING
350  );
351 
352  _Thread_Change_life_locked(
353  executing,
354  THREAD_LIFE_PROTECTED | THREAD_LIFE_RESTARTING,
355  0,
356  0
357  );
358 
359  _Thread_State_release( executing, lock_context );
360 
361  _Assert(
362  _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE
363  );
364 
366  _Thread_Load_environment( executing );
367 
368 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
369  if ( executing->fp_context != NULL ) {
370  _Context_Restore_fp( &executing->fp_context );
371  }
372 #endif
373 
374  _Context_Restart_self( &executing->Registers );
376 }
377 
378 static void _Thread_Add_life_change_request( Thread_Control *the_thread )
379 {
380  uint32_t pending_requests;
381 
382  _Assert( _Thread_State_is_owner( the_thread ) );
383 
384  pending_requests = the_thread->Life.pending_life_change_requests;
385  the_thread->Life.pending_life_change_requests = pending_requests + 1;
386 
387  if ( pending_requests == 0 ) {
389  }
390 }
391 
392 static void _Thread_Remove_life_change_request( Thread_Control *the_thread )
393 {
394  ISR_lock_Context lock_context;
395  uint32_t pending_requests;
396 
397  _Thread_State_acquire( the_thread, &lock_context );
398 
399  pending_requests = the_thread->Life.pending_life_change_requests;
400  the_thread->Life.pending_life_change_requests = pending_requests - 1;
401 
402  if ( pending_requests == 1 ) {
403  /*
404  * Do not remove states used for thread queues to avoid race conditions on
405  * SMP configurations. We could interrupt an extract operation on another
406  * processor disregarding the thread wait flags. Rely on
407  * _Thread_queue_Extract_with_proxy() for removal of these states.
408  */
410  the_thread,
413  );
414  }
415 
416  _Thread_State_release( the_thread, &lock_context );
417 }
418 
419 static void _Thread_Finalize_life_change(
420  Thread_Control *the_thread,
421  Priority_Control priority
422 )
423 {
424  _Thread_queue_Extract_with_proxy( the_thread );
425  _Thread_Timer_remove( the_thread );
426  _Thread_Raise_real_priority( the_thread, priority );
427  _Thread_Remove_life_change_request( the_thread );
428 }
429 
431  Thread_Control *the_thread,
432  States_Control waiting_for_join,
433  Thread_Control *executing,
434  Thread_queue_Context *queue_context
435 )
436 {
437  _Assert( the_thread != executing );
438  _Assert( _Thread_State_is_owner( the_thread ) );
439 
440  executing->Wait.return_argument = NULL;
441 
442  _Thread_queue_Context_set_thread_state( queue_context, waiting_for_join );
444  &the_thread->Join_queue.Queue,
445  THREAD_JOIN_TQ_OPERATIONS,
446  executing,
447  queue_context
448  );
449 }
450 
451 static void _Thread_Set_exit_value(
452  Thread_Control *the_thread,
453  void *exit_value
454 )
455 {
456  the_thread->Life.exit_value = exit_value;
457 }
458 
460  Thread_Control *the_thread,
461  Thread_Control *executing,
462  void *exit_value
463 )
464 {
465  ISR_lock_Context lock_context;
466  Thread_Life_state previous;
467  Per_CPU_Control *cpu_self;
468  Priority_Control priority;
469 
470  _Assert( the_thread != executing );
471 
472  _Thread_State_acquire( the_thread, &lock_context );
473 
474  _Thread_Set_exit_value( the_thread, exit_value );
475  previous = _Thread_Change_life_locked(
476  the_thread,
477  0,
478  THREAD_LIFE_TERMINATING,
479  0
480  );
481 
482  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
483  priority = _Thread_Get_priority( executing );
484 
485  if ( _States_Is_dormant( the_thread->current_state ) ) {
486  _Thread_State_release( the_thread, &lock_context );
487  _Thread_Make_zombie( the_thread );
488  } else if ( _Thread_Is_life_change_allowed( previous ) ) {
489  _Thread_Add_life_change_request( the_thread );
490  _Thread_State_release( the_thread, &lock_context );
491 
492  _Thread_Finalize_life_change( the_thread, priority );
493  } else {
494  _Thread_Add_life_change_request( the_thread );
496  _Thread_State_release( the_thread, &lock_context );
497 
498  _Thread_Raise_real_priority( the_thread, priority );
499  _Thread_Remove_life_change_request( the_thread );
500  }
501 
502  _Thread_Dispatch_enable( cpu_self );
503 }
504 
505 static void _Thread_Close_enqueue_callout(
506  Thread_queue_Queue *queue,
507  Thread_Control *the_thread,
508  Per_CPU_Control *cpu_self,
509  Thread_queue_Context *queue_context
510 )
511 {
512  Thread_Close_context *context;
513 
514  context = (Thread_Close_context *) queue_context;
515  _Thread_Cancel( context->cancel, the_thread, NULL );
516 }
517 
519  Thread_Control *the_thread,
520  Thread_Control *executing,
521  Thread_Close_context *context
522 )
523 {
524  context->cancel = the_thread;
526  &context->Base,
527  _Thread_Close_enqueue_callout
528  );
530  the_thread,
531  &context->Base.Lock_context.Lock_context
532  );
533  _Thread_Join(
534  the_thread,
536  executing,
537  &context->Base
538  );
539 }
540 
542  Thread_Control *executing,
543  Thread_Life_state set,
544  void *exit_value
545 )
546 {
547  ISR_lock_Context lock_context;
548 
549  _Assert(
550  _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE
551  );
552  _Assert(
553  executing->current_state == STATES_READY
554  || executing->current_state == STATES_SUSPENDED
555  );
556 
557  _Thread_State_acquire( executing, &lock_context );
558  _Thread_Set_exit_value( executing, exit_value );
559  _Thread_Change_life_locked(
560  executing,
561  0,
562  set,
563  THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED
564  );
565  _Thread_State_release( executing, &lock_context );
566 }
567 
569  Thread_Control *the_thread,
570  const Thread_Entry_information *entry,
571  ISR_lock_Context *lock_context
572 )
573 {
574  Thread_Life_state previous;
575  Per_CPU_Control *cpu_self;
576 
577  _Thread_State_acquire_critical( the_thread, lock_context );
578 
579  if ( _States_Is_dormant( the_thread->current_state ) ) {
580  _Thread_State_release( the_thread, lock_context );
581  return false;
582  }
583 
584  the_thread->Start.Entry = *entry;
585  previous = _Thread_Change_life_locked(
586  the_thread,
587  0,
588  THREAD_LIFE_RESTARTING,
589  0
590  );
591 
592  cpu_self = _Thread_Dispatch_disable_critical( lock_context );
593 
594  if ( _Thread_Is_life_change_allowed( previous ) ) {
595  _Thread_Add_life_change_request( the_thread );
596  _Thread_State_release( the_thread, lock_context );
597 
598  _Thread_Finalize_life_change(
599  the_thread,
600  the_thread->Start.initial_priority
601  );
602  } else {
604  _Thread_State_release( the_thread, lock_context );
605  }
606 
607  _Thread_Dispatch_enable( cpu_self );
608  return true;
609 }
610 
612  Thread_Control *executing,
613  const Thread_Entry_information *entry,
614  ISR_lock_Context *lock_context
615 )
616 {
617  Per_CPU_Control *cpu_self;
618  Thread_queue_Context queue_context;
619 
620  _Assert(
621  _Watchdog_Get_state( &executing->Timer.Watchdog ) == WATCHDOG_INACTIVE
622  );
623  _Assert(
624  executing->current_state == STATES_READY
625  || executing->current_state == STATES_SUSPENDED
626  );
627 
628  _Thread_queue_Context_initialize( &queue_context );
630  _Thread_State_acquire_critical( executing, lock_context );
631 
632  executing->Start.Entry = *entry;
633  _Thread_Change_life_locked(
634  executing,
635  0,
636  THREAD_LIFE_RESTARTING,
637  THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED
638  );
639 
640  cpu_self = _Thread_Dispatch_disable_critical( lock_context );
641  _Thread_State_release( executing, lock_context );
642 
643  _Thread_Wait_acquire_default( executing, lock_context );
645  executing,
646  &executing->Real_priority,
647  executing->Start.initial_priority,
648  false,
649  &queue_context
650  );
651  _Thread_Wait_release_default( executing, lock_context );
652 
653  _Thread_Priority_update( &queue_context );
654  _Thread_Dispatch_direct( cpu_self );
656 }
657 
659  Thread_Life_state clear,
660  Thread_Life_state set,
661  Thread_Life_state ignore
662 )
663 {
664  ISR_lock_Context lock_context;
665  Thread_Control *executing;
666  Per_CPU_Control *cpu_self;
667  Thread_Life_state previous;
668 
669  executing = _Thread_State_acquire_for_executing( &lock_context );
670 
671  previous = _Thread_Change_life_locked( executing, clear, set, ignore );
672 
673  cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
674  _Thread_State_release( executing, &lock_context );
675  _Thread_Dispatch_enable( cpu_self );
676 
677  return previous;
678 }
679 
681 {
682  return _Thread_Change_life(
683  THREAD_LIFE_PROTECTED,
684  state & THREAD_LIFE_PROTECTED,
685  0
686  );
687 }
void _Thread_Load_environment(Thread_Control *the_thread)
Initializes enviroment for a thread.
Definition: threadloadenv.c:24
static void _User_extensions_Thread_terminate(Thread_Control *executing)
Terminates the executing thread.
Definition: userextimpl.h:457
#define ISR_LOCK_INITIALIZER(_name)
Initializer for static initialization of ISR locks.
Definition: isrlock.h:146
Thread_Life_state state
The current thread life state.
Definition: thread.h:693
Thread_CPU_budget_algorithm_callout budget_callout
Definition: thread.h:816
#define _ISR_lock_Destroy(_lock)
Destroys an ISR lock.
Definition: isrlock.h:196
#define _Context_Restore_fp(_fp)
Restore floating point context area.
Definition: context.h:142
void _Thread_Close(Thread_Control *the_thread, Thread_Control *executing, Thread_Close_context *context)
Closes the thread.
The watchdog is inactive.
Definition: watchdogimpl.h:61
uint64_t Priority_Control
The thread priority control.
Definition: priority.h:70
bool is_preemptible
Definition: thread.h:795
#define STATES_WAITING_FOR_JOIN
Definition: statesimpl.h:93
Thread_Life_state
Thread life states.
Definition: thread.h:672
#define _ISR_lock_Release_and_ISR_enable(_lock, _context)
Releases an ISR lock.
Definition: isrlock.h:257
static __inline__ bool _Thread_Is_life_change_allowed(Thread_Life_state life_state)
Checks if the thread life state allos life change.
Definition: threadimpl.h:1294
Thread_Wait_information Wait
Definition: thread.h:767
static void _User_extensions_Thread_restart(Thread_Control *restarted)
Restarts a thread.
Definition: userextimpl.h:337
Thread queue context for the thread queue methods.
Definition: threadq.h:198
void _Thread_Dispatch_direct(Per_CPU_Control *cpu_self)
Directly do a thread dispatch.
Thread entry information.
Definition: thread.h:130
#define STATES_LOCALLY_BLOCKED
Definition: statesimpl.h:122
void _Thread_Kill_zombies(void)
Kills all zombie threads in the system.
static __inline__ void _Thread_State_acquire_critical(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Acquires the lock context in a critical section.
Definition: threadimpl.h:528
static __inline__ const Scheduler_Control * _Thread_Scheduler_get_home(const Thread_Control *the_thread)
Gets the home scheduler of the thread.
Definition: threadimpl.h:1419
uint32_t pending_life_change_requests
The count of pending life change requests.
Definition: thread.h:698
Inlined Routines in the Watchdog Handler.
static __inline__ bool _Thread_Is_executing_on_a_processor(const Thread_Control *the_thread)
Checks if the thread executes currently on some processor in the system.
Definition: threadimpl.h:930
Thread_Life_state _Thread_Change_life(Thread_Life_state clear, Thread_Life_state set, Thread_Life_state ignore)
Changes the currently executing thread to a new state with the sets.
Freechain Handler API.
Thread_Start_information Start
Definition: thread.h:825
static __inline__ Watchdog_State _Watchdog_Get_state(const Watchdog_Control *the_watchdog)
Gets the state of the watchdog.
Definition: watchdogimpl.h:149
static __inline__ bool _Thread_Is_life_restarting(Thread_Life_state life_state)
Checks if the thread life state is restarting.
Definition: threadimpl.h:1264
static __inline__ void _Thread_Add_post_switch_action(Thread_Control *the_thread, Thread_Action *action, Thread_Action_handler handler)
Adds a post switch action to the thread with the given handler.
Definition: threadimpl.h:1234
void _Thread_Exit(Thread_Control *executing, Thread_Life_state set, void *exit_value)
Exits the currently executing thread.
#define CHAIN_INITIALIZER_EMPTY(name)
Chain initializer for an empty chain with designator name.
Definition: chainimpl.h:39
void _Thread_queue_Acquire(Thread_queue_Control *the_thread_queue, Thread_queue_Context *queue_context)
Acquires the thread queue control in a critical section.
Definition: threadq.c:87
Inlined Routines Associated with the Manipulation of the Scheduler.
Objects_Information * _Objects_Get_information_id(Objects_Id id)
Gets information of an object from an ID.
static __inline__ void _Thread_queue_Context_initialize(Thread_queue_Context *queue_context)
Initializes a thread queue context.
Definition: threadqimpl.h:152
#define STATES_BLOCKED
Definition: statesimpl.h:135
#define STATES_LIFE_IS_CHANGING
Definition: statesimpl.h:102
static void _User_extensions_Thread_delete(Thread_Control *deleted)
Deletes a thread.
Definition: userextimpl.h:309
struct Thread_Wait_information::@26 Lock
Thread wait lock control block.
Thread_Entry_information Entry
Definition: thread.h:180
union Thread_Information::@27 Thread_queue_heads
Thread queue heads maintenance.
Thread_Keys_information Keys
The POSIX Keys information.
Definition: thread.h:845
#define _Context_Restart_self(_the_context)
Restart currently executing thread.
Definition: context.h:117
Thread_Scheduler_control Scheduler
Scheduler related control.
Definition: thread.h:764
ISR_lock_Control Default
Thread wait default lock.
Definition: thread.h:447
User Extension Handler API.
Objects_Information Objects
The object information.
Definition: thread.h:1004
static __inline__ void _Thread_State_release(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Releases the lock context and enables interrupts.
Definition: threadimpl.h:592
#define STATES_ZOMBIE
Definition: statesimpl.h:116
ISR lock control.
Definition: isrlock.h:56
static __inline__ void _Thread_queue_Context_set_enqueue_callout(Thread_queue_Context *queue_context, Thread_queue_Enqueue_callout enqueue_callout)
Sets the enqueue callout in the thread queue context.
Definition: threadqimpl.h:229
Inlined Routines from the Stack Handler.
uint32_t States_Control
Definition: states.h:46
Information for the Assert Handler.
void _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 given thread to wait for.
Thread_queue_Queue Queue
The actual thread queue.
Definition: threadq.h:583
static __inline__ void _Thread_queue_Context_set_thread_state(Thread_queue_Context *queue_context, States_Control thread_state)
Sets the thread state for the thread to enqueue in the thread queue context.
Definition: threadqimpl.h:178
static __inline__ void _Chain_Append_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Appends a node (unprotected).
Definition: chainimpl.h:680
static __inline__ Per_CPU_Control * _Thread_Dispatch_disable_critical(const ISR_lock_Context *lock_context)
Disables thread dispatching inside a critical section (interrupts disabled).
Thread_CPU_budget_algorithms budget_algorithm
Definition: thread.h:814
static __inline__ bool _States_Is_dormant(States_Control the_states)
Checks if DORMANT state is set.
Definition: statesimpl.h:213
static void _User_extensions_Destroy_iterators(Thread_Control *the_thread)
Destroys all user extension iterators of a thread.
Definition: userextimpl.h:500
size_t _Thread_queue_Flush_critical(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_queue_Flush_filter filter, Thread_queue_Context *queue_context)
Unblocks all threads enqueued on the thread queue.
Definition: threadqflush.c:63
Per CPU Core Structure.
Definition: percpu.h:347
static __inline__ void _Thread_Timer_remove(Thread_Control *the_thread)
Remove the watchdog timer from the thread.
Definition: threadimpl.h:2456
Thread_Life_state _Thread_Set_life_protection(Thread_Life_state state)
Set the thread to life protected.
States_Control _Thread_Set_state_locked(Thread_Control *the_thread, States_Control state)
Sets the specified thread state without locking the lock context.
static __inline__ Scheduler_Node * _Thread_Scheduler_get_home_node(const Thread_Control *the_thread)
Gets the scheduler&#39;s home node.
Definition: threadimpl.h:1438
static __inline__ 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:1868
Chain_Node Node
Definition: objectdata.h:41
The thread object information.
Definition: thread.h:1000
Thread action.
Definition: thread.h:633
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:203
Objects_Control Object
Definition: thread.h:727
API Mutex Handler API.
Constants and Structures Associated with the Manipulation of Objects.
void _Thread_queue_Extract_with_proxy(Thread_Control *the_thread)
Extracts the_thread from the_thread_queue.
States_Control current_state
Definition: thread.h:749
#define STATES_SUSPENDED
Definition: statesimpl.h:96
static __inline__ Priority_Control _Thread_Get_priority(const Thread_Control *the_thread)
Returns the priority of the thread.
Definition: threadimpl.h:1610
static __inline__ 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:1699
void _Thread_Priority_update(Thread_queue_Context *queue_context)
Updates the priority of all threads in the set.
void _Thread_Dispatch_enable(Per_CPU_Control *cpu_self)
Enables thread dispatching.
States_Control _Thread_Set_state(Thread_Control *the_thread, States_Control state)
Sets the specified thread state.
static __inline__ void _Thread_queue_Context_clear_priority_updates(Thread_queue_Context *queue_context)
Clears the priority update count of the thread queue context.
Definition: threadqimpl.h:338
Chain Handler API.
void * exit_value
The thread exit value.
Definition: thread.h:708
Priority_Control initial_priority
Definition: thread.h:195
Thread_CPU_budget_algorithm_callout budget_callout
Definition: thread.h:191
static __inline__ bool _Thread_Is_joinable(const Thread_Control *the_thread)
Checks if the thread is joinable.
Definition: threadimpl.h:1326
#define _ISR_lock_ISR_disable_and_acquire(_lock, _context)
Acquires an ISR lock.
Definition: isrlock.h:232
Freechain_Control Free
The free thread queue heads.
Definition: thread.h:1022
Stack_Control Initial_stack
Definition: thread.h:201
#define STATES_READY
Definition: statesimpl.h:45
void _Thread_Restart_self(Thread_Control *executing, const Thread_Entry_information *entry, ISR_lock_Context *lock_context)
Restarts the currently executing thread.
static void __inline__ _Freechain_Push(Freechain_Control *freechain, void *node)
Pushes a node back to the freechain.
Definition: freechainimpl.h:95
static __inline__ Per_CPU_Control * _Thread_Dispatch_disable(void)
Disables thread dispatching.
States_Control _Thread_Clear_state_locked(Thread_Control *the_thread, States_Control state)
Clears the specified thread state without locking the lock context.
System State Handler API.
Thread_queue_Control Join_queue
Thread queue for thread join operations and multi-purpose lock.
Definition: thread.h:746
static __inline__ bool _Thread_queue_Is_empty(const Thread_queue_Queue *queue)
Checks if the thread queue queue is empty.
Definition: threadqimpl.h:1152
void _Internal_error(Internal_errors_Core_list core_error) RTEMS_NO_RETURN
Terminates the system with an INTERNAL_ERROR_CORE fatal source and the specified core error code...
Definition: interr.c:51
Inlined Routines from the Thread Handler.
static __inline__ Thread_Control * _Thread_State_acquire_for_executing(ISR_lock_Context *lock_context)
Disables interrupts and acquires the lock context for the currently executing thread.
Definition: threadimpl.h:559
Thread_CPU_budget_algorithms budget_algorithm
Definition: thread.h:187
static __inline__ bool _Thread_Is_life_terminating(Thread_Life_state life_state)
Checks if the thread life state is terminating.
Definition: threadimpl.h:1279
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:65
static __inline__ 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:1929
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
Definition: threadq.h:130
static __inline__ void _Thread_queue_Destroy(Thread_queue_Control *the_thread_queue)
Destroys the thread queue.
Definition: threadqimpl.h:1378
static __inline__ bool _Thread_Is_life_changing(Thread_Life_state life_state)
Checks if the thread life state is life changing.
Definition: threadimpl.h:1310
Thread_Action Action
Thread life action used to react upon thread restart and delete requests.
Definition: thread.h:688
static __inline__ 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:722
void _Thread_Cancel(Thread_Control *the_thread, Thread_Control *executing, void *exit_value)
Cancels the thread.
ISR_lock_Control Lock
Lock to protect the scheduler node change requests.
Definition: thread.h:248
void _Thread_queue_Enqueue(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Blocks the thread and places it on the thread queue.
#define STATES_WAITING_FOR_JOIN_AT_EXIT
Definition: statesimpl.h:90
Context_Control Registers
Definition: thread.h:830
void * area
Definition: stack.h:57
static __inline__ void _Thread_State_acquire(Thread_Control *the_thread, ISR_lock_Context *lock_context)
Disables interrupts and acquires the lock_context.
Definition: threadimpl.h:542
Thread_Life_control Life
Thread life-cycle control.
Definition: thread.h:852
Priority_Node Real_priority
The base priority of this thread in its home scheduler instance.
Definition: thread.h:754
void _Objects_Close(const Objects_Information *information, Objects_Control *the_object)
Closes object.
Definition: objectclose.c:23
static __inline__ void _Scheduler_Node_destroy(const Scheduler_Control *scheduler, Scheduler_Node *node)
Destroys a scheduler node.
Information Related to the RAM Workspace.
ISR Locks.
static __inline__ 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:1734
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Definition: assert.h:100
#define RTEMS_UNREACHABLE()
Tells the compiler that this program point is unreachable.
Definition: basedefs.h:860
void(* stack_free)(void *)
This field points to the handler which should free the stack.
Definition: thread.h:199
Thread_Timer_information Timer
Definition: thread.h:769
static __inline__ Chain_Node * _Chain_Get_unprotected(Chain_Control *the_chain)
Gets the first node (unprotected).
Definition: chainimpl.h:630
bool _Thread_Restart_other(Thread_Control *the_thread, const Thread_Entry_information *entry, ISR_lock_Context *lock_context)
Restarts the thread.
static __inline__ void _Objects_Free(Objects_Information *information, Objects_Control *the_object)
Frees an object.
Definition: objectimpl.h:933
Objects_Id id
Definition: objectdata.h:43