28 #include <rtems/score/status.h> 31 #define THREAD_QUEUE_INTEND_TO_BLOCK \ 32 (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK) 34 #define THREAD_QUEUE_BLOCKED \ 35 (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_BLOCKED) 37 #define THREAD_QUEUE_READY_AGAIN \ 38 (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN) 40 #if defined(RTEMS_SMP) 61 static bool _Thread_queue_Link_equal(
72 return the_left == the_right->
source;
75 static bool _Thread_queue_Link_less(
86 return (uintptr_t) the_left < (uintptr_t) the_right->
source;
89 static void *_Thread_queue_Link_map(
RBTree_Node *node )
102 _Thread_queue_Link_equal,
103 _Thread_queue_Link_less,
104 _Thread_queue_Link_map
108 static bool _Thread_queue_Link_add(
121 links = &_Thread_queue_Links;
122 recursive_target = target;
129 recursive_link = _Thread_queue_Link_find( links, recursive_target );
131 if ( recursive_link == NULL ) {
135 recursive_target = recursive_link->
target;
137 if ( recursive_target == source ) {
147 _Thread_queue_Link_less
159 links = &_Thread_queue_Links;
167 #if !defined(RTEMS_SMP) 174 #if defined(RTEMS_SMP) 181 while ( head != node ) {
184 link = THREAD_QUEUE_LINK_OF_PATH_NODE( node );
187 _Thread_queue_Link_remove( link );
201 #if defined(RTEMS_DEBUG) 206 (void) queue_context;
210 #if defined(RTEMS_SMP) 211 static void _Thread_queue_Path_append_deadlock_thread(
228 while ( the_thread->
Wait.
operations != &_Thread_queue_Operations_default ) {
230 deadlock = the_thread;
233 if ( deadlock != NULL ) {
242 link->
owner = deadlock;
252 #if !defined(RTEMS_SMP) 262 #if defined(RTEMS_SMP) 276 owner = queue->
owner;
278 if ( owner == NULL ) {
282 if ( owner == the_thread ) {
305 if ( target != NULL ) {
306 if ( _Thread_queue_Link_add( link, queue, target ) ) {
318 _Thread_queue_Link_remove( link );
330 _Thread_queue_Path_append_deadlock_thread( owner, queue_context );
339 owner = queue->
owner;
340 }
while ( owner != NULL );
343 owner = queue->
owner;
345 if ( owner == NULL ) {
349 if ( owner == the_thread ) {
354 }
while ( queue != NULL );
392 #if defined(RTEMS_MULTIPROCESSING) 393 if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet ) {
394 the_thread = _Thread_MP_Allocate_proxy( queue_context->
thread_state );
412 ( *operations->
enqueue )( queue, the_thread, queue_context );
444 THREAD_QUEUE_INTEND_TO_BLOCK,
455 #if defined(RTEMS_SMP) 480 ( *operations->
enqueue )( queue, the_thread, queue_context );
491 INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_STICKY_FROM_BAD_STATE
518 #if defined(RTEMS_MULTIPROCESSING) 519 static bool _Thread_queue_MP_set_callout(
525 Thread_queue_MP_callout mp_callout;
532 mp_callout = queue_context->mp_callout;
534 the_proxy->thread_queue_callout = mp_callout;
539 static bool _Thread_queue_Make_ready_again(
Thread_Control *the_thread )
550 THREAD_QUEUE_INTEND_TO_BLOCK,
551 THREAD_QUEUE_READY_AGAIN
572 #if defined(RTEMS_MULTIPROCESSING) 573 _Thread_queue_MP_set_callout( the_thread, queue_context );
575 ( *operations->
extract )( queue, the_thread, queue_context );
576 return _Thread_queue_Make_ready_again( the_thread );
635 if ( queue != NULL ) {
641 _Thread_queue_MP_callout_do_nothing
681 queue->
owner = new_owner;
683 #if defined(RTEMS_MULTIPROCESSING) 684 if ( !_Thread_queue_MP_set_callout( new_owner, queue_context ) )
690 unblock = _Thread_queue_Make_ready_again( new_owner );
707 #if defined(RTEMS_SMP) 728 queue->
owner = new_owner;
729 _Thread_queue_Make_ready_again( new_owner );
745 #
if defined(RTEMS_MULTIPROCESSING)
747 Thread_queue_MP_callout mp_callout
760 if ( the_thread != NULL ) {
762 &the_thread_queue->
Queue,
774 #if defined(RTEMS_MULTIPROCESSING) 775 void _Thread_queue_Unblock_proxy(
782 Thread_queue_MP_callout mp_callout;
784 the_queue_object = THREAD_QUEUE_QUEUE_TO_OBJECT( queue );
786 mp_callout = the_proxy->thread_queue_callout;
787 ( *mp_callout )( the_thread, the_queue_object->Object.
id );
789 _Thread_MP_Free_proxy( the_thread );
Thread_Control * owner
The thread queue owner.
#define ISR_LOCK_INITIALIZER(_name)
Initializer for static initialization of ISR locks.
static __inline__ void * _RBTree_Find_inline(const RBTree_Control *the_rbtree, const void *key, bool(*equal)(const void *, const RBTree_Node *), bool(*less)(const void *, const RBTree_Node *), void *(*map)(RBTree_Node *))
Finds an object in the red-black tree with the specified key.
static __inline__ Thread_Control * _Thread_queue_First_locked(Thread_queue_Control *the_thread_queue, const Thread_queue_Operations *operations)
Returns the first thread on the thread queue if it exists, otherwise NULL.
static __inline__ bool _Objects_Is_local_id(Objects_Id id RTEMS_UNUSED)
Checks if the id is of a local object.
struct Thread_queue_Context::@30 Path
Representation of a thread queue path from a start thread queue to the terminal thread queue...
static __inline__ Thread_Wait_flags _Thread_Wait_flags_get_acquire(const Thread_Control *the_thread)
Gets the thread's wait flags according to the ATOMIC_ORDER_ACQUIRE.
Thread_queue_Queue * source
The source thread queue determined by the thread queue owner.
static __inline__ bool _RBTree_Insert_inline(RBTree_Control *the_rbtree, RBTree_Node *the_node, const void *key, bool(*less)(const void *, const RBTree_Node *))
Inserts the node into the red-black tree.
static __inline__ Per_CPU_Control * _Thread_queue_Dispatch_disable(Thread_queue_Context *queue_context)
Disables dispatching in a critical section.
static __inline__ void _Thread_Wait_restore_default(Thread_Control *the_thread)
Restores the default thread wait queue and operations.
bool _Thread_queue_Extract_locked(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Extracts the thread from the thread queue, restores the default wait operations and restores the defa...
Thread_Wait_information Wait
Thread queue context for the thread queue methods.
void _Thread_Dispatch_direct(Per_CPU_Control *cpu_self)
Directly do a thread dispatch.
#define _Thread_queue_Context_set_MP_callout(queue_context, mp_callout)
Sets the MP callout in the thread queue context.
Thread_Control * owner
The owner of this thread queue link.
static __inline__ void _Chain_Initialize_node(Chain_Node *the_node)
Initializes a chain node.
Inlined Routines in the Watchdog Handler.
Thread_queue_Lock_context Lock_context
The queue lock context used to acquire the thread wait lock of the owner.
Thread_queue_Enqueue_callout enqueue_callout
The enqueue callout for _Thread_queue_Enqueue().
A thread queue link from one thread to another specified by the thread queue owner and thread wait qu...
static __inline__ void _Thread_Resource_count_increment(Thread_Control *the_thread)
Increments the thread's resource count.
void _Thread_queue_Acquire(Thread_queue_Control *the_thread_queue, Thread_queue_Context *queue_context)
Acquires the thread queue control in a critical section.
Constants and Structures Related with Thread Dispatch.
static __inline__ void _Thread_queue_Context_initialize(Thread_queue_Context *queue_context)
Initializes a thread queue context.
Thread_queue_Deadlock_callout deadlock_callout
Invoked in case of a detected deadlock.
static __inline__ 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.
void _Thread_Priority_and_sticky_update(Thread_Control *the_thread, int sticky_level_change)
Updates the priority of the thread and changes it sticky level.
static __inline__ Thread_Wait_flags _Thread_Wait_flags_get(const Thread_Control *the_thread)
Gets the thread's wait flags according to the ATOMIC_ORDER_RELAXED.
void _Thread_queue_Unblock_critical(bool unblock, Thread_queue_Queue *queue, Thread_Control *the_thread, ISR_lock_Context *lock_context)
Unblocks the thread which was on the thread queue before.
bool _Thread_queue_Path_acquire_critical(Thread_queue_Queue *queue, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Does nothing.
Thread_queue_Queue * queue
The thread queue in case the thread is blocked on a thread queue.
Thread_queue_Link Deadlock
In case of a deadlock, a link for the first thread on the path that tries to enqueue on a thread queu...
Information for the Assert Handler.
Thread_Control * _Thread_queue_Do_dequeue(Thread_queue_Control *the_thread_queue, const Thread_queue_Operations *operations)
Dequeues the first thread waiting on the thread queue and returns it.
Thread_queue_Queue Queue
The actual thread queue.
static __inline__ void _Chain_Append_unprotected(Chain_Control *the_chain, Chain_Node *the_node)
Appends a node (unprotected).
static __inline__ Per_CPU_Control * _Thread_Dispatch_disable_critical(const ISR_lock_Context *lock_context)
Disables thread dispatching inside a critical section (interrupts disabled).
struct Thread_queue_Lock_context::@28 Wait
Data to support thread queue enqueue operations.
Chain_Node Path_node
Node to add this link to a thread queue path.
void _Thread_queue_Deadlock_fatal(Thread_Control *the_thread)
Results in an INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK fatal error.
static __inline__ void _Thread_Wait_flags_set(Thread_Control *the_thread, Thread_Wait_flags flags)
Sets the thread's wait flags.
void _Thread_queue_Deadlock_status(Thread_Control *the_thread)
Sets the thread wait return code to STATUS_DEADLOCK.
Thread_queue_Surrender_operation surrender
Thread queue surrender operation.
Thread_queue_Queue * target
The target thread queue determined by the thread wait queue of the source owner.
void _Thread_queue_Enqueue_do_nothing_extra(Thread_queue_Queue *queue, Thread_Control *the_thread, Per_CPU_Control *cpu_self, Thread_queue_Context *queue_context)
Does nothing.
Thread_queue_Gate Gate
Gate to synchronize thread wait lock requests.
static __inline__ void _Thread_Timer_remove(Thread_Control *the_thread)
Remove the watchdog timer from the thread.
static __inline__ void _Thread_Wait_acquire(Thread_Control *the_thread, Thread_queue_Context *queue_context)
Acquires the thread wait default lock and disables interrupts.
static __inline__ void _Thread_Wait_remove_request(Thread_Control *the_thread, Thread_queue_Lock_context *queue_lock_context)
Removes a thread wait lock request.
static __inline__ Chain_Node * _Chain_Head(Chain_Control *the_chain)
Returns pointer to chain head.
Thread_queue_Lock_context Lock_context
The lock context for the thread queue acquire and release operations.
static __inline__ 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.
Thread_queue_Extract_operation extract
Thread queue extract operation.
Constants and Structures Associated with the Manipulation of Objects.
#define _ISR_lock_Acquire(_lock, _context)
Acquires an ISR lock inside an ISR disabled section.
void _Thread_queue_Surrender(Thread_queue_Queue *queue, Thread_queue_Heads *heads, Thread_Control *previous_owner, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations)
Surrenders the thread queue previously owned by the thread to the first enqueued thread.
#define _ISR_lock_Release(_lock, _context)
Releases an ISR lock inside an ISR disabled section.
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.
static __inline__ void _Thread_Wait_release_queue_critical(Thread_queue_Queue *queue, Thread_queue_Lock_context *queue_lock_context)
Releases the wait queue inside a critical section.
static __inline__ void _Thread_Remove_timer_and_unblock(Thread_Control *the_thread, Thread_queue_Queue *queue)
Remove the watchdog timer from the thread and unblock if necessary.
static __inline__ void _Thread_queue_Queue_release(Thread_queue_Queue *queue, ISR_lock_Context *lock_context)
Releases the thread queue queue and enables interrupts.
#define RBTREE_INITIALIZER_EMPTY(name)
Initializer for an empty red-black tree with designator name.
void _Thread_queue_Surrender_sticky(Thread_queue_Queue *queue, Thread_queue_Heads *heads, Thread_Control *previous_owner, Thread_queue_Context *queue_context, const Thread_queue_Operations *operations)
Surrenders the thread queue previously owned by the thread to the first enqueued thread.
States_Control thread_state
The thread state for _Thread_queue_Enqueue().
static __inline__ void _Chain_Initialize_empty(Chain_Control *the_chain)
Initializes this chain as empty.
static __inline__ void _Thread_Wait_tranquilize(Thread_Control *the_thread)
Tranquilizes the thread after a wait on a thread queue.
static __inline__ void _RBTree_Initialize_node(RBTree_Node *the_node)
Initializes a red-black tree node.
Thread_queue_Enqueue_operation enqueue
Thread queue enqueue operation.
volatile uint32_t thread_dispatch_disable_level
The thread dispatch critical section nesting counter which is used to prevent context switches at ino...
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...
Inlined Routines from the Thread Handler.
static __inline__ Status_Control _Thread_Wait_get_status(const Thread_Control *the_thread)
Get the status of the wait return code of the thread.
static __inline__ Chain_Node * _Chain_Last(const Chain_Control *the_chain)
Returns pointer to chain's last node.
static __inline__ 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).
static __inline__ Chain_Node * _Chain_Previous(const Chain_Node *the_node)
Returns pointer to the previous node from this node.
RBTree_Node Registry_node
Node to register this link in the global thread queue links lookup tree.
Chain_Control Links
The chain of thread queue links defining the thread queue path.
static __inline__ void _Chain_Set_off_chain(Chain_Node *node)
Sets off chain.
void _Thread_queue_Extract(Thread_Control *the_thread)
Extracts thread from thread queue.
void _RBTree_Extract(RBTree_Control *the_rbtree, RBTree_Node *the_node)
Extracts (removes) the node from the red-black tree.
Local ISR lock context for acquire and release pairs.
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.
ISR_lock_Context Lock_context
The lock context for the thread queue acquire and release operations.
static __inline__ 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...
void _Thread_queue_Path_release_critical(Thread_queue_Context *queue_context)
Releases the thread queue path in a critical section.
Status_Control _Thread_queue_Enqueue_sticky(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Enqueues the thread on the thread queue and busy waits for dequeue.
static __inline__ 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).
void _Thread_queue_Release(Thread_queue_Control *the_thread_queue, Thread_queue_Context *queue_context)
Releases the thread queue control and enables interrupts.
Thread_queue_Link Start
The start of a thread queue path.
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.
void _Thread_queue_Extract_critical(Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, Thread_queue_Context *queue_context)
Extracts the thread from the thread queue and unblocks it.
static __inline__ void _Thread_Wait_claim(Thread_Control *the_thread, Thread_queue_Queue *queue)
Claims the thread wait queue.
static __inline__ void _Thread_Wait_acquire_queue_critical(Thread_queue_Queue *queue, Thread_queue_Lock_context *queue_lock_context)
Acquires the wait queue inside a critical section.
static __inline__ void _Thread_queue_Gate_add(Chain_Control *chain, Thread_queue_Gate *gate)
Adds the gate to the chain.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
Helper structure to ensure that all objects containing a thread queue have the right layout...
static __inline__ void _Thread_Wait_remove_request_locked(Thread_Control *the_thread, Thread_queue_Lock_context *queue_lock_context)
Removes the first pending wait lock request.