diff --git a/arm.gdb b/arm.gdb new file mode 100644 index 00000000000..e2ec6e13870 --- /dev/null +++ b/arm.gdb @@ -0,0 +1,24 @@ +set print elements 0 +set print pretty on +set pagination off +set confirm off +tar remote :1234 +load +info threads +define reset + monitor system_reset + load +end +define new + make + monitor system_reset + load + c +end +b _ARM_Exception_default +b _ARMV4_Exception_data_abort_default +b bsp_interrupt_handler_default +b bsp_reset +b _Terminate +b Init +reset diff --git a/cpukit/include/rtems/score/schedulerstrongapa.h b/cpukit/include/rtems/score/schedulerstrongapa.h index 0ac28cb4393..71bf62949c9 100644 --- a/cpukit/include/rtems/score/schedulerstrongapa.h +++ b/cpukit/include/rtems/score/schedulerstrongapa.h @@ -1,64 +1,14 @@ -/** - * @file - * - * @ingroup RTEMSScoreSchedulerStrongAPA - * - * @brief Strong APA Scheduler API - */ - -/* - * Copyright (c) 2013, 2018 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * 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_SCHEDULERSTRONGAPA_H -#define _RTEMS_SCORE_SCHEDULERSTRONGAPA_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/** - * @defgroup RTEMSScoreSchedulerStrongAPA Strong APA Scheduler - * - * @ingroup RTEMSScoreSchedulerSMP - * - * @brief Strong APA Scheduler - * - * This is an implementation of the global fixed priority scheduler (G-FP). It - * uses one ready chain per priority to ensure constant time insert operations. - * The scheduled chain uses linear insert operations and has at most processor - * count entries. Since the processor and priority count are constants all - * scheduler operations complete in a bounded execution time. - * - * The the_thread preempt mode will be ignored. - * - * @{ - */ - -/** - * @brief Scheduler context specialization for Strong APA - * schedulers. - */ typedef struct { Scheduler_SMP_Context Base; - Priority_bit_map_Control Bit_map; - Chain_Control Ready[ RTEMS_ZERO_LENGTH_ARRAY ]; + + /** + * @brief Chain of all nodes present in the scheduler + */ + Chain_Control Nodes; + } Scheduler_strong_APA_Context; + /** * @brief Scheduler node specialization for Strong APA * schedulers. @@ -68,188 +18,16 @@ typedef struct { * @brief SMP scheduler node. */ Scheduler_SMP_Node Base; - + /** - * @brief The associated ready queue of this node. + * @brief Chain node for Scheduler_strong_APA_Context::Nodes. */ - Scheduler_priority_Ready_queue Ready_queue; + Chain_Node Node; + + /** + * @brief The associated affinity set of this node. + */ + Processor_mask affinity; } Scheduler_strong_APA_Node; -/** - * @brief Entry points for the Strong APA Scheduler. - */ -#define SCHEDULER_STRONG_APA_ENTRY_POINTS \ - { \ - _Scheduler_strong_APA_Initialize, \ - _Scheduler_default_Schedule, \ - _Scheduler_strong_APA_Yield, \ - _Scheduler_strong_APA_Block, \ - _Scheduler_strong_APA_Unblock, \ - _Scheduler_strong_APA_Update_priority, \ - _Scheduler_default_Map_priority, \ - _Scheduler_default_Unmap_priority, \ - _Scheduler_strong_APA_Ask_for_help, \ - _Scheduler_strong_APA_Reconsider_help_request, \ - _Scheduler_strong_APA_Withdraw_node, \ - _Scheduler_default_Pin_or_unpin, \ - _Scheduler_default_Pin_or_unpin, \ - _Scheduler_strong_APA_Add_processor, \ - _Scheduler_strong_APA_Remove_processor, \ - _Scheduler_strong_APA_Node_initialize, \ - _Scheduler_default_Node_destroy, \ - _Scheduler_default_Release_job, \ - _Scheduler_default_Cancel_job, \ - _Scheduler_default_Tick, \ - _Scheduler_SMP_Start_idle \ - SCHEDULER_OPERATION_DEFAULT_GET_SET_AFFINITY \ - } - -/** - * @brief Initializes the scheduler. - * - * @param scheduler The scheduler to initialize. - */ -void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler ); - -/** - * @brief Initializes the node with the given priority. - * - * @param scheduler The scheduler control instance. - * @param[out] node The node to initialize. - * @param the_thread The thread of the node to initialize. - * @param priority The priority for @a node. - */ -void _Scheduler_strong_APA_Node_initialize( - const Scheduler_Control *scheduler, - Scheduler_Node *node, - Thread_Control *the_thread, - Priority_Control priority -); - -/** - * @brief Blocks the thread. - * - * @param scheduler The scheduler control instance. - * @param[in, out] the_thread The thread to block. - * @param[in, out] node The node of the thread to block. - */ -void _Scheduler_strong_APA_Block( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -); - -/** - * @brief Unblocks the thread. - * - * @param scheduler The scheduler control instance. - * @param[in, out] the_thread The thread to unblock. - * @param[in, out] node The node of the thread to unblock. - */ -void _Scheduler_strong_APA_Unblock( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -); - -/** - * @brief Updates the priority of the node. - * - * @param scheduler The scheduler control instance. - * @param the_thread The thread for the operation. - * @param[in, out] node The node to update the priority of. - */ -void _Scheduler_strong_APA_Update_priority( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -); - -/** - * @brief Asks for help. - * - * @param scheduler The scheduler control instance. - * @param the_thread The thread that asks for help. - * @param node The node of @a the_thread. - * - * @retval true The request for help was successful. - * @retval false The request for help was not successful. - */ -bool _Scheduler_strong_APA_Ask_for_help( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -); - -/** - * @brief Reconsiders help request. - * - * @param scheduler The scheduler control instance. - * @param the_thread The thread to reconsider the help request of. - * @param[in, out] node The node of @a the_thread - */ -void _Scheduler_strong_APA_Reconsider_help_request( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -); - -/** - * @brief Withdraws the node. - * - * @param scheduler The scheduler control instance. - * @param[in, out] the_thread The thread to change the state to @a next_state. - * @param[in, out] node The node to withdraw. - * @param next_state The next state for @a the_thread. - */ -void _Scheduler_strong_APA_Withdraw_node( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node, - Thread_Scheduler_state next_state -); - -/** - * @brief Adds the idle thread to a processor. - * - * @param scheduler The scheduler control instance. - * @param[in, out] The idle thread to add to the processor. - */ -void _Scheduler_strong_APA_Add_processor( - const Scheduler_Control *scheduler, - Thread_Control *idle -); - -/** - * @brief Removes an idle thread from the given cpu. - * - * @param scheduler The scheduler instance. - * @param cpu The cpu control to remove from @a scheduler. - * - * @return The idle thread of the processor. - */ -Thread_Control *_Scheduler_strong_APA_Remove_processor( - const Scheduler_Control *scheduler, - struct Per_CPU_Control *cpu -); - -/** - * @brief Performs a yield operation. - * - * @param scheduler The scheduler control instance. - * @param the_thread The thread to yield. - * @param[in, out] node The node of @a the_thread. - */ -void _Scheduler_strong_APA_Yield( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -); - -/** @} */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _RTEMS_SCORE_SCHEDULERSTRONGAPA_H */ diff --git a/cpukit/score/src/schedulerstrongapa.c b/cpukit/score/src/schedulerstrongapa.c index 924cd86412c..315da1bbf1f 100644 --- a/cpukit/score/src/schedulerstrongapa.c +++ b/cpukit/score/src/schedulerstrongapa.c @@ -1,174 +1,19 @@ -/** - * @file - * - * @ingroup RTEMSScoreSchedulerStrongAPA - * - * @brief Strong APA Scheduler Implementation - */ - -/* - * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -static Scheduler_strong_APA_Context *_Scheduler_strong_APA_Get_self( - Scheduler_Context *context -) -{ - return (Scheduler_strong_APA_Context *) context; -} - static Scheduler_strong_APA_Node * _Scheduler_strong_APA_Node_downcast( Scheduler_Node *node ) { return (Scheduler_strong_APA_Node *) node; } -static void _Scheduler_strong_APA_Move_from_scheduled_to_ready( - Scheduler_Context *context, - Scheduler_Node *scheduled_to_ready -) -{ - Scheduler_strong_APA_Context *self = - _Scheduler_strong_APA_Get_self( context ); - Scheduler_strong_APA_Node *node = - _Scheduler_strong_APA_Node_downcast( scheduled_to_ready ); - - _Chain_Extract_unprotected( &node->Base.Base.Node.Chain ); - _Scheduler_priority_Ready_queue_enqueue_first( - &node->Base.Base.Node.Chain, - &node->Ready_queue, - &self->Bit_map - ); -} - -static void _Scheduler_strong_APA_Move_from_ready_to_scheduled( - Scheduler_Context *context, - Scheduler_Node *ready_to_scheduled -) -{ - Scheduler_strong_APA_Context *self; - Scheduler_strong_APA_Node *node; - Priority_Control insert_priority; - - self = _Scheduler_strong_APA_Get_self( context ); - node = _Scheduler_strong_APA_Node_downcast( ready_to_scheduled ); - - _Scheduler_priority_Ready_queue_extract( - &node->Base.Base.Node.Chain, - &node->Ready_queue, - &self->Bit_map - ); - insert_priority = _Scheduler_SMP_Node_priority( &node->Base.Base ); - insert_priority = SCHEDULER_PRIORITY_APPEND( insert_priority ); - _Chain_Insert_ordered_unprotected( - &self->Base.Scheduled, - &node->Base.Base.Node.Chain, - &insert_priority, - _Scheduler_SMP_Priority_less_equal - ); -} - -static void _Scheduler_strong_APA_Insert_ready( - Scheduler_Context *context, - Scheduler_Node *node_base, - Priority_Control insert_priority -) -{ - Scheduler_strong_APA_Context *self; - Scheduler_strong_APA_Node *node; - - self = _Scheduler_strong_APA_Get_self( context ); - node = _Scheduler_strong_APA_Node_downcast( node_base ); - - if ( SCHEDULER_PRIORITY_IS_APPEND( insert_priority ) ) { - _Scheduler_priority_Ready_queue_enqueue( - &node->Base.Base.Node.Chain, - &node->Ready_queue, - &self->Bit_map - ); - } else { - _Scheduler_priority_Ready_queue_enqueue_first( - &node->Base.Base.Node.Chain, - &node->Ready_queue, - &self->Bit_map - ); - } -} - -static void _Scheduler_strong_APA_Extract_from_ready( - Scheduler_Context *context, - Scheduler_Node *the_thread -) -{ - Scheduler_strong_APA_Context *self = - _Scheduler_strong_APA_Get_self( context ); - Scheduler_strong_APA_Node *node = - _Scheduler_strong_APA_Node_downcast( the_thread ); - - _Scheduler_priority_Ready_queue_extract( - &node->Base.Base.Node.Chain, - &node->Ready_queue, - &self->Bit_map - ); -} - -static void _Scheduler_strong_APA_Do_update( - Scheduler_Context *context, - Scheduler_Node *node_to_update, - Priority_Control new_priority -) -{ - Scheduler_strong_APA_Context *self = - _Scheduler_strong_APA_Get_self( context ); - Scheduler_strong_APA_Node *node = - _Scheduler_strong_APA_Node_downcast( node_to_update ); - - _Scheduler_SMP_Node_update_priority( &node->Base, new_priority ); - _Scheduler_priority_Ready_queue_update( - &node->Ready_queue, - SCHEDULER_PRIORITY_UNMAP( new_priority ), - &self->Bit_map, - &self->Ready[ 0 ] - ); -} - -static Scheduler_strong_APA_Context * -_Scheduler_strong_APA_Get_context( const Scheduler_Control *scheduler ) -{ - return (Scheduler_strong_APA_Context *) _Scheduler_Get_context( scheduler ); -} - void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler ) { Scheduler_strong_APA_Context *self = _Scheduler_strong_APA_Get_context( scheduler ); _Scheduler_SMP_Initialize( &self->Base ); - _Priority_bit_map_Initialize( &self->Bit_map ); - _Scheduler_priority_Ready_queue_initialize( - &self->Ready[ 0 ], - scheduler->maximum_priority - ); + _Chain_Initialize_empty( &self->Nodes ); } + void _Scheduler_strong_APA_Node_initialize( const Scheduler_Control *scheduler, Scheduler_Node *node, @@ -176,260 +21,77 @@ void _Scheduler_strong_APA_Node_initialize( Priority_Control priority ) { - Scheduler_Context *context; - Scheduler_strong_APA_Context *self; - Scheduler_strong_APA_Node *the_node; - - the_node = _Scheduler_strong_APA_Node_downcast( node ); - _Scheduler_SMP_Node_initialize( - scheduler, - &the_node->Base, - the_thread, - priority - ); - - context = _Scheduler_Get_context( scheduler ); - self = _Scheduler_strong_APA_Get_self( context ); - _Scheduler_priority_Ready_queue_update( - &the_node->Ready_queue, - SCHEDULER_PRIORITY_UNMAP( priority ), - &self->Bit_map, - &self->Ready[ 0 ] - ); -} - -static bool _Scheduler_strong_APA_Has_ready( Scheduler_Context *context ) -{ - Scheduler_strong_APA_Context *self = - _Scheduler_strong_APA_Get_self( context ); - - return !_Priority_bit_map_Is_empty( &self->Bit_map ); -} - -static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready( - Scheduler_Context *context, - Scheduler_Node *node -) -{ - Scheduler_strong_APA_Context *self = - _Scheduler_strong_APA_Get_self( context ); - - (void) node; + Scheduler_strong_APA_Context *self = + _Scheduler_strong_APA_Get_context( scheduler ); + + Scheduler_SMP_Node *smp_node; + Scheduler_strong_APA_Node *self_node; + + self_node=_Scheduler_strong_APA_Node_downcast(node); - return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first( - &self->Bit_map, - &self->Ready[ 0 ] - ); + smp_node = _Scheduler_SMP_Node_downcast( node ); + _Scheduler_SMP_Node_initialize( scheduler, smp_node, the_thread, priority ); + + _Chain_Append_unprotected( &self->Nodes, &self_node->Node ); } -void _Scheduler_strong_APA_Block( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - _Scheduler_SMP_Block( - context, - the_thread, - node, - _Scheduler_SMP_Extract_from_scheduled, - _Scheduler_strong_APA_Extract_from_ready, - _Scheduler_strong_APA_Get_highest_ready, - _Scheduler_strong_APA_Move_from_ready_to_scheduled, - _Scheduler_SMP_Allocate_processor_exact - ); -} - -static bool _Scheduler_strong_APA_Enqueue( +static inline void _Scheduler_strong_APA_Do_set_affinity( Scheduler_Context *context, - Scheduler_Node *node, - Priority_Control insert_priority -) -{ - return _Scheduler_SMP_Enqueue( - context, - node, - insert_priority, - _Scheduler_SMP_Priority_less_equal, - _Scheduler_strong_APA_Insert_ready, - _Scheduler_SMP_Insert_scheduled, - _Scheduler_strong_APA_Move_from_scheduled_to_ready, - _Scheduler_SMP_Get_lowest_scheduled, - _Scheduler_SMP_Allocate_processor_exact - ); -} - -static bool _Scheduler_strong_APA_Enqueue_scheduled( - Scheduler_Context *context, - Scheduler_Node *node, - Priority_Control insert_priority -) -{ - return _Scheduler_SMP_Enqueue_scheduled( - context, - node, - insert_priority, - _Scheduler_SMP_Priority_less_equal, - _Scheduler_strong_APA_Extract_from_ready, - _Scheduler_strong_APA_Get_highest_ready, - _Scheduler_strong_APA_Insert_ready, - _Scheduler_SMP_Insert_scheduled, - _Scheduler_strong_APA_Move_from_ready_to_scheduled, - _Scheduler_SMP_Allocate_processor_exact - ); -} - -void _Scheduler_strong_APA_Unblock( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - - _Scheduler_SMP_Unblock( - context, - the_thread, - node, - _Scheduler_strong_APA_Do_update, - _Scheduler_strong_APA_Enqueue - ); -} - -static bool _Scheduler_strong_APA_Do_ask_for_help( - Scheduler_Context *context, - Thread_Control *the_thread, - Scheduler_Node *node -) -{ - return _Scheduler_SMP_Ask_for_help( - context, - the_thread, - node, - _Scheduler_SMP_Priority_less_equal, - _Scheduler_strong_APA_Insert_ready, - _Scheduler_SMP_Insert_scheduled, - _Scheduler_strong_APA_Move_from_scheduled_to_ready, - _Scheduler_SMP_Get_lowest_scheduled, - _Scheduler_SMP_Allocate_processor_lazy - ); -} - -void _Scheduler_strong_APA_Update_priority( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - - _Scheduler_SMP_Update_priority( - context, - the_thread, - node, - _Scheduler_strong_APA_Extract_from_ready, - _Scheduler_strong_APA_Do_update, - _Scheduler_strong_APA_Enqueue, - _Scheduler_strong_APA_Enqueue_scheduled, - _Scheduler_strong_APA_Do_ask_for_help - ); -} - -bool _Scheduler_strong_APA_Ask_for_help( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node + Scheduler_Node *node_base, + void *arg ) { - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + _Scheduler_strong_APA_Node *node; + const Processor_mask *affinity; - return _Scheduler_strong_APA_Do_ask_for_help( context, the_thread, node ); + node = _Scheduler_strong_APA_Node_downcast( node_base ); + affinity = arg; + node->affinity = *affinity; } -void _Scheduler_strong_APA_Reconsider_help_request( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - - _Scheduler_SMP_Reconsider_help_request( - context, - the_thread, - node, - _Scheduler_strong_APA_Extract_from_ready - ); -} -void _Scheduler_strong_APA_Withdraw_node( +bool _Scheduler_strong_APA_Set_affinity( const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node, - Thread_Scheduler_state next_state + Thread_Control *thread, + Scheduler_Node *node_base, + const Processor_mask *affinity ) { - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + Scheduler_Context *context; + Scheduler_strong_APA_Node *node; + Processor_mask local_affinity; + States_Control current_state; - _Scheduler_SMP_Withdraw_node( - context, - the_thread, - node, - next_state, - _Scheduler_strong_APA_Extract_from_ready, - _Scheduler_strong_APA_Get_highest_ready, - _Scheduler_strong_APA_Move_from_ready_to_scheduled, - _Scheduler_SMP_Allocate_processor_lazy - ); -} -void _Scheduler_strong_APA_Add_processor( - const Scheduler_Control *scheduler, - Thread_Control *idle -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - - _Scheduler_SMP_Add_processor( - context, - idle, - _Scheduler_strong_APA_Has_ready, - _Scheduler_strong_APA_Enqueue_scheduled, - _Scheduler_SMP_Do_nothing_register_idle - ); -} - -Thread_Control *_Scheduler_strong_APA_Remove_processor( - const Scheduler_Control *scheduler, - Per_CPU_Control *cpu -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); - - return _Scheduler_SMP_Remove_processor( - context, - cpu, - _Scheduler_strong_APA_Extract_from_ready, - _Scheduler_strong_APA_Enqueue - ); -} + context = _Scheduler_Get_context( scheduler ); + _Processor_mask_And( &local_affinity, &context->Processors, affinity ); -void _Scheduler_strong_APA_Yield( - const Scheduler_Control *scheduler, - Thread_Control *the_thread, - Scheduler_Node *node -) -{ - Scheduler_Context *context = _Scheduler_Get_context( scheduler ); + if ( _Processor_mask_Is_zero( &local_affinity ) ) { + return false; + } + + + node = Scheduler_strong_APA_Node_downcast( node_base ); + + if ( _Processor_mask_Is_equal( &node->affinity, affinity ) ) + return true; //Nothing to do. Return true. + + + + _Scheduler_SMP_Set_affinity( + context, + thread, + node_base, + &local_affinity, + _Scheduler_strong_APA_Do_set_affinity, + _Scheduler_strong_APA_Extract_from_ready, //--------------------------INCOMPLETE FROM HERE DOWNWARDS TILL Line no 96. + _Scheduler_strong_APA_Get_highest_ready, //TODO Next! We would also need the info of the cpu the node was executing on. + _Scheduler_strong_APA_Move_from_ready_to_scheduled, + _Scheduler_strong_APA_Enqueue, + _Scheduler_strong_APA_Allocate_processor + ); + - _Scheduler_SMP_Yield( - context, - the_thread, - node, - _Scheduler_strong_APA_Extract_from_ready, - _Scheduler_strong_APA_Enqueue, - _Scheduler_strong_APA_Enqueue_scheduled - ); + return true; }