summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-06-11 14:31:03 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-07-08 16:30:48 +0200
commit8568341d69d16609a3dcf71716a89839b16ac881 (patch)
tree900c88db84557962dda75671eedd39911e1f2dc5 /cpukit/score/include/rtems
parentscore: Add _Scheduler_Help() (diff)
downloadrtems-8568341d69d16609a3dcf71716a89839b16ac881.tar.bz2
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.
Diffstat (limited to 'cpukit/score/include/rtems')
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h27
-rw-r--r--cpukit/score/include/rtems/score/schedulercbs.h2
-rw-r--r--cpukit/score/include/rtems/score/scheduleredf.h6
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h42
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h6
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h4
-rw-r--r--cpukit/score/include/rtems/score/schedulerprioritysmp.h6
-rw-r--r--cpukit/score/include/rtems/score/schedulersimple.h6
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h6
-rw-r--r--cpukit/score/include/rtems/score/schedulersmpimpl.h82
10 files changed, 137 insertions, 50 deletions
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index bb30a8e61e..993ae55b29 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -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,
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index 3b59301125..008cc91261 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -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
);
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index 6d759f5535..1dda767cf6 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -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
);
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index edb68b649a..5e4e5098d2 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -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
}
/**
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index e412bab6bf..805e30257d 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -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
);
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index 831d1d47a6..3a235104cf 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -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,
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index e922c2b998..a1a148173d 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -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
);
diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h
index ef60613d1b..c97ad2f3c6 100644
--- a/cpukit/score/include/rtems/score/schedulersimple.h
+++ b/cpukit/score/include/rtems/score/schedulersimple.h
@@ -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,
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index 790ceddc1d..de338ab168 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -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
);
diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index b7d86a36e8..55d0697df1 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -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(