diff options
Diffstat (limited to 'cpukit/include/rtems/score/schedulernodeimpl.h')
-rw-r--r-- | cpukit/include/rtems/score/schedulernodeimpl.h | 175 |
1 files changed, 117 insertions, 58 deletions
diff --git a/cpukit/include/rtems/score/schedulernodeimpl.h b/cpukit/include/rtems/score/schedulernodeimpl.h index 5d6f795912..db14184723 100644 --- a/cpukit/include/rtems/score/schedulernodeimpl.h +++ b/cpukit/include/rtems/score/schedulernodeimpl.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * @@ -9,17 +11,28 @@ */ /* - * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved. + * Copyright (C) 2014, 2017 embedded brains GmbH & Co. KG * - * embedded brains GmbH - * Dornierstr. 4 - * 82178 Puchheim - * Germany - * <rtems@embedded-brains.de> + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #ifndef _RTEMS_SCORE_SCHEDULERNODEIMPL_H @@ -47,12 +60,6 @@ extern "C" { RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Priority ) /** - * @brief Priority append indicator for the priority control used for the - * scheduler node priority. - */ -#define SCHEDULER_PRIORITY_APPEND_FLAG 1 - -/** * @brief Maps a priority value to support the append indicator. */ #define SCHEDULER_PRIORITY_MAP( priority ) ( ( priority ) << 1 ) @@ -66,13 +73,13 @@ extern "C" { * @brief Clears the priority append indicator bit. */ #define SCHEDULER_PRIORITY_PURIFY( priority ) \ - ( ( priority ) & ~( (Priority_Control) SCHEDULER_PRIORITY_APPEND_FLAG ) ) + ( ( priority ) & ~( (Priority_Control) PRIORITY_GROUP_LAST ) ) /** * @brief Returns the priority control with the append indicator bit set. */ #define SCHEDULER_PRIORITY_APPEND( priority ) \ - ( ( priority ) | SCHEDULER_PRIORITY_APPEND_FLAG ) + ( ( priority ) | ( (Priority_Control) PRIORITY_GROUP_LAST ) ) /** * @brief Returns true, if the item should be appended to its priority group, @@ -80,17 +87,20 @@ extern "C" { * group. */ #define SCHEDULER_PRIORITY_IS_APPEND( priority ) \ - ( ( ( priority ) & SCHEDULER_PRIORITY_APPEND_FLAG ) != 0 ) + ( ( ( priority ) & ( (Priority_Control) PRIORITY_GROUP_LAST ) ) != 0 ) /** - * @brief Initializes a node. + * @brief Initializes the node. + * + * @param scheduler is the scheduler of the node. + * + * @param[out] node is the node to initialize. * - * @param scheduler The scheduler for the initialization of @a node. - * @param[out] node The node to initialize. - * @param the_thread The thread for the initialization of @a node. - * @param priority The priority value for @a node. + * @param[in, out] the_thread is the thread of the node. + * + * @param priority is the initial priority of the node. */ -RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize( +static inline void _Scheduler_Node_do_initialize( const struct _Scheduler_Control *scheduler, Scheduler_Node *node, Thread_Control *the_thread, @@ -106,7 +116,9 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize( node->Wait.Priority.scheduler = scheduler; node->user = the_thread; node->idle = NULL; - _SMP_sequence_lock_Initialize( &node->Priority.Lock ); +#if CPU_SIZEOF_POINTER != 8 + _ISR_lock_Initialize( &node->Priority.Lock, "Scheduler Node Priority" ); +#endif #else (void) scheduler; (void) the_thread; @@ -114,13 +126,34 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize( } /** + * @brief Destroys the node. + * + * @param scheduler is the scheduler of the node. + * + * @param[in, out] node is the node to destroy. + */ +static inline void _Scheduler_Node_do_destroy( + const struct _Scheduler_Control *scheduler, + Scheduler_Node *node +) +{ + (void) scheduler; + +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER != 8 + _ISR_lock_Destroy( &node->Priority.Lock ); +#else + (void) node; +#endif +} + +/** * @brief Gets the scheduler of the node. * * @param node The node to get the scheduler of. * * @return The scheduler of the node. */ -RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Node_get_scheduler( +static inline const Scheduler_Control *_Scheduler_Node_get_scheduler( const Scheduler_Node *node ) { @@ -134,7 +167,7 @@ RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Node_get_scheduler( * * @return The owner of the node. */ -RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner( +static inline Thread_Control *_Scheduler_Node_get_owner( const Scheduler_Node *node ) { @@ -148,23 +181,24 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner( * * @return The priority of the node. */ -RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority( +static inline Priority_Control _Scheduler_Node_get_priority( Scheduler_Node *node ) { Priority_Control priority; -#if defined(RTEMS_SMP) - unsigned int seq; - - do { - seq = _SMP_sequence_lock_Read_begin( &node->Priority.Lock ); -#endif - - priority = node->Priority.value; +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8 + priority = _Atomic_Fetch_add_ulong( + &node->Priority.value, + 0, + ATOMIC_ORDER_RELAXED + ); +#else + ISR_lock_Context lock_context; -#if defined(RTEMS_SMP) - } while ( _SMP_sequence_lock_Read_retry( &node->Priority.Lock, seq ) ); + _ISR_lock_Acquire( &node->Priority.Lock, &lock_context ); + priority = node->Priority.value; + _ISR_lock_Release( &node->Priority.Lock, &lock_context ); #endif return priority; @@ -173,27 +207,31 @@ RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority( /** * @brief Sets the priority of the node. * - * @param[in, out] node The node to set the priority of. - * @param new_priority The new priority for @a node. - * @param prepend_it Indicates whether the new priority should be prepended. + * @param[in, out] node is the scheduler node. + * + * @param new_priority is the priority to set. + * + * @param group_order is the priority group order, see #PRIORITY_GROUP_FIRST + * and #PRIORITY_GROUP_LAST. */ -RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_priority( - Scheduler_Node *node, - Priority_Control new_priority, - bool prepend_it +static inline void _Scheduler_Node_set_priority( + Scheduler_Node *node, + Priority_Control new_priority, + Priority_Group_order group_order ) { -#if defined(RTEMS_SMP) - unsigned int seq; - - seq = _SMP_sequence_lock_Write_begin( &node->Priority.Lock ); -#endif - - new_priority |= ( prepend_it ? 0 : SCHEDULER_PRIORITY_APPEND_FLAG ); - node->Priority.value = new_priority; +#if defined(RTEMS_SMP) && CPU_SIZEOF_POINTER == 8 + _Atomic_Store_ulong( + &node->Priority.value, + new_priority | (Priority_Control) group_order, + ATOMIC_ORDER_RELAXED + ); +#else + ISR_lock_Context lock_context; -#if defined(RTEMS_SMP) - _SMP_sequence_lock_Write_end( &node->Priority.Lock, seq ); + _ISR_lock_Acquire( &node->Priority.Lock, &lock_context ); + node->Priority.value = new_priority | ( (Priority_Control) group_order ); + _ISR_lock_Release( &node->Priority.Lock, &lock_context ); #endif } @@ -205,7 +243,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_priority( * * @return The user of the node. */ -RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user( +static inline Thread_Control *_Scheduler_Node_get_user( const Scheduler_Node *node ) { @@ -218,7 +256,7 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user( * @param[out] node The node to set the user of. * @param user The new user for @a node. */ -RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_user( +static inline void _Scheduler_Node_set_user( Scheduler_Node *node, Thread_Control *user ) @@ -233,12 +271,33 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_user( * * @return The idle thread of @a node. */ -RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_idle( +static inline Thread_Control *_Scheduler_Node_get_idle( const Scheduler_Node *node ) { return node->idle; } + +/** + * @brief Sets the scheduler node's user to the idle thread. + * + * @param[in, out] node is the node to receive an idle thread. + * + * @param idle is the idle thread to use. + */ +static inline void _Scheduler_Node_set_idle_user( + Scheduler_Node *node, + Thread_Control *idle +) +{ + _Assert( _Scheduler_Node_get_idle( node ) == NULL ); + _Assert( + _Scheduler_Node_get_owner( node ) == _Scheduler_Node_get_user( node ) + ); + + _Scheduler_Node_set_user( node, idle ); + node->idle = idle; +} #endif #ifdef __cplusplus |