summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/threadimpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/include/rtems/score/threadimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h1969
1 files changed, 0 insertions, 1969 deletions
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
deleted file mode 100644
index b6722fae19..0000000000
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ /dev/null
@@ -1,1969 +0,0 @@
-/**
- * @file
- *
- * @brief Inlined Routines from the Thread Handler
- *
- * This file contains the macro implementation of the inlined
- * routines from the Thread handler.
- */
-
-/*
- * COPYRIGHT (c) 1989-2008.
- * On-Line Applications Research Corporation (OAR).
- *
- * Copyright (c) 2014, 2017 embedded brains GmbH.
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#ifndef _RTEMS_SCORE_THREADIMPL_H
-#define _RTEMS_SCORE_THREADIMPL_H
-
-#include <rtems/score/thread.h>
-#include <rtems/score/assert.h>
-#include <rtems/score/chainimpl.h>
-#include <rtems/score/interr.h>
-#include <rtems/score/isr.h>
-#include <rtems/score/objectimpl.h>
-#include <rtems/score/schedulernodeimpl.h>
-#include <rtems/score/statesimpl.h>
-#include <rtems/score/status.h>
-#include <rtems/score/sysstate.h>
-#include <rtems/score/threadqimpl.h>
-#include <rtems/score/todimpl.h>
-#include <rtems/score/freechain.h>
-#include <rtems/score/watchdogimpl.h>
-#include <rtems/config.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @addtogroup ScoreThread
- */
-/**@{**/
-
-/**
- * The following structure contains the information necessary to manage
- * a thread which it is waiting for a resource.
- */
-#define THREAD_STATUS_PROXY_BLOCKING 0x1111111
-
-/**
- * Self for the GNU Ada Run-Time
- */
-extern void *rtems_ada_self;
-
-typedef struct {
- Objects_Information Objects;
-
- Freechain_Control Free_thread_queue_heads;
-} Thread_Information;
-
-/**
- * The following defines the information control block used to
- * manage this class of objects.
- */
-extern Thread_Information _Thread_Internal_information;
-
-/**
- * @brief Object identifier of the global constructor thread.
- *
- * This variable is set by _RTEMS_tasks_Initialize_user_tasks_body() or
- * _POSIX_Threads_Initialize_user_threads_body().
- *
- * It is consumed by _Thread_Handler().
- */
-extern Objects_Id _Thread_Global_constructor;
-
-/**
- * The following points to the thread whose floating point
- * context is currently loaded.
- */
-#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-extern Thread_Control *_Thread_Allocated_fp;
-#endif
-
-#if defined(RTEMS_SMP)
-#define THREAD_OF_SCHEDULER_HELP_NODE( node ) \
- RTEMS_CONTAINER_OF( node, Thread_Control, Scheduler.Help_node )
-#endif
-
-typedef bool ( *Thread_Visitor )( Thread_Control *the_thread, void *arg );
-
-void _Thread_Iterate(
- Thread_Visitor visitor,
- void *arg
-);
-
-void _Thread_Initialize_information(
- Thread_Information *information,
- Objects_APIs the_api,
- uint16_t the_class,
- uint32_t maximum,
- bool is_string,
- uint32_t maximum_name_length
-);
-
-/**
- * @brief Initialize thread handler.
- *
- * This routine performs the initialization necessary for this handler.
- */
-void _Thread_Handler_initialization(void);
-
-/**
- * @brief Create idle thread.
- *
- * This routine creates the idle thread.
- *
- * @warning No thread should be created before this one.
- */
-void _Thread_Create_idle(void);
-
-/**
- * @brief Start thread multitasking.
- *
- * This routine initiates multitasking. It is invoked only as
- * part of initialization and its invocation is the last act of
- * the non-multitasking part of the system initialization.
- */
-void _Thread_Start_multitasking( void ) RTEMS_NO_RETURN;
-
-/**
- * @brief Allocate the requested stack space for the thread.
- *
- * Allocate the requested stack space for the thread.
- * Set the Start.stack field to the address of the stack.
- *
- * @param[in] the_thread is the thread where the stack space is requested
- * @param[in] stack_size is the stack space is requested
- *
- * @retval actual size allocated after any adjustment
- * @retval zero if the allocation failed
- */
-size_t _Thread_Stack_Allocate(
- Thread_Control *the_thread,
- size_t stack_size
-);
-
-/**
- * @brief Deallocate thread stack.
- *
- * Deallocate the Thread's stack.
- */
-void _Thread_Stack_Free(
- Thread_Control *the_thread
-);
-
-/**
- * @brief Initialize thread.
- *
- * This routine initializes the specified the thread. It allocates
- * all memory associated with this thread. It completes by adding
- * the thread to the local object table so operations on this
- * thread id are allowed.
- *
- * @note If stack_area is NULL, it is allocated from the workspace.
- *
- * @note If the stack is allocated from the workspace, then it is
- * guaranteed to be of at least minimum size.
- */
-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
-);
-
-/**
- * @brief Initializes thread and executes it.
- *
- * This routine initializes the executable information for a thread
- * and makes it ready to execute. After this routine executes, the
- * thread competes with all other threads for CPU time.
- *
- * @param the_thread The thread to be started.
- * @param entry The thread entry information.
- */
-bool _Thread_Start(
- Thread_Control *the_thread,
- const Thread_Entry_information *entry,
- ISR_lock_Context *lock_context
-);
-
-void _Thread_Restart_self(
- Thread_Control *executing,
- const Thread_Entry_information *entry,
- ISR_lock_Context *lock_context
-) RTEMS_NO_RETURN;
-
-bool _Thread_Restart_other(
- Thread_Control *the_thread,
- const Thread_Entry_information *entry,
- ISR_lock_Context *lock_context
-);
-
-void _Thread_Yield( Thread_Control *executing );
-
-Thread_Life_state _Thread_Change_life(
- Thread_Life_state clear,
- Thread_Life_state set,
- Thread_Life_state ignore
-);
-
-Thread_Life_state _Thread_Set_life_protection( Thread_Life_state state );
-
-/**
- * @brief Kills all zombie threads in the system.
- *
- * Threads change into the zombie state as the last step in the thread
- * termination sequence right before a context switch to the heir thread is
- * initiated. Since the thread stack is still in use during this phase we have
- * to postpone the thread stack reclamation until this point. On SMP
- * configurations we may have to busy wait for context switch completion here.
- */
-void _Thread_Kill_zombies( void );
-
-void _Thread_Exit(
- Thread_Control *executing,
- Thread_Life_state set,
- void *exit_value
-);
-
-void _Thread_Join(
- Thread_Control *the_thread,
- States_Control waiting_for_join,
- Thread_Control *executing,
- Thread_queue_Context *queue_context
-);
-
-void _Thread_Cancel(
- Thread_Control *the_thread,
- Thread_Control *executing,
- void *exit_value
-);
-
-typedef struct {
- Thread_queue_Context Base;
- Thread_Control *cancel;
-} Thread_Close_context;
-
-/**
- * @brief Closes the thread.
- *
- * Closes the thread object and starts the thread termination sequence. In
- * case the executing thread is not terminated, then this function waits until
- * the terminating thread reached the zombie state.
- */
-void _Thread_Close(
- Thread_Control *the_thread,
- Thread_Control *executing,
- Thread_Close_context *context
-);
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_ready( const Thread_Control *the_thread )
-{
- return _States_Is_ready( the_thread->current_state );
-}
-
-States_Control _Thread_Clear_state_locked(
- Thread_Control *the_thread,
- States_Control state
-);
-
-/**
- * @brief Clears the specified thread state.
- *
- * In case the previous state is a non-ready state and the next state is the
- * ready state, then the thread is unblocked by the scheduler.
- *
- * @param[in] the_thread The thread.
- * @param[in] state The state to clear. It must not be zero.
- *
- * @return The previous state.
- */
-States_Control _Thread_Clear_state(
- Thread_Control *the_thread,
- States_Control state
-);
-
-States_Control _Thread_Set_state_locked(
- Thread_Control *the_thread,
- States_Control state
-);
-
-/**
- * @brief Sets the specified thread state.
- *
- * In case the previous state is the ready state, then the thread is blocked by
- * the scheduler.
- *
- * @param[in] the_thread The thread.
- * @param[in] state The state to set. It must not be zero.
- *
- * @return The previous state.
- */
-States_Control _Thread_Set_state(
- Thread_Control *the_thread,
- States_Control state
-);
-
-/**
- * @brief Initializes enviroment for a thread.
- *
- * This routine initializes the context of @a the_thread to its
- * appropriate starting state.
- *
- * @param[in] the_thread is the pointer to the thread control block.
- */
-void _Thread_Load_environment(
- Thread_Control *the_thread
-);
-
-void _Thread_Entry_adaptor_idle( Thread_Control *executing );
-
-void _Thread_Entry_adaptor_numeric( Thread_Control *executing );
-
-void _Thread_Entry_adaptor_pointer( Thread_Control *executing );
-
-/**
- * @brief Wrapper function for all threads.
- *
- * This routine is the wrapper function for all threads. It is
- * the starting point for all threads. The user provided thread
- * entry point is invoked by this routine. Operations
- * which must be performed immediately before and after the user's
- * thread executes are found here.
- *
- * @note On entry, it is assumed all interrupts are blocked and that this
- * routine needs to set the initial isr level. This may or may not
- * actually be needed by the context switch routine and as a result
- * interrupts may already be at there proper level. Either way,
- * setting the initial isr level properly here is safe.
- */
-void _Thread_Handler( void );
-
-RTEMS_INLINE_ROUTINE void _Thread_State_acquire_critical(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _Thread_queue_Do_acquire_critical( &the_thread->Join_queue, lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_State_acquire(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_ISR_disable( lock_context );
- _Thread_State_acquire_critical( the_thread, lock_context );
-}
-
-RTEMS_INLINE_ROUTINE Thread_Control *_Thread_State_acquire_for_executing(
- ISR_lock_Context *lock_context
-)
-{
- Thread_Control *executing;
-
- _ISR_lock_ISR_disable( lock_context );
- executing = _Thread_Executing;
- _Thread_State_acquire_critical( executing, lock_context );
-
- return executing;
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_State_release_critical(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _Thread_queue_Do_release_critical( &the_thread->Join_queue, lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_State_release(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _Thread_State_release_critical( the_thread, lock_context );
- _ISR_lock_ISR_enable( lock_context );
-}
-
-#if defined(RTEMS_DEBUG)
-RTEMS_INLINE_ROUTINE bool _Thread_State_is_owner(
- const Thread_Control *the_thread
-)
-{
- return _Thread_queue_Is_lock_owner( &the_thread->Join_queue );
-}
-#endif
-
-/**
- * @brief Performs the priority actions specified by the thread queue context
- * along the thread queue path.
- *
- * The caller must be the owner of the thread wait lock.
- *
- * @param start_of_path The start thread of the thread queue path.
- * @param queue_context The thread queue context specifying the thread queue
- * path and initial thread priority actions.
- *
- * @see _Thread_queue_Path_acquire_critical().
- */
-void _Thread_Priority_perform_actions(
- Thread_Control *start_of_path,
- Thread_queue_Context *queue_context
-);
-
-/**
- * @brief Adds the specified thread priority node to the corresponding thread
- * priority aggregation.
- *
- * The caller must be the owner of the thread wait lock.
- *
- * @param the_thread The thread.
- * @param priority_node The thread priority node to add.
- * @param queue_context The thread queue context to return an updated set of
- * threads for _Thread_Priority_update(). The thread queue context must be
- * initialized via _Thread_queue_Context_clear_priority_updates() before a
- * call of this function.
- *
- * @see _Thread_Wait_acquire().
- */
-void _Thread_Priority_add(
- Thread_Control *the_thread,
- Priority_Node *priority_node,
- Thread_queue_Context *queue_context
-);
-
-/**
- * @brief Removes the specified thread priority node from the corresponding
- * thread priority aggregation.
- *
- * The caller must be the owner of the thread wait lock.
- *
- * @param the_thread The thread.
- * @param priority_node The thread priority node to remove.
- * @param queue_context The thread queue context to return an updated set of
- * threads for _Thread_Priority_update(). The thread queue context must be
- * initialized via _Thread_queue_Context_clear_priority_updates() before a
- * call of this function.
- *
- * @see _Thread_Wait_acquire().
- */
-void _Thread_Priority_remove(
- Thread_Control *the_thread,
- Priority_Node *priority_node,
- Thread_queue_Context *queue_context
-);
-
-/**
- * @brief Propagates a thread priority value change in the specified thread
- * priority node to the corresponding thread priority aggregation.
- *
- * The caller must be the owner of the thread wait lock.
- *
- * @param the_thread The thread.
- * @param priority_node The thread priority node to change.
- * @param prepend_it In case this is true, then the thread is prepended to
- * its priority group in its home scheduler instance, otherwise it is
- * appended.
- * @param queue_context The thread queue context to return an updated set of
- * threads for _Thread_Priority_update(). The thread queue context must be
- * initialized via _Thread_queue_Context_clear_priority_updates() before a
- * call of this function.
- *
- * @see _Thread_Wait_acquire().
- */
-void _Thread_Priority_changed(
- Thread_Control *the_thread,
- Priority_Node *priority_node,
- bool prepend_it,
- Thread_queue_Context *queue_context
-);
-
-/**
- * @brief Changes the thread priority value of the specified thread priority
- * node in the corresponding thread priority aggregation.
- *
- * The caller must be the owner of the thread wait lock.
- *
- * @param the_thread The thread.
- * @param priority_node The thread priority node to change.
- * @param new_priority The new thread priority value of the thread priority
- * node to change.
- * @param prepend_it In case this is true, then the thread is prepended to
- * its priority group in its home scheduler instance, otherwise it is
- * appended.
- * @param queue_context The thread queue context to return an updated set of
- * threads for _Thread_Priority_update(). The thread queue context must be
- * initialized via _Thread_queue_Context_clear_priority_updates() before a
- * call of this function.
- *
- * @see _Thread_Wait_acquire().
- */
-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
-)
-{
- _Priority_Node_set_priority( priority_node, new_priority );
- _Thread_Priority_changed(
- the_thread,
- priority_node,
- prepend_it,
- queue_context
- );
-}
-
-/**
- * @brief Replaces the victim priority node with the replacement priority node
- * in the corresponding thread priority aggregation.
- *
- * The caller must be the owner of the thread wait lock.
- *
- * @param the_thread The thread.
- * @param victim_node The victim thread priority node.
- * @param replacement_node The replacement thread priority node.
- *
- * @see _Thread_Wait_acquire().
- */
-void _Thread_Priority_replace(
- Thread_Control *the_thread,
- Priority_Node *victim_node,
- Priority_Node *replacement_node
-);
-
-/**
- * @brief Adds a priority node to the corresponding thread priority
- * aggregation.
- *
- * The caller must be the owner of the thread wait lock.
- *
- * @param the_thread The thread.
- * @param priority_node The thread priority node to add.
- * @param queue_context The thread queue context to return an updated set of
- * threads for _Thread_Priority_update(). The thread queue context must be
- * initialized via _Thread_queue_Context_clear_priority_updates() before a
- * call of this function.
- *
- * @see _Thread_Priority_add(), _Thread_Priority_change(),
- * _Thread_Priority_changed() and _Thread_Priority_remove().
- */
-void _Thread_Priority_update( Thread_queue_Context *queue_context );
-
-#if defined(RTEMS_SMP)
-void _Thread_Priority_and_sticky_update(
- Thread_Control *the_thread,
- int sticky_level_change
-);
-#endif
-
-/**
- * @brief Returns true if the left thread priority is less than the right
- * thread priority in the intuitive sense of priority and false otherwise.
- */
-RTEMS_INLINE_ROUTINE bool _Thread_Priority_less_than(
- Priority_Control left,
- Priority_Control right
-)
-{
- return left > right;
-}
-
-/**
- * @brief Returns the highest priority of the left and right thread priorities
- * in the intuitive sense of priority.
- */
-RTEMS_INLINE_ROUTINE Priority_Control _Thread_Priority_highest(
- Priority_Control left,
- Priority_Control right
-)
-{
- return _Thread_Priority_less_than( left, right ) ? right : left;
-}
-
-RTEMS_INLINE_ROUTINE Objects_Information *_Thread_Get_objects_information(
- Objects_Id id
-)
-{
- uint32_t the_api;
-
- the_api = _Objects_Get_API( id );
-
- if ( !_Objects_Is_api_valid( the_api ) ) {
- return NULL;
- }
-
- /*
- * Threads are always first class :)
- *
- * There is no need to validate the object class of the object identifier,
- * since this will be done by the object get methods.
- */
- return _Objects_Information_table[ the_api ][ 1 ];
-}
-
-/**
- * @brief Gets a thread by its identifier.
- *
- * @see _Objects_Get().
- */
-Thread_Control *_Thread_Get(
- Objects_Id id,
- ISR_lock_Context *lock_context
-);
-
-RTEMS_INLINE_ROUTINE Per_CPU_Control *_Thread_Get_CPU(
- const Thread_Control *thread
-)
-{
-#if defined(RTEMS_SMP)
- return thread->Scheduler.cpu;
-#else
- (void) thread;
-
- return _Per_CPU_Get();
-#endif
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Set_CPU(
- Thread_Control *thread,
- Per_CPU_Control *cpu
-)
-{
-#if defined(RTEMS_SMP)
- thread->Scheduler.cpu = cpu;
-#else
- (void) thread;
- (void) cpu;
-#endif
-}
-
-/**
- * This function returns true if the_thread is the currently executing
- * thread, and false otherwise.
- */
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_executing (
- const Thread_Control *the_thread
-)
-{
- return ( the_thread == _Thread_Executing );
-}
-
-#if defined(RTEMS_SMP)
-/**
- * @brief Returns @a true in case the thread executes currently on some
- * processor in the system, otherwise @a false.
- *
- * Do not confuse this with _Thread_Is_executing() which checks only the
- * current processor.
- */
-RTEMS_INLINE_ROUTINE bool _Thread_Is_executing_on_a_processor(
- const Thread_Control *the_thread
-)
-{
- return _CPU_Context_Get_is_executing( &the_thread->Registers );
-}
-#endif
-
-/**
- * This function returns true if the_thread is the heir
- * thread, and false otherwise.
- */
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_heir (
- const Thread_Control *the_thread
-)
-{
- return ( the_thread == _Thread_Heir );
-}
-
-/**
- * This routine clears any blocking state for the_thread. It performs
- * any necessary scheduling operations including the selection of
- * a new heir thread.
- */
-
-RTEMS_INLINE_ROUTINE void _Thread_Unblock (
- Thread_Control *the_thread
-)
-{
- _Thread_Clear_state( the_thread, STATES_BLOCKED );
-}
-
-/**
- * This function returns true if the floating point context of
- * the_thread is currently loaded in the floating point unit, and
- * false otherwise.
- */
-
-#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-RTEMS_INLINE_ROUTINE bool _Thread_Is_allocated_fp (
- const Thread_Control *the_thread
-)
-{
- return ( the_thread == _Thread_Allocated_fp );
-}
-#endif
-
-/*
- * If the CPU has hardware floating point, then we must address saving
- * and restoring it as part of the context switch.
- *
- * The second conditional compilation section selects the algorithm used
- * to context switch between floating point tasks. The deferred algorithm
- * can be significantly better in a system with few floating point tasks
- * because it reduces the total number of save and restore FP context
- * operations. However, this algorithm can not be used on all CPUs due
- * to unpredictable use of FP registers by some compilers for integer
- * operations.
- */
-
-RTEMS_INLINE_ROUTINE void _Thread_Save_fp( Thread_Control *executing )
-{
-#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-#if ( CPU_USE_DEFERRED_FP_SWITCH != TRUE )
- if ( executing->fp_context != NULL )
- _Context_Save_fp( &executing->fp_context );
-#endif
-#endif
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Restore_fp( Thread_Control *executing )
-{
-#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
- if ( (executing->fp_context != NULL) &&
- !_Thread_Is_allocated_fp( executing ) ) {
- if ( _Thread_Allocated_fp != NULL )
- _Context_Save_fp( &_Thread_Allocated_fp->fp_context );
- _Context_Restore_fp( &executing->fp_context );
- _Thread_Allocated_fp = executing;
- }
-#else
- if ( executing->fp_context != NULL )
- _Context_Restore_fp( &executing->fp_context );
-#endif
-#endif
-}
-
-/**
- * This routine is invoked when the currently loaded floating
- * point context is now longer associated with an active thread.
- */
-
-#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-RTEMS_INLINE_ROUTINE void _Thread_Deallocate_fp( void )
-{
- _Thread_Allocated_fp = NULL;
-}
-#endif
-
-/**
- * This function returns true if dispatching is disabled, and false
- * otherwise.
- */
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_context_switch_necessary( void )
-{
- return ( _Thread_Dispatch_necessary );
-}
-
-/**
- * This function returns true if the_thread is NULL and false otherwise.
- */
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_null (
- const Thread_Control *the_thread
-)
-{
- return ( the_thread == NULL );
-}
-
-/**
- * @brief Is proxy blocking.
- *
- * status which indicates that a proxy is blocking, and false otherwise.
- */
-RTEMS_INLINE_ROUTINE bool _Thread_Is_proxy_blocking (
- uint32_t code
-)
-{
- return (code == THREAD_STATUS_PROXY_BLOCKING);
-}
-
-RTEMS_INLINE_ROUTINE uint32_t _Thread_Get_maximum_internal_threads(void)
-{
- /* Idle threads */
- uint32_t maximum_internal_threads =
- rtems_configuration_get_maximum_processors();
-
- /* MPCI thread */
-#if defined(RTEMS_MULTIPROCESSING)
- if ( _System_state_Is_multiprocessing ) {
- ++maximum_internal_threads;
- }
-#endif
-
- return maximum_internal_threads;
-}
-
-RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void )
-{
- return (Thread_Control *)
- _Objects_Allocate_unprotected( &_Thread_Internal_information.Objects );
-}
-
-/**
- * @brief Gets the heir of the processor and makes it executing.
- *
- * Must be called with interrupts disabled. The thread dispatch necessary
- * indicator is cleared as a side-effect.
- *
- * @return The heir thread.
- *
- * @see _Thread_Dispatch(), _Thread_Start_multitasking() and
- * _Thread_Dispatch_update_heir().
- */
-RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Get_heir_and_make_it_executing(
- Per_CPU_Control *cpu_self
-)
-{
- Thread_Control *heir;
-
- heir = cpu_self->heir;
- cpu_self->dispatch_necessary = false;
- cpu_self->executing = heir;
-
- return heir;
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Update_CPU_time_used(
- Thread_Control *the_thread,
- Per_CPU_Control *cpu
-)
-{
- Timestamp_Control last;
- Timestamp_Control ran;
-
- last = cpu->cpu_usage_timestamp;
- _TOD_Get_uptime( &cpu->cpu_usage_timestamp );
- _Timestamp_Subtract( &last, &cpu->cpu_usage_timestamp, &ran );
- _Timestamp_Add_to( &the_thread->cpu_time_used, &ran );
-}
-
-#if defined( RTEMS_SMP )
-RTEMS_INLINE_ROUTINE void _Thread_Dispatch_update_heir(
- Per_CPU_Control *cpu_self,
- Per_CPU_Control *cpu_for_heir,
- Thread_Control *heir
-)
-{
- _Thread_Update_CPU_time_used( cpu_for_heir->heir, cpu_for_heir );
-
- cpu_for_heir->heir = heir;
-
- _Thread_Dispatch_request( cpu_self, cpu_for_heir );
-}
-#endif
-
-void _Thread_Get_CPU_time_used(
- Thread_Control *the_thread,
- Timestamp_Control *cpu_time_used
-);
-
-RTEMS_INLINE_ROUTINE void _Thread_Action_control_initialize(
- Thread_Action_control *action_control
-)
-{
- _Chain_Initialize_empty( &action_control->Chain );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Action_initialize(
- Thread_Action *action
-)
-{
- _Chain_Set_off_chain( &action->Node );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Add_post_switch_action(
- Thread_Control *the_thread,
- Thread_Action *action,
- Thread_Action_handler handler
-)
-{
- Per_CPU_Control *cpu_of_thread;
-
- _Assert( _Thread_State_is_owner( the_thread ) );
-
- cpu_of_thread = _Thread_Get_CPU( the_thread );
-
- action->handler = handler;
-
- _Thread_Dispatch_request( _Per_CPU_Get(), cpu_of_thread );
-
- _Chain_Append_if_is_off_chain_unprotected(
- &the_thread->Post_switch_actions.Chain,
- &action->Node
- );
-}
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_life_restarting(
- Thread_Life_state life_state
-)
-{
- return ( life_state & THREAD_LIFE_RESTARTING ) != 0;
-}
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_life_terminating(
- Thread_Life_state life_state
-)
-{
- return ( life_state & THREAD_LIFE_TERMINATING ) != 0;
-}
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_life_change_allowed(
- Thread_Life_state life_state
-)
-{
- return ( life_state
- & ( THREAD_LIFE_PROTECTED | THREAD_LIFE_CHANGE_DEFERRED ) ) == 0;
-}
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_life_changing(
- Thread_Life_state life_state
-)
-{
- return ( life_state
- & ( THREAD_LIFE_RESTARTING | THREAD_LIFE_TERMINATING ) ) != 0;
-}
-
-RTEMS_INLINE_ROUTINE bool _Thread_Is_joinable(
- const Thread_Control *the_thread
-)
-{
- _Assert( _Thread_State_is_owner( the_thread ) );
- return ( the_thread->Life.state & THREAD_LIFE_DETACHED ) == 0;
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Resource_count_increment(
- Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
- ++the_thread->resource_count;
-#else
- (void) the_thread;
-#endif
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Resource_count_decrement(
- Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
- --the_thread->resource_count;
-#else
- (void) the_thread;
-#endif
-}
-
-#if defined(RTEMS_SCORE_THREAD_ENABLE_RESOURCE_COUNT)
-/**
- * @brief Returns true if the thread owns resources, and false otherwise.
- *
- * Resources are accounted with the Thread_Control::resource_count resource
- * counter. This counter is used by mutex objects for example.
- *
- * @param[in] the_thread The thread.
- */
-RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources(
- const Thread_Control *the_thread
-)
-{
- return the_thread->resource_count != 0;
-}
-#endif
-
-#if defined(RTEMS_SMP)
-RTEMS_INLINE_ROUTINE void _Thread_Scheduler_cancel_need_for_help(
- Thread_Control *the_thread,
- Per_CPU_Control *cpu
-)
-{
- _Per_CPU_Acquire( cpu );
-
- if ( !_Chain_Is_node_off_chain( &the_thread->Scheduler.Help_node ) ) {
- _Chain_Extract_unprotected( &the_thread->Scheduler.Help_node );
- _Chain_Set_off_chain( &the_thread->Scheduler.Help_node );
- }
-
- _Per_CPU_Release( cpu );
-}
-#endif
-
-RTEMS_INLINE_ROUTINE const Scheduler_Control *_Thread_Scheduler_get_home(
- const Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SMP)
- return the_thread->Scheduler.home;
-#else
- (void) the_thread;
- return &_Scheduler_Table[ 0 ];
-#endif
-}
-
-RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_home_node(
- const Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SMP)
- _Assert( !_Chain_Is_empty( &the_thread->Scheduler.Wait_nodes ) );
- return SCHEDULER_NODE_OF_THREAD_WAIT_NODE(
- _Chain_First( &the_thread->Scheduler.Wait_nodes )
- );
-#else
- return the_thread->Scheduler.nodes;
-#endif
-}
-
-RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_node_by_index(
- const Thread_Control *the_thread,
- size_t scheduler_index
-)
-{
-#if defined(RTEMS_SMP)
- return (Scheduler_Node *)
- ( (uintptr_t) the_thread->Scheduler.nodes
- + scheduler_index * _Scheduler_Node_size );
-#else
- _Assert( scheduler_index == 0 );
- (void) scheduler_index;
- return the_thread->Scheduler.nodes;
-#endif
-}
-
-#if defined(RTEMS_SMP)
-RTEMS_INLINE_ROUTINE void _Thread_Scheduler_acquire_critical(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_Acquire( &the_thread->Scheduler.Lock, lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Scheduler_release_critical(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context );
-}
-
-#if defined(RTEMS_SMP)
-void _Thread_Scheduler_process_requests( Thread_Control *the_thread );
-#endif
-
-RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_request(
- Thread_Control *the_thread,
- Scheduler_Node *scheduler_node,
- Scheduler_Node_request request
-)
-{
- ISR_lock_Context lock_context;
- Scheduler_Node_request current_request;
-
- _Thread_Scheduler_acquire_critical( the_thread, &lock_context );
-
- current_request = scheduler_node->Thread.request;
-
- if ( current_request == SCHEDULER_NODE_REQUEST_NOT_PENDING ) {
- _Assert(
- request == SCHEDULER_NODE_REQUEST_ADD
- || request == SCHEDULER_NODE_REQUEST_REMOVE
- );
- _Assert( scheduler_node->Thread.next_request == NULL );
- scheduler_node->Thread.next_request = the_thread->Scheduler.requests;
- the_thread->Scheduler.requests = scheduler_node;
- } else if ( current_request != SCHEDULER_NODE_REQUEST_NOTHING ) {
- _Assert(
- ( current_request == SCHEDULER_NODE_REQUEST_ADD
- && request == SCHEDULER_NODE_REQUEST_REMOVE )
- || ( current_request == SCHEDULER_NODE_REQUEST_REMOVE
- && request == SCHEDULER_NODE_REQUEST_ADD )
- );
- request = SCHEDULER_NODE_REQUEST_NOTHING;
- }
-
- scheduler_node->Thread.request = request;
-
- _Thread_Scheduler_release_critical( the_thread, &lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_wait_node(
- Thread_Control *the_thread,
- Scheduler_Node *scheduler_node
-)
-{
- _Chain_Append_unprotected(
- &the_thread->Scheduler.Wait_nodes,
- &scheduler_node->Thread.Wait_node
- );
- _Thread_Scheduler_add_request(
- the_thread,
- scheduler_node,
- SCHEDULER_NODE_REQUEST_ADD
- );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Scheduler_remove_wait_node(
- Thread_Control *the_thread,
- Scheduler_Node *scheduler_node
-)
-{
- _Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
- _Thread_Scheduler_add_request(
- the_thread,
- scheduler_node,
- SCHEDULER_NODE_REQUEST_REMOVE
- );
-}
-#endif
-
-/**
- * @brief Returns the priority of the thread.
- *
- * Returns the user API and thread wait information relevant thread priority.
- * This includes temporary thread priority adjustments due to locking
- * protocols, a job release or the POSIX sporadic server for example.
- *
- * @return The priority of the thread.
- */
-RTEMS_INLINE_ROUTINE Priority_Control _Thread_Get_priority(
- const Thread_Control *the_thread
-)
-{
- Scheduler_Node *scheduler_node;
-
- scheduler_node = _Thread_Scheduler_get_home_node( the_thread );
- return _Priority_Get_priority( &scheduler_node->Wait.Priority );
-}
-
-/**
- * @brief Acquires the thread wait default lock inside a critical section
- * (interrupts disabled).
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context used for the corresponding lock
- * release.
- *
- * @see _Thread_Wait_release_default_critical().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default_critical(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_Acquire( &the_thread->Wait.Lock.Default, lock_context );
-}
-
-/**
- * @brief Acquires the thread wait default lock and returns the executing
- * thread.
- *
- * @param[in] lock_context The lock context used for the corresponding lock
- * release.
- *
- * @return The executing thread.
- *
- * @see _Thread_Wait_release_default().
- */
-RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Wait_acquire_default_for_executing(
- ISR_lock_Context *lock_context
-)
-{
- Thread_Control *executing;
-
- _ISR_lock_ISR_disable( lock_context );
- executing = _Thread_Executing;
- _Thread_Wait_acquire_default_critical( executing, lock_context );
-
- return executing;
-}
-
-/**
- * @brief Acquires the thread wait default lock and disables interrupts.
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context used for the corresponding lock
- * release.
- *
- * @see _Thread_Wait_release_default().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_default(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_ISR_disable( lock_context );
- _Thread_Wait_acquire_default_critical( the_thread, lock_context );
-}
-
-/**
- * @brief Releases the thread wait default lock inside a critical section
- * (interrupts disabled).
- *
- * The previous interrupt status is not restored.
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context used for the corresponding lock
- * acquire.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default_critical(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _ISR_lock_Release( &the_thread->Wait.Lock.Default, lock_context );
-}
-
-/**
- * @brief Releases the thread wait default lock and restores the previous
- * interrupt status.
- *
- * @param[in] the_thread The thread.
- * @param[in] lock_context The lock context used for the corresponding lock
- * acquire.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_release_default(
- Thread_Control *the_thread,
- ISR_lock_Context *lock_context
-)
-{
- _Thread_Wait_release_default_critical( the_thread, lock_context );
- _ISR_lock_ISR_enable( lock_context );
-}
-
-#if defined(RTEMS_SMP)
-#define THREAD_QUEUE_CONTEXT_OF_REQUEST( node ) \
- RTEMS_CONTAINER_OF( node, Thread_queue_Context, Lock_context.Wait.Gate.Node )
-
-RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request_locked(
- Thread_Control *the_thread,
- Thread_queue_Lock_context *queue_lock_context
-)
-{
- Chain_Node *first;
-
- _Chain_Extract_unprotected( &queue_lock_context->Wait.Gate.Node );
- first = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
-
- if ( first != _Chain_Tail( &the_thread->Wait.Lock.Pending_requests ) ) {
- _Thread_queue_Gate_open( (Thread_queue_Gate *) first );
- }
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_queue_critical(
- Thread_queue_Queue *queue,
- Thread_queue_Lock_context *queue_lock_context
-)
-{
- _Thread_queue_Queue_acquire_critical(
- queue,
- &_Thread_Executing->Potpourri_stats,
- &queue_lock_context->Lock_context
- );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Wait_release_queue_critical(
- Thread_queue_Queue *queue,
- Thread_queue_Lock_context *queue_lock_context
-)
-{
- _Thread_queue_Queue_release_critical(
- queue,
- &queue_lock_context->Lock_context
- );
-}
-#endif
-
-/**
- * @brief Acquires the thread wait lock inside a critical section (interrupts
- * disabled).
- *
- * @param[in] the_thread The thread.
- * @param[in] queue_context The thread queue context for the corresponding
- * _Thread_Wait_release_critical().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire_critical(
- Thread_Control *the_thread,
- Thread_queue_Context *queue_context
-)
-{
-#if defined(RTEMS_SMP)
- Thread_queue_Queue *queue;
-
- _Thread_Wait_acquire_default_critical(
- the_thread,
- &queue_context->Lock_context.Lock_context
- );
-
- queue = the_thread->Wait.queue;
- queue_context->Lock_context.Wait.queue = queue;
-
- if ( queue != NULL ) {
- _Thread_queue_Gate_add(
- &the_thread->Wait.Lock.Pending_requests,
- &queue_context->Lock_context.Wait.Gate
- );
- _Thread_Wait_release_default_critical(
- the_thread,
- &queue_context->Lock_context.Lock_context
- );
- _Thread_Wait_acquire_queue_critical( queue, &queue_context->Lock_context );
-
- if ( queue_context->Lock_context.Wait.queue == NULL ) {
- _Thread_Wait_release_queue_critical(
- queue,
- &queue_context->Lock_context
- );
- _Thread_Wait_acquire_default_critical(
- the_thread,
- &queue_context->Lock_context.Lock_context
- );
- _Thread_Wait_remove_request_locked(
- the_thread,
- &queue_context->Lock_context
- );
- _Assert( the_thread->Wait.queue == NULL );
- }
- }
-#else
- (void) the_thread;
- (void) queue_context;
-#endif
-}
-
-/**
- * @brief Acquires the thread wait default lock and disables interrupts.
- *
- * @param[in] the_thread The thread.
- * @param[in] queue_context The thread queue context for the corresponding
- * _Thread_Wait_release().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_acquire(
- Thread_Control *the_thread,
- Thread_queue_Context *queue_context
-)
-{
- _ISR_lock_ISR_disable( &queue_context->Lock_context.Lock_context );
- _Thread_Wait_acquire_critical( the_thread, queue_context );
-}
-
-/**
- * @brief Releases the thread wait lock inside a critical section (interrupts
- * disabled).
- *
- * The previous interrupt status is not restored.
- *
- * @param[in] the_thread The thread.
- * @param[in] queue_context The thread queue context used for corresponding
- * _Thread_Wait_acquire_critical().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_release_critical(
- Thread_Control *the_thread,
- Thread_queue_Context *queue_context
-)
-{
-#if defined(RTEMS_SMP)
- Thread_queue_Queue *queue;
-
- queue = queue_context->Lock_context.Wait.queue;
-
- if ( queue != NULL ) {
- _Thread_Wait_release_queue_critical(
- queue, &queue_context->Lock_context
- );
- _Thread_Wait_acquire_default_critical(
- the_thread,
- &queue_context->Lock_context.Lock_context
- );
- _Thread_Wait_remove_request_locked(
- the_thread,
- &queue_context->Lock_context
- );
- }
-
- _Thread_Wait_release_default_critical(
- the_thread,
- &queue_context->Lock_context.Lock_context
- );
-#else
- (void) the_thread;
- (void) queue_context;
-#endif
-}
-
-/**
- * @brief Releases the thread wait lock and restores the previous interrupt
- * status.
- *
- * @param[in] the_thread The thread.
- * @param[in] queue_context The thread queue context used for corresponding
- * _Thread_Wait_acquire().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_release(
- Thread_Control *the_thread,
- Thread_queue_Context *queue_context
-)
-{
- _Thread_Wait_release_critical( the_thread, queue_context );
- _ISR_lock_ISR_enable( &queue_context->Lock_context.Lock_context );
-}
-
-/**
- * @brief Claims the thread wait queue.
- *
- * The caller must not be the owner of the default thread wait lock. The
- * caller must be the owner of the corresponding thread queue lock. The
- * registration of the corresponding thread queue operations is deferred and
- * done after the deadlock detection. This is crucial to support timeouts on
- * SMP configurations.
- *
- * @param[in] the_thread The thread.
- * @param[in] queue The new thread queue.
- *
- * @see _Thread_Wait_claim_finalize() and _Thread_Wait_restore_default().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_claim(
- Thread_Control *the_thread,
- Thread_queue_Queue *queue
-)
-{
- ISR_lock_Context lock_context;
-
- _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
-
- _Assert( the_thread->Wait.queue == NULL );
-
-#if defined(RTEMS_SMP)
- _Chain_Initialize_empty( &the_thread->Wait.Lock.Pending_requests );
- _Chain_Initialize_node( &the_thread->Wait.Lock.Tranquilizer.Node );
- _Thread_queue_Gate_close( &the_thread->Wait.Lock.Tranquilizer );
-#endif
-
- the_thread->Wait.queue = queue;
-
- _Thread_Wait_release_default_critical( the_thread, &lock_context );
-}
-
-/**
- * @brief Finalizes the thread wait queue claim via registration of the
- * corresponding thread queue operations.
- *
- * @param[in] the_thread The thread.
- * @param[in] operations The corresponding thread queue operations.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_claim_finalize(
- Thread_Control *the_thread,
- const Thread_queue_Operations *operations
-)
-{
- the_thread->Wait.operations = operations;
-}
-
-/**
- * @brief Removes a thread wait lock request.
- *
- * On SMP configurations, removes a thread wait lock request.
- *
- * On other configurations, this function does nothing.
- *
- * @param[in] the_thread The thread.
- * @param[in] queue_lock_context The thread queue lock context used for
- * corresponding _Thread_Wait_acquire().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_remove_request(
- Thread_Control *the_thread,
- Thread_queue_Lock_context *queue_lock_context
-)
-{
-#if defined(RTEMS_SMP)
- ISR_lock_Context lock_context;
-
- _Thread_Wait_acquire_default( the_thread, &lock_context );
- _Thread_Wait_remove_request_locked( the_thread, queue_lock_context );
- _Thread_Wait_release_default( the_thread, &lock_context );
-#else
- (void) the_thread;
- (void) queue_lock_context;
-#endif
-}
-
-/**
- * @brief Restores the default thread wait queue and operations.
- *
- * The caller must be the owner of the current thread wait queue lock.
- *
- * On SMP configurations, the pending requests are updated to use the stale
- * thread queue operations.
- *
- * @param[in] the_thread The thread.
- *
- * @see _Thread_Wait_claim().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_restore_default(
- Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SMP)
- ISR_lock_Context lock_context;
- Chain_Node *node;
- const Chain_Node *tail;
-
- _Thread_Wait_acquire_default_critical( the_thread, &lock_context );
-
- node = _Chain_First( &the_thread->Wait.Lock.Pending_requests );
- tail = _Chain_Immutable_tail( &the_thread->Wait.Lock.Pending_requests );
-
- if ( node != tail ) {
- do {
- Thread_queue_Context *queue_context;
-
- queue_context = THREAD_QUEUE_CONTEXT_OF_REQUEST( node );
- queue_context->Lock_context.Wait.queue = NULL;
-
- node = _Chain_Next( node );
- } while ( node != tail );
-
- _Thread_queue_Gate_add(
- &the_thread->Wait.Lock.Pending_requests,
- &the_thread->Wait.Lock.Tranquilizer
- );
- } else {
- _Thread_queue_Gate_open( &the_thread->Wait.Lock.Tranquilizer );
- }
-#endif
-
- the_thread->Wait.queue = NULL;
- the_thread->Wait.operations = &_Thread_queue_Operations_default;
-
-#if defined(RTEMS_SMP)
- _Thread_Wait_release_default_critical( the_thread, &lock_context );
-#endif
-}
-
-/**
- * @brief Tranquilizes the thread after a wait on a thread queue.
- *
- * After the violent blocking procedure this function makes the thread calm and
- * peaceful again so that it can carry out its normal work.
- *
- * On SMP configurations, ensures that all pending thread wait lock requests
- * completed before the thread is able to begin a new thread wait procedure.
- *
- * On other configurations, this function does nothing.
- *
- * It must be called after a _Thread_Wait_claim() exactly once
- * - after the corresponding thread queue lock was released, and
- * - the default wait state is restored or some other processor is about to do
- * this.
- *
- * @param[in] the_thread The thread.
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_tranquilize(
- Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SMP)
- _Thread_queue_Gate_wait( &the_thread->Wait.Lock.Tranquilizer );
-#else
- (void) the_thread;
-#endif
-}
-
-/**
- * @brief Cancels a thread wait on a thread queue.
- *
- * @param[in] the_thread The thread.
- * @param[in] queue_context The thread queue context used for corresponding
- * _Thread_Wait_acquire().
- */
-RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel(
- Thread_Control *the_thread,
- Thread_queue_Context *queue_context
-)
-{
- Thread_queue_Queue *queue;
-
- queue = the_thread->Wait.queue;
-
-#if defined(RTEMS_SMP)
- if ( queue != NULL ) {
- _Assert( queue_context->Lock_context.Wait.queue == queue );
-#endif
-
- ( *the_thread->Wait.operations->extract )(
- queue,
- the_thread,
- queue_context
- );
- _Thread_Wait_restore_default( the_thread );
-
-#if defined(RTEMS_SMP)
- _Assert( queue_context->Lock_context.Wait.queue == NULL );
- queue_context->Lock_context.Wait.queue = queue;
- }
-#endif
-}
-
-/**
- * @brief The initial thread wait flags value set by _Thread_Initialize().
- */
-#define THREAD_WAIT_FLAGS_INITIAL 0x0U
-
-/**
- * @brief Mask to get the thread wait state flags.
- */
-#define THREAD_WAIT_STATE_MASK 0xffU
-
-/**
- * @brief Indicates that the thread begins with the blocking operation.
- *
- * A blocking operation consists of an optional watchdog initialization and the
- * setting of the appropriate thread blocking state with the corresponding
- * scheduler block operation.
- */
-#define THREAD_WAIT_STATE_INTEND_TO_BLOCK 0x1U
-
-/**
- * @brief Indicates that the thread completed the blocking operation.
- */
-#define THREAD_WAIT_STATE_BLOCKED 0x2U
-
-/**
- * @brief Indicates that a condition to end the thread wait occurred.
- *
- * This could be a timeout, a signal, an event or a resource availability.
- */
-#define THREAD_WAIT_STATE_READY_AGAIN 0x4U
-
-/**
- * @brief Mask to get the thread wait class flags.
- */
-#define THREAD_WAIT_CLASS_MASK 0xff00U
-
-/**
- * @brief Indicates that the thread waits for an event.
- */
-#define THREAD_WAIT_CLASS_EVENT 0x100U
-
-/**
- * @brief Indicates that the thread waits for a system event.
- */
-#define THREAD_WAIT_CLASS_SYSTEM_EVENT 0x200U
-
-/**
- * @brief Indicates that the thread waits for an object.
- */
-#define THREAD_WAIT_CLASS_OBJECT 0x400U
-
-/**
- * @brief Indicates that the thread waits for a period.
- */
-#define THREAD_WAIT_CLASS_PERIOD 0x800U
-
-RTEMS_INLINE_ROUTINE void _Thread_Wait_flags_set(
- Thread_Control *the_thread,
- Thread_Wait_flags flags
-)
-{
-#if defined(RTEMS_SMP)
- _Atomic_Store_uint( &the_thread->Wait.flags, flags, ATOMIC_ORDER_RELAXED );
-#else
- the_thread->Wait.flags = flags;
-#endif
-}
-
-RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get(
- const Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SMP)
- return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_RELAXED );
-#else
- return the_thread->Wait.flags;
-#endif
-}
-
-RTEMS_INLINE_ROUTINE Thread_Wait_flags _Thread_Wait_flags_get_acquire(
- const Thread_Control *the_thread
-)
-{
-#if defined(RTEMS_SMP)
- return _Atomic_Load_uint( &the_thread->Wait.flags, ATOMIC_ORDER_ACQUIRE );
-#else
- return the_thread->Wait.flags;
-#endif
-}
-
-/**
- * @brief Tries to change the thread wait flags with release semantics in case
- * of success.
- *
- * Must be called inside a critical section (interrupts disabled).
- *
- * In case the wait flags are equal to the expected wait flags, then the wait
- * flags are set to the desired wait flags.
- *
- * @param[in] the_thread The thread.
- * @param[in] expected_flags The expected wait flags.
- * @param[in] desired_flags The desired wait flags.
- *
- * @retval true The wait flags were equal to the expected wait flags.
- * @retval false Otherwise.
- */
-RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_release(
- Thread_Control *the_thread,
- Thread_Wait_flags expected_flags,
- Thread_Wait_flags desired_flags
-)
-{
- _Assert( _ISR_Get_level() != 0 );
-
-#if defined(RTEMS_SMP)
- return _Atomic_Compare_exchange_uint(
- &the_thread->Wait.flags,
- &expected_flags,
- desired_flags,
- ATOMIC_ORDER_RELEASE,
- ATOMIC_ORDER_RELAXED
- );
-#else
- bool success = ( the_thread->Wait.flags == expected_flags );
-
- if ( success ) {
- the_thread->Wait.flags = desired_flags;
- }
-
- return success;
-#endif
-}
-
-/**
- * @brief Tries to change the thread wait flags with acquire semantics.
- *
- * In case the wait flags are equal to the expected wait flags, then the wait
- * flags are set to the desired wait flags.
- *
- * @param[in] the_thread The thread.
- * @param[in] expected_flags The expected wait flags.
- * @param[in] desired_flags The desired wait flags.
- *
- * @retval true The wait flags were equal to the expected wait flags.
- * @retval false Otherwise.
- */
-RTEMS_INLINE_ROUTINE bool _Thread_Wait_flags_try_change_acquire(
- Thread_Control *the_thread,
- Thread_Wait_flags expected_flags,
- Thread_Wait_flags desired_flags
-)
-{
- bool success;
-#if defined(RTEMS_SMP)
- return _Atomic_Compare_exchange_uint(
- &the_thread->Wait.flags,
- &expected_flags,
- desired_flags,
- ATOMIC_ORDER_ACQUIRE,
- ATOMIC_ORDER_ACQUIRE
- );
-#else
- ISR_Level level;
-
- _ISR_Local_disable( level );
-
- success = _Thread_Wait_flags_try_change_release(
- the_thread,
- expected_flags,
- desired_flags
- );
-
- _ISR_Local_enable( level );
-#endif
-
- return success;
-}
-
-/**
- * @brief Returns the object identifier of the object containing the current
- * thread wait queue.
- *
- * This function may be used for debug and system information purposes. The
- * caller must be the owner of the thread lock.
- *
- * @retval 0 The thread waits on no thread queue currently, the thread wait
- * queue is not contained in an object, or the current thread state provides
- * insufficient information, e.g. the thread is in the middle of a blocking
- * operation.
- * @retval other The object identifier of the object containing the thread wait
- * queue.
- */
-Objects_Id _Thread_Wait_get_id( const Thread_Control *the_thread );
-
-RTEMS_INLINE_ROUTINE Status_Control _Thread_Wait_get_status(
- const Thread_Control *the_thread
-)
-{
- return (Status_Control) the_thread->Wait.return_code;
-}
-
-/**
- * @brief Cancels a blocking operation so that the thread can continue its
- * execution.
- *
- * In case this function actually cancelled the blocking operation, then the
- * thread wait return code is set to the specified status.
- *
- * A specialization of this function is _Thread_Timeout().
- *
- * @param[in] the_thread The thread.
- * @param[in] status The thread wait status.
- */
-void _Thread_Continue( Thread_Control *the_thread, Status_Control status );
-
-/**
- * @brief General purpose thread wait timeout.
- *
- * @param[in] the_watchdog The thread timer watchdog.
- */
-void _Thread_Timeout( Watchdog_Control *the_watchdog );
-
-RTEMS_INLINE_ROUTINE void _Thread_Timer_initialize(
- Thread_Timer_information *timer,
- Per_CPU_Control *cpu
-)
-{
- _ISR_lock_Initialize( &timer->Lock, "Thread Timer" );
- timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
- _Watchdog_Preinitialize( &timer->Watchdog, cpu );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Add_timeout_ticks(
- Thread_Control *the_thread,
- Per_CPU_Control *cpu,
- Watchdog_Interval ticks
-)
-{
- ISR_lock_Context lock_context;
-
- _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
-
- the_thread->Timer.header =
- &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
- the_thread->Timer.Watchdog.routine = _Thread_Timeout;
- _Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks );
-
- _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Timer_insert_realtime(
- Thread_Control *the_thread,
- Per_CPU_Control *cpu,
- Watchdog_Service_routine_entry routine,
- uint64_t expire
-)
-{
- ISR_lock_Context lock_context;
-
- _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
-
- the_thread->Timer.header =
- &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
- the_thread->Timer.Watchdog.routine = routine;
- _Watchdog_Per_CPU_insert_realtime( &the_thread->Timer.Watchdog, cpu, expire );
-
- _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Timer_remove( Thread_Control *the_thread )
-{
- ISR_lock_Context lock_context;
-
- _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context );
-
- _Watchdog_Per_CPU_remove(
- &the_thread->Timer.Watchdog,
-#if defined(RTEMS_SMP)
- the_thread->Timer.Watchdog.cpu,
-#else
- _Per_CPU_Get(),
-#endif
- the_thread->Timer.header
- );
-
- _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context );
-}
-
-RTEMS_INLINE_ROUTINE void _Thread_Remove_timer_and_unblock(
- Thread_Control *the_thread,
- Thread_queue_Queue *queue
-)
-{
- _Thread_Wait_tranquilize( the_thread );
- _Thread_Timer_remove( the_thread );
-
-#if defined(RTEMS_MULTIPROCESSING)
- if ( _Objects_Is_local_id( the_thread->Object.id ) ) {
- _Thread_Unblock( the_thread );
- } else {
- _Thread_queue_Unblock_proxy( queue, the_thread );
- }
-#else
- (void) queue;
- _Thread_Unblock( the_thread );
-#endif
-}
-
-Status_Control _Thread_Set_name(
- Thread_Control *the_thread,
- const char *name
-);
-
-size_t _Thread_Get_name(
- const Thread_Control *the_thread,
- char *buffer,
- size_t buffer_size
-);
-
-/** @}*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#if defined(RTEMS_MULTIPROCESSING)
-#include <rtems/score/threadmp.h>
-#endif
-
-#endif
-/* end of include file */