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 RTEMSScoreScheduler
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScoreScheduler related to scheduler nodes which are used by the
0010  *   implementation and the @ref RTEMSImplApplConfig.
0011  */
0012 
0013 /*
0014  * Copyright (C) 2014, 2016 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_SCHEDULERNODE_H
0039 #define _RTEMS_SCORE_SCHEDULERNODE_H
0040 
0041 #include <rtems/score/basedefs.h>
0042 #include <rtems/score/chain.h>
0043 #include <rtems/score/priority.h>
0044 #include <rtems/score/isrlock.h>
0045 
0046 /**
0047  * @addtogroup RTEMSScoreScheduler
0048  *
0049  * @{
0050  */
0051 
0052 struct _Thread_Control;
0053 
0054 #ifdef __cplusplus
0055 extern "C" {
0056 #endif /* __cplusplus */
0057 
0058 #if defined(RTEMS_SMP)
0059 /**
0060  * @brief The scheduler node requests.
0061  */
0062 typedef enum {
0063   /**
0064    * @brief The scheduler node is not on the list of pending requests.
0065    */
0066   SCHEDULER_NODE_REQUEST_NOT_PENDING,
0067 
0068   /**
0069    * @brief There is a pending scheduler node request to add this scheduler
0070    * node to the Thread_Control::Scheduler::Scheduler_nodes chain.
0071    */
0072   SCHEDULER_NODE_REQUEST_ADD,
0073 
0074   /**
0075    * @brief There is a pending scheduler node request to remove this scheduler
0076    * node from the Thread_Control::Scheduler::Scheduler_nodes chain.
0077    */
0078   SCHEDULER_NODE_REQUEST_REMOVE,
0079 
0080   /**
0081    * @brief The scheduler node is on the list of pending requests, but nothing
0082    * should change.
0083    */
0084   SCHEDULER_NODE_REQUEST_NOTHING,
0085 
0086 } Scheduler_Node_request;
0087 #endif
0088 
0089 typedef struct Scheduler_Node Scheduler_Node;
0090 
0091 /**
0092  * @brief Scheduler node for per-thread data.
0093  */
0094 struct Scheduler_Node {
0095 #if defined(RTEMS_SMP)
0096   /**
0097    * @brief Chain node for usage in various scheduler data structures.
0098    *
0099    * Strictly, this is the wrong place for this field since the data structures
0100    * to manage scheduler nodes belong to the particular scheduler
0101    * implementation.  Currently, all SMP scheduler implementations use chains
0102    * or red-black trees.  The node is here to simplify things, just like the
0103    * object node in the thread control block.
0104    */
0105   union {
0106     Chain_Node Chain;
0107     RBTree_Node RBTree;
0108   } Node;
0109 
0110   /**
0111    * @brief The sticky level determines if this scheduler node should use an
0112    * idle thread in case this node is scheduled and the owner thread is
0113    * blocked.
0114    */
0115   int sticky_level;
0116 
0117   /**
0118    * @brief The thread using this node.
0119    *
0120    * This is either the owner or an idle thread.
0121    */
0122   struct _Thread_Control *user;
0123 
0124   /**
0125    * @brief The idle thread claimed by this node in case the sticky level is
0126    * greater than zero and the thread is block or is scheduled on another
0127    * scheduler instance.
0128    *
0129    * This is necessary to ensure the priority ceiling protocols work across
0130    * scheduler boundaries.
0131    */
0132   struct _Thread_Control *idle;
0133 #endif
0134 
0135   /**
0136    * @brief The thread owning this node.
0137    */
0138   struct _Thread_Control *owner;
0139 
0140 #if defined(RTEMS_SMP)
0141   /**
0142    * @brief Block to register and manage this scheduler node in the thread
0143    * control block of the owner of this scheduler node.
0144    */
0145   struct {
0146     /**
0147      * @brief Node to add this scheduler node to
0148      * Thread_Control::Scheduler::Wait_nodes.
0149      */
0150     Chain_Node Wait_node;
0151 
0152     /**
0153      * @brief Node to add this scheduler node to
0154      * Thread_Control::Scheduler::Scheduler_nodes or a temporary remove list.
0155      */
0156     union {
0157       /**
0158        * @brief The node for Thread_Control::Scheduler::Scheduler_nodes.
0159        */
0160       Chain_Node Chain;
0161 
0162       /**
0163        * @brief The next pointer for a temporary remove list.
0164        *
0165        * @see _Thread_Scheduler_process_requests().
0166        */
0167       Scheduler_Node *next;
0168     } Scheduler_node;
0169 
0170     /**
0171      * @brief Link to the next scheduler node in the
0172      * Thread_Control::Scheduler::requests list.
0173      */
0174     Scheduler_Node *next_request;
0175 
0176     /**
0177      * @brief The current scheduler node request.
0178      */
0179     Scheduler_Node_request request;
0180   } Thread;
0181 #endif
0182 
0183   /**
0184    * @brief Thread wait support block.
0185    */
0186   struct {
0187     Priority_Aggregation Priority;
0188   } Wait;
0189 
0190   /**
0191    * @brief The thread priority information used by the scheduler.
0192    *
0193    * The thread priority is manifest in two independent areas.  One area is the
0194    * user visible thread priority along with a potential thread queue.  The
0195    * other is the scheduler.  During a thread priority change, the user visible
0196    * thread priority and the thread queue are first updated and the thread
0197    * priority value here is changed.  Once this is done the scheduler is
0198    * notified via the update priority operation, so that it can update its
0199    * internal state and honour a new thread priority value.
0200    */
0201   struct {
0202     /**
0203      * @brief The thread priority value of this scheduler node.
0204      *
0205      * The producer of this value is _Thread_Change_priority().  The consumer
0206      * is the scheduler via the unblock and update priority operations.
0207      *
0208      * This priority control consists of two parts.  One part is the plain
0209      * priority value (most-significant 63 bits).  The other part is the
0210      * least-significant bit which indicates if the thread should be appended
0211      * (bit set) or prepended (bit cleared) to its priority group, see
0212      * SCHEDULER_PRIORITY_APPEND().
0213      *
0214      * @see _Scheduler_Node_get_priority() and _Scheduler_Node_set_priority().
0215      */
0216 #if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8
0217     Atomic_Ulong value;
0218 #else
0219     Priority_Control value;
0220 #endif
0221 
0222 #if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER != 8
0223     /**
0224      * @brief The lock protects the priority value.
0225      */
0226     ISR_lock_Control Lock;
0227 #endif
0228   } Priority;
0229 };
0230 
0231 #if defined(RTEMS_SMP)
0232 /**
0233  * @brief The size of a scheduler node.
0234  *
0235  * This value is provided via <rtems/confdefs.h>.
0236  */
0237 extern const size_t _Scheduler_Node_size;
0238 #endif
0239 
0240 #if defined(RTEMS_SMP)
0241 #define SCHEDULER_NODE_OF_THREAD_WAIT_NODE( node ) \
0242   RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Wait_node )
0243 
0244 #define SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ) \
0245   RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Scheduler_node.Chain )
0246 #endif
0247 
0248 #ifdef __cplusplus
0249 }
0250 #endif /* __cplusplus */
0251 
0252 /** @} */
0253 
0254 #endif /* _RTEMS_SCORE_SCHEDULERNODE_H */