Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreSchedulerPrioritySMP
0007  *
0008  * @brief This source file contains the implementation of
0009  *   _Scheduler_priority_SMP_Add_processor(),
0010  *   _Scheduler_priority_SMP_Ask_for_help(), _Scheduler_priority_SMP_Block(),
0011  *   _Scheduler_priority_SMP_Initialize(),
0012  *   _Scheduler_priority_SMP_Node_initialize(),
0013  *   _Scheduler_priority_SMP_Reconsider_help_request(),
0014  *   _Scheduler_priority_SMP_Remove_processor(),
0015  *   _Scheduler_priority_SMP_Unblock(),
0016  *   _Scheduler_priority_SMP_Update_priority(),
0017  *   _Scheduler_priority_SMP_Withdraw_node(),
0018  *   _Scheduler_priority_SMP_Make_sticky(),
0019  *   _Scheduler_priority_SMP_Clean_sticky(), and
0020  *   _Scheduler_priority_SMP_Yield().
0021  */
0022 
0023 /*
0024  * Copyright (C) 2013, 2014 embedded brains GmbH & Co. KG
0025  *
0026  * Redistribution and use in source and binary forms, with or without
0027  * modification, are permitted provided that the following conditions
0028  * are met:
0029  * 1. Redistributions of source code must retain the above copyright
0030  *    notice, this list of conditions and the following disclaimer.
0031  * 2. Redistributions in binary form must reproduce the above copyright
0032  *    notice, this list of conditions and the following disclaimer in the
0033  *    documentation and/or other materials provided with the distribution.
0034  *
0035  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0036  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0037  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0038  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0039  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0040  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0041  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0042  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0043  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0044  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0045  * POSSIBILITY OF SUCH DAMAGE.
0046  */
0047 
0048 #ifdef HAVE_CONFIG_H
0049 #include "config.h"
0050 #endif
0051 
0052 #include <rtems/score/schedulerprioritysmpimpl.h>
0053 
0054 static Scheduler_priority_SMP_Context *
0055 _Scheduler_priority_SMP_Get_context( const Scheduler_Control *scheduler )
0056 {
0057   return (Scheduler_priority_SMP_Context *) _Scheduler_Get_context( scheduler );
0058 }
0059 
0060 void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
0061 {
0062   Scheduler_priority_SMP_Context *self =
0063     _Scheduler_priority_SMP_Get_context( scheduler );
0064 
0065   _Scheduler_SMP_Initialize( &self->Base );
0066   self->idle_ready_queue = &self->Ready[ scheduler->maximum_priority ];
0067   _Priority_bit_map_Initialize( &self->Bit_map );
0068   _Scheduler_priority_Ready_queue_initialize(
0069     &self->Ready[ 0 ],
0070     scheduler->maximum_priority
0071   );
0072 }
0073 
0074 void _Scheduler_priority_SMP_Node_initialize(
0075   const Scheduler_Control *scheduler,
0076   Scheduler_Node          *node,
0077   Thread_Control          *the_thread,
0078   Priority_Control         priority
0079 )
0080 {
0081   Scheduler_Context              *context;
0082   Scheduler_priority_SMP_Context *self;
0083   Scheduler_priority_SMP_Node    *the_node;
0084 
0085   the_node = _Scheduler_priority_SMP_Node_downcast( node );
0086   _Scheduler_SMP_Node_initialize(
0087     scheduler,
0088     &the_node->Base,
0089     the_thread,
0090     priority
0091   );
0092 
0093   context = _Scheduler_Get_context( scheduler );
0094   self = _Scheduler_priority_SMP_Get_self( context );
0095   _Scheduler_priority_Ready_queue_update(
0096     &the_node->Ready_queue,
0097     SCHEDULER_PRIORITY_UNMAP( priority ),
0098     &self->Bit_map,
0099     &self->Ready[ 0 ]
0100   );
0101 }
0102 
0103 static Scheduler_Node *_Scheduler_priority_SMP_Get_highest_ready(
0104   Scheduler_Context *context,
0105   Scheduler_Node    *node
0106 )
0107 {
0108   Scheduler_priority_SMP_Context *self =
0109     _Scheduler_priority_SMP_Get_self( context );
0110 
0111   (void) node;
0112 
0113   return (Scheduler_Node *) _Scheduler_priority_Ready_queue_first(
0114     &self->Bit_map,
0115     &self->Ready[ 0 ]
0116   );
0117 }
0118 
0119 void _Scheduler_priority_SMP_Block(
0120   const Scheduler_Control *scheduler,
0121   Thread_Control          *thread,
0122   Scheduler_Node          *node
0123 )
0124 {
0125   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0126 
0127   _Scheduler_SMP_Block(
0128     context,
0129     thread,
0130     node,
0131     _Scheduler_SMP_Extract_from_scheduled,
0132     _Scheduler_priority_SMP_Extract_from_ready,
0133     _Scheduler_priority_SMP_Get_highest_ready,
0134     _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
0135     _Scheduler_SMP_Allocate_processor_lazy,
0136     _Scheduler_priority_SMP_Get_idle
0137   );
0138 }
0139 
0140 static bool _Scheduler_priority_SMP_Enqueue(
0141   Scheduler_Context *context,
0142   Scheduler_Node    *node,
0143   Priority_Control   insert_priority
0144 )
0145 {
0146   return _Scheduler_SMP_Enqueue(
0147     context,
0148     node,
0149     insert_priority,
0150     _Scheduler_SMP_Priority_less_equal,
0151     _Scheduler_priority_SMP_Insert_ready,
0152     _Scheduler_SMP_Insert_scheduled,
0153     _Scheduler_priority_SMP_Move_from_scheduled_to_ready,
0154     _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
0155     _Scheduler_SMP_Get_lowest_scheduled,
0156     _Scheduler_SMP_Allocate_processor_lazy,
0157     _Scheduler_priority_SMP_Get_idle,
0158     _Scheduler_priority_SMP_Release_idle
0159   );
0160 }
0161 
0162 static void _Scheduler_priority_SMP_Enqueue_scheduled(
0163   Scheduler_Context *context,
0164   Scheduler_Node    *node,
0165   Priority_Control   insert_priority
0166 )
0167 {
0168   _Scheduler_SMP_Enqueue_scheduled(
0169     context,
0170     node,
0171     insert_priority,
0172     _Scheduler_SMP_Priority_less_equal,
0173     _Scheduler_priority_SMP_Extract_from_ready,
0174     _Scheduler_priority_SMP_Get_highest_ready,
0175     _Scheduler_priority_SMP_Insert_ready,
0176     _Scheduler_SMP_Insert_scheduled,
0177     _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
0178     _Scheduler_SMP_Allocate_processor_lazy,
0179     _Scheduler_priority_SMP_Get_idle,
0180     _Scheduler_priority_SMP_Release_idle
0181   );
0182 }
0183 
0184 void _Scheduler_priority_SMP_Unblock(
0185   const Scheduler_Control *scheduler,
0186   Thread_Control          *thread,
0187   Scheduler_Node          *node
0188 )
0189 {
0190   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0191 
0192   _Scheduler_SMP_Unblock(
0193     context,
0194     thread,
0195     node,
0196     _Scheduler_priority_SMP_Do_update,
0197     _Scheduler_priority_SMP_Enqueue,
0198     _Scheduler_priority_SMP_Release_idle
0199   );
0200 }
0201 
0202 static bool _Scheduler_priority_SMP_Do_ask_for_help(
0203   Scheduler_Context *context,
0204   Thread_Control    *the_thread,
0205   Scheduler_Node    *node
0206 )
0207 {
0208   return _Scheduler_SMP_Ask_for_help(
0209     context,
0210     the_thread,
0211     node,
0212     _Scheduler_SMP_Priority_less_equal,
0213     _Scheduler_priority_SMP_Insert_ready,
0214     _Scheduler_SMP_Insert_scheduled,
0215     _Scheduler_priority_SMP_Move_from_scheduled_to_ready,
0216     _Scheduler_SMP_Get_lowest_scheduled,
0217     _Scheduler_SMP_Allocate_processor_lazy,
0218     _Scheduler_priority_SMP_Release_idle
0219   );
0220 }
0221 
0222 void _Scheduler_priority_SMP_Update_priority(
0223   const Scheduler_Control *scheduler,
0224   Thread_Control          *thread,
0225   Scheduler_Node          *node
0226 )
0227 {
0228   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0229 
0230   _Scheduler_SMP_Update_priority(
0231     context,
0232     thread,
0233     node,
0234     _Scheduler_SMP_Extract_from_scheduled,
0235     _Scheduler_priority_SMP_Extract_from_ready,
0236     _Scheduler_priority_SMP_Do_update,
0237     _Scheduler_priority_SMP_Enqueue,
0238     _Scheduler_priority_SMP_Enqueue_scheduled,
0239     _Scheduler_priority_SMP_Do_ask_for_help
0240   );
0241 }
0242 
0243 bool _Scheduler_priority_SMP_Ask_for_help(
0244   const Scheduler_Control *scheduler,
0245   Thread_Control          *the_thread,
0246   Scheduler_Node          *node
0247 )
0248 {
0249   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0250 
0251   return _Scheduler_priority_SMP_Do_ask_for_help( context, the_thread, node );
0252 }
0253 
0254 void _Scheduler_priority_SMP_Reconsider_help_request(
0255   const Scheduler_Control *scheduler,
0256   Thread_Control          *the_thread,
0257   Scheduler_Node          *node
0258 )
0259 {
0260   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0261 
0262   _Scheduler_SMP_Reconsider_help_request(
0263     context,
0264     the_thread,
0265     node,
0266     _Scheduler_priority_SMP_Extract_from_ready
0267   );
0268 }
0269 
0270 void _Scheduler_priority_SMP_Withdraw_node(
0271   const Scheduler_Control *scheduler,
0272   Thread_Control          *the_thread,
0273   Scheduler_Node          *node,
0274   Thread_Scheduler_state   next_state
0275 )
0276 {
0277   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0278 
0279   _Scheduler_SMP_Withdraw_node(
0280     context,
0281     the_thread,
0282     node,
0283     next_state,
0284     _Scheduler_SMP_Extract_from_scheduled,
0285     _Scheduler_priority_SMP_Extract_from_ready,
0286     _Scheduler_priority_SMP_Get_highest_ready,
0287     _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
0288     _Scheduler_SMP_Allocate_processor_lazy,
0289     _Scheduler_priority_SMP_Get_idle
0290   );
0291 }
0292 
0293 void _Scheduler_priority_SMP_Make_sticky(
0294   const Scheduler_Control *scheduler,
0295   Thread_Control          *the_thread,
0296   Scheduler_Node          *node
0297 )
0298 {
0299   _Scheduler_SMP_Make_sticky(
0300     scheduler,
0301     the_thread,
0302     node,
0303     _Scheduler_priority_SMP_Do_update,
0304     _Scheduler_priority_SMP_Enqueue
0305   );
0306 }
0307 
0308 void _Scheduler_priority_SMP_Clean_sticky(
0309   const Scheduler_Control *scheduler,
0310   Thread_Control          *the_thread,
0311   Scheduler_Node          *node
0312 )
0313 {
0314   _Scheduler_SMP_Clean_sticky(
0315     scheduler,
0316     the_thread,
0317     node,
0318     _Scheduler_SMP_Extract_from_scheduled,
0319     _Scheduler_priority_SMP_Extract_from_ready,
0320     _Scheduler_priority_SMP_Get_highest_ready,
0321     _Scheduler_priority_SMP_Move_from_ready_to_scheduled,
0322     _Scheduler_SMP_Allocate_processor_lazy,
0323     _Scheduler_priority_SMP_Get_idle,
0324     _Scheduler_priority_SMP_Release_idle
0325   );
0326 }
0327 
0328 void _Scheduler_priority_SMP_Add_processor(
0329   const Scheduler_Control *scheduler,
0330   Thread_Control          *idle
0331 )
0332 {
0333   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0334 
0335   _Scheduler_SMP_Add_processor(
0336     context,
0337     idle,
0338     _Scheduler_priority_SMP_Has_ready,
0339     _Scheduler_priority_SMP_Enqueue_scheduled,
0340     _Scheduler_SMP_Do_nothing_register_idle
0341   );
0342 }
0343 
0344 Thread_Control *_Scheduler_priority_SMP_Remove_processor(
0345   const Scheduler_Control *scheduler,
0346   Per_CPU_Control         *cpu
0347 )
0348 {
0349   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0350 
0351   return _Scheduler_SMP_Remove_processor(
0352     context,
0353     cpu,
0354     _Scheduler_SMP_Extract_from_scheduled,
0355     _Scheduler_priority_SMP_Extract_from_ready,
0356     _Scheduler_priority_SMP_Enqueue,
0357     _Scheduler_priority_SMP_Get_idle,
0358     _Scheduler_priority_SMP_Release_idle
0359   );
0360 }
0361 
0362 void _Scheduler_priority_SMP_Yield(
0363   const Scheduler_Control *scheduler,
0364   Thread_Control          *thread,
0365   Scheduler_Node          *node
0366 )
0367 {
0368   Scheduler_Context *context = _Scheduler_Get_context( scheduler );
0369 
0370   _Scheduler_SMP_Yield(
0371     context,
0372     thread,
0373     node,
0374     _Scheduler_SMP_Extract_from_scheduled,
0375     _Scheduler_priority_SMP_Extract_from_ready,
0376     _Scheduler_priority_SMP_Enqueue,
0377     _Scheduler_priority_SMP_Enqueue_scheduled
0378   );
0379 }