score: Add thread priority to scheduler nodes

The thread priority is manifest in two independent areas.  One area is
the user visible thread priority along with a potential thread queue.
The other is the scheduler.  Currently, a thread priority update via
_Thread_Change_priority() first updates the user visble thread priority
and the thread queue, then the scheduler is notified if necessary.  The
priority is passed to the scheduler via a local variable.  A generation
counter ensures that the scheduler discards out-of-date priorities.

This use of a local variable ties the update in these two areas close
together.  For later enhancements and the OMIP locking protocol
implementation we need more flexibility.  Add a thread priority
information block to Scheduler_Node and synchronize priority value
updates via a sequence lock on SMP configurations.

Update #2556.
This commit is contained in:
Sebastian Huber
2016-06-08 22:22:46 +02:00
parent 69a6802bfa
commit 9bfad8cd51
37 changed files with 421 additions and 524 deletions

View File

@@ -234,7 +234,6 @@ libscore_a_SOURCES += src/schedulerdefaultreleasejob.c
libscore_a_SOURCES += src/schedulerdefaultschedule.c
libscore_a_SOURCES += src/schedulerdefaultstartidle.c
libscore_a_SOURCES += src/schedulerdefaulttick.c
libscore_a_SOURCES += src/schedulerdefaultupdate.c
## SCHEDULERPRIORITY_C_FILES
libscore_a_SOURCES += src/schedulerpriority.c \
@@ -242,7 +241,6 @@ libscore_a_SOURCES += src/schedulerpriority.c \
src/schedulerprioritychangepriority.c \
src/schedulerpriorityschedule.c \
src/schedulerpriorityunblock.c \
src/schedulerpriorityupdate.c \
src/schedulerpriorityyield.c
## SCHEDULERSIMPLE_C_FILES
@@ -261,7 +259,6 @@ libscore_a_SOURCES += src/scheduleredf.c \
src/scheduleredfreleasejob.c \
src/scheduleredfschedule.c \
src/scheduleredfunblock.c \
src/scheduleredfupdate.c \
src/scheduleredfyield.c
## SCHEDULERCBS_C_FILES

View File

@@ -20,6 +20,7 @@
#define _RTEMS_SCORE_SCHEDULER_H
#include <rtems/score/priority.h>
#include <rtems/score/smplockseq.h>
#include <rtems/score/thread.h>
#if defined(__RTEMS_HAVE_SYS_CPUSET_H__) && defined(RTEMS_SMP)
#include <sys/cpuset.h>
@@ -83,12 +84,10 @@ typedef struct {
Thread_Control *
);
/** @see _Scheduler_Change_priority() */
Scheduler_Void_or_thread ( *change_priority )(
/** @see _Scheduler_Update_priority() */
Scheduler_Void_or_thread ( *update_priority )(
const Scheduler_Control *,
Thread_Control *,
Priority_Control,
bool
Thread_Control *
);
/** @see _Scheduler_Map_priority() */
@@ -129,18 +128,15 @@ typedef struct {
#endif
/** @see _Scheduler_Node_initialize() */
void ( *node_initialize )( const Scheduler_Control *, Thread_Control * );
/** @see _Scheduler_Node_destroy() */
void ( *node_destroy )( const Scheduler_Control *, Thread_Control * );
/** @see _Scheduler_Update_priority() */
void ( *update_priority )(
void ( *node_initialize )(
const Scheduler_Control *,
Thread_Control *,
Priority_Control
);
/** @see _Scheduler_Node_destroy() */
void ( *node_destroy )( const Scheduler_Control *, Thread_Control * );
/** @see _Scheduler_Release_job() */
void ( *release_job ) (
const Scheduler_Control *,
@@ -338,6 +334,41 @@ struct Scheduler_Node {
*/
Thread_Control *accepts_help;
#endif
/**
* @brief The thread priority information used by the scheduler.
*
* The thread priority is manifest in two independent areas. One area is the
* user visible thread priority along with a potential thread queue. The
* other is the scheduler. During a thread priority change, the user visible
* thread priority and the thread queue are first updated and the thread
* priority value here is changed. Once this is done the scheduler is
* notified via the update priority operation, so that it can update its
* internal state and honour a new thread priority value.
*/
struct {
/**
* @brief The thread priority value of this scheduler node.
*
* The producer of this value is _Thread_Change_priority(). The consumer
* is the scheduler via the unblock and update priority operations.
*/
Priority_Control value;
#if defined(RTEMS_SMP)
/**
* @brief Sequence lock to synchronize priority value updates.
*/
SMP_sequence_lock_Control Lock;
#endif
/**
* @brief In case a priority update is necessary and this is true, then
* enqueue the thread as the first of its priority group, otherwise enqueue
* the thread as the last of its priority group.
*/
bool prepend_it;
} Priority;
};
/**
@@ -464,14 +495,16 @@ void _Scheduler_default_Schedule(
);
/**
* @brief Does nothing.
* @brief Performs the scheduler base node initialization.
*
* @param[in] scheduler Unused.
* @param[in] the_thread Unused.
* @param[in] priority The thread priority.
*/
void _Scheduler_default_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
);
/**
@@ -485,19 +518,6 @@ void _Scheduler_default_Node_destroy(
Thread_Control *the_thread
);
/**
* @brief Does nothing.
*
* @param[in] scheduler Unused.
* @param[in] the_thread Unused.
* @param[in] new_priority Unused.
*/
void _Scheduler_default_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
);
/**
* @brief Does nothing.
*

View File

@@ -54,13 +54,12 @@ extern "C" {
_Scheduler_EDF_Yield, /* yield entry point */ \
_Scheduler_EDF_Block, /* block entry point */ \
_Scheduler_CBS_Unblock, /* unblock entry point */ \
_Scheduler_EDF_Change_priority, /* change priority entry point */ \
_Scheduler_EDF_Update_priority, /* update priority entry point */ \
_Scheduler_EDF_Map_priority, /* map priority entry point */ \
_Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
_Scheduler_CBS_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
_Scheduler_EDF_Update_priority, /* update priority entry point */ \
_Scheduler_CBS_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -346,7 +345,8 @@ void _Scheduler_CBS_Budget_callout(
*/
void _Scheduler_CBS_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
);
#ifdef __cplusplus

View File

@@ -47,13 +47,12 @@ extern "C" {
_Scheduler_EDF_Yield, /* yield entry point */ \
_Scheduler_EDF_Block, /* block entry point */ \
_Scheduler_EDF_Unblock, /* unblock entry point */ \
_Scheduler_EDF_Change_priority, /* change priority entry point */ \
_Scheduler_EDF_Update_priority, /* update priority entry point */ \
_Scheduler_EDF_Map_priority, /* map priority entry point */ \
_Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
_Scheduler_EDF_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
_Scheduler_EDF_Update_priority, /* update priority entry point */ \
_Scheduler_EDF_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -156,26 +155,12 @@ void _Scheduler_EDF_Schedule(
*
* @param[in] scheduler The scheduler instance.
* @param[in] the_thread being initialized.
* @param[in] priority The thread priority.
*/
void _Scheduler_EDF_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
/**
* @brief Updates position in the ready queue of @a the_thread.
*
* This routine updates position in the ready queue of @a the_thread.
*
* @param[in] scheduler The scheduler instance.
* @param[in] the_thread will have its scheduler specific information
* structure updated.
* @param[in] new_priority is the desired new priority.
*/
void _Scheduler_EDF_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
Priority_Control priority
);
/**
@@ -193,11 +178,9 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
Thread_Control *the_thread
);
Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
Scheduler_Void_or_thread _Scheduler_EDF_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
);
Priority_Control _Scheduler_EDF_Map_priority(

View File

@@ -341,12 +341,12 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread )
/**
* @brief Unblocks a thread with respect to the scheduler.
*
* This routine adds @a the_thread to the scheduling decision for
* the scheduler. The primary task is to add the thread to the
* ready queue per the schedulering policy and update any appropriate
* scheduling variables, for example the heir thread.
* This operation must fetch the latest thread priority value for this
* scheduler instance and update its internal state if necessary.
*
* @param[in] the_thread The thread.
*
* @see _Scheduler_Node_get_priority().
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
{
@@ -374,24 +374,18 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
/**
* @brief Propagates a priority change of a thread to the scheduler.
*
* The caller must ensure that the thread is in the ready state. The caller
* must ensure that the priority value actually changed and is not equal to the
* current priority value.
* On uni-processor configurations, this operation must evaluate the thread
* state. In case the thread is not ready, then the priority update should be
* deferred to the next scheduler unblock operation.
*
* The operation must update the heir and thread dispatch necessary variables
* in case the set of scheduled threads changes.
*
* @param[in] the_thread The thread changing its priority.
* @param[in] new_priority The new thread priority.
* @param[in] prepend_it In case this is true, then enqueue the thread as the
* first of its priority group, otherwise enqueue the thread as the last of its
* priority group.
*
* @see _Scheduler_Node_get_priority().
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
)
RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority( Thread_Control *the_thread )
{
const Scheduler_Control *own_scheduler;
ISR_lock_Context lock_context;
@@ -405,12 +399,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
#if defined(RTEMS_SMP)
needs_help =
#endif
( *own_scheduler->Operations.change_priority )(
own_scheduler,
the_thread,
new_priority,
prepend_it
);
( *own_scheduler->Operations.update_priority )( own_scheduler, the_thread );
#if defined(RTEMS_SMP)
_Scheduler_Ask_for_help_if_necessary( needs_help );
@@ -466,13 +455,19 @@ RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Unmap_priority(
*
* @param[in] scheduler The scheduler instance.
* @param[in] the_thread The thread containing the scheduler node.
* @param[in] priority The thread priority.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
)
{
return ( *scheduler->Operations.node_initialize )( scheduler, the_thread );
( *scheduler->Operations.node_initialize )(
scheduler,
the_thread,
priority
);
}
/**
@@ -492,32 +487,6 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Node_destroy(
( *scheduler->Operations.node_destroy )( scheduler, the_thread );
}
/**
* @brief Updates the scheduler about a priority change of a not ready thread.
*
* @param[in] the_thread The thread.
* @param[in] new_priority The new priority of the thread.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Update_priority(
Thread_Control *the_thread,
Priority_Control new_priority
)
{
const Scheduler_Control *scheduler;
ISR_lock_Context lock_context;
scheduler = _Scheduler_Get( the_thread );
_Scheduler_Acquire_critical( scheduler, &lock_context );
( *scheduler->Operations.update_priority )(
scheduler,
the_thread,
new_priority
);
_Scheduler_Release_critical( scheduler, &lock_context );
}
/**
* @brief Releases a job of a thread with respect to the scheduler.
*
@@ -639,8 +608,11 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Set(
_Scheduler_Node_destroy( current_scheduler, the_thread );
the_thread->Scheduler.own_control = scheduler;
the_thread->Scheduler.control = scheduler;
_Scheduler_Node_initialize( scheduler, the_thread );
_Scheduler_Update_priority( the_thread, the_thread->current_priority );
_Scheduler_Node_initialize(
scheduler,
the_thread,
the_thread->current_priority
);
if ( _States_Is_ready( current_state ) ) {
_Scheduler_Unblock( the_thread );
@@ -827,22 +799,73 @@ RTEMS_INLINE_ROUTINE Scheduler_Node *_Scheduler_Thread_get_node(
}
RTEMS_INLINE_ROUTINE void _Scheduler_Node_do_initialize(
Scheduler_Node *node,
Thread_Control *the_thread
Scheduler_Node *node,
Thread_Control *the_thread,
Priority_Control priority
)
{
node->Priority.value = priority;
node->Priority.prepend_it = false;
#if defined(RTEMS_SMP)
node->user = the_thread;
node->help_state = SCHEDULER_HELP_YOURSELF;
node->owner = the_thread;
node->idle = NULL;
node->accepts_help = the_thread;
_SMP_sequence_lock_Initialize( &node->Priority.Lock );
#else
(void) node;
(void) the_thread;
#endif
}
RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Node_get_priority(
Scheduler_Node *node,
bool *prepend_it_p
)
{
Priority_Control priority;
bool prepend_it;
#if defined(RTEMS_SMP)
unsigned int seq;
do {
seq = _SMP_sequence_lock_Read_begin( &node->Priority.Lock );
#endif
priority = node->Priority.value;
prepend_it = node->Priority.prepend_it;
#if defined(RTEMS_SMP)
} while ( _SMP_sequence_lock_Read_retry( &node->Priority.Lock, seq ) );
#endif
*prepend_it_p = prepend_it;
return priority;
}
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
node->Priority.value = new_priority;
node->Priority.prepend_it = prepend_it;
#if defined(RTEMS_SMP)
_SMP_sequence_lock_Write_end( &node->Priority.Lock, seq );
#endif
}
#if defined(RTEMS_SMP)
/**
* @brief Gets an idle thread from the scheduler instance.

View File

@@ -44,13 +44,12 @@ extern "C" {
_Scheduler_priority_Yield, /* yield entry point */ \
_Scheduler_priority_Block, /* block entry point */ \
_Scheduler_priority_Unblock, /* unblock entry point */ \
_Scheduler_priority_Change_priority, /* change priority entry point */ \
_Scheduler_priority_Update_priority, /* update priority entry point */ \
_Scheduler_default_Map_priority, /* map priority entry point */ \
_Scheduler_default_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
_Scheduler_default_Node_initialize, /* node initialize entry point */ \
_Scheduler_priority_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
_Scheduler_priority_Update_priority, /* update priority entry point */ \
_Scheduler_default_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -78,6 +77,11 @@ typedef struct {
* @brief Data for ready queue operations.
*/
typedef struct {
/**
* @brief The thread priority currently used by the scheduler.
*/
unsigned int current_priority;
/** This field points to the Ready FIFO for this thread's priority. */
Chain_Control *ready_chain;
@@ -133,16 +137,6 @@ void _Scheduler_priority_Schedule(
Thread_Control *the_thread
);
/**
* @brief Updates the scheduler node to reflect the new priority of the
* thread.
*/
void _Scheduler_priority_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
);
/**
* @brief Add @a the_thread to the scheduling decision.
*
@@ -158,11 +152,15 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock(
Thread_Control *the_thread
);
Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
Scheduler_Void_or_thread _Scheduler_priority_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
void _Scheduler_priority_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Priority_Control priority
);
/**

View File

@@ -54,13 +54,12 @@ extern "C" {
_Scheduler_priority_SMP_Yield, \
_Scheduler_priority_affinity_SMP_Block, \
_Scheduler_priority_affinity_SMP_Unblock, \
_Scheduler_priority_affinity_SMP_Change_priority, \
_Scheduler_priority_affinity_SMP_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_priority_affinity_SMP_Ask_for_help, \
_Scheduler_priority_affinity_SMP_Node_initialize, \
_Scheduler_default_Node_destroy, \
_Scheduler_priority_SMP_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle, \
@@ -76,10 +75,12 @@ extern "C" {
* @param[in] scheduler points to the scheduler specific information.
* @param[in] thread is the thread the scheduler is allocating
* management memory for.
* @param[in] priority is the thread priority.
*/
void _Scheduler_priority_affinity_SMP_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *thread
Thread_Control *the_thread,
Priority_Control priority
);
/**
@@ -127,18 +128,14 @@ bool _Scheduler_priority_affinity_SMP_Get_affinity(
);
/**
* @brief Change priority for the priority affinity SMP scheduler.
* @brief Update priority for the priority affinity SMP scheduler.
*
* @param[in] scheduler The scheduler of the thread.
* @param[in] the_thread The associated thread.
* @param[in] new_priority The new priority for the thread.
* @param[in] prepend_it Append or prepend the thread to its priority FIFO.
*/
Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
Thread_Control *_Scheduler_priority_affinity_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
);
Thread_Control *_Scheduler_priority_affinity_SMP_Ask_for_help(

View File

@@ -210,6 +210,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
Chain_Control *ready_queues
)
{
ready_queue->current_priority = new_priority;
ready_queue->ready_chain = &ready_queues[ new_priority ];
_Priority_bit_map_Initialize_information(

View File

@@ -83,13 +83,12 @@ typedef struct {
_Scheduler_priority_SMP_Yield, \
_Scheduler_priority_SMP_Block, \
_Scheduler_priority_SMP_Unblock, \
_Scheduler_priority_SMP_Change_priority, \
_Scheduler_priority_SMP_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_priority_SMP_Ask_for_help, \
_Scheduler_priority_SMP_Node_initialize, \
_Scheduler_default_Node_destroy, \
_Scheduler_priority_SMP_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle \
@@ -100,7 +99,8 @@ void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler );
void _Scheduler_priority_SMP_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *thread
Thread_Control *the_thread,
Priority_Control priority
);
void _Scheduler_priority_SMP_Block(
@@ -113,11 +113,9 @@ Thread_Control *_Scheduler_priority_SMP_Unblock(
Thread_Control *thread
);
Thread_Control *_Scheduler_priority_SMP_Change_priority(
Thread_Control *_Scheduler_priority_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
);
Thread_Control *_Scheduler_priority_SMP_Ask_for_help(
@@ -126,12 +124,6 @@ Thread_Control *_Scheduler_priority_SMP_Ask_for_help(
Thread_Control *offers_help
);
void _Scheduler_priority_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority
);
Thread_Control *_Scheduler_priority_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread

View File

@@ -44,13 +44,12 @@ extern "C" {
_Scheduler_simple_Yield, /* yield entry point */ \
_Scheduler_simple_Block, /* block entry point */ \
_Scheduler_simple_Unblock, /* unblock entry point */ \
_Scheduler_simple_Change_priority, /* change priority entry point */ \
_Scheduler_simple_Update_priority, /* update priority entry point */ \
_Scheduler_default_Map_priority, /* map priority entry point */ \
_Scheduler_default_Unmap_priority, /* unmap priority entry point */ \
SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \
_Scheduler_default_Node_initialize, /* node initialize entry point */ \
_Scheduler_default_Node_destroy, /* node destroy entry point */ \
_Scheduler_default_Update_priority, /* update priority entry point */ \
_Scheduler_default_Release_job, /* new period of task */ \
_Scheduler_default_Tick, /* tick entry point */ \
_Scheduler_default_Start_idle /* start idle entry point */ \
@@ -145,11 +144,9 @@ Scheduler_Void_or_thread _Scheduler_simple_Unblock(
Thread_Control *the_thread
);
Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
Scheduler_Void_or_thread _Scheduler_simple_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
);
/**@}*/

View File

@@ -66,13 +66,12 @@ typedef struct {
_Scheduler_simple_SMP_Yield, \
_Scheduler_simple_SMP_Block, \
_Scheduler_simple_SMP_Unblock, \
_Scheduler_simple_SMP_Change_priority, \
_Scheduler_simple_SMP_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_simple_SMP_Ask_for_help, \
_Scheduler_simple_SMP_Node_initialize, \
_Scheduler_default_Node_destroy, \
_Scheduler_simple_SMP_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle \
@@ -83,7 +82,8 @@ void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler );
void _Scheduler_simple_SMP_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
);
void _Scheduler_simple_SMP_Block(
@@ -96,11 +96,9 @@ Thread_Control *_Scheduler_simple_SMP_Unblock(
Thread_Control *thread
);
Thread_Control *_Scheduler_simple_SMP_Change_priority(
Thread_Control *_Scheduler_simple_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
);
Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
@@ -109,12 +107,6 @@ Thread_Control *_Scheduler_simple_SMP_Ask_for_help(
Thread_Control *needs_help
);
void _Scheduler_simple_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority
);
Thread_Control *_Scheduler_simple_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread

View File

@@ -387,11 +387,13 @@ static inline Scheduler_SMP_Node *_Scheduler_SMP_Node_downcast(
static inline void _Scheduler_SMP_Node_initialize(
Scheduler_SMP_Node *node,
Thread_Control *thread
Thread_Control *thread,
Priority_Control priority
)
{
_Scheduler_Node_do_initialize( &node->Base, thread );
_Scheduler_Node_do_initialize( &node->Base, thread, priority );
node->state = SCHEDULER_SMP_NODE_BLOCKED;
node->priority = priority;
}
static inline void _Scheduler_SMP_Node_update_priority(
@@ -889,23 +891,38 @@ static inline void _Scheduler_SMP_Block(
}
static inline Thread_Control *_Scheduler_SMP_Unblock(
Scheduler_Context *context,
Thread_Control *thread,
Scheduler_SMP_Enqueue enqueue_fifo
Scheduler_Context *context,
Thread_Control *thread,
Scheduler_SMP_Update update,
Scheduler_SMP_Enqueue enqueue_fifo
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread );
bool is_scheduled = node->state == SCHEDULER_SMP_NODE_SCHEDULED;
bool unblock = _Scheduler_Unblock_node(
Scheduler_SMP_Node *node;
bool is_scheduled;
bool unblock;
Thread_Control *needs_help;
node = _Scheduler_SMP_Thread_get_node( thread );
is_scheduled = ( node->state == SCHEDULER_SMP_NODE_SCHEDULED );
unblock = _Scheduler_Unblock_node(
context,
thread,
&node->Base,
is_scheduled,
_Scheduler_SMP_Release_idle_thread
);
Thread_Control *needs_help;
if ( unblock ) {
Priority_Control new_priority;
bool prepend_it;
new_priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
(void) prepend_it;
if ( new_priority != node->priority ) {
( *update )( context, &node->Base, new_priority );
}
if ( node->state == SCHEDULER_SMP_NODE_BLOCKED ) {
_Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
@@ -931,11 +948,9 @@ static inline Thread_Control *_Scheduler_SMP_Unblock(
return needs_help;
}
static inline Thread_Control *_Scheduler_SMP_Change_priority(
static inline Thread_Control *_Scheduler_SMP_Update_priority(
Scheduler_Context *context,
Thread_Control *thread,
Priority_Control new_priority,
bool prepend_it,
Scheduler_SMP_Extract extract_from_ready,
Scheduler_SMP_Update update,
Scheduler_SMP_Enqueue enqueue_fifo,
@@ -944,8 +959,18 @@ static inline Thread_Control *_Scheduler_SMP_Change_priority(
Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_lifo
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( thread );
Thread_Control *needs_help;
Scheduler_SMP_Node *node;
Thread_Control *needs_help;
Priority_Control new_priority;
bool prepend_it;
node = _Scheduler_SMP_Thread_get_own_node( thread );
new_priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
if ( new_priority == node->priority ) {
/* Nothing to do */
return NULL;
}
if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
_Scheduler_SMP_Extract_from_scheduled( &node->Base );

View File

@@ -83,13 +83,12 @@ typedef struct {
_Scheduler_strong_APA_Yield, \
_Scheduler_strong_APA_Block, \
_Scheduler_strong_APA_Unblock, \
_Scheduler_strong_APA_Change_priority, \
_Scheduler_strong_APA_Update_priority, \
_Scheduler_default_Map_priority, \
_Scheduler_default_Unmap_priority, \
_Scheduler_strong_APA_Ask_for_help, \
_Scheduler_strong_APA_Node_initialize, \
_Scheduler_default_Node_destroy, \
_Scheduler_strong_APA_Update_priority, \
_Scheduler_default_Release_job, \
_Scheduler_default_Tick, \
_Scheduler_SMP_Start_idle \
@@ -100,7 +99,8 @@ void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler );
void _Scheduler_strong_APA_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
);
void _Scheduler_strong_APA_Block(
@@ -113,11 +113,9 @@ Thread_Control *_Scheduler_strong_APA_Unblock(
Thread_Control *the_thread
);
Thread_Control *_Scheduler_strong_APA_Change_priority(
Thread_Control *_Scheduler_strong_APA_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
);
Thread_Control *_Scheduler_strong_APA_Ask_for_help(
@@ -126,12 +124,6 @@ Thread_Control *_Scheduler_strong_APA_Ask_for_help(
Thread_Control *offers_help
);
void _Scheduler_strong_APA_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
);
Thread_Control *_Scheduler_strong_APA_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread

View File

@@ -362,14 +362,6 @@ typedef struct {
*/
Priority_Control real_priority;
/**
* @brief Generation of the current priority value.
*
* It is used in _Thread_Change_priority() to serialize the update of
* priority related data structures.
*/
uint32_t priority_generation;
/**
* @brief Hints if a priority restore is necessary once the resource count
* changes from one to zero.
@@ -743,14 +735,6 @@ struct _Thread_Control {
*/
Priority_Control real_priority;
/**
* @brief Generation of the current priority value.
*
* It is used in _Thread_Change_priority() to serialize the update of
* priority related data structures.
*/
uint32_t priority_generation;
/**
* @brief Hints if a priority restore is necessary once the resource count
* changes from one to zero.

View File

@@ -253,6 +253,11 @@ void _Thread_Cancel(
*/
void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing );
RTEMS_INLINE_ROUTINE bool _Thread_Is_ready( const Thread_Control *the_thread )
{
return _States_Is_ready( the_thread->current_state );
}
States_Control _Thread_Clear_state_locked(
Thread_Control *the_thread,
States_Control state

View File

@@ -22,12 +22,13 @@
void _Scheduler_CBS_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
)
{
Scheduler_CBS_Node *node;
_Scheduler_EDF_Node_initialize( scheduler, the_thread );
_Scheduler_EDF_Node_initialize( scheduler, the_thread, priority );
node = _Scheduler_CBS_Thread_get_node( the_thread );
node->cbs_server = NULL;

View File

@@ -34,11 +34,13 @@ Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
Scheduler_CBS_Node *node;
Scheduler_CBS_Server *serv_info;
Priority_Control priority;
bool prepend_it;
context = _Scheduler_EDF_Get_context( scheduler );
node = _Scheduler_CBS_Thread_get_node( the_thread );
serv_info = node->cbs_server;
priority = node->Base.current_priority;
priority = _Scheduler_Node_get_priority( &node->Base.Base, &prepend_it );
(void) prepend_it;
/*
* Late unblock rule for deadline-driven tasks. The remaining time to

View File

@@ -23,12 +23,13 @@
void _Scheduler_default_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
)
{
Scheduler_Node *node = _Scheduler_Thread_get_own_node( the_thread );
(void) scheduler;
_Scheduler_Node_do_initialize( node, the_thread );
_Scheduler_Node_do_initialize( node, the_thread, priority );
}

View File

@@ -1,33 +0,0 @@
/**
* @file
*
* @brief Scheduler Default Update Operation
*
* @ingroup ScoreScheduler
*/
/*
* COPYRIGHT (c) 2011.
* On-Line Applications Research Corporation (OAR).
*
* 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.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/scheduler.h>
void _Scheduler_default_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
)
{
(void) scheduler;
(void) the_thread;
(void) new_priority;
}

View File

@@ -36,31 +36,42 @@ Priority_Control _Scheduler_EDF_Unmap_priority(
return priority & ~SCHEDULER_EDF_PRIO_MSB;
}
Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
Scheduler_Void_or_thread _Scheduler_EDF_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
)
{
Scheduler_EDF_Context *context;
Scheduler_EDF_Node *node;
Priority_Control priority;
bool prepend_it;
context = _Scheduler_EDF_Get_context( scheduler );
node = _Scheduler_EDF_Thread_get_node( the_thread );
if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
node->background_priority = new_priority;
if ( !_Thread_Is_ready( the_thread ) ) {
/* Nothing to do */
SCHEDULER_RETURN_VOID_OR_NULL;
}
node->current_priority = new_priority;
node = _Scheduler_EDF_Thread_get_node( the_thread );
priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
if ( priority == node->current_priority ) {
/* Nothing to do */
SCHEDULER_RETURN_VOID_OR_NULL;
}
if ( ( priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
node->background_priority = priority;
}
node->current_priority = priority;
context = _Scheduler_EDF_Get_context( scheduler );
_Scheduler_EDF_Extract( context, node );
if ( prepend_it ) {
_Scheduler_EDF_Enqueue_first( context, node, new_priority );
_Scheduler_EDF_Enqueue_first( context, node, priority );
} else {
_Scheduler_EDF_Enqueue( context, node, new_priority );
_Scheduler_EDF_Enqueue( context, node, priority );
}
_Scheduler_EDF_Schedule_body( scheduler, the_thread, false );

View File

@@ -22,14 +22,15 @@
void _Scheduler_EDF_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
)
{
Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread );
(void) scheduler;
_Scheduler_Node_do_initialize( &node->Base, the_thread );
_Scheduler_Node_do_initialize( &node->Base, the_thread, priority );
node->thread = the_thread;
}

View File

@@ -29,11 +29,16 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
{
Scheduler_EDF_Context *context;
Scheduler_EDF_Node *node;
Priority_Control priority;
bool prepend_it;
context = _Scheduler_EDF_Get_context( scheduler );
node = _Scheduler_EDF_Thread_get_node( the_thread );
priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
(void) prepend_it;
_Scheduler_EDF_Enqueue( context, node, node->current_priority );
node->current_priority = priority;
_Scheduler_EDF_Enqueue( context, node, priority );
/*
* If the thread that was unblocked is more important than the heir,
@@ -47,11 +52,8 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
* Even if the thread isn't preemptible, if the new heir is
* a pseudo-ISR system task, we need to do a context switch.
*/
if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
_Scheduler_Update_heir(
the_thread,
the_thread->current_priority == PRIORITY_PSEUDO_ISR
);
if ( priority < _Thread_Heir->current_priority ) {
_Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
}
SCHEDULER_RETURN_VOID_OR_NULL;

View File

@@ -1,38 +0,0 @@
/**
* @file
*
* @brief Scheduler EDF Update
* @ingroup ScoreScheduler
*/
/*
* Copyright (C) 2011 Petr Benes.
* Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
*
* 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.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/scheduleredfimpl.h>
void _Scheduler_EDF_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
)
{
Scheduler_EDF_Node *node;
node = _Scheduler_EDF_Thread_get_node( the_thread );
if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
node->background_priority = new_priority;
}
node->current_priority = new_priority;
}

View File

@@ -32,3 +32,24 @@ void _Scheduler_priority_Initialize( const Scheduler_Control *scheduler )
scheduler->maximum_priority
);
}
void _Scheduler_priority_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control priority
)
{
Scheduler_priority_Context *context;
Scheduler_priority_Node *node;
context = _Scheduler_priority_Get_context( scheduler );
node = _Scheduler_priority_Thread_get_node( the_thread );
_Scheduler_Node_do_initialize( &node->Base, the_thread, priority );
_Scheduler_priority_Ready_queue_update(
&node->Ready_queue,
priority,
&context->Bit_map,
&context->Ready[ 0 ]
);
}

View File

@@ -96,15 +96,14 @@ _Scheduler_priority_affinity_SMP_Node_downcast(
*/
void _Scheduler_priority_affinity_SMP_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *thread
Thread_Control *the_thread,
Priority_Control priority
)
{
Scheduler_priority_affinity_SMP_Node *node =
_Scheduler_priority_affinity_SMP_Thread_get_own_node( thread );
_Scheduler_priority_affinity_SMP_Thread_get_own_node( the_thread );
(void) scheduler;
_Scheduler_SMP_Node_initialize( &node->Base.Base, thread );
_Scheduler_priority_SMP_Node_initialize( scheduler, the_thread, priority );
/*
* All we add is affinity information to the basic SMP node.
@@ -409,6 +408,7 @@ Thread_Control *_Scheduler_priority_affinity_SMP_Unblock(
needs_help = _Scheduler_SMP_Unblock(
context,
thread,
_Scheduler_priority_SMP_Do_update,
_Scheduler_priority_affinity_SMP_Enqueue_fifo
);
@@ -535,21 +535,17 @@ static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
/*
* This is the public scheduler specific Change Priority operation.
*/
Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
Thread_Control *_Scheduler_priority_affinity_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
Thread_Control *displaced;
displaced = _Scheduler_SMP_Change_priority(
displaced = _Scheduler_SMP_Update_priority(
context,
thread,
new_priority,
prepend_it,
_Scheduler_priority_SMP_Extract_from_ready,
_Scheduler_priority_SMP_Do_update,
_Scheduler_priority_affinity_SMP_Enqueue_fifo,

View File

@@ -21,16 +21,30 @@
#include <rtems/score/schedulerpriorityimpl.h>
Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
Scheduler_Void_or_thread _Scheduler_priority_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
)
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
Scheduler_priority_Context *context;
Scheduler_priority_Node *node;
unsigned int priority;
bool prepend_it;
if ( !_Thread_Is_ready( the_thread ) ) {
/* Nothing to do */
SCHEDULER_RETURN_VOID_OR_NULL;
}
node = _Scheduler_priority_Thread_get_node( the_thread );
priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
if ( priority == node->Ready_queue.current_priority ) {
/* Nothing to do */
SCHEDULER_RETURN_VOID_OR_NULL;
}
context = _Scheduler_priority_Get_context( scheduler );
_Scheduler_priority_Ready_queue_extract(
&the_thread->Object.Node,
@@ -40,7 +54,7 @@ Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
_Scheduler_priority_Ready_queue_update(
&node->Ready_queue,
new_priority,
priority,
&context->Bit_map,
&context->Ready[ 0 ]
);

View File

@@ -47,24 +47,27 @@ void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
void _Scheduler_priority_SMP_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *thread
Thread_Control *the_thread,
Priority_Control priority
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( thread );
Scheduler_Context *context;
Scheduler_priority_SMP_Context *self;
Scheduler_priority_SMP_Node *node;
_Scheduler_SMP_Node_initialize( node, thread );
}
context = _Scheduler_Get_context( scheduler );
self = _Scheduler_priority_SMP_Get_self( context );
node = _Scheduler_priority_SMP_Node_downcast(
_Scheduler_Thread_get_own_node( the_thread )
);
void _Scheduler_priority_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
Scheduler_Node *node = _Scheduler_Thread_get_node( thread );
_Scheduler_priority_SMP_Do_update( context, node, new_priority );
_Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority );
_Scheduler_priority_Ready_queue_update(
&node->Ready_queue,
priority,
&self->Bit_map,
&self->Ready[ 0 ]
);
}
static Scheduler_Node *_Scheduler_priority_SMP_Get_highest_ready(
@@ -213,24 +216,21 @@ Thread_Control *_Scheduler_priority_SMP_Unblock(
return _Scheduler_SMP_Unblock(
context,
thread,
_Scheduler_priority_SMP_Do_update,
_Scheduler_priority_SMP_Enqueue_fifo
);
}
Thread_Control *_Scheduler_priority_SMP_Change_priority(
Thread_Control *_Scheduler_priority_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
return _Scheduler_SMP_Change_priority(
return _Scheduler_SMP_Update_priority(
context,
thread,
new_priority,
prepend_it,
_Scheduler_priority_SMP_Extract_from_ready,
_Scheduler_priority_SMP_Do_update,
_Scheduler_priority_SMP_Enqueue_fifo,

View File

@@ -27,9 +27,24 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock (
Thread_Control *the_thread
)
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
Scheduler_priority_Context *context;
Scheduler_priority_Node *node;
unsigned int priority;
bool prepend_it;
context = _Scheduler_priority_Get_context( scheduler );
node = _Scheduler_priority_Thread_get_node( the_thread );
priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
(void) prepend_it;
if ( priority != node->Ready_queue.current_priority ) {
_Scheduler_priority_Ready_queue_update(
&node->Ready_queue,
priority,
&context->Bit_map,
&context->Ready[ 0 ]
);
}
_Scheduler_priority_Ready_queue_enqueue(
&the_thread->Object.Node,
@@ -51,11 +66,8 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock (
* Even if the thread isn't preemptible, if the new heir is
* a pseudo-ISR system task, we need to do a context switch.
*/
if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
_Scheduler_Update_heir(
the_thread,
the_thread->current_priority == PRIORITY_PSEUDO_ISR
);
if ( priority < _Thread_Heir->current_priority ) {
_Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
}
SCHEDULER_RETURN_VOID_OR_NULL;

View File

@@ -1,39 +0,0 @@
/**
* @file
*
* @brief Update Scheduler Priority
* @ingroup ScoreScheduler
*/
/*
* Copyright (C) 2010 Gedare Bloom.
* Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
*
* 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.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems/score/schedulerpriorityimpl.h>
void _Scheduler_priority_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
)
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
_Scheduler_priority_Ready_queue_update(
&node->Ready_queue,
new_priority,
&context->Bit_map,
&context->Ready[ 0 ]
);
}

View File

@@ -21,15 +21,23 @@
#include <rtems/score/schedulersimpleimpl.h>
Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
Scheduler_Void_or_thread _Scheduler_simple_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
)
{
Scheduler_simple_Context *context =
_Scheduler_simple_Get_context( scheduler );
Scheduler_simple_Context *context;
Scheduler_Node *node;
bool prepend_it;
if ( !_Thread_Is_ready( the_thread ) ) {
/* Nothing to do */
SCHEDULER_RETURN_VOID_OR_NULL;
}
context = _Scheduler_simple_Get_context( scheduler );
node = _Scheduler_Thread_get_node( the_thread );
_Scheduler_Node_get_priority( node, &prepend_it );
_Scheduler_simple_Extract( scheduler, the_thread );

View File

@@ -44,12 +44,13 @@ void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler )
void _Scheduler_simple_SMP_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
Thread_Control *the_thread,
Priority_Control priority
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
_Scheduler_SMP_Node_initialize( node, the_thread );
_Scheduler_SMP_Node_initialize( node, the_thread, priority );
}
static void _Scheduler_simple_SMP_Do_update(
@@ -65,18 +66,6 @@ static void _Scheduler_simple_SMP_Do_update(
_Scheduler_SMP_Node_update_priority( node, new_priority );
}
void _Scheduler_simple_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
Scheduler_Node *node = _Scheduler_Thread_get_node( thread );
_Scheduler_simple_SMP_Do_update( context, node, new_priority );
}
static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
Scheduler_Context *context,
Scheduler_Node *node
@@ -295,24 +284,21 @@ Thread_Control *_Scheduler_simple_SMP_Unblock(
return _Scheduler_SMP_Unblock(
context,
thread,
_Scheduler_simple_SMP_Do_update,
_Scheduler_simple_SMP_Enqueue_fifo
);
}
Thread_Control *_Scheduler_simple_SMP_Change_priority(
Thread_Control *_Scheduler_simple_SMP_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
return _Scheduler_SMP_Change_priority(
return _Scheduler_SMP_Update_priority(
context,
thread,
new_priority,
prepend_it,
_Scheduler_simple_SMP_Extract_from_ready,
_Scheduler_simple_SMP_Do_update,
_Scheduler_simple_SMP_Enqueue_fifo,

View File

@@ -172,25 +172,28 @@ void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler )
}
void _Scheduler_strong_APA_Node_initialize(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
_Scheduler_SMP_Node_initialize( node, the_thread );
}
void _Scheduler_strong_APA_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority
Priority_Control priority
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
Scheduler_Node *node = _Scheduler_Thread_get_node( the_thread );
Scheduler_Context *context;
Scheduler_strong_APA_Context *self;
Scheduler_strong_APA_Node *node;
_Scheduler_strong_APA_Do_update( context, node, new_priority );
context = _Scheduler_Get_context( scheduler );
self = _Scheduler_strong_APA_Get_self( context );
node = _Scheduler_strong_APA_Node_downcast(
_Scheduler_Thread_get_own_node( the_thread )
);
_Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority );
_Scheduler_priority_Ready_queue_update(
&node->Ready_queue,
priority,
&self->Bit_map,
&self->Ready[ 0 ]
);
}
static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready(
@@ -339,24 +342,21 @@ Thread_Control *_Scheduler_strong_APA_Unblock(
return _Scheduler_SMP_Unblock(
context,
the_thread,
_Scheduler_strong_APA_Do_update,
_Scheduler_strong_APA_Enqueue_fifo
);
}
Thread_Control *_Scheduler_strong_APA_Change_priority(
Thread_Control *_Scheduler_strong_APA_Update_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
bool prepend_it
Thread_Control *the_thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
return _Scheduler_SMP_Change_priority(
return _Scheduler_SMP_Update_priority(
context,
the_thread,
new_priority,
prepend_it,
_Scheduler_strong_APA_Extract_from_ready,
_Scheduler_strong_APA_Do_update,
_Scheduler_strong_APA_Enqueue_fifo,

View File

@@ -34,7 +34,6 @@ THREAD_OFFSET_ASSERT( Join_queue );
THREAD_OFFSET_ASSERT( current_state );
THREAD_OFFSET_ASSERT( current_priority );
THREAD_OFFSET_ASSERT( real_priority );
THREAD_OFFSET_ASSERT( priority_generation );
THREAD_OFFSET_ASSERT( priority_restore_hint );
THREAD_OFFSET_ASSERT( resource_count );
THREAD_OFFSET_ASSERT( Wait );

View File

@@ -50,11 +50,12 @@ void _Thread_Change_priority(
* we are not REALLY changing priority.
*/
if ( ( *filter )( the_thread, &new_priority, arg ) ) {
uint32_t my_generation;
Scheduler_Node *own_node;
own_node = _Scheduler_Thread_get_own_node( the_thread );
_Scheduler_Node_set_priority( own_node, new_priority, prepend_it );
my_generation = the_thread->priority_generation + 1;
the_thread->current_priority = new_priority;
the_thread->priority_generation = my_generation;
( *the_thread->Wait.operations->priority_change )(
the_thread,
@@ -65,19 +66,7 @@ void _Thread_Change_priority(
_Thread_Lock_release( lock, &lock_context );
_Thread_State_acquire( the_thread, &lock_context );
if ( the_thread->priority_generation == my_generation ) {
if ( _States_Is_ready( the_thread->current_state ) ) {
_Scheduler_Change_priority(
the_thread,
new_priority,
prepend_it
);
} else {
_Scheduler_Update_priority( the_thread, new_priority );
}
}
_Scheduler_Update_priority( the_thread );
_Thread_State_release( the_thread, &lock_context );
} else {
_Thread_Lock_release( lock, &lock_context );

View File

@@ -200,11 +200,9 @@ bool _Thread_Initialize(
RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags );
_Scheduler_Node_initialize( scheduler, the_thread );
_Scheduler_Node_initialize( scheduler, the_thread, priority );
scheduler_node_initialized = true;
_Scheduler_Update_priority( the_thread, priority );
/* POSIX Keys */
_RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs );
_ISR_lock_Initialize( &the_thread->Keys.Lock, "POSIX Key Value Pairs" );

View File

@@ -187,7 +187,7 @@ static void test_change_priority(void)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
static Thread_Control *change_priority_op(
static Thread_Control *update_priority_op(
Thread_Control *thread,
Priority_Control new_priority,
bool prepend_it
@@ -197,18 +197,17 @@ static Thread_Control *change_priority_op(
ISR_lock_Context state_lock_context;
ISR_lock_Context scheduler_lock_context;
Thread_Control *needs_help;
Scheduler_Node *node;
thread->current_priority = new_priority;
node = _Scheduler_Thread_get_node(thread);
_Scheduler_Node_set_priority(node, new_priority, prepend_it);
_Thread_State_acquire( thread, &state_lock_context );
scheduler = _Scheduler_Get( thread );
_Scheduler_Acquire_critical( scheduler, &scheduler_lock_context );
thread->current_priority = new_priority;
needs_help = (*scheduler->Operations.change_priority)(
scheduler,
thread,
new_priority,
prepend_it
);
needs_help = (*scheduler->Operations.update_priority)( scheduler, thread);
_Scheduler_Release_critical( scheduler, &scheduler_lock_context );
_Thread_State_release( thread, &state_lock_context );
@@ -216,7 +215,7 @@ static Thread_Control *change_priority_op(
return needs_help;
}
static void test_case_change_priority_op(
static void test_case_update_priority_op(
Thread_Control *executing,
Scheduler_SMP_Node *executing_node,
Thread_Control *other,
@@ -244,7 +243,7 @@ static void test_case_change_priority_op(
}
rtems_test_assert(executing_node->state == start_state);
needs_help = change_priority_op(executing, prio, prepend_it);
needs_help = update_priority_op(executing, prio, prepend_it);
rtems_test_assert(executing_node->state == new_state);
if (start_state != new_state) {
@@ -269,7 +268,7 @@ static void test_case_change_priority_op(
_Thread_Dispatch_enable( cpu_self );
}
static void test_change_priority_op(void)
static void test_update_priority_op(void)
{
rtems_status_code sc;
rtems_id task_id;
@@ -289,7 +288,7 @@ static void test_change_priority_op(void)
for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
for (j = 0; j < RTEMS_ARRAY_SIZE(priorities); ++j) {
for (k = 0; k < RTEMS_ARRAY_SIZE(prepend_it); ++k) {
test_case_change_priority_op(
test_case_update_priority_op(
executing,
executing_node,
other,
@@ -555,7 +554,7 @@ static void test_unblock_op(void)
static void tests(void)
{
test_change_priority();
test_change_priority_op();
test_update_priority_op();
test_yield_op();
test_unblock_op();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 embedded brains GmbH. All rights reserved.
* Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved.
*
* embedded brains GmbH
* Dornierstr. 4
@@ -22,7 +22,7 @@
#include <string.h>
#include <rtems.h>
#include <rtems/score/schedulerpriority.h>
#include <rtems/score/schedulerpriorityimpl.h>
#include <rtems/score/threadimpl.h>
const char rtems_test_name[] = "SPINTRCRITICAL 23";
@@ -30,37 +30,14 @@ const char rtems_test_name[] = "SPINTRCRITICAL 23";
typedef struct {
RTEMS_INTERRUPT_LOCK_MEMBER(lock)
rtems_id task_id;
Thread_Control *tcb;
Scheduler_priority_Node *scheduler_node;
rtems_task_priority priority_task;
rtems_task_priority priority_interrupt;
uint32_t priority_generation;
Scheduler_priority_Node scheduler_node;
bool done;
} test_context;
static test_context ctx_instance;
static Thread_Control *get_tcb(rtems_id id)
{
ISR_lock_Context lock_context;
Thread_Control *tcb;
tcb = _Thread_Get(id, &lock_context);
rtems_test_assert(tcb != NULL);
_ISR_lock_ISR_enable(&lock_context);
return tcb;
}
static bool scheduler_node_unchanged(const test_context *ctx)
{
return memcmp(
&ctx->scheduler_node,
ctx->tcb->Scheduler.node,
sizeof(ctx->scheduler_node)
) == 0;
}
static void change_priority(rtems_id timer, void *arg)
{
/* The arg is NULL */
@@ -69,8 +46,8 @@ static void change_priority(rtems_id timer, void *arg)
rtems_interrupt_lock_acquire(&ctx->lock, &lock_context);
if (
ctx->priority_generation != ctx->tcb->priority_generation
&& scheduler_node_unchanged(ctx)
ctx->scheduler_node->Ready_queue.current_priority
!= ctx->scheduler_node->Base.Priority.value
) {
rtems_task_priority priority_interrupt;
rtems_task_priority priority_task;
@@ -112,12 +89,6 @@ static bool test_body(void *arg)
priority_interrupt = 1 + (priority_task + 1) % 3;
ctx->priority_task = priority_task;
ctx->priority_interrupt = priority_interrupt;
ctx->priority_generation = ctx->tcb->priority_generation;
memcpy(
&ctx->scheduler_node,
ctx->tcb->Scheduler.node,
sizeof(ctx->scheduler_node)
);
rtems_interrupt_lock_release(&ctx->lock, &lock_context);
sc = rtems_task_set_priority(
@@ -144,24 +115,14 @@ static bool test_body(void *arg)
static void Init(rtems_task_argument arg)
{
test_context *ctx = &ctx_instance;
rtems_status_code sc;
TEST_BEGIN();
rtems_interrupt_lock_initialize(&ctx->lock, "Test");
ctx->priority_task = 1;
sc = rtems_task_create(
rtems_build_name('T', 'E', 'S', 'T'),
ctx->priority_task,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&ctx->task_id
);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
ctx->tcb = get_tcb(ctx->task_id);
ctx->task_id = rtems_task_self();
ctx->scheduler_node =
_Scheduler_priority_Thread_get_node(_Thread_Get_executing());
interrupt_critical_section_test(test_body, ctx, change_priority);
rtems_test_assert(ctx->done);
@@ -175,7 +136,7 @@ static void Init(rtems_task_argument arg)
#define CONFIGURE_MICROSECONDS_PER_TICK 1000
#define CONFIGURE_MAXIMUM_TASKS 2
#define CONFIGURE_MAXIMUM_TASKS 1
#define CONFIGURE_MAXIMUM_TIMERS 1
#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1