summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-08-11 10:26:57 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-08-11 11:13:42 +0200
commit424ffe4db039878eae13428d1ddeeb4a7c7f47fe (patch)
tree8f6e984f0f0c386e3c7aa58b9fb817aba6e56ea2
parentscore: Dismantle _Thread_queue_Do_extract_locked() (diff)
downloadrtems-424ffe4db039878eae13428d1ddeeb4a7c7f47fe.tar.bz2
score: Introduce thread queue surrender operation
This is an optimization for _Thread_queue_Surrender(). It helps to encapsulate the priority boosting in the priority inheritance thread queue operations.
-rw-r--r--cpukit/score/include/rtems/score/threadq.h22
-rw-r--r--cpukit/score/include/rtems/score/threadqimpl.h25
-rw-r--r--cpukit/score/src/threadqenqueue.c4
-rw-r--r--cpukit/score/src/threadqops.c79
4 files changed, 94 insertions, 36 deletions
diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h
index 3c689ac974..48e951eef1 100644
--- a/cpukit/score/include/rtems/score/threadq.h
+++ b/cpukit/score/include/rtems/score/threadq.h
@@ -371,6 +371,23 @@ typedef void ( *Thread_queue_Extract_operation )(
);
/**
+ * @brief Thread queue surrender operation.
+ *
+ * This operation must dequeue and return the first thread on the queue.
+ *
+ * @param[in] queue The actual thread queue.
+ * @param[in] heads The thread queue heads. It must not be NULL.
+ * @param[in] previous_owner The previous owner of the thread queue.
+ *
+ * @return The previous first thread on the queue.
+ */
+typedef Thread_Control *( *Thread_queue_Surrender_operation )(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner
+);
+
+/**
* @brief Thread queue first operation.
*
* @param[in] heads The thread queue heads.
@@ -416,6 +433,11 @@ struct Thread_queue_Operations {
Thread_queue_Extract_operation extract;
/**
+ * @brief Thread queue surrender operation.
+ */
+ Thread_queue_Surrender_operation surrender;
+
+ /**
* @brief Thread queue first operation.
*/
Thread_queue_First_operation first;
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index 8137800841..8a3b991516 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -946,31 +946,6 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Destroy(
#endif
}
-/**
- * @brief Boosts the priority of the thread if threads of another scheduler
- * instance are enqueued on the thread queue.
- *
- * The thread queue must use the priority waiting discipline.
- *
- * @param[in] queue The actual thread queue.
- * @param[in] the_thread The thread to boost the priority if necessary.
- */
-#if defined(RTEMS_SMP)
-void _Thread_queue_Boost_priority(
- Thread_queue_Queue *queue,
- Thread_Control *the_thread
-);
-#else
-RTEMS_INLINE_ROUTINE void _Thread_queue_Boost_priority(
- Thread_queue_Queue *queue,
- Thread_Control *the_thread
-)
-{
- (void) queue;
- (void) the_thread;
-}
-#endif
-
#if defined(RTEMS_MULTIPROCESSING)
void _Thread_queue_MP_callout_do_nothing(
Thread_Control *the_proxy,
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 2f6b041789..5a7fd6def5 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -596,7 +596,7 @@ void _Thread_queue_Surrender(
Thread_Control *new_owner;
bool unblock;
- new_owner = ( *operations->first )( heads );
+ new_owner = ( *operations->surrender )( queue, heads, previous_owner );
queue->owner = new_owner;
#if defined(RTEMS_MULTIPROCESSING)
@@ -604,10 +604,8 @@ void _Thread_queue_Surrender(
#endif
{
++new_owner->resource_count;
- _Thread_queue_Boost_priority( queue, new_owner );
}
- ( *operations->extract )( queue, new_owner );
unblock = _Thread_queue_Make_ready_again( new_owner );
_Thread_queue_Unblock_critical(
diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c
index df7054f0c8..41506bfceb 100644
--- a/cpukit/score/src/threadqops.c
+++ b/cpukit/score/src/threadqops.c
@@ -71,12 +71,11 @@ static Thread_queue_Heads *_Thread_queue_Queue_enqueue(
static void _Thread_queue_Queue_extract(
Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
Thread_Control *the_thread,
void ( *extract )( Thread_queue_Heads *, Thread_Control * )
)
{
- Thread_queue_Heads *heads = queue->heads;
-
_Assert( heads != NULL );
the_thread->Wait.spare_heads = RTEMS_CONTAINER_OF(
@@ -142,6 +141,7 @@ static void _Thread_queue_FIFO_extract(
{
_Thread_queue_Queue_extract(
queue,
+ queue->heads,
the_thread,
_Thread_queue_FIFO_do_extract
);
@@ -160,6 +160,25 @@ static Thread_Control *_Thread_queue_FIFO_first(
return THREAD_CHAIN_NODE_TO_THREAD( first );
}
+static Thread_Control *_Thread_queue_FIFO_surrender(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner
+)
+{
+ Thread_Control *first;
+
+ first = _Thread_queue_FIFO_first( heads );
+ _Thread_queue_Queue_extract(
+ queue,
+ heads,
+ first,
+ _Thread_queue_FIFO_do_extract
+ );
+
+ return first;
+}
+
static Thread_queue_Priority_queue *_Thread_queue_Priority_queue(
Thread_queue_Heads *heads,
const Thread_Control *the_thread
@@ -296,6 +315,7 @@ static void _Thread_queue_Priority_extract(
{
_Thread_queue_Queue_extract(
queue,
+ queue->heads,
the_thread,
_Thread_queue_Priority_do_extract
);
@@ -322,6 +342,25 @@ static Thread_Control *_Thread_queue_Priority_first(
return THREAD_RBTREE_NODE_TO_THREAD( first );
}
+static Thread_Control *_Thread_queue_Priority_surrender(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner
+)
+{
+ Thread_Control *first;
+
+ first = _Thread_queue_Priority_first( heads );
+ _Thread_queue_Queue_extract(
+ queue,
+ heads,
+ first,
+ _Thread_queue_Priority_do_extract
+ );
+
+ return first;
+}
+
static void _Thread_queue_Priority_inherit_enqueue(
Thread_queue_Queue *queue,
Thread_Control *the_thread,
@@ -374,14 +413,12 @@ static void _Thread_queue_Priority_inherit_enqueue(
}
}
-#if defined(RTEMS_SMP)
-void _Thread_queue_Boost_priority(
- Thread_queue_Queue *queue,
+static void _Thread_queue_Boost_priority(
+ Thread_queue_Heads *heads,
Thread_Control *the_thread
)
{
- Thread_queue_Heads *heads = queue->heads;
-
+#if defined(RTEMS_SMP)
if ( !_Chain_Has_only_one_node( &heads->Heads.Fifo ) ) {
const Scheduler_Control *scheduler;
Priority_Control boost_priority;
@@ -394,8 +431,31 @@ void _Thread_queue_Boost_priority(
_Scheduler_Thread_set_priority( the_thread, boost_priority, false );
}
-}
+#else
+ (void) heads;
+ (void) the_thread;
#endif
+}
+
+static Thread_Control *_Thread_queue_Priority_inherit_surrender(
+ Thread_queue_Queue *queue,
+ Thread_queue_Heads *heads,
+ Thread_Control *previous_owner
+)
+{
+ Thread_Control *first;
+
+ first = _Thread_queue_Priority_first( heads );
+ _Thread_queue_Boost_priority( heads, first );
+ _Thread_queue_Queue_extract(
+ queue,
+ heads,
+ first,
+ _Thread_queue_Priority_do_extract
+ );
+
+ return first;
+}
const Thread_queue_Operations _Thread_queue_Operations_default = {
.priority_change = _Thread_queue_Do_nothing_priority_change,
@@ -411,6 +471,7 @@ const Thread_queue_Operations _Thread_queue_Operations_FIFO = {
.priority_change = _Thread_queue_Do_nothing_priority_change,
.enqueue = _Thread_queue_FIFO_enqueue,
.extract = _Thread_queue_FIFO_extract,
+ .surrender = _Thread_queue_FIFO_surrender,
.first = _Thread_queue_FIFO_first
};
@@ -418,6 +479,7 @@ const Thread_queue_Operations _Thread_queue_Operations_priority = {
.priority_change = _Thread_queue_Priority_priority_change,
.enqueue = _Thread_queue_Priority_enqueue,
.extract = _Thread_queue_Priority_extract,
+ .surrender = _Thread_queue_Priority_surrender,
.first = _Thread_queue_Priority_first
};
@@ -425,5 +487,6 @@ const Thread_queue_Operations _Thread_queue_Operations_priority_inherit = {
.priority_change = _Thread_queue_Priority_priority_change,
.enqueue = _Thread_queue_Priority_inherit_enqueue,
.extract = _Thread_queue_Priority_extract,
+ .surrender = _Thread_queue_Priority_inherit_surrender,
.first = _Thread_queue_Priority_first
};