source: rtems/cpukit/include/rtems/score/schedulernodeimpl.h @ 7b85efb8

Last change on this file since 7b85efb8 was 7b85efb8, checked in by Joel Sherrill <joel@…>, on 02/16/22 at 21:16:11

cpukit/include/rtems/score/[s-z]*.h: Change license to BSD-2

Updates #3053.

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