score: Need for help indicator for scheduler ops

Return a thread in need for help for the following scheduler operations

- unblock,
- change priority, and
- yield.

A thread in need for help is a thread that encounters a scheduler state
change from scheduled to ready or a thread that cannot be scheduled in
an unblock operation.  Such a thread can ask threads which depend on
resources owned by this thread for help.
This commit is contained in:
Sebastian Huber
2014-07-08 16:30:48 +02:00
parent ac532f3350
commit 8568341d69
24 changed files with 645 additions and 142 deletions
+23 -4
View File
@@ -44,6 +44,16 @@ typedef struct Scheduler_Control Scheduler_Control;
typedef struct Scheduler_Node Scheduler_Node;
#if defined(RTEMS_SMP)
typedef Thread_Control * Scheduler_Void_or_thread;
#define SCHEDULER_RETURN_VOID_OR_NULL return NULL
#else
typedef void Scheduler_Void_or_thread;
#define SCHEDULER_RETURN_VOID_OR_NULL return
#endif
/**
* @brief The scheduler operations.
*/
@@ -55,16 +65,25 @@ typedef struct {
void ( *schedule )( const Scheduler_Control *, Thread_Control *);
/** @see _Scheduler_Yield() */
void ( *yield )( const Scheduler_Control *, Thread_Control *);
Scheduler_Void_or_thread ( *yield )(
const Scheduler_Control *,
Thread_Control *
);
/** @see _Scheduler_Block() */
void ( *block )( const Scheduler_Control *, Thread_Control * );
void ( *block )(
const Scheduler_Control *,
Thread_Control *
);
/** @see _Scheduler_Unblock() */
void ( *unblock )( const Scheduler_Control *, Thread_Control * );
Scheduler_Void_or_thread ( *unblock )(
const Scheduler_Control *,
Thread_Control *
);
/** @see _Scheduler_Change_priority() */
void ( *change_priority )(
Scheduler_Void_or_thread ( *change_priority )(
const Scheduler_Control *,
Thread_Control *,
Priority_Control,
@@ -153,7 +153,7 @@ extern Scheduler_CBS_Server _Scheduler_CBS_Server_list[];
*
* @note This has to be asessed as missed deadline of the current job.
*/
void _Scheduler_CBS_Unblock(
Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
@@ -177,12 +177,12 @@ void _Scheduler_EDF_Update_priority(
*
* @param[in] the_thread will be unblocked.
*/
void _Scheduler_EDF_Unblock(
Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
void _Scheduler_EDF_Change_priority(
Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -204,7 +204,7 @@ void _Scheduler_EDF_Change_priority(
*
* @param[in,out] thread The yielding thread.
*/
void _Scheduler_EDF_Yield(
Scheduler_Void_or_thread _Scheduler_EDF_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
@@ -116,6 +116,24 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread )
( *scheduler->Operations.schedule )( scheduler, the_thread );
}
#if defined(RTEMS_SMP)
/**
* @brief Ask threads depending on resources owned by the thread for help.
*
* A thread is in need for help if it lost its assigned processor due to
* pre-emption by a higher priority thread or it was not possible to assign it
* a processor since its priority is to low on its current scheduler instance.
*
* @param[in] needs_help The thread needing help.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help_if_necessary(
Thread_Control *needs_help
)
{
(void) needs_help;
}
#endif
/**
* @brief Scheduler yield with a particular thread.
*
@@ -127,8 +145,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread )
RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread )
{
const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
#if defined(RTEMS_SMP)
Thread_Control *needs_help;
needs_help =
#endif
( *scheduler->Operations.yield )( scheduler, the_thread );
#if defined(RTEMS_SMP)
_Scheduler_Ask_for_help_if_necessary( needs_help );
#endif
}
/**
@@ -161,8 +187,16 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread )
RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
{
const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
#if defined(RTEMS_SMP)
Thread_Control *needs_help;
needs_help =
#endif
( *scheduler->Operations.unblock )( scheduler, the_thread );
#if defined(RTEMS_SMP)
_Scheduler_Ask_for_help_if_necessary( needs_help );
#endif
}
/**
@@ -185,13 +219,21 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority(
)
{
const Scheduler_Control *scheduler = _Scheduler_Get( the_thread );
#if defined(RTEMS_SMP)
Thread_Control *needs_help;
needs_help =
#endif
( *scheduler->Operations.change_priority )(
scheduler,
the_thread,
new_priority,
prepend_it
);
#if defined(RTEMS_SMP)
_Scheduler_Ask_for_help_if_necessary( needs_help );
#endif
}
/**
@@ -149,12 +149,12 @@ void _Scheduler_priority_Update_priority(
*
* @param[in] the_thread will be unblocked
*/
void _Scheduler_priority_Unblock(
Scheduler_Void_or_thread _Scheduler_priority_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
void _Scheduler_priority_Change_priority(
Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -180,7 +180,7 @@ void _Scheduler_priority_Change_priority(
*
* @param[in,out] thread The yielding thread.
*/
void _Scheduler_priority_Yield(
Scheduler_Void_or_thread _Scheduler_priority_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
@@ -101,7 +101,7 @@ void _Scheduler_priority_affinity_SMP_Block(
* @param[in] scheduler is the scheduler instance information
* @param[in] thread is the thread to unblock
*/
void _Scheduler_priority_affinity_SMP_Unblock(
Thread_Control *_Scheduler_priority_affinity_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
@@ -132,7 +132,7 @@ bool _Scheduler_priority_affinity_SMP_Get_affinity(
* @param[in] new_priority The new priority for the thread.
* @param[in] prepend_it Append or prepend the thread to its priority FIFO.
*/
void _Scheduler_priority_affinity_SMP_Change_priority(
Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -106,12 +106,12 @@ void _Scheduler_priority_SMP_Block(
Thread_Control *thread
);
void _Scheduler_priority_SMP_Unblock(
Thread_Control *_Scheduler_priority_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
void _Scheduler_priority_SMP_Change_priority(
Thread_Control *_Scheduler_priority_SMP_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -124,7 +124,7 @@ void _Scheduler_priority_SMP_Update_priority(
Priority_Control new_priority
);
void _Scheduler_priority_SMP_Yield(
Thread_Control *_Scheduler_priority_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
@@ -101,7 +101,7 @@ void _Scheduler_simple_Schedule(
*
* @param[in,out] thread The yielding thread.
*/
void _Scheduler_simple_Yield(
Scheduler_Void_or_thread _Scheduler_simple_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
@@ -130,12 +130,12 @@ void _Scheduler_simple_Block(
*
* @param[in] the_thread is the thread that is to be unblocked
*/
void _Scheduler_simple_Unblock(
Scheduler_Void_or_thread _Scheduler_simple_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
);
void _Scheduler_simple_Change_priority(
Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -87,12 +87,12 @@ void _Scheduler_simple_SMP_Block(
Thread_Control *thread
);
void _Scheduler_simple_SMP_Unblock(
Thread_Control *_Scheduler_simple_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
void _Scheduler_simple_SMP_Change_priority(
Thread_Control *_Scheduler_simple_SMP_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -105,7 +105,7 @@ void _Scheduler_simple_SMP_Update_priority(
Priority_Control new_priority
);
void _Scheduler_simple_SMP_Yield(
Thread_Control *_Scheduler_simple_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread
);
@@ -306,7 +306,13 @@ typedef void ( *Scheduler_SMP_Update )(
Priority_Control new_priority
);
typedef void ( *Scheduler_SMP_Enqueue )(
typedef Thread_Control *( *Scheduler_SMP_Enqueue )(
Scheduler_Context *context,
Scheduler_Node *node_to_enqueue,
Thread_Control *needs_help
);
typedef Thread_Control *( *Scheduler_SMP_Enqueue_scheduled )(
Scheduler_Context *context,
Scheduler_Node *node_to_enqueue
);
@@ -492,6 +498,8 @@ static inline Scheduler_Node *_Scheduler_SMP_Get_lowest_scheduled(
*
* @param[in] context The scheduler instance context.
* @param[in] node The node to enqueue.
* @param[in] needs_help The thread needing help in case the node cannot be
* scheduled.
* @param[in] order The order function.
* @param[in] insert_ready Function to insert a node into the set of ready
* nodes.
@@ -506,9 +514,10 @@ static inline Scheduler_Node *_Scheduler_SMP_Get_lowest_scheduled(
* @param[in] allocate_processor Function to allocate a processor to a node
* based on the rules of the scheduler.
*/
static inline void _Scheduler_SMP_Enqueue_ordered(
static inline Thread_Control *_Scheduler_SMP_Enqueue_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Thread_Control *needs_help,
Chain_Node_order order,
Scheduler_SMP_Insert insert_ready,
Scheduler_SMP_Insert insert_scheduled,
@@ -535,9 +544,13 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
( *insert_scheduled )( context, node );
( *move_from_scheduled_to_ready )( context, lowest_scheduled );
needs_help = _Scheduler_Node_get_user( lowest_scheduled );
} else {
( *insert_ready )( context, node );
}
return needs_help;
}
/**
@@ -557,7 +570,7 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
* @param[in] allocate_processor Function to allocate a processor to a node
* based on the rules of the scheduler.
*/
static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
static inline Thread_Control *_Scheduler_SMP_Enqueue_scheduled_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Chain_Node_order order,
@@ -569,6 +582,7 @@ static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
)
{
Scheduler_Node *highest_ready = ( *get_highest_ready )( context, node );
Thread_Control *needs_help;
_Assert( highest_ready != NULL );
@@ -578,6 +592,8 @@ static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
*/
if ( ( *order )( &node->Node, &highest_ready->Node ) ) {
( *insert_scheduled )( context, node );
needs_help = NULL;
} else {
_Scheduler_SMP_Node_change_state(
_Scheduler_SMP_Node_downcast( node ),
@@ -593,7 +609,11 @@ static inline void _Scheduler_SMP_Enqueue_scheduled_ordered(
( *insert_ready )( context, node );
( *move_from_ready_to_scheduled )( context, highest_ready );
needs_help = _Scheduler_Node_get_user( node );
}
return needs_help;
}
static inline void _Scheduler_SMP_Extract_from_scheduled(
@@ -663,7 +683,7 @@ static inline void _Scheduler_SMP_Block(
}
}
static inline void _Scheduler_SMP_Unblock(
static inline Thread_Control *_Scheduler_SMP_Unblock(
Scheduler_Context *context,
Thread_Control *thread,
Scheduler_SMP_Enqueue enqueue_fifo
@@ -673,23 +693,24 @@ static inline void _Scheduler_SMP_Unblock(
_Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
( *enqueue_fifo )( context, &node->Base );
return ( *enqueue_fifo )( context, &node->Base, thread );
}
static inline void _Scheduler_SMP_Change_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,
Scheduler_SMP_Enqueue enqueue_lifo,
Scheduler_SMP_Enqueue enqueue_scheduled_fifo,
Scheduler_SMP_Enqueue enqueue_scheduled_lifo
static inline Thread_Control *_Scheduler_SMP_Change_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,
Scheduler_SMP_Enqueue enqueue_lifo,
Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_fifo,
Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_lifo
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread );
Thread_Control *needs_help;
if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
_Scheduler_SMP_Extract_from_scheduled( &node->Base );
@@ -697,9 +718,9 @@ static inline void _Scheduler_SMP_Change_priority(
( *update )( context, &node->Base, new_priority );
if ( prepend_it ) {
( *enqueue_scheduled_lifo )( context, &node->Base );
needs_help = ( *enqueue_scheduled_lifo )( context, &node->Base );
} else {
( *enqueue_scheduled_fifo )( context, &node->Base );
needs_help = ( *enqueue_scheduled_fifo )( context, &node->Base );
}
} else {
( *extract_from_ready )( context, &node->Base );
@@ -707,32 +728,37 @@ static inline void _Scheduler_SMP_Change_priority(
( *update )( context, &node->Base, new_priority );
if ( prepend_it ) {
( *enqueue_lifo )( context, &node->Base );
needs_help = ( *enqueue_lifo )( context, &node->Base, NULL );
} else {
( *enqueue_fifo )( context, &node->Base );
needs_help = ( *enqueue_fifo )( context, &node->Base, NULL );
}
}
return needs_help;
}
static inline void _Scheduler_SMP_Yield(
Scheduler_Context *context,
Thread_Control *thread,
Scheduler_SMP_Extract extract_from_ready,
Scheduler_SMP_Enqueue enqueue_fifo,
Scheduler_SMP_Enqueue enqueue_scheduled_fifo
static inline Thread_Control *_Scheduler_SMP_Yield(
Scheduler_Context *context,
Thread_Control *thread,
Scheduler_SMP_Extract extract_from_ready,
Scheduler_SMP_Enqueue enqueue_fifo,
Scheduler_SMP_Enqueue_scheduled enqueue_scheduled_fifo
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_node( thread );
Thread_Control *needs_help;
if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
_Scheduler_SMP_Extract_from_scheduled( &node->Base );
( *enqueue_scheduled_fifo )( context, &node->Base );
needs_help = ( *enqueue_scheduled_fifo )( context, &node->Base );
} else {
( *extract_from_ready )( context, &node->Base );
( *enqueue_fifo )( context, &node->Base );
needs_help = ( *enqueue_fifo )( context, &node->Base, NULL );
}
return needs_help;
}
static inline void _Scheduler_SMP_Insert_scheduled_lifo(
+3 -1
View File
@@ -25,7 +25,7 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/watchdogimpl.h>
void _Scheduler_CBS_Unblock(
Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
@@ -84,4 +84,6 @@ void _Scheduler_CBS_Unblock(
the_thread->current_priority == 0 )
_Thread_Dispatch_necessary = true;
}
SCHEDULER_RETURN_VOID_OR_NULL;
}
@@ -20,7 +20,7 @@
#include <rtems/score/scheduleredfimpl.h>
void _Scheduler_EDF_Change_priority(
Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -33,4 +33,6 @@ void _Scheduler_EDF_Change_priority(
_RBTree_Extract( &context->Ready, &node->Node );
_RBTree_Insert( &context->Ready, &node->Node );
SCHEDULER_RETURN_VOID_OR_NULL;
}
+3 -1
View File
@@ -22,7 +22,7 @@
#include <rtems/score/schedulerimpl.h>
#include <rtems/score/thread.h>
void _Scheduler_EDF_Unblock(
Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
@@ -51,4 +51,6 @@ void _Scheduler_EDF_Unblock(
the_thread->current_priority == 0 )
_Thread_Dispatch_necessary = true;
}
SCHEDULER_RETURN_VOID_OR_NULL;
}
+3 -1
View File
@@ -21,7 +21,7 @@
#include <rtems/score/scheduleredfimpl.h>
void _Scheduler_EDF_Yield(
Scheduler_Void_or_thread _Scheduler_EDF_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
@@ -38,4 +38,6 @@ void _Scheduler_EDF_Yield(
_RBTree_Insert( &context->Ready, &node->Node );
_Scheduler_EDF_Schedule_body( scheduler, the_thread, false );
SCHEDULER_RETURN_VOID_OR_NULL;
}
+31 -18
View File
@@ -288,14 +288,16 @@ static Scheduler_Node * _Scheduler_priority_affinity_SMP_Get_lowest_scheduled(
* _Scheduler_priority_affinity_SMP_Get_lowest_scheduled into
* _Scheduler_SMP_Enqueue_ordered.
*/
static void _Scheduler_priority_affinity_SMP_Enqueue_fifo(
static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_fifo(
Scheduler_Context *context,
Scheduler_Node *node
Scheduler_Node *node,
Thread_Control *needs_help
)
{
_Scheduler_SMP_Enqueue_ordered(
return _Scheduler_SMP_Enqueue_ordered(
context,
node,
needs_help,
_Scheduler_priority_affinity_SMP_Insert_priority_fifo_order,
_Scheduler_priority_SMP_Insert_ready_fifo,
_Scheduler_SMP_Insert_scheduled_fifo,
@@ -374,14 +376,15 @@ static void _Scheduler_priority_affinity_SMP_Check_for_migrations(
/*
* This is the public scheduler specific Unblock operation.
*/
void _Scheduler_priority_affinity_SMP_Unblock(
Thread_Control *_Scheduler_priority_affinity_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
Thread_Control *needs_help;
_Scheduler_SMP_Unblock(
needs_help = _Scheduler_SMP_Unblock(
context,
thread,
_Scheduler_priority_affinity_SMP_Enqueue_fifo
@@ -391,23 +394,27 @@ void _Scheduler_priority_affinity_SMP_Unblock(
* Perform any thread migrations that are needed due to these changes.
*/
_Scheduler_priority_affinity_SMP_Check_for_migrations( context );
return needs_help;
}
/*
* This is unique to this scheduler because it passes scheduler specific
* get_lowest_scheduled helper to _Scheduler_SMP_Enqueue_ordered.
*/
static void _Scheduler_priority_affinity_SMP_Enqueue_ordered(
static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Thread_Control *needs_help,
Chain_Node_order order,
Scheduler_SMP_Insert insert_ready,
Scheduler_SMP_Insert insert_scheduled
)
{
_Scheduler_SMP_Enqueue_ordered(
return _Scheduler_SMP_Enqueue_ordered(
context,
node,
needs_help,
order,
insert_ready,
insert_scheduled,
@@ -422,14 +429,16 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_ordered(
* to _Scheduler_priority_affinity_SMP_Enqueue_ordered() which
* invokes a scheduler unique get_lowest_scheduled helper.
*/
static void _Scheduler_priority_affinity_SMP_Enqueue_lifo(
static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_lifo(
Scheduler_Context *context,
Scheduler_Node *node
Scheduler_Node *node,
Thread_Control *needs_help
)
{
_Scheduler_priority_affinity_SMP_Enqueue_ordered(
return _Scheduler_priority_affinity_SMP_Enqueue_ordered(
context,
node,
needs_help,
_Scheduler_priority_affinity_SMP_Insert_priority_lifo_order,
_Scheduler_priority_SMP_Insert_ready_lifo,
_Scheduler_SMP_Insert_scheduled_lifo
@@ -441,7 +450,8 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_lifo(
* invoke _Scheduler_SMP_Enqueue_scheduled_ordered() with
* this scheduler's get_highest_ready() helper.
*/
static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
static Thread_Control *
_Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Chain_Node_order order,
@@ -449,7 +459,7 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
Scheduler_SMP_Insert insert_scheduled
)
{
_Scheduler_SMP_Enqueue_scheduled_ordered(
return _Scheduler_SMP_Enqueue_scheduled_ordered(
context,
node,
order,
@@ -466,12 +476,12 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
* to _Scheduler_priority_affinity_SMP_Enqueue_scheduled__ordered() which
* invokes a scheduler unique get_lowest_scheduled helper.
*/
static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo(
static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo(
Scheduler_Context *context,
Scheduler_Node *node
)
{
_Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
return _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
context,
node,
_Scheduler_SMP_Insert_priority_lifo_order,
@@ -485,12 +495,12 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_lifo(
* to _Scheduler_priority_affinity_SMP_Enqueue_scheduled__ordered() which
* invokes a scheduler unique get_lowest_scheduled helper.
*/
static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
Scheduler_Context *context,
Scheduler_Node *node
)
{
_Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
return _Scheduler_priority_affinity_SMP_Enqueue_scheduled_ordered(
context,
node,
_Scheduler_SMP_Insert_priority_fifo_order,
@@ -502,7 +512,7 @@ static void _Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
/*
* This is the public scheduler specific Change Priority operation.
*/
void _Scheduler_priority_affinity_SMP_Change_priority(
Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority,
@@ -510,8 +520,9 @@ void _Scheduler_priority_affinity_SMP_Change_priority(
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
Thread_Control *displaced;
_Scheduler_SMP_Change_priority(
displaced = _Scheduler_SMP_Change_priority(
context,
thread,
new_priority,
@@ -528,6 +539,8 @@ void _Scheduler_priority_affinity_SMP_Change_priority(
* Perform any thread migrations that are needed due to these changes.
*/
_Scheduler_priority_affinity_SMP_Check_for_migrations( context );
return displaced;
}
/*
@@ -21,7 +21,7 @@
#include <rtems/score/schedulerpriorityimpl.h>
void _Scheduler_priority_Change_priority(
Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -58,4 +58,6 @@ void _Scheduler_priority_Change_priority(
&context->Bit_map
);
}
SCHEDULER_RETURN_VOID_OR_NULL;
}
+30 -24
View File
@@ -97,17 +97,19 @@ void _Scheduler_priority_SMP_Block(
);
}
static void _Scheduler_priority_SMP_Enqueue_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Chain_Node_order order,
Scheduler_SMP_Insert insert_ready,
Scheduler_SMP_Insert insert_scheduled
static Thread_Control *_Scheduler_priority_SMP_Enqueue_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Thread_Control *needs_help,
Chain_Node_order order,
Scheduler_SMP_Insert insert_ready,
Scheduler_SMP_Insert insert_scheduled
)
{
_Scheduler_SMP_Enqueue_ordered(
return _Scheduler_SMP_Enqueue_ordered(
context,
node,
needs_help,
order,
insert_ready,
insert_scheduled,
@@ -117,35 +119,39 @@ static void _Scheduler_priority_SMP_Enqueue_ordered(
);
}
static void _Scheduler_priority_SMP_Enqueue_lifo(
static Thread_Control *_Scheduler_priority_SMP_Enqueue_lifo(
Scheduler_Context *context,
Scheduler_Node *node
Scheduler_Node *node,
Thread_Control *needs_help
)
{
_Scheduler_priority_SMP_Enqueue_ordered(
return _Scheduler_priority_SMP_Enqueue_ordered(
context,
node,
needs_help,
_Scheduler_SMP_Insert_priority_lifo_order,
_Scheduler_priority_SMP_Insert_ready_lifo,
_Scheduler_SMP_Insert_scheduled_lifo
);
}
static void _Scheduler_priority_SMP_Enqueue_fifo(
static Thread_Control *_Scheduler_priority_SMP_Enqueue_fifo(
Scheduler_Context *context,
Scheduler_Node *node
Scheduler_Node *node,
Thread_Control *needs_help
)
{
_Scheduler_priority_SMP_Enqueue_ordered(
return _Scheduler_priority_SMP_Enqueue_ordered(
context,
node,
needs_help,
_Scheduler_SMP_Insert_priority_fifo_order,
_Scheduler_priority_SMP_Insert_ready_fifo,
_Scheduler_SMP_Insert_scheduled_fifo
);
}
static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Chain_Node_order order,
@@ -153,7 +159,7 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
Scheduler_SMP_Insert insert_scheduled
)
{
_Scheduler_SMP_Enqueue_scheduled_ordered(
return _Scheduler_SMP_Enqueue_scheduled_ordered(
context,
node,
order,
@@ -165,12 +171,12 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
);
}
static void _Scheduler_priority_SMP_Enqueue_scheduled_lifo(
static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_lifo(
Scheduler_Context *context,
Scheduler_Node *node
)
{
_Scheduler_priority_SMP_Enqueue_scheduled_ordered(
return _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
context,
node,
_Scheduler_SMP_Insert_priority_lifo_order,
@@ -179,12 +185,12 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_lifo(
);
}
static void _Scheduler_priority_SMP_Enqueue_scheduled_fifo(
static Thread_Control *_Scheduler_priority_SMP_Enqueue_scheduled_fifo(
Scheduler_Context *context,
Scheduler_Node *node
)
{
_Scheduler_priority_SMP_Enqueue_scheduled_ordered(
return _Scheduler_priority_SMP_Enqueue_scheduled_ordered(
context,
node,
_Scheduler_SMP_Insert_priority_fifo_order,
@@ -193,21 +199,21 @@ static void _Scheduler_priority_SMP_Enqueue_scheduled_fifo(
);
}
void _Scheduler_priority_SMP_Unblock(
Thread_Control *_Scheduler_priority_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
_Scheduler_SMP_Unblock(
return _Scheduler_SMP_Unblock(
context,
thread,
_Scheduler_priority_SMP_Enqueue_fifo
);
}
void _Scheduler_priority_SMP_Change_priority(
Thread_Control *_Scheduler_priority_SMP_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority,
@@ -216,7 +222,7 @@ void _Scheduler_priority_SMP_Change_priority(
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
_Scheduler_SMP_Change_priority(
return _Scheduler_SMP_Change_priority(
context,
thread,
new_priority,
@@ -230,7 +236,7 @@ void _Scheduler_priority_SMP_Change_priority(
);
}
void _Scheduler_priority_SMP_Yield(
Thread_Control *_Scheduler_priority_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread
)
+3 -1
View File
@@ -22,7 +22,7 @@
#include <rtems/score/schedulerpriorityimpl.h>
void _Scheduler_priority_Unblock (
Scheduler_Void_or_thread _Scheduler_priority_Unblock (
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
@@ -57,4 +57,6 @@ void _Scheduler_priority_Unblock (
the_thread->current_priority == 0 )
_Thread_Dispatch_necessary = true;
}
SCHEDULER_RETURN_VOID_OR_NULL;
}
+3 -1
View File
@@ -21,7 +21,7 @@
#include <rtems/score/schedulerpriorityimpl.h>
#include <rtems/score/threadimpl.h>
void _Scheduler_priority_Yield(
Scheduler_Void_or_thread _Scheduler_priority_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
@@ -43,4 +43,6 @@ void _Scheduler_priority_Yield(
} else if ( !_Thread_Is_heir( the_thread ) ) {
_Thread_Dispatch_necessary = true;
}
SCHEDULER_RETURN_VOID_OR_NULL;
}
@@ -21,7 +21,7 @@
#include <rtems/score/schedulersimpleimpl.h>
void _Scheduler_simple_Change_priority(
Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Priority_Control new_priority,
@@ -38,4 +38,6 @@ void _Scheduler_simple_Change_priority(
} else {
_Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
}
SCHEDULER_RETURN_VOID_OR_NULL;
}
+30 -24
View File
@@ -179,17 +179,19 @@ void _Scheduler_simple_SMP_Block(
);
}
static void _Scheduler_simple_SMP_Enqueue_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Chain_Node_order order,
Scheduler_SMP_Insert insert_ready,
Scheduler_SMP_Insert insert_scheduled
static Thread_Control *_Scheduler_simple_SMP_Enqueue_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Thread_Control *needs_help,
Chain_Node_order order,
Scheduler_SMP_Insert insert_ready,
Scheduler_SMP_Insert insert_scheduled
)
{
_Scheduler_SMP_Enqueue_ordered(
return _Scheduler_SMP_Enqueue_ordered(
context,
node,
needs_help,
order,
insert_ready,
insert_scheduled,
@@ -199,35 +201,39 @@ static void _Scheduler_simple_SMP_Enqueue_ordered(
);
}
static void _Scheduler_simple_SMP_Enqueue_lifo(
static Thread_Control *_Scheduler_simple_SMP_Enqueue_lifo(
Scheduler_Context *context,
Scheduler_Node *node
Scheduler_Node *node,
Thread_Control *needs_help
)
{
_Scheduler_simple_SMP_Enqueue_ordered(
return _Scheduler_simple_SMP_Enqueue_ordered(
context,
node,
needs_help,
_Scheduler_SMP_Insert_priority_lifo_order,
_Scheduler_simple_SMP_Insert_ready_lifo,
_Scheduler_SMP_Insert_scheduled_lifo
);
}
static void _Scheduler_simple_SMP_Enqueue_fifo(
static Thread_Control *_Scheduler_simple_SMP_Enqueue_fifo(
Scheduler_Context *context,
Scheduler_Node *node
Scheduler_Node *node,
Thread_Control *needs_help
)
{
_Scheduler_simple_SMP_Enqueue_ordered(
return _Scheduler_simple_SMP_Enqueue_ordered(
context,
node,
needs_help,
_Scheduler_SMP_Insert_priority_fifo_order,
_Scheduler_simple_SMP_Insert_ready_fifo,
_Scheduler_SMP_Insert_scheduled_fifo
);
}
static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_ordered(
Scheduler_Context *context,
Scheduler_Node *node,
Chain_Node_order order,
@@ -235,7 +241,7 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
Scheduler_SMP_Insert insert_scheduled
)
{
_Scheduler_SMP_Enqueue_scheduled_ordered(
return _Scheduler_SMP_Enqueue_scheduled_ordered(
context,
node,
order,
@@ -247,12 +253,12 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
);
}
static void _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_lifo(
Scheduler_Context *context,
Scheduler_Node *node
)
{
_Scheduler_simple_SMP_Enqueue_scheduled_ordered(
return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
context,
node,
_Scheduler_SMP_Insert_priority_lifo_order,
@@ -261,12 +267,12 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_lifo(
);
}
static void _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
static Thread_Control *_Scheduler_simple_SMP_Enqueue_scheduled_fifo(
Scheduler_Context *context,
Scheduler_Node *node
)
{
_Scheduler_simple_SMP_Enqueue_scheduled_ordered(
return _Scheduler_simple_SMP_Enqueue_scheduled_ordered(
context,
node,
_Scheduler_SMP_Insert_priority_fifo_order,
@@ -275,21 +281,21 @@ static void _Scheduler_simple_SMP_Enqueue_scheduled_fifo(
);
}
void _Scheduler_simple_SMP_Unblock(
Thread_Control *_Scheduler_simple_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
_Scheduler_SMP_Unblock(
return _Scheduler_SMP_Unblock(
context,
thread,
_Scheduler_simple_SMP_Enqueue_fifo
);
}
void _Scheduler_simple_SMP_Change_priority(
Thread_Control *_Scheduler_simple_SMP_Change_priority(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Priority_Control new_priority,
@@ -298,7 +304,7 @@ void _Scheduler_simple_SMP_Change_priority(
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
_Scheduler_SMP_Change_priority(
return _Scheduler_SMP_Change_priority(
context,
thread,
new_priority,
@@ -312,7 +318,7 @@ void _Scheduler_simple_SMP_Change_priority(
);
}
void _Scheduler_simple_SMP_Yield(
Thread_Control *_Scheduler_simple_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread
)
+3 -1
View File
@@ -21,7 +21,7 @@
#include <rtems/score/schedulersimpleimpl.h>
#include <rtems/score/thread.h>
void _Scheduler_simple_Unblock(
Scheduler_Void_or_thread _Scheduler_simple_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
@@ -49,4 +49,6 @@ void _Scheduler_simple_Unblock(
the_thread->current_priority == 0 )
_Thread_Dispatch_necessary = true;
}
SCHEDULER_RETURN_VOID_OR_NULL;
}
+3 -1
View File
@@ -20,7 +20,7 @@
#include <rtems/score/schedulersimpleimpl.h>
void _Scheduler_simple_Yield(
Scheduler_Void_or_thread _Scheduler_simple_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
@@ -31,4 +31,6 @@ void _Scheduler_simple_Yield(
_Chain_Extract_unprotected( &the_thread->Object.Node );
_Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );
_Scheduler_simple_Schedule_body( scheduler, the_thread, false );
SCHEDULER_RETURN_VOID_OR_NULL;
}
+387 -16
View File
@@ -53,7 +53,40 @@ static void task(rtems_task_argument arg)
rtems_test_assert(0);
}
static void test_case(
static rtems_id start_task(rtems_task_priority prio)
{
rtems_status_code sc;
rtems_id task_id;
sc = rtems_task_create(
rtems_build_name('T', 'A', 'S', 'K'),
prio,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&task_id
);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
sc = rtems_task_start(task_id, task, 0);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
return task_id;
}
static Thread_Control *get_thread_by_id(rtems_id task_id)
{
Objects_Locations location;
Thread_Control *thread;
thread = _Thread_Get(task_id, &location);
rtems_test_assert(location == OBJECTS_LOCAL);
_Thread_Enable_dispatch();
return thread;
}
static void test_case_change_priority(
Thread_Control *executing,
Scheduler_SMP_Node *node,
Scheduler_SMP_Node_state start_state,
@@ -98,18 +131,7 @@ static void test_change_priority(void)
size_t j;
size_t k;
sc = rtems_task_create(
rtems_build_name('T', 'A', 'S', 'K'),
3,
RTEMS_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&task_id
);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
sc = rtems_task_start(task_id, task, 0);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
task_id = start_task(3);
_Thread_Disable_dispatch();
@@ -119,7 +141,7 @@ static void test_change_priority(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(
test_case_change_priority(
executing,
node,
states[i],
@@ -140,11 +162,360 @@ static void test_change_priority(void)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
static Thread_Control *change_priority_op(
Thread_Control *thread,
Priority_Control new_priority,
bool prepend_it
)
{
const Scheduler_Control *scheduler = _Scheduler_Get(thread);
Thread_Control *needs_help;
ISR_Level level;
_ISR_Disable( level );
thread->current_priority = new_priority;
needs_help = (*scheduler->Operations.change_priority)(
scheduler,
thread,
new_priority,
prepend_it
);
_ISR_Enable( level );
return needs_help;
}
static void test_case_change_priority_op(
Thread_Control *executing,
Scheduler_SMP_Node *executing_node,
Thread_Control *other,
Scheduler_SMP_Node_state start_state,
Priority_Control prio,
bool prepend_it,
Scheduler_SMP_Node_state new_state
)
{
Thread_Control *needs_help;
switch (start_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
_Thread_Change_priority(executing, 1, true);
break;
case SCHEDULER_SMP_NODE_READY:
_Thread_Change_priority(executing, 4, true);
break;
default:
rtems_test_assert(0);
break;
}
rtems_test_assert(executing_node->state == start_state);
needs_help = change_priority_op(executing, prio, prepend_it);
rtems_test_assert(executing_node->state == new_state);
if (start_state != new_state) {
switch (start_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
rtems_test_assert(needs_help == executing);
break;
case SCHEDULER_SMP_NODE_READY:
rtems_test_assert(needs_help == other);
break;
default:
rtems_test_assert(0);
break;
}
} else {
rtems_test_assert(needs_help == NULL);
}
}
static void test_change_priority_op(void)
{
rtems_status_code sc;
rtems_id task_id;
Thread_Control *executing;
Scheduler_SMP_Node *executing_node;
Thread_Control *other;
size_t i;
size_t j;
size_t k;
task_id = start_task(3);
_Thread_Disable_dispatch();
executing = _Thread_Executing;
executing_node = _Scheduler_SMP_Thread_get_node(executing);
other = get_thread_by_id(task_id);
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(
executing,
executing_node,
other,
states[i],
priorities[j],
prepend_it[k],
states[j]
);
}
}
}
_Thread_Change_priority(executing, 1, true);
rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
_Thread_Enable_dispatch();
sc = rtems_task_delete(task_id);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
static Thread_Control *yield_op(Thread_Control *thread)
{
const Scheduler_Control *scheduler = _Scheduler_Get(thread);
Thread_Control *needs_help;
ISR_Level level;
_ISR_Disable( level );
needs_help = (*scheduler->Operations.yield)(scheduler, thread);
_ISR_Enable( level );
return needs_help;
}
static void test_case_yield_op(
Thread_Control *executing,
Scheduler_SMP_Node *executing_node,
Thread_Control *other,
Scheduler_SMP_Node_state start_state,
Scheduler_SMP_Node_state new_state
)
{
Thread_Control *needs_help;
_Thread_Change_priority(executing, 4, false);
_Thread_Change_priority(other, 4, false);
switch (start_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
switch (new_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
_Thread_Change_priority(executing, 2, false);
_Thread_Change_priority(other, 3, false);
break;
case SCHEDULER_SMP_NODE_READY:
_Thread_Change_priority(executing, 2, false);
_Thread_Change_priority(other, 2, false);
break;
default:
rtems_test_assert(0);
break;
}
break;
case SCHEDULER_SMP_NODE_READY:
switch (new_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
rtems_test_assert(0);
break;
case SCHEDULER_SMP_NODE_READY:
_Thread_Change_priority(executing, 3, false);
_Thread_Change_priority(other, 2, false);
break;
default:
rtems_test_assert(0);
break;
}
break;
default:
rtems_test_assert(0);
break;
}
rtems_test_assert(executing_node->state == start_state);
needs_help = yield_op(executing);
rtems_test_assert(executing_node->state == new_state);
if (start_state != new_state) {
switch (start_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
rtems_test_assert(needs_help == executing);
break;
case SCHEDULER_SMP_NODE_READY:
rtems_test_assert(needs_help == other);
break;
default:
rtems_test_assert(0);
break;
}
} else {
rtems_test_assert(needs_help == NULL);
}
}
static void test_yield_op(void)
{
rtems_status_code sc;
rtems_id task_id;
Thread_Control *executing;
Scheduler_SMP_Node *executing_node;
Thread_Control *other;
size_t i;
size_t j;
task_id = start_task(2);
_Thread_Disable_dispatch();
executing = _Thread_Executing;
executing_node = _Scheduler_SMP_Thread_get_node(executing);
other = get_thread_by_id(task_id);
for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
for (j = 0; j < RTEMS_ARRAY_SIZE(states); ++j) {
if (
states[i] != SCHEDULER_SMP_NODE_READY
|| states[j] != SCHEDULER_SMP_NODE_SCHEDULED
) {
test_case_yield_op(
executing,
executing_node,
other,
states[i],
states[j]
);
}
}
}
_Thread_Change_priority(executing, 1, true);
rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
_Thread_Enable_dispatch();
sc = rtems_task_delete(task_id);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
static void block_op(Thread_Control *thread)
{
const Scheduler_Control *scheduler = _Scheduler_Get(thread);
ISR_Level level;
_ISR_Disable( level );
(*scheduler->Operations.block)(scheduler, thread);
_ISR_Enable( level );
}
static Thread_Control *unblock_op(Thread_Control *thread)
{
const Scheduler_Control *scheduler = _Scheduler_Get(thread);
Thread_Control *needs_help;
ISR_Level level;
_ISR_Disable( level );
needs_help = (*scheduler->Operations.unblock)(scheduler, thread);
_ISR_Enable( level );
return needs_help;
}
static void test_case_unblock_op(
Thread_Control *executing,
Scheduler_SMP_Node *executing_node,
Thread_Control *other,
Scheduler_SMP_Node_state new_state
)
{
Thread_Control *needs_help;
switch (new_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
_Thread_Change_priority(executing, 2, false);
rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
break;
case SCHEDULER_SMP_NODE_READY:
_Thread_Change_priority(executing, 4, false);
rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_READY);
break;
default:
rtems_test_assert(0);
break;
}
block_op(executing);
rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_BLOCKED);
needs_help = unblock_op(executing);
rtems_test_assert(executing_node->state == new_state);
switch (new_state) {
case SCHEDULER_SMP_NODE_SCHEDULED:
rtems_test_assert(needs_help == other);
break;
case SCHEDULER_SMP_NODE_READY:
rtems_test_assert(needs_help == executing);
break;
default:
rtems_test_assert(0);
break;
}
}
static void test_unblock_op(void)
{
rtems_status_code sc;
rtems_id task_id;
Thread_Control *executing;
Scheduler_SMP_Node *executing_node;
Thread_Control *other;
size_t i;
task_id = start_task(3);
_Thread_Disable_dispatch();
executing = _Thread_Executing;
executing_node = _Scheduler_SMP_Thread_get_node(executing);
other = get_thread_by_id(task_id);
for (i = 0; i < RTEMS_ARRAY_SIZE(states); ++i) {
test_case_unblock_op(
executing,
executing_node,
other,
states[i]
);
}
_Thread_Change_priority(executing, 1, true);
rtems_test_assert(executing_node->state == SCHEDULER_SMP_NODE_SCHEDULED);
_Thread_Enable_dispatch();
sc = rtems_task_delete(task_id);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
static void tests(void)
{
test_change_priority();
test_change_priority_op();
test_yield_op();
test_unblock_op();
}
static void test_task(rtems_task_argument arg)
{
test_context *ctx = &test_instance;
test_change_priority();
tests();
ctx->cpu_index[arg] = rtems_get_current_processor();
@@ -202,7 +573,7 @@ static void Init(rtems_task_argument arg)
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
}
test_change_priority();
tests();
barrier_wait(ctx);