forked from Imagelibrary/rtems
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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 ]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 ]
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ]
|
||||
);
|
||||
}
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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" );
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user