void _Thread_queue_Extract_with_return_code( Thread_queue_Control *the_thread_queue, Thread_Control *the_thread, uint32_t return_code ) { ISR_lock_Context lock_context; _Thread_queue_Acquire( &lock_context ); if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) { _Thread_queue_Release( &lock_context ); return; } if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) { _Chain_Extract_unprotected( &the_thread->Object.Node ); } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */ _RBTree_Extract( &the_thread->Wait.queue->Queues.Priority, &the_thread->RBNode ); _Thread_Priority_restore_default_change_handler( the_thread ); _Thread_Lock_restore_default( the_thread ); } the_thread->Wait.return_code = return_code; /* * We found a thread to unblock. * * NOTE: This is invoked with interrupts still disabled. */ _Thread_blocking_operation_Finalize( the_thread, &lock_context ); }
Scheduler_Void_or_thread _Scheduler_EDF_Yield( const Scheduler_Control *scheduler, Thread_Control *the_thread ) { Scheduler_EDF_Context *context = _Scheduler_EDF_Get_context( scheduler ); Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread ); /* * The RBTree has more than one node, enqueue behind the tasks * with the same priority in case there are such ones. */ _RBTree_Extract( &context->Ready, &node->Node ); _RBTree_Insert( &context->Ready, &node->Node, _Scheduler_EDF_Compare, false ); _Scheduler_EDF_Schedule_body( scheduler, the_thread, false ); SCHEDULER_RETURN_VOID_OR_NULL; }
static void _Thread_queue_Priority_priority_change( Thread_queue_Queue *queue, Thread_Control *the_thread, Priority_Control new_priority ) { Thread_queue_Heads *heads; Thread_queue_Priority_queue *priority_queue; Scheduler_Node *scheduler_node; heads = queue->heads; _Assert( heads != NULL ); priority_queue = _Thread_queue_Priority_queue( heads, the_thread ); scheduler_node = _Scheduler_Thread_get_own_node( the_thread ); _RBTree_Extract( &priority_queue->Queue, &scheduler_node->Wait.Node.RBTree ); _RBTree_Insert_inline( &priority_queue->Queue, &scheduler_node->Wait.Node.RBTree, &new_priority, _Thread_queue_Priority_less ); }
static void _Thread_queue_Priority_do_extract( Thread_queue_Heads *heads, Thread_Control *the_thread ) { _RBTree_Extract( &heads->Heads.Priority, &the_thread->Wait.Node.RBTree ); }
void _Scheduler_EDF_Extract( Thread_Control *the_thread ) { Scheduler_EDF_Per_thread *sched_info = (Scheduler_EDF_Per_thread*) the_thread->scheduler_info; RBTree_Node *node = &(sched_info->Node); _RBTree_Extract( &_Scheduler_EDF_Ready_queue, node ); sched_info->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY; }
static void _Thread_queue_Link_remove( Thread_queue_Link *link ) { Thread_queue_Links *links; ISR_lock_Context lock_context; links = &_Thread_queue_Links; _ISR_lock_Acquire( &links->Lock, &lock_context ); _RBTree_Extract( &links->Links, &link->Registry_node ); _ISR_lock_Release( &links->Lock, &lock_context ); }
/* * _POSIX_Keys_Run_destructors * * 17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163 * * NOTE: This is the routine executed when a thread exits to * run through all the keys and do the destructor action. */ void _POSIX_Keys_Run_destructors( Thread_Control *thread ) { Chain_Control *chain; POSIX_Keys_Key_value_pair *iter, *next; void *value; void (*destructor) (void *); POSIX_Keys_Control *the_key; Objects_Locations location; _Thread_Disable_dispatch(); chain = &( (POSIX_API_Control *)thread->API_Extensions[ THREAD_API_POSIX ] )->Key_Chain; iter = (POSIX_Keys_Key_value_pair *) _Chain_First( chain ); while ( !_Chain_Is_tail( chain, &iter->Key_values_per_thread_node ) ) { next = (POSIX_Keys_Key_value_pair *) _Chain_Next( &iter->Key_values_per_thread_node ); /** * remove key from rbtree and chain. * here Chain_Node *iter can be convert to POSIX_Keys_Key_value_pair *, * because Chain_Node is the first member of POSIX_Keys_Key_value_pair * structure. */ _RBTree_Extract( &_POSIX_Keys_Key_value_lookup_tree, &iter->Key_value_lookup_node ); _Chain_Extract_unprotected( &iter->Key_values_per_thread_node ); /** * run key value's destructor if destructor and value are both non-null. */ the_key = _POSIX_Keys_Get( iter->key, &location ); destructor = the_key->destructor; value = iter->value; if ( destructor != NULL && value != NULL ) (*destructor)( value ); _Objects_Put( &the_key->Object ); _POSIX_Keys_Key_value_pair_free( iter ); iter = next; } _Thread_Enable_dispatch(); }
void _Scheduler_EDF_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, bool prepend_it ) { Scheduler_EDF_Context *context = _Scheduler_EDF_Get_context( scheduler ); Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread ); _RBTree_Extract( &context->Ready, &node->Node ); _RBTree_Insert( &context->Ready, &node->Node ); }
static void _Thread_queue_Requeue_priority( Thread_Control *the_thread, Priority_Control new_priority, void *context ) { Thread_queue_Control *tq = context; _RBTree_Extract( &tq->Queues.Priority, &the_thread->RBNode ); _RBTree_Insert( &tq->Queues.Priority, &the_thread->RBNode, _Thread_queue_Compare_priority, false ); }
void _Thread_MP_Free_proxy( Thread_Control *the_thread ) { Thread_Proxy_control *the_proxy; ISR_lock_Context lock_context; the_proxy = (Thread_Proxy_control *) the_thread; _Thread_MP_Proxies_acquire( &lock_context ); _RBTree_Extract( &_Thread_MP_Active_proxies, &the_proxy->Active ); _Chain_Append_unprotected( &_Thread_MP_Inactive_proxies, &the_proxy->Object.Node ); _Thread_MP_Proxies_release( &lock_context ); }
void _Thread_queue_Requeue( Thread_queue_Control *the_thread_queue, Thread_Control *the_thread ) { /* * Just in case the thread really wasn't blocked on a thread queue * when we get here. */ if ( !the_thread_queue ) return; /* * If queueing by FIFO, there is nothing to do. This only applies to * priority blocking discipline. */ if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) { Thread_queue_Control *tq = the_thread_queue; ISR_Level level; _ISR_Disable( level ); if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) { _Thread_queue_Enter_critical_section( tq ); /* extract the thread */ _RBTree_Extract( &the_thread->Wait.queue->Queues.Priority, &the_thread->RBNode ); /* enqueue the thread at the new priority */ _RBTree_Insert( &the_thread_queue->Queues.Priority, &the_thread->RBNode, _Thread_queue_Compare_priority, false ); } _ISR_Enable( level ); } }
static void _Thread_queue_Priority_do_extract( Thread_queue_Heads *heads, Thread_Control *the_thread ) { Thread_queue_Priority_queue *priority_queue = _Thread_queue_Priority_queue( heads, the_thread ); _RBTree_Extract( &priority_queue->Queue, &the_thread->Wait.Node.RBTree ); #if defined(RTEMS_SMP) _Chain_Extract_unprotected( &priority_queue->Node ); if ( !_RBTree_Is_empty( &priority_queue->Queue ) ) { _Chain_Append_unprotected( &heads->Heads.Fifo, &priority_queue->Node ); } #endif }
static void _Thread_queue_Priority_priority_change( Thread_Control *the_thread, Priority_Control new_priority, Thread_queue_Queue *queue ) { Thread_queue_Heads *heads = queue->heads; _Assert( heads != NULL ); _RBTree_Extract( &heads->Heads.Priority, &the_thread->Wait.Node.RBTree ); _RBTree_Insert( &heads->Heads.Priority, &the_thread->Wait.Node.RBTree, _Thread_queue_Compare_priority, false ); }
Scheduler_Void_or_thread _Scheduler_EDF_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, Priority_Control new_priority, bool prepend_it ) { Scheduler_EDF_Context *context = _Scheduler_EDF_Get_context( scheduler ); Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread ); _RBTree_Extract( &context->Ready, &node->Node ); _RBTree_Insert( &context->Ready, &node->Node, _Scheduler_EDF_Compare, false ); SCHEDULER_RETURN_VOID_OR_NULL; }
static void _Thread_queue_Priority_priority_change( Thread_Control *the_thread, Priority_Control new_priority, Thread_queue_Queue *queue ) { Thread_queue_Heads *heads = queue->heads; Thread_queue_Priority_queue *priority_queue; _Assert( heads != NULL ); priority_queue = _Thread_queue_Priority_queue( heads, the_thread ); _RBTree_Extract( &priority_queue->Queue, &the_thread->Wait.Node.RBTree ); _RBTree_Insert_inline( &priority_queue->Queue, &the_thread->Wait.Node.RBTree, &new_priority, _Thread_queue_Priority_less ); }