source: rtems/cpukit/include/rtems/score/schedulernodeimpl.h

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 7.7 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreScheduler
7 *
8 * @brief This header file provides interfaces of the
9 *   @ref RTEMSScoreScheduler related to scheduler nodes which are only used by
10 *   the implementation.
11 */
12
13/*
14 * Copyright (C) 2014, 2017 embedded brains GmbH & Co. KG
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef _RTEMS_SCORE_SCHEDULERNODEIMPL_H
39#define _RTEMS_SCORE_SCHEDULERNODEIMPL_H
40
41#include <rtems/score/schedulernode.h>
42#include <rtems/score/priorityimpl.h>
43
44/**
45 * @addtogroup RTEMSScoreScheduler
46 *
47 * @{
48 */
49
50struct _Scheduler_Control;
51
52#ifdef __cplusplus
53extern "C" {
54#endif /* __cplusplus */
55
56#define SCHEDULER_NODE_OF_WAIT_PRIORITY_NODE( node ) \
57  RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Priority.Node.Node.Chain )
58
59#define SCHEDULER_NODE_OF_WAIT_PRIORITY( node ) \
60  RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Priority )
61
62/**
63 * @brief Maps a priority value to support the append indicator.
64 */
65#define SCHEDULER_PRIORITY_MAP( priority ) ( ( priority ) << 1 )
66
67/**
68 * @brief Returns the plain priority value.
69 */
70#define SCHEDULER_PRIORITY_UNMAP( priority ) ( ( priority ) >> 1 )
71
72/**
73 * @brief Clears the priority append indicator bit.
74 */
75#define SCHEDULER_PRIORITY_PURIFY( priority )  \
76  ( ( priority ) & ~( (Priority_Control) PRIORITY_GROUP_LAST ) )
77
78/**
79 * @brief Returns the priority control with the append indicator bit set.
80 */
81#define SCHEDULER_PRIORITY_APPEND( priority )  \
82  ( ( priority ) | ( (Priority_Control) PRIORITY_GROUP_LAST ) )
83
84/**
85 * @brief Returns true, if the item should be appended to its priority group,
86 * otherwise returns false and the item should be prepended to its priority
87 * group.
88 */
89#define SCHEDULER_PRIORITY_IS_APPEND( priority ) \
90  ( ( ( priority ) & ( (Priority_Control) PRIORITY_GROUP_LAST ) ) != 0 )
91
92/**
93 * @brief Initializes the node.
94 *
95 * @param scheduler is the scheduler of the node.
96 *
97 * @param[out] node is the node to initialize.
98 *
99 * @param[in, out] the_thread is the thread of the node.
100 *
101 * @param priority is the initial priority of the node.
102 */
103static inline void _Scheduler_Node_do_initialize(
104  const struct _Scheduler_Control *scheduler,
105  Scheduler_Node                  *node,
106  Thread_Control                  *the_thread,
107  Priority_Control                 priority
108)
109{
110  node->owner = the_thread;
111
112  node->Priority.value = priority;
113
114#if defined(RTEMS_SMP)
115  _Chain_Initialize_node( &node->Thread.Wait_node );
116  node->Wait.Priority.scheduler = scheduler;
117  node->user = the_thread;
118  node->idle = NULL;
119#if CPU_SIZEOF_POINTER != 8
120  _ISR_lock_Initialize( &node->Priority.Lock, "Scheduler Node Priority" );
121#endif
122#else
123  (void) scheduler;
124  (void) the_thread;
125#endif
126}
127
128/**
129 * @brief Destroys the node.
130 *
131 * @param scheduler is the scheduler of the node.
132 *
133 * @param[in, out] node is the node to destroy.
134 */
135static inline void _Scheduler_Node_do_destroy(
136  const struct _Scheduler_Control *scheduler,
137  Scheduler_Node                  *node
138)
139{
140  (void) scheduler;
141
142#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER != 8
143  _ISR_lock_Destroy( &node->Priority.Lock );
144#else
145  (void) node;
146#endif
147}
148
149/**
150 * @brief Gets the scheduler of the node.
151 *
152 * @param node The node to get the scheduler of.
153 *
154 * @return The scheduler of the node.
155 */
156static inline const Scheduler_Control *_Scheduler_Node_get_scheduler(
157  const Scheduler_Node *node
158)
159{
160  return _Priority_Get_scheduler( &node->Wait.Priority );
161}
162
163/**
164 * @brief Gets the owner of the node.
165 *
166 * @param node The node to get the owner of.
167 *
168 * @return The owner of the node.
169 */
170static inline Thread_Control *_Scheduler_Node_get_owner(
171  const Scheduler_Node *node
172)
173{
174  return node->owner;
175}
176
177/**
178 * @brief Gets the priority of the node.
179 *
180 * @param node The node to get the priority of.
181 *
182 * @return The priority of the node.
183 */
184static inline Priority_Control _Scheduler_Node_get_priority(
185  Scheduler_Node *node
186)
187{
188  Priority_Control priority;
189
190#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8
191  priority = _Atomic_Fetch_add_ulong(
192    &node->Priority.value,
193    0,
194    ATOMIC_ORDER_RELAXED
195  );
196#else
197  ISR_lock_Context lock_context;
198
199  _ISR_lock_Acquire( &node->Priority.Lock, &lock_context );
200  priority = node->Priority.value;
201  _ISR_lock_Release( &node->Priority.Lock, &lock_context );
202#endif
203
204  return priority;
205}
206
207/**
208 * @brief Sets the priority of the node.
209 *
210 * @param[in, out] node is the scheduler node.
211 *
212 * @param new_priority is the priority to set.
213 *
214 * @param group_order is the priority group order, see #PRIORITY_GROUP_FIRST
215 *   and #PRIORITY_GROUP_LAST.
216 */
217static inline void _Scheduler_Node_set_priority(
218  Scheduler_Node      *node,
219  Priority_Control     new_priority,
220  Priority_Group_order group_order
221)
222{
223#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8
224  _Atomic_Store_ulong(
225    &node->Priority.value,
226    new_priority | (Priority_Control) group_order,
227    ATOMIC_ORDER_RELAXED
228  );
229#else
230  ISR_lock_Context lock_context;
231
232  _ISR_lock_Acquire( &node->Priority.Lock, &lock_context );
233  node->Priority.value = new_priority | ( (Priority_Control) group_order );
234  _ISR_lock_Release( &node->Priority.Lock, &lock_context );
235#endif
236}
237
238#if defined(RTEMS_SMP)
239/**
240 * @brief Gets the user of the node.
241 *
242 * @param node The node to get the user of.
243 *
244 * @return The user of the node.
245 */
246static inline Thread_Control *_Scheduler_Node_get_user(
247  const Scheduler_Node *node
248)
249{
250  return node->user;
251}
252
253/**
254 * @brief Sets the user of the node.
255 *
256 * @param[out] node The node to set the user of.
257 * @param user The new user for @a node.
258 */
259static inline void _Scheduler_Node_set_user(
260  Scheduler_Node *node,
261  Thread_Control *user
262)
263{
264  node->user = user;
265}
266
267/**
268 * @brief Gets the idle thread of the node.
269 *
270 * @param node The node to get the idle thread of.
271 *
272 * @return The idle thread of @a node.
273 */
274static inline Thread_Control *_Scheduler_Node_get_idle(
275  const Scheduler_Node *node
276)
277{
278  return node->idle;
279}
280
281/**
282 * @brief Sets the scheduler node's user to the idle thread.
283 *
284 * @param[in, out] node is the node to receive an idle thread.
285 *
286 * @param idle is the idle thread to use.
287 */
288static inline void _Scheduler_Node_set_idle_user(
289  Scheduler_Node *node,
290  Thread_Control *idle
291)
292{
293  _Assert( _Scheduler_Node_get_idle( node ) == NULL );
294  _Assert(
295    _Scheduler_Node_get_owner( node ) == _Scheduler_Node_get_user( node )
296  );
297
298  _Scheduler_Node_set_user( node, idle );
299  node->idle = idle;
300}
301#endif
302
303#ifdef __cplusplus
304}
305#endif /* __cplusplus */
306
307/** @} */
308
309#endif /* _RTEMS_SCORE_SCHEDULERNODEIMPL_H */
Note: See TracBrowser for help on using the repository browser.