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 RTEMSScoreSchedulerEDF
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScoreSchedulerEDF which are only used by the implementation.
0010  */
0011 
0012 /*
0013  *  Copryight (c) 2011 Petr Benes.
0014  *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
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_SCHEDULEREDFIMPL_H
0039 #define _RTEMS_SCORE_SCHEDULEREDFIMPL_H
0040 
0041 #include <rtems/score/scheduleredf.h>
0042 #include <rtems/score/scheduleruniimpl.h>
0043 
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif
0047 
0048 /**
0049  * @addtogroup RTEMSScoreSchedulerEDF
0050  *
0051  * @{
0052  */
0053 
0054 /**
0055  * This is just a most significant bit of Priority_Control type. It
0056  * distinguishes threads which are deadline driven (priority
0057  * represented by a lower number than @a SCHEDULER_EDF_PRIO_MSB) from those
0058  * ones who do not have any deadlines and thus are considered background
0059  * tasks.
0060  */
0061 #define SCHEDULER_EDF_PRIO_MSB 0x8000000000000000
0062 
0063 /**
0064  * @brief Gets the context of the scheduler.
0065  *
0066  * @param scheduler The scheduler instance.
0067  *
0068  * @return The scheduler context of @a scheduler.
0069  */
0070 static inline Scheduler_EDF_Context *
0071   _Scheduler_EDF_Get_context( const Scheduler_Control *scheduler )
0072 {
0073   return (Scheduler_EDF_Context *) _Scheduler_Get_context( scheduler );
0074 }
0075 
0076 /**
0077  * @brief Gets the scheduler EDF node of the thread.
0078  *
0079  * @param the_thread The thread to get the scheduler node of.
0080  *
0081  * @return The EDF scheduler node of @a the_thread.
0082  */
0083 static inline Scheduler_EDF_Node *_Scheduler_EDF_Thread_get_node(
0084   Thread_Control *the_thread
0085 )
0086 {
0087   return (Scheduler_EDF_Node *) _Thread_Scheduler_get_home_node( the_thread );
0088 }
0089 
0090 /**
0091  * @brief Returns the scheduler EDF node for the scheduler node.
0092  *
0093  * @param node The scheduler node of which the scheduler EDF node is returned.
0094  *
0095  * @return The corresponding scheduler EDF node.
0096  */
0097 static inline Scheduler_EDF_Node * _Scheduler_EDF_Node_downcast(
0098   Scheduler_Node *node
0099 )
0100 {
0101   return (Scheduler_EDF_Node *) node;
0102 }
0103 
0104 /**
0105  * @brief Checks if @a left is less than the priority of the node @a right.
0106  *
0107  * @param left The priority on the left hand side of the comparison.
0108  * @param right The node of which the priority is compared to left.
0109  *
0110  * @retval true @a left is less than the priority of @a right.
0111  * @retval false @a left is greater or equal than the priority of @a right.
0112  */
0113 static inline bool _Scheduler_EDF_Less(
0114   const void        *left,
0115   const RBTree_Node *right
0116 )
0117 {
0118   const Priority_Control   *the_left;
0119   const Scheduler_EDF_Node *the_right;
0120   Priority_Control          prio_left;
0121   Priority_Control          prio_right;
0122 
0123   the_left = (const Priority_Control *) left;
0124   the_right = RTEMS_CONTAINER_OF( right, Scheduler_EDF_Node, Node );
0125 
0126   prio_left = *the_left;
0127   prio_right = the_right->priority;
0128 
0129   return prio_left < prio_right;
0130 }
0131 
0132 /**
0133  * @brief Checks if @a left is less or equal than the priority of the node @a right.
0134  *
0135  * @param left The priority on the left hand side of the comparison.
0136  * @param right The node of which the priority is compared to left.
0137  *
0138  * @retval true @a left is less or equal than the priority of @a right.
0139  * @retval false @a left is greater than the priority of @a right.
0140  */
0141 static inline bool _Scheduler_EDF_Priority_less_equal(
0142   const void        *left,
0143   const RBTree_Node *right
0144 )
0145 {
0146   const Priority_Control   *the_left;
0147   const Scheduler_EDF_Node *the_right;
0148   Priority_Control          prio_left;
0149   Priority_Control          prio_right;
0150 
0151   the_left = (const Priority_Control *) left;
0152   the_right = RTEMS_CONTAINER_OF( right, Scheduler_EDF_Node, Node );
0153 
0154   prio_left = *the_left;
0155   prio_right = the_right->priority;
0156 
0157   return prio_left <= prio_right;
0158 }
0159 
0160 /**
0161  * @brief Inserts the scheduler node with the given priority in the ready
0162  *      queue of the context.
0163  *
0164  * @param[in, out] context The context to insert the node in.
0165  * @param node The node to be inserted.
0166  * @param insert_priority The priority with which the node will be inserted.
0167  */
0168 static inline void _Scheduler_EDF_Enqueue(
0169   Scheduler_EDF_Context *context,
0170   Scheduler_EDF_Node    *node,
0171   Priority_Control       insert_priority
0172 )
0173 {
0174   _RBTree_Insert_inline(
0175     &context->Ready,
0176     &node->Node,
0177     &insert_priority,
0178     _Scheduler_EDF_Priority_less_equal
0179   );
0180 }
0181 
0182 /**
0183  * @brief Extracts the scheduler node from the ready queue of the context.
0184  *
0185  * @param[in, out] context The context to extract the node from.
0186  * @param[in, out] node The node to extract.
0187  */
0188 static inline void _Scheduler_EDF_Extract(
0189   Scheduler_EDF_Context *context,
0190   Scheduler_EDF_Node    *node
0191 )
0192 {
0193   _RBTree_Extract( &context->Ready, &node->Node );
0194 }
0195 
0196 /**
0197  * @brief Extracts the node from the context of the given scheduler.
0198  *
0199  * @param scheduler The scheduler instance.
0200  * @param the_thread The thread is not used in this method.
0201  * @param[in, out] node The node to be extracted.
0202  */
0203 static inline void _Scheduler_EDF_Extract_body(
0204   const Scheduler_Control *scheduler,
0205   Thread_Control          *the_thread,
0206   Scheduler_Node          *node
0207 )
0208 {
0209   Scheduler_EDF_Context *context;
0210   Scheduler_EDF_Node    *the_node;
0211 
0212   context = _Scheduler_EDF_Get_context( scheduler );
0213   the_node = _Scheduler_EDF_Node_downcast( node );
0214 
0215   _Scheduler_EDF_Extract( context, the_node );
0216 }
0217 
0218 /**
0219  * @brief Gets the highest priority ready thread of the scheduler.
0220  *
0221  * @param scheduler is the scheduler.
0222  */
0223 static inline Thread_Control *_Scheduler_EDF_Get_highest_ready(
0224   const Scheduler_Control *scheduler
0225 )
0226 {
0227   Scheduler_EDF_Context *context;
0228   RBTree_Node           *first;
0229   Scheduler_EDF_Node    *node;
0230 
0231   context = _Scheduler_EDF_Get_context( scheduler );
0232   first = _RBTree_Minimum( &context->Ready );
0233   node = RTEMS_CONTAINER_OF( first, Scheduler_EDF_Node, Node );
0234 
0235   return node->Base.owner;
0236 }
0237 
0238 /** @} */
0239 
0240 #ifdef __cplusplus
0241 }
0242 #endif
0243 
0244 #endif
0245 /* end of include file */