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 RTEMSScoreSchedulerPriority
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScoreSchedulerPriority which are only used by the implementation.
0010  */
0011 
0012 /*
0013  *  Copyright (C) 2010 Gedare Bloom.
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_SCHEDULERPRIORITYIMPL_H
0039 #define _RTEMS_SCORE_SCHEDULERPRIORITYIMPL_H
0040 
0041 #include <rtems/score/schedulerpriority.h>
0042 #include <rtems/score/chainimpl.h>
0043 #include <rtems/score/prioritybitmapimpl.h>
0044 #include <rtems/score/scheduleruniimpl.h>
0045 #include <rtems/score/thread.h>
0046 
0047 #ifdef __cplusplus
0048 extern "C" {
0049 #endif
0050 
0051 /**
0052  * @addtogroup RTEMSScoreSchedulerPriority
0053  *
0054  * @{
0055  */
0056 
0057 /**
0058  * @brief Gets the context of the scheduler.
0059  *
0060  * @param scheduler The scheduler to get the context of.
0061  *
0062  * @return The context of the scheduler.
0063  */
0064 static inline Scheduler_priority_Context *
0065   _Scheduler_priority_Get_context( const Scheduler_Control *scheduler )
0066 {
0067   return (Scheduler_priority_Context *) _Scheduler_Get_context( scheduler );
0068 }
0069 
0070 /**
0071  * @brief Gets the scheduler node of the thread.
0072  *
0073  * @param the_thread The thread to get the scheduler node of.
0074  *
0075  * @return The scheduler node of @a the_thread.
0076  */
0077 static inline Scheduler_priority_Node *_Scheduler_priority_Thread_get_node(
0078   Thread_Control *the_thread
0079 )
0080 {
0081   return (Scheduler_priority_Node *) _Thread_Scheduler_get_home_node( the_thread );
0082 }
0083 
0084 /**
0085  * @brief Gets the priority node of the scheduler node.
0086  *
0087  * @param node The node to get the priority node of.
0088  *
0089  * @return The priority node.
0090  */
0091 static inline Scheduler_priority_Node *_Scheduler_priority_Node_downcast(
0092   Scheduler_Node *node
0093 )
0094 {
0095   return (Scheduler_priority_Node *) node;
0096 }
0097 
0098 /**
0099  * @brief Ready queue initialization.
0100  *
0101  * This routine initializes @a ready_queues for priority-based scheduling.
0102  *
0103  * @param[out] ready_queues The ready queue to initialize.
0104  * @param maximum_priority The maximum priority in the ready queue.
0105  */
0106 static inline void _Scheduler_priority_Ready_queue_initialize(
0107   Chain_Control    *ready_queues,
0108   Priority_Control  maximum_priority
0109 )
0110 {
0111   size_t index;
0112 
0113   for ( index = 0 ; index <= (size_t) maximum_priority ; ++index ) {
0114     _Chain_Initialize_empty( &ready_queues[ index ] );
0115   }
0116 }
0117 
0118 /**
0119  * @brief Enqueues a node on the specified ready queue.
0120  *
0121  * The node is placed as the last element of its priority group.
0122  *
0123  * @param node The node to enqueue.
0124  * @param[in, out] ready_queue The ready queue.
0125  * @param[out] bit_map The priority bit map of the scheduler instance.
0126  */
0127 static inline void _Scheduler_priority_Ready_queue_enqueue(
0128   Chain_Node                     *node,
0129   Scheduler_priority_Ready_queue *ready_queue,
0130   Priority_bit_map_Control       *bit_map
0131 )
0132 {
0133   Chain_Control *ready_chain = ready_queue->ready_chain;
0134 
0135   _Chain_Append_unprotected( ready_chain, node );
0136   _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
0137 }
0138 
0139 /**
0140  * @brief Enqueues a node on the specified ready queue as first.
0141  *
0142  * The node is placed as the first element of its priority group.
0143  *
0144  * @param node The node to enqueue as first.
0145  * @param[in, out] ready_queue The ready queue.
0146  * @param[out] bit_map The priority bit map of the scheduler instance.
0147  */
0148 static inline void _Scheduler_priority_Ready_queue_enqueue_first(
0149   Chain_Node                     *node,
0150   Scheduler_priority_Ready_queue *ready_queue,
0151   Priority_bit_map_Control       *bit_map
0152 )
0153 {
0154   Chain_Control *ready_chain = ready_queue->ready_chain;
0155 
0156   _Chain_Prepend_unprotected( ready_chain, node );
0157   _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
0158 }
0159 
0160 /**
0161  * @brief Extracts a node from the specified ready queue.
0162  *
0163  * @param node The node to extract.
0164  * @param[in, out] ready_queue The ready queue.
0165  * @param[out] bit_map The priority bit map of the scheduler instance.
0166  */
0167 static inline void _Scheduler_priority_Ready_queue_extract(
0168   Chain_Node                     *node,
0169   Scheduler_priority_Ready_queue *ready_queue,
0170   Priority_bit_map_Control       *bit_map
0171 )
0172 {
0173   Chain_Control *ready_chain = ready_queue->ready_chain;
0174 
0175   if ( _Chain_Has_only_one_node( ready_chain ) ) {
0176     _Chain_Initialize_empty( ready_chain );
0177     _Chain_Initialize_node( node );
0178     _Priority_bit_map_Remove( bit_map, &ready_queue->Priority_map );
0179   } else {
0180     _Chain_Extract_unprotected( node );
0181   }
0182 }
0183 
0184 /**
0185  * @brief Extracts a node from the context of the scheduler.
0186  *
0187  * @param scheduler The scheduler instance.
0188  * @param the_thread The thread of which the node will be extracted.
0189  * @param[in, out] The node which preserves the ready queue.
0190  */
0191 static inline void _Scheduler_priority_Extract_body(
0192   const Scheduler_Control *scheduler,
0193   Thread_Control          *the_thread,
0194   Scheduler_Node          *node
0195 )
0196 {
0197   Scheduler_priority_Context *context;
0198   Scheduler_priority_Node    *the_node;
0199 
0200   context = _Scheduler_priority_Get_context( scheduler );
0201   the_node = _Scheduler_priority_Node_downcast( node );
0202 
0203   _Scheduler_priority_Ready_queue_extract(
0204     &the_thread->Object.Node,
0205     &the_node->Ready_queue,
0206     &context->Bit_map
0207   );
0208 }
0209 
0210 /**
0211  * @brief Returns a pointer to the first node.
0212  *
0213  * This routines returns a pointer to the first node on @a ready_queues.
0214  *
0215  * @param bit_map The priority bit map of the scheduler instance.
0216  * @param ready_queues The ready queues of the scheduler instance.
0217  *
0218  * @return This method returns the first node.
0219  */
0220 static inline Chain_Node *_Scheduler_priority_Ready_queue_first(
0221   Priority_bit_map_Control *bit_map,
0222   Chain_Control            *ready_queues
0223 )
0224 {
0225   Priority_Control index = _Priority_bit_map_Get_highest( bit_map );
0226   Chain_Node *first = _Chain_First( &ready_queues[ index ] );
0227 
0228   _Assert( first != _Chain_Tail( &ready_queues[ index ] ) );
0229 
0230   return first;
0231 }
0232 
0233 /**
0234  * @brief Gets the highest priority ready thread of the scheduler.
0235  *
0236  * @param scheduler is the scheduler.
0237  */
0238 static inline Thread_Control *_Scheduler_priority_Get_highest_ready(
0239   const Scheduler_Control *scheduler
0240 )
0241 {
0242   Scheduler_priority_Context *context =
0243     _Scheduler_priority_Get_context( scheduler );
0244 
0245   return (Thread_Control *) _Scheduler_priority_Ready_queue_first(
0246     &context->Bit_map,
0247     &context->Ready[ 0 ]
0248   );
0249 }
0250 
0251 /**
0252  * @brief Updates the specified ready queue data according to the new priority
0253  * value.
0254  *
0255  * @param[in, out] ready_queue The ready queue.
0256  * @param new_priority The new priority.
0257  * @param bit_map The priority bit map of the scheduler instance.
0258  * @param ready_queues The ready queues of the scheduler instance.
0259  */
0260 static inline void _Scheduler_priority_Ready_queue_update(
0261   Scheduler_priority_Ready_queue *ready_queue,
0262   unsigned int                    new_priority,
0263   Priority_bit_map_Control       *bit_map,
0264   Chain_Control                  *ready_queues
0265 )
0266 {
0267   ready_queue->current_priority = new_priority;
0268   ready_queue->ready_chain = &ready_queues[ new_priority ];
0269 
0270   _Priority_bit_map_Initialize_information(
0271     bit_map,
0272     &ready_queue->Priority_map,
0273     new_priority
0274   );
0275 }
0276 
0277 /** @} */
0278 
0279 #ifdef __cplusplus
0280 }
0281 #endif
0282 
0283 #endif
0284 /* end of include file */