forked from Imagelibrary/rtems
score: Add scheduler node requests
Add the ability to add/remove scheduler nodes to/from the set of scheduler nodes available to the schedulers for a particular thread. Update #2556.
This commit is contained in:
@@ -1471,6 +1471,14 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
|
||||
&the_thread->Scheduler.Wait_nodes,
|
||||
&new_scheduler_node->Thread.Wait_node
|
||||
);
|
||||
_Chain_Extract_unprotected(
|
||||
&old_scheduler_node->Thread.Scheduler_node.Chain
|
||||
);
|
||||
_Assert( _Chain_Is_empty( &the_thread->Scheduler.Scheduler_nodes ) );
|
||||
_Chain_Initialize_one(
|
||||
&the_thread->Scheduler.Scheduler_nodes,
|
||||
&new_scheduler_node->Thread.Scheduler_node.Chain
|
||||
);
|
||||
|
||||
{
|
||||
const Scheduler_Control *old_scheduler;
|
||||
|
||||
@@ -95,10 +95,43 @@ typedef enum {
|
||||
} Scheduler_Help_state;
|
||||
#endif
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
/**
|
||||
* @brief The scheduler node requests.
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* @brief The scheduler node is not on the list of pending requests.
|
||||
*/
|
||||
SCHEDULER_NODE_REQUEST_NOT_PENDING,
|
||||
|
||||
/**
|
||||
* @brief There is a pending scheduler node request to add this scheduler
|
||||
* node to the Thread_Control::Scheduler::Scheduler_nodes chain.
|
||||
*/
|
||||
SCHEDULER_NODE_REQUEST_ADD,
|
||||
|
||||
/**
|
||||
* @brief There is a pending scheduler node request to remove this scheduler
|
||||
* node from the Thread_Control::Scheduler::Scheduler_nodes chain.
|
||||
*/
|
||||
SCHEDULER_NODE_REQUEST_REMOVE,
|
||||
|
||||
/**
|
||||
* @brief The scheduler node is on the list of pending requests, but nothing
|
||||
* should change.
|
||||
*/
|
||||
SCHEDULER_NODE_REQUEST_NOTHING,
|
||||
|
||||
} Scheduler_Node_request;
|
||||
#endif
|
||||
|
||||
typedef struct Scheduler_Node Scheduler_Node;
|
||||
|
||||
/**
|
||||
* @brief Scheduler node for per-thread data.
|
||||
*/
|
||||
typedef struct Scheduler_Node {
|
||||
struct Scheduler_Node {
|
||||
#if defined(RTEMS_SMP)
|
||||
/**
|
||||
* @brief Chain node for usage in various scheduler data structures.
|
||||
@@ -149,6 +182,28 @@ typedef struct Scheduler_Node {
|
||||
* Thread_Control::Scheduler::Wait_nodes.
|
||||
*/
|
||||
Chain_Node Wait_node;
|
||||
|
||||
/**
|
||||
* @brief Node to add this scheduler node to
|
||||
* Thread_Control::Scheduler::Scheduler_nodes.
|
||||
*/
|
||||
union {
|
||||
/**
|
||||
* @brief The node for Thread_Control::Scheduler::Scheduler_nodes.
|
||||
*/
|
||||
Chain_Node Chain;
|
||||
} Scheduler_node;
|
||||
|
||||
/**
|
||||
* @brief Link to the next scheduler node in the
|
||||
* Thread_Control::Scheduler::requests list.
|
||||
*/
|
||||
Scheduler_Node *next_request;
|
||||
|
||||
/**
|
||||
* @brief The current scheduler node request.
|
||||
*/
|
||||
Scheduler_Node_request request;
|
||||
} Thread;
|
||||
#endif
|
||||
|
||||
@@ -198,7 +253,7 @@ typedef struct Scheduler_Node {
|
||||
*/
|
||||
bool prepend_it;
|
||||
} Priority;
|
||||
} Scheduler_Node;
|
||||
};
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
/**
|
||||
@@ -212,6 +267,9 @@ extern const size_t _Scheduler_Node_size;
|
||||
#if defined(RTEMS_SMP)
|
||||
#define SCHEDULER_NODE_OF_THREAD_WAIT_NODE( node ) \
|
||||
RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Wait_node )
|
||||
|
||||
#define SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node ) \
|
||||
RTEMS_CONTAINER_OF( node, Scheduler_Node, Thread.Scheduler_node.Chain )
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -300,6 +300,21 @@ typedef struct {
|
||||
* This chain is protected by the thread wait lock.
|
||||
*/
|
||||
Chain_Control Wait_nodes;
|
||||
|
||||
/**
|
||||
* @brief Scheduler nodes immediately available to the schedulers for this
|
||||
* thread.
|
||||
*
|
||||
* This chain is protected by the thread state lock.
|
||||
*/
|
||||
Chain_Control Scheduler_nodes;
|
||||
|
||||
/**
|
||||
* @brief List of pending scheduler node requests.
|
||||
*
|
||||
* This list is protected by the thread scheduler lock.
|
||||
*/
|
||||
Scheduler_Node *requests;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -1051,6 +1051,42 @@ RTEMS_INLINE_ROUTINE void _Thread_Scheduler_release_critical(
|
||||
_ISR_lock_Release( &the_thread->Scheduler.Lock, lock_context );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_request(
|
||||
Thread_Control *the_thread,
|
||||
Scheduler_Node *scheduler_node,
|
||||
Scheduler_Node_request request
|
||||
)
|
||||
{
|
||||
ISR_lock_Context lock_context;
|
||||
Scheduler_Node_request current_request;
|
||||
|
||||
_Thread_Scheduler_acquire_critical( the_thread, &lock_context );
|
||||
|
||||
current_request = scheduler_node->Thread.request;
|
||||
|
||||
if ( current_request == SCHEDULER_NODE_REQUEST_NOT_PENDING ) {
|
||||
_Assert(
|
||||
request == SCHEDULER_NODE_REQUEST_ADD
|
||||
|| request == SCHEDULER_NODE_REQUEST_REMOVE
|
||||
);
|
||||
_Assert( scheduler_node->Thread.next_request == NULL );
|
||||
scheduler_node->Thread.next_request = the_thread->Scheduler.requests;
|
||||
the_thread->Scheduler.requests = scheduler_node;
|
||||
} else if ( current_request != SCHEDULER_NODE_REQUEST_NOTHING ) {
|
||||
_Assert(
|
||||
( current_request == SCHEDULER_NODE_REQUEST_ADD
|
||||
&& request == SCHEDULER_NODE_REQUEST_REMOVE )
|
||||
|| ( current_request == SCHEDULER_NODE_REQUEST_REMOVE
|
||||
&& request == SCHEDULER_NODE_REQUEST_ADD )
|
||||
);
|
||||
request = SCHEDULER_NODE_REQUEST_NOTHING;
|
||||
}
|
||||
|
||||
scheduler_node->Thread.request = request;
|
||||
|
||||
_Thread_Scheduler_release_critical( the_thread, &lock_context );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_wait_node(
|
||||
Thread_Control *the_thread,
|
||||
Scheduler_Node *scheduler_node
|
||||
@@ -1060,6 +1096,11 @@ RTEMS_INLINE_ROUTINE void _Thread_Scheduler_add_wait_node(
|
||||
&the_thread->Scheduler.Wait_nodes,
|
||||
&scheduler_node->Thread.Wait_node
|
||||
);
|
||||
_Thread_Scheduler_add_request(
|
||||
the_thread,
|
||||
scheduler_node,
|
||||
SCHEDULER_NODE_REQUEST_ADD
|
||||
);
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Scheduler_remove_wait_node(
|
||||
@@ -1067,8 +1108,12 @@ RTEMS_INLINE_ROUTINE void _Thread_Scheduler_remove_wait_node(
|
||||
Scheduler_Node *scheduler_node
|
||||
)
|
||||
{
|
||||
(void) the_thread;
|
||||
_Chain_Extract_unprotected( &scheduler_node->Thread.Wait_node );
|
||||
_Thread_Scheduler_add_request(
|
||||
the_thread,
|
||||
scheduler_node,
|
||||
SCHEDULER_NODE_REQUEST_REMOVE
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -210,6 +210,10 @@ bool _Thread_Initialize(
|
||||
&the_thread->Scheduler.Wait_nodes,
|
||||
&scheduler_node->Thread.Wait_node
|
||||
);
|
||||
_Chain_Initialize_one(
|
||||
&the_thread->Scheduler.Scheduler_nodes,
|
||||
&scheduler_node->Thread.Scheduler_node.Chain
|
||||
);
|
||||
#else
|
||||
scheduler_node = _Thread_Scheduler_get_own_node( the_thread );
|
||||
_Scheduler_Node_initialize(
|
||||
|
||||
Reference in New Issue
Block a user