score: Add scheduler node table for each thread

Update #2556.
This commit is contained in:
Sebastian Huber
2016-09-21 08:59:32 +02:00
parent 300f6a481a
commit 5d6b211981
7 changed files with 156 additions and 58 deletions
+35 -29
View File
@@ -3224,38 +3224,44 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
)
#ifdef CONFIGURE_INIT
typedef union {
Scheduler_Node Base;
#ifdef CONFIGURE_SCHEDULER_CBS
Scheduler_CBS_Node CBS;
#endif
#ifdef CONFIGURE_SCHEDULER_EDF
Scheduler_EDF_Node EDF;
#endif
#ifdef CONFIGURE_SCHEDULER_PRIORITY
Scheduler_priority_Node Priority;
#endif
#ifdef CONFIGURE_SCHEDULER_SIMPLE_SMP
Scheduler_SMP_Node Simple_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_PRIORITY_SMP
Scheduler_priority_SMP_Node Priority_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
Scheduler_priority_affinity_SMP_Node Priority_affinity_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_STRONG_APA
Scheduler_strong_APA_Node Strong_APA;
#endif
#ifdef CONFIGURE_SCHEDULER_USER_PER_THREAD
CONFIGURE_SCHEDULER_USER_PER_THREAD User;
#endif
} Configuration_Scheduler_node;
#ifdef RTEMS_SMP
const size_t _Scheduler_Node_size = sizeof( Configuration_Scheduler_node );
#endif
typedef struct {
Thread_Control Control;
#if CONFIGURE_MAXIMUM_USER_EXTENSIONS > 0
void *extensions[ CONFIGURE_MAXIMUM_USER_EXTENSIONS + 1 ];
#endif
union {
Scheduler_Node Base;
#ifdef CONFIGURE_SCHEDULER_CBS
Scheduler_CBS_Node CBS;
#endif
#ifdef CONFIGURE_SCHEDULER_EDF
Scheduler_EDF_Node EDF;
#endif
#ifdef CONFIGURE_SCHEDULER_PRIORITY
Scheduler_priority_Node Priority;
#endif
#ifdef CONFIGURE_SCHEDULER_SIMPLE_SMP
Scheduler_SMP_Node Simple_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_PRIORITY_SMP
Scheduler_priority_SMP_Node Priority_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
Scheduler_priority_affinity_SMP_Node Priority_affinity_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_STRONG_APA
Scheduler_strong_APA_Node Strong_APA;
#endif
#ifdef CONFIGURE_SCHEDULER_USER_PER_THREAD
CONFIGURE_SCHEDULER_USER_PER_THREAD User;
#endif
} Scheduler;
Configuration_Scheduler_node Scheduler_nodes[ CONFIGURE_SCHEDULER_COUNT ];
RTEMS_API_Control API_RTEMS;
#ifdef RTEMS_POSIX_API
POSIX_API_Control API_POSIX;
@@ -3273,8 +3279,8 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
const Thread_Control_add_on _Thread_Control_add_ons[] = {
{
offsetof( Configuration_Thread_control, Control.Scheduler.node ),
offsetof( Configuration_Thread_control, Scheduler )
offsetof( Configuration_Thread_control, Control.Scheduler.nodes ),
offsetof( Configuration_Thread_control, Scheduler_nodes )
}, {
offsetof(
Configuration_Thread_control,
@@ -772,7 +772,11 @@ RTEMS_INLINE_ROUTINE Scheduler_Node *_Scheduler_Thread_get_node(
const Thread_Control *the_thread
)
{
#if defined(RTEMS_SMP)
return the_thread->Scheduler.node;
#else
return the_thread->Scheduler.nodes;
#endif
}
RTEMS_INLINE_ROUTINE void _Scheduler_Thread_set_priority(
@@ -1377,7 +1381,8 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
Priority_Control priority
)
{
Scheduler_Node *own_node;
Scheduler_Node *new_scheduler_node;
Scheduler_Node *old_scheduler_node;
if (
_Thread_Owns_resources( the_thread )
@@ -1386,22 +1391,34 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
return STATUS_RESOURCE_IN_USE;
}
own_node = _Thread_Scheduler_get_own_node( the_thread );
_Priority_Plain_extract( &own_node->Wait.Priority, &the_thread->Real_priority );
old_scheduler_node = _Thread_Scheduler_get_own_node( the_thread );
_Priority_Plain_extract(
&old_scheduler_node->Wait.Priority,
&the_thread->Real_priority
);
if ( !_Priority_Is_empty( &own_node->Wait.Priority ) ) {
if ( !_Priority_Is_empty( &old_scheduler_node->Wait.Priority ) ) {
_Priority_Plain_insert(
&own_node->Wait.Priority,
&old_scheduler_node->Wait.Priority,
&the_thread->Real_priority,
the_thread->Real_priority.priority
);
return STATUS_RESOURCE_IN_USE;
}
#if defined(RTEMS_SMP)
new_scheduler_node = _Thread_Scheduler_get_node_by_index(
the_thread,
_Scheduler_Get_index( new_scheduler )
);
#else
new_scheduler_node = old_scheduler_node;
#endif
the_thread->Start.initial_priority = priority;
_Priority_Node_set_priority( &the_thread->Real_priority, priority );
_Priority_Initialize_one(
&own_node->Wait.Priority,
&new_scheduler_node->Wait.Priority,
&the_thread->Real_priority
);
@@ -1420,15 +1437,11 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
_Scheduler_Block( the_thread );
}
_Scheduler_Node_destroy( old_scheduler, own_node );
the_thread->Scheduler.own_control = new_scheduler;
the_thread->Scheduler.control = new_scheduler;
_Scheduler_Node_initialize(
new_scheduler,
own_node,
the_thread,
priority
);
the_thread->Scheduler.own_node = new_scheduler_node;
the_thread->Scheduler.node = new_scheduler_node;
_Scheduler_Node_set_priority( new_scheduler_node, priority, false );
if ( _States_Is_ready( current_state ) ) {
_Scheduler_Unblock( the_thread );
@@ -1439,7 +1452,7 @@ RTEMS_INLINE_ROUTINE Status_Control _Scheduler_Set(
}
#endif
_Scheduler_Node_set_priority( own_node, priority, false );
_Scheduler_Node_set_priority( new_scheduler_node, priority, false );
_Scheduler_Update_priority( the_thread );
return STATUS_SUCCESSFUL;
}
@@ -188,6 +188,15 @@ typedef struct Scheduler_Node {
} Priority;
} Scheduler_Node;
#if defined(RTEMS_SMP)
/**
* @brief The size of a scheduler node.
*
* This value is provided via <rtems/confdefs.h>.
*/
extern const size_t _Scheduler_Node_size;
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
+7 -2
View File
@@ -271,7 +271,6 @@ typedef struct {
* priority and ask for help operations.
*/
Scheduler_Node *own_node;
#endif
/**
* @brief The scheduler node of this thread.
@@ -284,12 +283,18 @@ typedef struct {
*/
Scheduler_Node *node;
#if defined(RTEMS_SMP)
/**
* @brief The processor assigned by the current scheduler.
*/
struct Per_CPU_Control *cpu;
#endif
/**
* @brief The scheduler nodes of this thread.
*
* Each thread has a scheduler node for each scheduler instance.
*/
Scheduler_Node *nodes;
} Thread_Scheduler_control;
/**
+17 -1
View File
@@ -993,7 +993,23 @@ RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_own_node(
#if defined(RTEMS_SMP)
return the_thread->Scheduler.own_node;
#else
return the_thread->Scheduler.node;
return the_thread->Scheduler.nodes;
#endif
}
RTEMS_INLINE_ROUTINE Scheduler_Node *_Thread_Scheduler_get_node_by_index(
const Thread_Control *the_thread,
size_t scheduler_index
)
{
#if defined(RTEMS_SMP)
return (Scheduler_Node *)
( (uintptr_t) the_thread->Scheduler.nodes
+ scheduler_index * _Scheduler_Node_size );
#else
_Assert( scheduler_index == 0 );
(void) scheduler_index;
return the_thread->Scheduler.nodes;
#endif
}
+60 -11
View File
@@ -53,7 +53,11 @@ bool _Thread_Initialize(
bool extension_status;
size_t i;
Scheduler_Node *scheduler_node;
bool scheduler_node_initialized = false;
#if defined(RTEMS_SMP)
Scheduler_Node *scheduler_node_for_index;
const Scheduler_Control *scheduler_for_index;
#endif
size_t scheduler_index;
Per_CPU_Control *cpu = _Per_CPU_Get_by_index( 0 );
#if defined( RTEMS_SMP )
@@ -105,6 +109,8 @@ bool _Thread_Initialize(
actual_stack_size
);
scheduler_index = 0;
/* Thread-local storage (TLS) area allocation */
if ( tls_size > 0 ) {
uintptr_t tls_align = _TLS_Heap_align_up( (uintptr_t) _TLS_Alignment );
@@ -174,13 +180,54 @@ bool _Thread_Initialize(
#endif
}
scheduler_node = the_thread->Scheduler.node;
#if defined(RTEMS_SMP)
scheduler_node_for_index = the_thread->Scheduler.nodes;
scheduler_for_index = &_Scheduler_Table[ 0 ];
while ( scheduler_index < _Scheduler_Count ) {
Priority_Control priority_for_index;
if ( scheduler_for_index == scheduler ) {
priority_for_index = priority;
scheduler_node = scheduler_node_for_index;
} else {
priority_for_index = 0;
}
_Scheduler_Node_initialize(
scheduler_for_index,
scheduler_node_for_index,
the_thread,
priority_for_index
);
scheduler_node_for_index = (Scheduler_Node *)
( (uintptr_t) scheduler_node_for_index + _Scheduler_Node_size );
++scheduler_for_index;
++scheduler_index;
}
#else
scheduler_node = _Thread_Scheduler_get_own_node( the_thread );
_Scheduler_Node_initialize(
scheduler,
scheduler_node,
the_thread,
priority
);
scheduler_index = 1;
#endif
_Priority_Node_initialize( &the_thread->Real_priority, priority );
_Priority_Initialize_one(
&scheduler_node->Wait.Priority,
&the_thread->Real_priority
);
#if defined(RTEMS_SMP)
RTEMS_STATIC_ASSERT( THREAD_SCHEDULER_BLOCKED == 0, Scheduler_state );
the_thread->Scheduler.own_control = scheduler;
the_thread->Scheduler.control = scheduler;
the_thread->Scheduler.own_node = scheduler_node;
the_thread->Scheduler.node = scheduler_node;
_Resource_Node_initialize( &the_thread->Resource_node );
_ISR_lock_Initialize(
&the_thread->Wait.Lock.Default,
@@ -202,14 +249,6 @@ bool _Thread_Initialize(
RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags );
_Priority_Node_initialize( &the_thread->Real_priority, priority );
_Priority_Initialize_one(
&scheduler_node->Wait.Priority,
&the_thread->Real_priority
);
_Scheduler_Node_initialize( scheduler, scheduler_node, the_thread, priority );
scheduler_node_initialized = true;
/* POSIX Keys */
_RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs );
_ISR_lock_Initialize( &the_thread->Keys.Lock, "POSIX Key Value Pairs" );
@@ -234,9 +273,19 @@ bool _Thread_Initialize(
failed:
if ( scheduler_node_initialized ) {
#if defined(RTEMS_SMP)
while ( scheduler_index > 0 ) {
scheduler_node_for_index = (Scheduler_Node *)
( (uintptr_t) scheduler_node_for_index - _Scheduler_Node_size );
--scheduler_for_index;
--scheduler_index;
_Scheduler_Node_destroy( scheduler_for_index, scheduler_node_for_index );
}
#else
if ( scheduler_index > 0 ) {
_Scheduler_Node_destroy( scheduler, scheduler_node );
}
#endif
_Workspace_Free( the_thread->Start.tls_area );
+1 -1
View File
@@ -78,7 +78,7 @@ void _Thread_MP_Handler_initialization (
#if defined(RTEMS_SMP)
proxy->Scheduler.own_node = &proxy->Scheduler_node;
#endif
proxy->Scheduler.node = &proxy->Scheduler_node;
proxy->Scheduler.nodes = &proxy->Scheduler_node;
_Scheduler_Node_do_initialize(
_Scheduler_Get_by_CPU_index( 0 ),
&proxy->Scheduler_node,