summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-02-02 16:24:05 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-02-03 10:17:38 +0100
commitca1e546e7772838b20d0792155e2c71514d6b5d3 (patch)
treea5af2d74d6fcefa8d36f0fa32debd886e63cca4b /cpukit/score/include/rtems
parentsparc: Fix volatile clobber (diff)
downloadrtems-ca1e546e7772838b20d0792155e2c71514d6b5d3.tar.bz2
score: Improve scheduler helping protocol
Only register ask for help requests in the scheduler unblock and yield operations. The actual ask for help operation is carried out during _Thread_Do_dispatch() on a processor related to the thread. This yields a better separation of scheduler instances. A thread of one scheduler instance should not be forced to carry out too much work for threads on other scheduler instances. Update #2556.
Diffstat (limited to 'cpukit/score/include/rtems')
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h14
-rw-r--r--cpukit/score/include/rtems/score/schedulercbs.h2
-rw-r--r--cpukit/score/include/rtems/score/scheduleredf.h4
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h139
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h4
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h2
-rw-r--r--cpukit/score/include/rtems/score/schedulerprioritysmp.h4
-rw-r--r--cpukit/score/include/rtems/score/schedulersimple.h4
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h4
-rw-r--r--cpukit/score/include/rtems/score/schedulersmpimpl.h18
-rw-r--r--cpukit/score/include/rtems/score/schedulerstrongapa.h4
11 files changed, 67 insertions, 132 deletions
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index fd59f16dee..1b9509ae4f 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -42,16 +42,6 @@ struct Per_CPU_Control;
typedef struct Scheduler_Control Scheduler_Control;
-#if defined(RTEMS_SMP)
- typedef bool Scheduler_Void_or_bool;
-
- #define SCHEDULER_RETURN_VOID_OR_BOOL return false
-#else
- typedef void Scheduler_Void_or_bool;
-
- #define SCHEDULER_RETURN_VOID_OR_BOOL return
-#endif
-
/**
* @brief The scheduler operations.
*/
@@ -63,7 +53,7 @@ typedef struct {
void ( *schedule )( const Scheduler_Control *, Thread_Control *);
/** @see _Scheduler_Yield() */
- Scheduler_Void_or_bool ( *yield )(
+ void ( *yield )(
const Scheduler_Control *,
Thread_Control *,
Scheduler_Node *
@@ -77,7 +67,7 @@ typedef struct {
);
/** @see _Scheduler_Unblock() */
- Scheduler_Void_or_bool ( *unblock )(
+ void ( *unblock )(
const Scheduler_Control *,
Thread_Control *,
Scheduler_Node *
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index e56747bdc5..635abce125 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -146,7 +146,7 @@ typedef struct {
*/
extern Scheduler_CBS_Server _Scheduler_CBS_Server_list[];
-Scheduler_Void_or_bool _Scheduler_CBS_Unblock(
+void _Scheduler_CBS_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index 9fc2eb9ea3..91c303ca56 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -144,7 +144,7 @@ void _Scheduler_EDF_Node_initialize(
Priority_Control priority
);
-Scheduler_Void_or_bool _Scheduler_EDF_Unblock(
+void _Scheduler_EDF_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
@@ -166,7 +166,7 @@ Priority_Control _Scheduler_EDF_Unmap_priority(
Priority_Control priority
);
-Scheduler_Void_or_bool _Scheduler_EDF_Yield(
+void _Scheduler_EDF_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 90a9bcca68..53631ab4e5 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -113,6 +113,43 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Release_critical(
#endif
}
+#if defined(RTEMS_SMP)
+/**
+ * @brief Registers an ask for help request.
+ *
+ * The actual ask for help operation is carried out during
+ * _Thread_Do_dispatch() on a processor related to the thread. This yields a
+ * better separation of scheduler instances. A thread of one scheduler
+ * instance should not be forced to carry out too much work for threads on
+ * other scheduler instances.
+ *
+ * @param[in] the_thread The thread in need for help.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_Ask_for_help( Thread_Control *the_thread )
+{
+ _Assert( _Thread_State_is_owner( the_thread ) );
+
+ if ( the_thread->Scheduler.helping_nodes > 0 ) {
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu;
+
+ _Thread_Scheduler_acquire_critical( the_thread, &lock_context );
+ cpu = _Thread_Get_CPU( the_thread );
+ _Per_CPU_Acquire( cpu );
+
+ _Chain_Append_unprotected(
+ &cpu->Threads_in_need_for_help,
+ &the_thread->Scheduler.Help_node
+ );
+
+ _Per_CPU_Release( cpu );
+ _Thread_Scheduler_release_critical( the_thread, &lock_context );
+
+ _Thread_Dispatch_request( _Per_CPU_Get(), cpu );
+ }
+}
+#endif
+
/**
* The preferred method to add a new scheduler is to define the jump table
* entries and add a case to the _Scheduler_Initialize routine.
@@ -159,64 +196,17 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Schedule( Thread_Control *the_thread )
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Yield( Thread_Control *the_thread )
{
-#if defined(RTEMS_SMP)
- Chain_Node *node;
- const Chain_Node *tail;
- Scheduler_Node *scheduler_node;
const Scheduler_Control *scheduler;
ISR_lock_Context lock_context;
- bool needs_help;
-
- node = _Chain_First( &the_thread->Scheduler.Scheduler_nodes );
- tail = _Chain_Immutable_tail( &the_thread->Scheduler.Scheduler_nodes );
-
- scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
- scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
-
- _Scheduler_Acquire_critical( scheduler, &lock_context );
- needs_help = ( *scheduler->Operations.yield )(
- scheduler,
- the_thread,
- _Thread_Scheduler_get_home_node( the_thread )
- );
- _Scheduler_Release_critical( scheduler, &lock_context );
-
- if ( !needs_help ) {
- return;
- }
-
- node = _Chain_Next( node );
-
- while ( node != tail ) {
- bool success;
-
- scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
- scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
-
- _Scheduler_Acquire_critical( scheduler, &lock_context );
- success = ( *scheduler->Operations.ask_for_help )(
- scheduler,
- the_thread,
- scheduler_node
- );
- _Scheduler_Release_critical( scheduler, &lock_context );
-
- if ( success ) {
- break;
- }
-
- node = _Chain_Next( node );
- }
-#else
- const Scheduler_Control *scheduler;
scheduler = _Thread_Scheduler_get_home( the_thread );
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
( *scheduler->Operations.yield )(
scheduler,
the_thread,
_Thread_Scheduler_get_home_node( the_thread )
);
-#endif
+ _Scheduler_Release_critical( scheduler, &lock_context );
}
/**
@@ -293,64 +283,17 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Block( Thread_Control *the_thread )
*/
RTEMS_INLINE_ROUTINE void _Scheduler_Unblock( Thread_Control *the_thread )
{
-#if defined(RTEMS_SMP)
- Chain_Node *node;
- const Chain_Node *tail;
- Scheduler_Node *scheduler_node;
const Scheduler_Control *scheduler;
ISR_lock_Context lock_context;
- bool needs_help;
-
- node = _Chain_First( &the_thread->Scheduler.Scheduler_nodes );
- tail = _Chain_Immutable_tail( &the_thread->Scheduler.Scheduler_nodes );
-
- scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
- scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
-
- _Scheduler_Acquire_critical( scheduler, &lock_context );
- needs_help = ( *scheduler->Operations.unblock )(
- scheduler,
- the_thread,
- scheduler_node
- );
- _Scheduler_Release_critical( scheduler, &lock_context );
-
- if ( !needs_help ) {
- return;
- }
-
- node = _Chain_Next( node );
-
- while ( node != tail ) {
- bool success;
-
- scheduler_node = SCHEDULER_NODE_OF_THREAD_SCHEDULER_NODE( node );
- scheduler = _Scheduler_Node_get_scheduler( scheduler_node );
-
- _Scheduler_Acquire_critical( scheduler, &lock_context );
- success = ( *scheduler->Operations.ask_for_help )(
- scheduler,
- the_thread,
- scheduler_node
- );
- _Scheduler_Release_critical( scheduler, &lock_context );
-
- if ( success ) {
- break;
- }
-
- node = _Chain_Next( node );
- }
-#else
- const Scheduler_Control *scheduler;
scheduler = _Thread_Scheduler_get_home( the_thread );
+ _Scheduler_Acquire_critical( scheduler, &lock_context );
( *scheduler->Operations.unblock )(
scheduler,
the_thread,
_Thread_Scheduler_get_home_node( the_thread )
);
-#endif
+ _Scheduler_Release_critical( scheduler, &lock_context );
}
/**
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 91ebb3852a..f5ae66102d 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -128,7 +128,7 @@ void _Scheduler_priority_Schedule(
Thread_Control *the_thread
);
-Scheduler_Void_or_bool _Scheduler_priority_Unblock(
+void _Scheduler_priority_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
@@ -147,7 +147,7 @@ void _Scheduler_priority_Node_initialize(
Priority_Control priority
);
-Scheduler_Void_or_bool _Scheduler_priority_Yield(
+void _Scheduler_priority_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index d1275bc727..850c72bb40 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -96,7 +96,7 @@ void _Scheduler_priority_affinity_SMP_Block(
Scheduler_Node *node
);
-bool _Scheduler_priority_affinity_SMP_Unblock(
+void _Scheduler_priority_affinity_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Scheduler_Node *node
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index 75cc9b6e67..6671da5b7a 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -115,7 +115,7 @@ void _Scheduler_priority_SMP_Block(
Scheduler_Node *node
);
-bool _Scheduler_priority_SMP_Unblock(
+void _Scheduler_priority_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Scheduler_Node *node
@@ -156,7 +156,7 @@ Thread_Control *_Scheduler_priority_SMP_Remove_processor(
struct Per_CPU_Control *cpu
);
-bool _Scheduler_priority_SMP_Yield(
+void _Scheduler_priority_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Scheduler_Node *node
diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
index 1d97e1cd7d..0d410d5676 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -92,7 +92,7 @@ void _Scheduler_simple_Schedule(
Thread_Control *the_thread
);
-Scheduler_Void_or_bool _Scheduler_simple_Yield(
+void _Scheduler_simple_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
@@ -104,7 +104,7 @@ void _Scheduler_simple_Block(
Scheduler_Node *node
);
-Scheduler_Void_or_bool _Scheduler_simple_Unblock(
+void _Scheduler_simple_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index 0cf3877b43..bc75b205d5 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -98,7 +98,7 @@ void _Scheduler_simple_SMP_Block(
Scheduler_Node *node
);
-bool _Scheduler_simple_SMP_Unblock(
+void _Scheduler_simple_SMP_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Scheduler_Node *node
@@ -139,7 +139,7 @@ Thread_Control *_Scheduler_simple_SMP_Remove_processor(
struct Per_CPU_Control *cpu
);
-bool _Scheduler_simple_SMP_Yield(
+void _Scheduler_simple_SMP_Yield(
const Scheduler_Control *scheduler,
Thread_Control *thread,
Scheduler_Node *node
diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index 92a22d2ff8..7a281277fa 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -962,7 +962,7 @@ static inline void _Scheduler_SMP_Block(
}
}
-static inline bool _Scheduler_SMP_Unblock(
+static inline void _Scheduler_SMP_Unblock(
Scheduler_Context *context,
Thread_Control *thread,
Scheduler_Node *node,
@@ -972,7 +972,6 @@ static inline bool _Scheduler_SMP_Unblock(
{
Scheduler_SMP_Node_state node_state;
bool unblock;
- bool needs_help;
node_state = _Scheduler_SMP_Node_state( node );
unblock = _Scheduler_Unblock_node(
@@ -986,6 +985,7 @@ static inline bool _Scheduler_SMP_Unblock(
if ( unblock ) {
Priority_Control new_priority;
bool prepend_it;
+ bool needs_help;
new_priority = _Scheduler_Node_get_priority( node, &prepend_it );
(void) prepend_it;
@@ -1004,11 +1004,11 @@ static inline bool _Scheduler_SMP_Unblock(
_Assert( node->idle == NULL );
needs_help = true;
}
- } else {
- needs_help = false;
- }
- return needs_help;
+ if ( needs_help ) {
+ _Scheduler_Ask_for_help( thread );
+ }
+ }
}
static inline void _Scheduler_SMP_Update_priority(
@@ -1069,7 +1069,7 @@ static inline void _Scheduler_SMP_Update_priority(
}
}
-static inline bool _Scheduler_SMP_Yield(
+static inline void _Scheduler_SMP_Yield(
Scheduler_Context *context,
Thread_Control *thread,
Scheduler_Node *node,
@@ -1095,7 +1095,9 @@ static inline bool _Scheduler_SMP_Yield(
needs_help = true;
}
- return needs_help;
+ if ( needs_help ) {
+ _Scheduler_Ask_for_help( thread );
+ }
}
static inline void _Scheduler_SMP_Insert_scheduled_lifo(
diff --git a/cpukit/score/include/rtems/score/schedulerstrongapa.h b/cpukit/score/include/rtems/score/schedulerstrongapa.h
index 29dee66c44..d961f20c68 100644
--- a/cpukit/score/include/rtems/score/schedulerstrongapa.h
+++ b/cpukit/score/include/rtems/score/schedulerstrongapa.h
@@ -115,7 +115,7 @@ void _Scheduler_strong_APA_Block(
Scheduler_Node *node
);
-bool _Scheduler_strong_APA_Unblock(
+void _Scheduler_strong_APA_Unblock(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node
@@ -156,7 +156,7 @@ Thread_Control *_Scheduler_strong_APA_Remove_processor(
struct Per_CPU_Control *cpu
);
-bool _Scheduler_strong_APA_Yield(
+void _Scheduler_strong_APA_Yield(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
Scheduler_Node *node