Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreSchedulerStrongAPA
0007  *
0008  * @brief This header file provides the interfaces of the
0009  *   @ref RTEMSScoreSchedulerStrongAPA.
0010  */
0011 
0012 /*
0013  * Copyright (C) 2020 Richi Dubey
0014  * Copyright (C) 2013, 2018 embedded brains GmbH & Co. KG
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifndef _RTEMS_SCORE_SCHEDULERSTRONGAPA_H
0039 #define _RTEMS_SCORE_SCHEDULERSTRONGAPA_H
0040 
0041 #include <rtems/score/scheduler.h>
0042 #include <rtems/score/schedulersmp.h>
0043 
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif /* __cplusplus */
0047 
0048 /* Forward Declaration of Per_CPU_Control */
0049 struct Per_CPU_Control;
0050 
0051 /**
0052  * @defgroup RTEMSScoreSchedulerStrongAPA Strong APA Scheduler
0053  *
0054  * @ingroup RTEMSScoreSchedulerSMP
0055  *
0056  * @brief This group contains the Strong APA Scheduler implementation.
0057  *
0058  * This is an implementation of the Strong APA scheduler defined by
0059  * Cerqueira et al. in Linux's Processor Affinity API, Refined:
0060  * Shifting Real-Time Tasks Towards Higher Schedulability.
0061  *
0062  * The scheduled and ready nodes are accessed via the
0063  * Scheduler_strong_APA_Context::Ready which helps in backtracking when a
0064  * node which is executing on a CPU gets blocked. New node is allocated to
0065  * the cpu by checking all the executing nodes in the affinity set of the
0066  * node and the subsequent nodes executing on the processors in its
0067  * affinity set.
0068  * @{
0069  */
0070 
0071 /**
0072  * @brief Scheduler node specialization for Strong APA schedulers.
0073  */
0074 typedef struct {
0075   /**
0076    * @brief SMP scheduler node.
0077    */
0078   Scheduler_SMP_Node Base;
0079 
0080   /**
0081    * @brief Chain node for Scheduler_strong_APA_Context::Ready.
0082    */
0083   Chain_Node Ready_node;
0084 
0085   /**
0086    * @brief CPU that this node would preempt in the backtracking part of
0087    * _Scheduler_strong_APA_Get_highest_ready and
0088    * _Scheduler_strong_APA_Do_Enqueue.
0089    */
0090   struct Per_CPU_Control *cpu_to_preempt;
0091 
0092   /**
0093    * @brief The associated affinity set of this node.
0094    */
0095   Processor_mask Affinity;
0096 } Scheduler_strong_APA_Node;
0097 
0098 
0099 /**
0100  * @brief CPU related variables and a CPU_Control to implement BFS.
0101  */
0102 typedef struct {
0103   /**
0104    * @brief CPU in a queue.
0105    */
0106   struct Per_CPU_Control *cpu;
0107 
0108   /**
0109    * @brief The node that would preempt this CPU.
0110    */
0111   Scheduler_Node *preempting_node;
0112 
0113   /**
0114    * @brief Whether or not this cpu has been added to the queue
0115    * (visited in BFS).
0116    */
0117   bool visited;
0118 
0119   /**
0120    * @brief The node currently executing on this cpu.
0121    */
0122   Scheduler_Node *executing;
0123 } Scheduler_strong_APA_CPU;
0124 
0125 /**
0126  * @brief Scheduler context and node definition for Strong APA scheduler.
0127  */
0128 typedef struct {
0129   /**
0130    * @brief @see Scheduler_SMP_Context.
0131    */
0132   Scheduler_SMP_Context Base;
0133 
0134   /**
0135    * @brief Chain of all the ready and scheduled nodes present in
0136    * the Strong APA scheduler.
0137    */
0138   Chain_Control Ready;
0139 
0140   /**
0141    * @brief Stores cpu-specific variables.
0142    */
0143   Scheduler_strong_APA_CPU CPU[ RTEMS_ZERO_LENGTH_ARRAY ];
0144 } Scheduler_strong_APA_Context;
0145 
0146 #define SCHEDULER_STRONG_APA_MAXIMUM_PRIORITY 255
0147 
0148 /**
0149  * @brief Entry points for the Strong APA Scheduler.
0150  */
0151 #define SCHEDULER_STRONG_APA_ENTRY_POINTS \
0152   { \
0153     _Scheduler_strong_APA_Initialize, \
0154     _Scheduler_default_Schedule, \
0155     _Scheduler_strong_APA_Yield, \
0156     _Scheduler_strong_APA_Block, \
0157     _Scheduler_strong_APA_Unblock, \
0158     _Scheduler_strong_APA_Update_priority, \
0159     _Scheduler_default_Map_priority, \
0160     _Scheduler_default_Unmap_priority, \
0161     _Scheduler_strong_APA_Ask_for_help, \
0162     _Scheduler_strong_APA_Reconsider_help_request, \
0163     _Scheduler_strong_APA_Withdraw_node, \
0164     _Scheduler_strong_APA_Make_sticky, \
0165     _Scheduler_strong_APA_Clean_sticky, \
0166     _Scheduler_default_Pin_or_unpin_not_supported, \
0167     _Scheduler_default_Pin_or_unpin_not_supported, \
0168     _Scheduler_strong_APA_Add_processor, \
0169     _Scheduler_strong_APA_Remove_processor, \
0170     _Scheduler_strong_APA_Node_initialize, \
0171     _Scheduler_default_Node_destroy, \
0172     _Scheduler_default_Release_job, \
0173     _Scheduler_default_Cancel_job, \
0174     _Scheduler_strong_APA_Start_idle, \
0175     _Scheduler_strong_APA_Set_affinity \
0176   }
0177 
0178 /**
0179  * @brief Initializes the scheduler.
0180  *
0181  * @param scheduler The scheduler to initialize.
0182  */
0183 void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler );
0184 
0185 /**
0186  * @brief Initializes the node with the given priority.
0187  *
0188  * @param scheduler The scheduler control instance.
0189  * @param[out] node The node to initialize.
0190  * @param the_thread The thread of the node to initialize.
0191  * @param priority The priority for @a node.
0192  */
0193 void _Scheduler_strong_APA_Node_initialize(
0194   const Scheduler_Control *scheduler,
0195   Scheduler_Node          *node,
0196   Thread_Control          *the_thread,
0197   Priority_Control         priority
0198 );
0199 
0200 /**
0201  * @brief Blocks the thread.
0202  *
0203  * @param scheduler The scheduler control instance.
0204  * @param[in, out] the_thread The thread to block.
0205  * @param[in, out] node The node of the thread to block.
0206  */
0207 void _Scheduler_strong_APA_Block(
0208   const Scheduler_Control *scheduler,
0209   Thread_Control          *the_thread,
0210   Scheduler_Node          *node
0211 );
0212 
0213 /**
0214  * @brief Unblocks the thread.
0215  *
0216  * @param scheduler The scheduler control instance.
0217  * @param[in, out] the_thread The thread to unblock.
0218  * @param[in, out] node The node of the thread to unblock.
0219  */
0220 void _Scheduler_strong_APA_Unblock(
0221   const Scheduler_Control *scheduler,
0222   Thread_Control          *the_thread,
0223   Scheduler_Node          *node
0224 );
0225 
0226 /**
0227  * @brief Updates the priority of the node.
0228  *
0229  * @param scheduler The scheduler control instance.
0230  * @param the_thread The thread for the operation.
0231  * @param[in, out] node The node to update the priority of.
0232  */
0233 void _Scheduler_strong_APA_Update_priority(
0234   const Scheduler_Control *scheduler,
0235   Thread_Control          *the_thread,
0236   Scheduler_Node          *node
0237 );
0238 
0239 /**
0240  * @brief Asks for help.
0241  *
0242  * @param scheduler The scheduler control instance.
0243  * @param the_thread The thread that asks for help.
0244  * @param node The node of @a the_thread.
0245  *
0246  * @retval true The request for help was successful.
0247  * @retval false The request for help was not successful.
0248  */
0249 bool _Scheduler_strong_APA_Ask_for_help(
0250   const Scheduler_Control *scheduler,
0251   Thread_Control          *the_thread,
0252   Scheduler_Node          *node
0253 );
0254 
0255 /**
0256  * @brief Reconsiders help request.
0257  *
0258  * @param scheduler The scheduler control instance.
0259  * @param the_thread The thread to reconsider the help request of.
0260  * @param[in, out] node The node of @a the_thread
0261  */
0262 void _Scheduler_strong_APA_Reconsider_help_request(
0263   const Scheduler_Control *scheduler,
0264   Thread_Control          *the_thread,
0265   Scheduler_Node          *node
0266 );
0267 
0268 /**
0269  * @brief Withdraws the node.
0270  *
0271  * @param scheduler The scheduler control instance.
0272  * @param[in, out] the_thread The thread to change the state to @a next_state.
0273  * @param[in, out] node The node to withdraw.
0274  * @param next_state The next state for @a the_thread.
0275  */
0276 void _Scheduler_strong_APA_Withdraw_node(
0277   const Scheduler_Control *scheduler,
0278   Thread_Control          *the_thread,
0279   Scheduler_Node          *node,
0280   Thread_Scheduler_state   next_state
0281 );
0282 
0283 /**
0284  * @brief Makes the node sticky.
0285  *
0286  * @param scheduler is the scheduler of the node.
0287  *
0288  * @param[in, out] the_thread is the thread owning the node.
0289  *
0290  * @param[in, out] node is the scheduler node to make sticky.
0291  */
0292 void _Scheduler_strong_APA_Make_sticky(
0293   const Scheduler_Control *scheduler,
0294   Thread_Control          *the_thread,
0295   Scheduler_Node          *node
0296 );
0297 
0298 /**
0299  * @brief Cleans the sticky property from the node.
0300  *
0301  * @param scheduler is the scheduler of the node.
0302  *
0303  * @param[in, out] the_thread is the thread owning the node.
0304  *
0305  * @param[in, out] node is the scheduler node to clean the sticky property.
0306  */
0307 void _Scheduler_strong_APA_Clean_sticky(
0308   const Scheduler_Control *scheduler,
0309   Thread_Control          *the_thread,
0310   Scheduler_Node          *node
0311 );
0312 
0313 /**
0314  * @brief Makes the node sticky.
0315  *
0316  * @param scheduler is the scheduler of the node.
0317  *
0318  * @param[in, out] the_thread is the thread owning the node.
0319  *
0320  * @param[in, out] node is the scheduler node to make sticky.
0321  */
0322 void _Scheduler_strong_APA_Make_sticky(
0323   const Scheduler_Control *scheduler,
0324   Thread_Control          *the_thread,
0325   Scheduler_Node          *node
0326 );
0327 
0328 /**
0329  * @brief Cleans the sticky property from the node.
0330  *
0331  * @param scheduler is the scheduler of the node.
0332  *
0333  * @param[in, out] the_thread is the thread owning the node.
0334  *
0335  * @param[in, out] node is the scheduler node to clean the sticky property.
0336  */
0337 void _Scheduler_strong_APA_sticky(
0338   const Scheduler_Control *scheduler,
0339   Thread_Control          *the_thread,
0340   Scheduler_Node          *node
0341 );
0342 
0343 /**
0344  * @brief Adds the idle thread to a processor.
0345  *
0346  * @param scheduler The scheduler control instance.
0347  * @param[in, out] The idle thread to add to the processor.
0348  */
0349 void _Scheduler_strong_APA_Add_processor(
0350   const Scheduler_Control *scheduler,
0351   Thread_Control          *idle
0352 );
0353 
0354 /**
0355  * @brief Removes an idle thread from the given cpu.
0356  *
0357  * @param scheduler The scheduler instance.
0358  * @param cpu The cpu control to remove from @a scheduler.
0359  *
0360  * @return The idle thread of the processor.
0361  */
0362 Thread_Control *_Scheduler_strong_APA_Remove_processor(
0363   const Scheduler_Control *scheduler,
0364   struct Per_CPU_Control  *cpu
0365 );
0366 
0367 /**
0368  * @brief Performs a yield operation.
0369  *
0370  * @param scheduler The scheduler control instance.
0371  * @param the_thread The thread to yield.
0372  * @param[in, out] node The node of @a the_thread.
0373  */
0374 void _Scheduler_strong_APA_Yield(
0375   const Scheduler_Control *scheduler,
0376   Thread_Control          *the_thread,
0377   Scheduler_Node          *node
0378 );
0379 
0380 /**
0381  * @brief Starts an idle thread.
0382  *
0383  * @param scheduler The scheduler instance.
0384  * @param[in, out] the_thread An idle thread.
0385  * @param cpu The cpu for the operation.
0386  */
0387 void _Scheduler_strong_APA_Start_idle(
0388   const Scheduler_Control *scheduler,
0389   Thread_Control          *idle,
0390   struct Per_CPU_Control  *cpu
0391 );
0392 
0393 /**
0394  * @brief Sets the affinity .
0395  *
0396  * @param scheduler The scheduler control instance.
0397  * @param the_thread The thread to yield.
0398  * @param[in, out] node The node of @a the_thread.
0399  */
0400 Status_Control _Scheduler_strong_APA_Set_affinity(
0401   const Scheduler_Control *scheduler,
0402   Thread_Control          *thread,
0403   Scheduler_Node          *node_base,
0404   const Processor_mask    *affinity
0405 );
0406 
0407 /** @} */
0408 
0409 #ifdef __cplusplus
0410 }
0411 #endif /* __cplusplus */
0412 
0413 #endif /* _RTEMS_SCORE_SCHEDULERSTRONGAPA_H */