void _Scheduler_Request_ask_for_help( Thread_Control *the_thread ) { ISR_lock_Context lock_context; _Thread_Scheduler_acquire_critical( the_thread, &lock_context ); if ( _Chain_Is_node_off_chain( &the_thread->Scheduler.Help_node ) ) { Per_CPU_Control *cpu; cpu = _Thread_Get_CPU( the_thread ); _Per_CPU_Acquire( cpu ); _Chain_Append_unprotected( &cpu->Threads_in_need_for_help, &the_thread->Scheduler.Help_node ); _Per_CPU_Release( cpu ); _Thread_Dispatch_request( _Per_CPU_Get(), cpu ); } _Thread_Scheduler_release_critical( the_thread, &lock_context ); }
void _Thread_Scheduler_process_requests( Thread_Control *the_thread ) { ISR_lock_Context lock_context; Scheduler_Node *scheduler_node; _Thread_Scheduler_acquire_critical( the_thread, &lock_context ); scheduler_node = the_thread->Scheduler.requests; if ( scheduler_node != NULL ) { Scheduler_Node *next; Scheduler_Node *remove; the_thread->Scheduler.requests = NULL; remove = NULL; do { Scheduler_Node_request request; request = scheduler_node->Thread.request; scheduler_node->Thread.request = SCHEDULER_NODE_REQUEST_NOT_PENDING; next = scheduler_node->Thread.next_request; #if defined(RTEMS_DEBUG) scheduler_node->Thread.next_request = NULL; #endif if ( request == SCHEDULER_NODE_REQUEST_ADD ) { ++the_thread->Scheduler.helping_nodes; _Chain_Append_unprotected( &the_thread->Scheduler.Scheduler_nodes, &scheduler_node->Thread.Scheduler_node.Chain ); } else if ( request == SCHEDULER_NODE_REQUEST_REMOVE ) { --the_thread->Scheduler.helping_nodes; _Chain_Extract_unprotected( &scheduler_node->Thread.Scheduler_node.Chain ); scheduler_node->Thread.Scheduler_node.next = remove; remove = scheduler_node; } else { _Assert( request == SCHEDULER_NODE_REQUEST_NOTHING ); } scheduler_node = next; } while ( scheduler_node != NULL ); _Thread_Scheduler_release_critical( the_thread, &lock_context ); scheduler_node = remove; while ( scheduler_node != NULL ) { const Scheduler_Control *scheduler; ISR_lock_Context lock_context; next = scheduler_node->Thread.Scheduler_node.next; #if defined(RTEMS_DEBUG) scheduler_node->Thread.Scheduler_node.next = NULL; #endif scheduler = _Scheduler_Node_get_scheduler( scheduler_node ); _Scheduler_Acquire_critical( scheduler, &lock_context ); ( *scheduler->Operations.withdraw_node )( scheduler, the_thread, scheduler_node, THREAD_SCHEDULER_READY ); _Scheduler_Release_critical( scheduler, &lock_context ); scheduler_node = next; } } else { _Thread_Scheduler_release_critical( the_thread, &lock_context ); } }