[PATCH] score: Add thread priority change notification
Sebastian Huber
sebastian.huber at embedded-brains.de
Tue Mar 17 16:23:15 UTC 2015
Since the thread priority change is now performed atomically in one
critical section it is possible to simplify the thread queue update
procedure. Add a thread queue agnostic thread priority change
notification handler so that we are able to use alternative thread queue
implementations.
Update #2273.
---
cpukit/score/Makefile.am | 2 +-
cpukit/score/include/rtems/score/thread.h | 16 ++++++++++++++++
cpukit/score/include/rtems/score/threadimpl.h | 5 +++++
cpukit/score/include/rtems/score/threadqimpl.h | 17 -----------------
cpukit/score/src/threadchangepriority.c | 2 +-
cpukit/score/src/threadinitialize.c | 19 ++++++++++++++-----
cpukit/score/src/threadqdequeue.c | 2 ++
cpukit/score/src/threadqenqueue.c | 19 +++++++++++++++++++
cpukit/score/src/threadqextract.c | 2 ++
9 files changed, 60 insertions(+), 24 deletions(-)
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 509a243..ae407fe 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -299,7 +299,7 @@ endif
## THREADQ_C_FILES
libscore_a_SOURCES += src/threadq.c src/threadqdequeue.c \
- src/threadqenqueue.c src/threadqextract.c src/threadqrequeue.c \
+ src/threadqenqueue.c src/threadqextract.c \
src/threadqextractwithproxy.c src/threadqfirst.c \
src/threadqflush.c src/threadqprocesstimeout.c src/threadqtimeout.c
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index cea88f4..9b1d8d9 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -263,6 +263,17 @@ typedef union {
} Thread_Wait_information_Object_argument_type;
/**
+ * @brief Priority change notification handler.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] new_priority The new priority value.
+ */
+typedef void (*Thread_Wait_priority_change)(
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+);
+
+/**
* @brief This type is able to contain several flags used to control the wait
* class and state of a thread.
*
@@ -310,6 +321,11 @@ typedef struct {
Thread_queue_Control *queue;
/**
+ * @brief Priority change notification handler.
+ */
+ Thread_Wait_priority_change priority_change;
+
+ /**
* @brief This field contains several flags used to control the wait class
* and state of a thread in case fine-grained locking is used.
*/
diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h
index 9d98fe8..a31ff9f 100644
--- a/cpukit/score/include/rtems/score/threadimpl.h
+++ b/cpukit/score/include/rtems/score/threadimpl.h
@@ -925,6 +925,11 @@ RTEMS_INLINE_ROUTINE bool _Thread_Owns_resources(
return owns_resources;
}
+void _Thread_Wait_priority_change_do_nothing(
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+);
+
/**
* @brief The initial thread wait flags value set by _Thread_Initialize().
*/
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h
index 4a1084d..4c8d22e 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -266,23 +266,6 @@ RBTree_Compare_result _Thread_queue_Compare_priority(
);
/**
- * @brief Invoked when a thread changes priority and is blocked.
- *
- * This routine is invoked when a thread changes priority and is
- * blocked on a thread queue. If the queue is priority ordered,
- * the_thread is removed from the_thread_queue and reinserted using
- * its new priority. This method has no impact on the state of the_thread
- * or of any timeouts associated with this blocking.
- *
- * @param[in] the_thread_queue pointer to a threadq header
- * @param[in] the_thread pointer to a thread control block
- */
-void _Thread_queue_Requeue(
- Thread_queue_Control *the_thread_queue,
- Thread_Control *the_thread
-);
-
-/**
* This routine is invoked to indicate that the specified thread queue is
* entering a critical section.
*/
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index 34a5a14..c209dbd 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -50,7 +50,7 @@ void _Thread_Change_priority(
_Scheduler_Update_priority( the_thread, new_priority );
}
- _Thread_queue_Requeue( the_thread->Wait.queue, the_thread );
+ (*the_thread->Wait.priority_change)( the_thread, new_priority );
}
_ISR_Enable( level );
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 934fea9..b0ce0e3 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -29,6 +29,14 @@
#include <rtems/score/cpusetimpl.h>
#include <rtems/config.h>
+void _Thread_Wait_priority_change_do_nothing(
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+)
+{
+ /* Do nothing */
+}
+
bool _Thread_Initialize(
Objects_Information *information,
Thread_Control *the_thread,
@@ -194,11 +202,12 @@ bool _Thread_Initialize(
/* Initialize the CPU for the non-SMP schedulers */
_Thread_Set_CPU( the_thread, cpu );
- the_thread->current_state = STATES_DORMANT;
- the_thread->Wait.queue = NULL;
- the_thread->resource_count = 0;
- the_thread->real_priority = priority;
- the_thread->Start.initial_priority = priority;
+ the_thread->current_state = STATES_DORMANT;
+ the_thread->Wait.queue = NULL;
+ the_thread->Wait.priority_change = _Thread_Wait_priority_change_do_nothing;
+ the_thread->resource_count = 0;
+ the_thread->real_priority = priority;
+ the_thread->Start.initial_priority = priority;
_Thread_Wait_flags_set( the_thread, THREAD_WAIT_FLAGS_INITIAL );
diff --git a/cpukit/score/src/threadqdequeue.c b/cpukit/score/src/threadqdequeue.c
index 52ba009..c8d355e 100644
--- a/cpukit/score/src/threadqdequeue.c
+++ b/cpukit/score/src/threadqdequeue.c
@@ -70,6 +70,8 @@ Thread_Control *_Thread_queue_Dequeue(
}
}
+ the_thread->Wait.priority_change = _Thread_Wait_priority_change_do_nothing;
+
/*
* We found a thread to unblock.
*
diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c
index 0fa5fa6..bc0dc02 100644
--- a/cpukit/score/src/threadqenqueue.c
+++ b/cpukit/score/src/threadqenqueue.c
@@ -23,6 +23,23 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/watchdogimpl.h>
+static void _Thread_queue_Requeue_priority(
+ Thread_Control *the_thread,
+ Priority_Control new_priority
+)
+{
+ Thread_queue_Control *tq = the_thread->Wait.queue;
+
+ _Thread_queue_Enter_critical_section( tq );
+ _RBTree_Extract( &tq->Queues.Priority, &the_thread->RBNode );
+ _RBTree_Insert(
+ &tq->Queues.Priority,
+ &the_thread->RBNode,
+ _Thread_queue_Compare_priority,
+ false
+ );
+}
+
void _Thread_queue_Enqueue_with_handler(
Thread_queue_Control *the_thread_queue,
Thread_Control *the_thread,
@@ -83,6 +100,8 @@ void _Thread_queue_Enqueue_with_handler(
_Thread_queue_Compare_priority,
false
);
+
+ the_thread->Wait.priority_change = _Thread_queue_Requeue_priority;
}
the_thread->Wait.queue = the_thread_queue;
diff --git a/cpukit/score/src/threadqextract.c b/cpukit/score/src/threadqextract.c
index d12d3c8..b7772b9 100644
--- a/cpukit/score/src/threadqextract.c
+++ b/cpukit/score/src/threadqextract.c
@@ -46,6 +46,8 @@ void _Thread_queue_Extract_with_return_code(
&the_thread->Wait.queue->Queues.Priority,
&the_thread->RBNode
);
+
+ the_thread->Wait.priority_change = _Thread_Wait_priority_change_do_nothing;
}
the_thread->Wait.return_code = return_code;
--
2.1.4
More information about the devel
mailing list