blob: 5d6f795912cd5f4a511e474840b9c48847efcf89 (
plain) (
tree)
|
|
/**
* @file
*
* @ingroup RTEMSScoreScheduler
*
* @brief This header file provides interfaces of the
* @ref RTEMSScoreScheduler related to scheduler nodes which are only used by
* the implementation.
*/
/*
* Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
*
* 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.
*/
#ifndef _RTEMS_SCORE_SCHEDULERNODEIMPL_H
#define _RTEMS_SCORE_SCHEDULERNODEIMPL_H
#include <rtems/score/schedulernode.h>
#include <rtems/score/priorityimpl.h>
/**
* @addtogroup RTEMSScoreScheduler
*
* @{
*/
struct _Scheduler_Control;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define SCHEDULER_NODE_OF_WAIT_PRIORITY_NODE( node ) \
RTEMS_CONTAINER_OF( node, Scheduler_Node, Wait.Priority.Node.Node.Chain )
#define SCHEDULER_NODE_OF_WAIT_PRIORITY( node ) \
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 )
/**
* @brief Returns the plain priority value.
*/
#define SCHEDULER_PRIORITY_UNMAP( priority ) ( ( priority ) >> 1 )
/**
* @brief Clears the priority append indicator bit.
*/
#define SCHEDULER_PRIORITY_PURIFY( priority ) \
( ( priority ) & ~( (Priority_Control) SCHEDULER_PRIORITY_APPEND_FLAG ) )
/**
* @brief Returns the priority control with the append indicator bit set.
*/
#define SCHEDULER_PRIORITY_APPEND( priority ) \
( ( priority ) | SCHEDULER_PRIORITY_APPEND_FLAG )
/**
* @brief Returns true, if the item should be appended to its priority group,
* otherwise returns false and the item should be prepended to its priority
* group.
*/
#define SCHEDULER_PRIORITY_IS_APPEND( priority ) \
( ( ( priority ) & SCHEDULER_PRIORITY_APPEND_FLAG ) != 0 )
/**
* @brief Initializes a node.
*
* @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.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize(
const struct _Scheduler_Control *scheduler,
Scheduler_Node *node,
Thread_Control *the_thread,
Priority_Control priority
)
{
node->owner = the_thread;
node->Priority.value = priority;
#if defined(RTEMS_SMP)
_Chain_Initialize_node( &node->Thread.Wait_node );
node->Wait.Priority.scheduler = scheduler;
node->user = the_thread;
node->idle = NULL;
_SMP_sequence_lock_Initialize( &node->Priority.Lock );
#else
(void) scheduler;
(void) the_thread;
#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(
const Scheduler_Node *node
)
{
return _Priority_Get_scheduler( &node->Wait.Priority );
}
/**
* @brief Gets the owner of the node.
*
* @param node The node to get the owner of.
*
* @return The owner of the node.
*/
RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_owner(
const Scheduler_Node *node
)
{
return node->owner;
}
/**
* @brief Gets the priority of the node.
*
* @param node The node to get the priority of.
*
* @return The priority of the node.
*/
RTEMS_INLINE_ROUTINE 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)
} while ( _SMP_sequence_lock_Read_retry( &node->Priority.Lock, seq ) );
#endif
return 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.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Node_set_priority(
Scheduler_Node *node,
Priority_Control new_priority,
bool prepend_it
)
{
#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)
_SMP_sequence_lock_Write_end( &node->Priority.Lock, seq );
#endif
}
#if defined(RTEMS_SMP)
/**
* @brief Gets the user of the node.
*
* @param node The node to get the user of.
*
* @return The user of the node.
*/
RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_user(
const Scheduler_Node *node
)
{
return node->user;
}
/**
* @brief Sets the user of the node.
*
* @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(
Scheduler_Node *node,
Thread_Control *user
)
{
node->user = user;
}
/**
* @brief Gets the idle thread of the node.
*
* @param node The node to get the idle thread of.
*
* @return The idle thread of @a node.
*/
RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Node_get_idle(
const Scheduler_Node *node
)
{
return node->idle;
}
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
/** @} */
#endif /* _RTEMS_SCORE_SCHEDULERNODEIMPL_H */
|