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 RTEMSScoreSchedulerSMPEDF
0007  *
0008  * @brief This header file provides the interfaces of the
0009  *   @ref RTEMSScoreSchedulerSMPEDF.
0010  */
0011 
0012 /*
0013  * Copyright (C) 2017, 2018 embedded brains GmbH & Co. KG
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #ifndef _RTEMS_SCORE_SCHEDULEREDFSMP_H
0038 #define _RTEMS_SCORE_SCHEDULEREDFSMP_H
0039 
0040 #include <rtems/score/scheduler.h>
0041 #include <rtems/score/scheduleredf.h>
0042 #include <rtems/score/schedulersmp.h>
0043 
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif
0047 
0048 /**
0049  * @defgroup RTEMSScoreSchedulerSMPEDF Earliest Deadline First (EDF) Priority SMP Scheduler
0050  *
0051  * @ingroup RTEMSScoreSchedulerSMP
0052  *
0053  * @brief This group contains the Earliest Deadline First (EDF) Priority SMP
0054  *   Scheduler implementation.
0055  *
0056  * @{
0057  */
0058 
0059 typedef struct {
0060   Scheduler_SMP_Node Base;
0061 
0062   /**
0063    * @brief Generation number to ensure FIFO/LIFO order for threads of the same
0064    * priority across different ready queues.
0065    */
0066   int64_t generation;
0067 
0068   /**
0069    * @brief The ready queue index depending on the processor affinity and
0070    * pinning of the thread.
0071    *
0072    * The ready queue index zero is used for threads with a one-to-all thread
0073    * processor affinity.  Threads with a one-to-one processor affinity use the
0074    * processor index plus one as the ready queue index.
0075    */
0076   uint8_t ready_queue_index;
0077 
0078   /**
0079    * @brief Ready queue index according to thread affinity.
0080    */
0081   uint8_t affinity_ready_queue_index;
0082 
0083   /**
0084    * @brief Ready queue index according to thread pinning.
0085    */
0086   uint8_t pinning_ready_queue_index;
0087 } Scheduler_EDF_SMP_Node;
0088 
0089 typedef struct {
0090   /**
0091    * @brief Chain node for Scheduler_SMP_Context::Affine_queues.
0092    */
0093   Chain_Node Node;
0094 
0095   /**
0096    * @brief The ready threads of the corresponding affinity.
0097    */
0098   RBTree_Control Queue;
0099 
0100   /**
0101    * @brief If this member is not NULL, then it references the scheduled thread
0102    *   affine only to the corresponding processor, otherwise the processor is
0103    *   allocated to a thread which may execute on any of the processors owned
0104    *   by the scheduler.
0105    */
0106   Scheduler_EDF_SMP_Node *affine_scheduled;
0107 
0108   /**
0109    * @brief This member references the thread allocated to the corresponding
0110    *   processor.
0111    */
0112   Scheduler_EDF_SMP_Node *allocated;
0113 } Scheduler_EDF_SMP_Ready_queue;
0114 
0115 typedef struct {
0116   Scheduler_SMP_Context Base;
0117 
0118   /**
0119    * @brief Current generation for LIFO (index 0) and FIFO (index 1) ordering.
0120    */
0121   int64_t generations[ 2 ];
0122 
0123   /**
0124    * @brief Chain of ready queues with affine threads to determine the highest
0125    * priority ready thread.
0126    */
0127   Chain_Control Affine_queues;
0128 
0129   /**
0130    * @brief A table with ready queues.
0131    *
0132    * The index zero queue is used for threads with a one-to-all processor
0133    * affinity.  Index one corresponds to processor index zero, and so on.
0134    */
0135   Scheduler_EDF_SMP_Ready_queue Ready[ RTEMS_ZERO_LENGTH_ARRAY ];
0136 } Scheduler_EDF_SMP_Context;
0137 
0138 #define SCHEDULER_EDF_SMP_ENTRY_POINTS \
0139   { \
0140     _Scheduler_EDF_SMP_Initialize, \
0141     NULL, \
0142     _Scheduler_EDF_SMP_Yield, \
0143     _Scheduler_EDF_SMP_Block, \
0144     _Scheduler_EDF_SMP_Unblock, \
0145     _Scheduler_EDF_SMP_Update_priority, \
0146     _Scheduler_EDF_Map_priority, \
0147     _Scheduler_EDF_Unmap_priority, \
0148     _Scheduler_EDF_SMP_Ask_for_help, \
0149     _Scheduler_EDF_SMP_Reconsider_help_request, \
0150     _Scheduler_EDF_SMP_Withdraw_node, \
0151     _Scheduler_EDF_SMP_Make_sticky, \
0152     _Scheduler_EDF_SMP_Clean_sticky, \
0153     _Scheduler_EDF_SMP_Pin, \
0154     _Scheduler_EDF_SMP_Unpin, \
0155     _Scheduler_EDF_SMP_Add_processor, \
0156     _Scheduler_EDF_SMP_Remove_processor, \
0157     _Scheduler_EDF_SMP_Node_initialize, \
0158     _Scheduler_default_Node_destroy, \
0159     _Scheduler_EDF_Release_job, \
0160     _Scheduler_EDF_Cancel_job, \
0161     _Scheduler_EDF_SMP_Start_idle, \
0162     _Scheduler_EDF_SMP_Set_affinity \
0163   }
0164 
0165 /**
0166  * @brief Initializes the context of the scheduler control.
0167  *
0168  * @param scheduler The scheduler control.
0169  */
0170 void _Scheduler_EDF_SMP_Initialize( const Scheduler_Control *scheduler );
0171 
0172 /**
0173  * @brief Initializes the node with the given priority.
0174  *
0175  * @param scheduler The scheduler instance.
0176  * @param[out] node The node to initialize.
0177  * @param the_thread The thread of the scheduler node.
0178  * @param priority The priority for the initialization.
0179  */
0180 void _Scheduler_EDF_SMP_Node_initialize(
0181   const Scheduler_Control *scheduler,
0182   Scheduler_Node          *node,
0183   Thread_Control          *the_thread,
0184   Priority_Control         priority
0185 );
0186 
0187 /**
0188  * @brief Blocks the thread.
0189  *
0190  * @param scheduler The scheduler instance.
0191  * @param[in, out] the_thread The thread to block.
0192  * @param[in, out] node The @a thread's scheduler node.
0193  */
0194 void _Scheduler_EDF_SMP_Block(
0195   const Scheduler_Control *scheduler,
0196   Thread_Control          *thread,
0197   Scheduler_Node          *node
0198 );
0199 
0200 /**
0201  * @brief Unblocks the thread.
0202  *
0203  * @param scheduler The scheduler instance.
0204  * @param[in, out] the_thread The thread to unblock.
0205  * @param[in, out] node The @a thread's scheduler node.
0206  */
0207 void _Scheduler_EDF_SMP_Unblock(
0208   const Scheduler_Control *scheduler,
0209   Thread_Control          *thread,
0210   Scheduler_Node          *node
0211 );
0212 
0213 /**
0214  * @brief Updates the priority of the node.
0215  *
0216  * @param scheduler The scheduler instance.
0217  * @param the_thread The thread for the operation.
0218  * @param node The thread's scheduler node.
0219  */
0220 void _Scheduler_EDF_SMP_Update_priority(
0221   const Scheduler_Control *scheduler,
0222   Thread_Control          *the_thread,
0223   Scheduler_Node          *node
0224 );
0225 
0226 /**
0227  * @brief Asks for help operation.
0228  *
0229  * @param scheduler The scheduler instance to ask for help.
0230  * @param the_thread The thread needing help.
0231  * @param node The scheduler node.
0232  *
0233  * @retval true Ask for help was successful.
0234  * @retval false Ask for help was not successful.
0235  */
0236 bool _Scheduler_EDF_SMP_Ask_for_help(
0237   const Scheduler_Control *scheduler,
0238   Thread_Control          *the_thread,
0239   Scheduler_Node          *node
0240 );
0241 
0242 /**
0243  * @brief Reconsiders help operation.
0244  *
0245  * @param scheduler The scheduler instance to reconsider the help
0246  *   request.
0247  * @param the_thread The thread reconsidering a help request.
0248  * @param node The scheduler node.
0249  */
0250 void _Scheduler_EDF_SMP_Reconsider_help_request(
0251   const Scheduler_Control *scheduler,
0252   Thread_Control          *the_thread,
0253   Scheduler_Node          *node
0254 );
0255 
0256 /**
0257  * @brief Withdraws node operation.
0258  *
0259  * @param scheduler The scheduler instance to withdraw the node.
0260  * @param the_thread The thread using the node.
0261  * @param node The scheduler node to withdraw.
0262  * @param next_state The next thread scheduler state in case the node is
0263  *   scheduled.
0264  */
0265 void _Scheduler_EDF_SMP_Withdraw_node(
0266   const Scheduler_Control *scheduler,
0267   Thread_Control          *the_thread,
0268   Scheduler_Node          *node,
0269   Thread_Scheduler_state   next_state
0270 );
0271 
0272 /**
0273  * @brief Makes the node sticky.
0274  *
0275  * @param scheduler is the scheduler of the node.
0276  *
0277  * @param[in, out] the_thread is the thread owning the node.
0278  *
0279  * @param[in, out] node is the scheduler node to make sticky.
0280  */
0281 void _Scheduler_EDF_SMP_Make_sticky(
0282   const Scheduler_Control *scheduler,
0283   Thread_Control          *the_thread,
0284   Scheduler_Node          *node
0285 );
0286 
0287 /**
0288  * @brief Cleans the sticky property from the node.
0289  *
0290  * @param scheduler is the scheduler of the node.
0291  *
0292  * @param[in, out] the_thread is the thread owning the node.
0293  *
0294  * @param[in, out] node is the scheduler node to clean the sticky property.
0295  */
0296 void _Scheduler_EDF_SMP_Clean_sticky(
0297   const Scheduler_Control *scheduler,
0298   Thread_Control          *the_thread,
0299   Scheduler_Node          *node
0300 );
0301 
0302 /**
0303  * @brief Pin thread operation.
0304  *
0305  * @param scheduler The scheduler instance of the specified processor.
0306  * @param the_thread The thread to pin.
0307  * @param node The scheduler node of the thread.
0308  * @param cpu The processor to pin the thread.
0309  */
0310 void _Scheduler_EDF_SMP_Pin(
0311   const Scheduler_Control *scheduler,
0312   Thread_Control          *the_thread,
0313   Scheduler_Node          *node,
0314   struct Per_CPU_Control  *cpu
0315 );
0316 
0317 /**
0318  * @brief Unpin thread operation.
0319  *
0320  * @param scheduler The scheduler instance of the specified processor.
0321  * @param the_thread The thread to unpin.
0322  * @param node The scheduler node of the thread.
0323  * @param cpu The processor to unpin the thread.
0324  */
0325 void _Scheduler_EDF_SMP_Unpin(
0326   const Scheduler_Control *scheduler,
0327   Thread_Control          *the_thread,
0328   Scheduler_Node          *node,
0329   struct Per_CPU_Control  *cpu
0330 );
0331 
0332 /**
0333  * @brief Adds processor.
0334  *
0335  * @param[in, out] scheduler The scheduler instance to add the processor to.
0336  * @param idle The idle thread of the processor to add.
0337  */
0338 void _Scheduler_EDF_SMP_Add_processor(
0339   const Scheduler_Control *scheduler,
0340   Thread_Control          *idle
0341 );
0342 
0343 /**
0344  * @brief Removes an idle thread from the given cpu.
0345  *
0346  * @param scheduler The scheduler instance.
0347  * @param cpu The cpu control to remove from @a scheduler.
0348  *
0349  * @return The idle thread of the processor.
0350  */
0351 Thread_Control *_Scheduler_EDF_SMP_Remove_processor(
0352   const Scheduler_Control *scheduler,
0353   struct Per_CPU_Control  *cpu
0354 );
0355 
0356 /**
0357  * @brief Performs the yield of a thread.
0358  *
0359  * @param scheduler The scheduler instance.
0360  * @param[in, out] the_thread The thread that performed the yield operation.
0361  * @param node The scheduler node of @a the_thread.
0362  */
0363 void _Scheduler_EDF_SMP_Yield(
0364   const Scheduler_Control *scheduler,
0365   Thread_Control          *thread,
0366   Scheduler_Node          *node
0367 );
0368 
0369 /**
0370  * @brief Starts an idle thread.
0371  *
0372  * @param scheduler The scheduler instance.
0373  * @param[in, out] the_thread An idle thread.
0374  * @param cpu The cpu for the operation.
0375  */
0376 void _Scheduler_EDF_SMP_Start_idle(
0377   const Scheduler_Control *scheduler,
0378   Thread_Control          *idle,
0379   struct Per_CPU_Control  *cpu
0380 );
0381 
0382 /**
0383  * @brief Checks if the processor set of the scheduler is the subset of the affinity set.
0384  *
0385  * Default implementation of the set affinity scheduler operation.
0386  *
0387  * @param scheduler This parameter is unused.
0388  * @param thread This parameter is unused.
0389  * @param node This parameter is unused.
0390  * @param affinity The new processor affinity set for the thread.
0391  *
0392  * @retval STATUS_SUCCESSFUL The processor set of the scheduler is a subset of
0393  *   the affinity set.
0394  *
0395  * @retval STATUS_INVALID_NUMBER The processor set of the scheduler is not a
0396  *   subset of the affinity set.
0397  */
0398 Status_Control _Scheduler_EDF_SMP_Set_affinity(
0399   const Scheduler_Control *scheduler,
0400   Thread_Control          *thread,
0401   Scheduler_Node          *node,
0402   const Processor_mask    *affinity
0403 );
0404 
0405 /** @} */
0406 
0407 #ifdef __cplusplus
0408 }
0409 #endif
0410 
0411 #endif /* _RTEMS_SCORE_SCHEDULEREDFSMP_H */