summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-10-07 17:11:26 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-10-07 17:11:26 -0600
commit1753a0251a941fa4d1a5b95aec631209e9957670 (patch)
treea2c838b70f71b98df273b75fd86c404ab1f5d4f5
parentcb42882d01ad071f66f6809a49c643eb32730688 (diff)
downloadnuttx-1753a0251a941fa4d1a5b95aec631209e9957670.tar.gz
nuttx-1753a0251a941fa4d1a5b95aec631209e9957670.tar.bz2
nuttx-1753a0251a941fa4d1a5b95aec631209e9957670.zip
Update some Kconfig comments; Add a upper limit on the lower priority worker thread for priority inheritance
-rw-r--r--nuttx/include/nuttx/wqueue.h27
-rw-r--r--nuttx/libc/Kconfig77
-rw-r--r--nuttx/sched/wqueue/work_inherit.c14
3 files changed, 109 insertions, 9 deletions
diff --git a/nuttx/include/nuttx/wqueue.h b/nuttx/include/nuttx/wqueue.h
index 424373a17..036ea0da3 100644
--- a/nuttx/include/nuttx/wqueue.h
+++ b/nuttx/include/nuttx/wqueue.h
@@ -79,8 +79,10 @@
* then an additional, lower-priority work queue will also be created. This
* lower priority work queue is better suited for more extended processing
* (such as file system clean-up operations)
- * CONFIG_SCHED_LPWORKPRIORITY - The execution priority of the lower priority
- * worker thread. Default: 50
+ * CONFIG_SCHED_LPWORKPRIORITY - The minimum execution priority of the lower
+ * priority worker thread. Default: 50
+ * CONFIG_SCHED_LPWORKPRIOMAX - The maximum execution priority of the lower
+ * priority worker thread. Default: 176
* CONFIG_SCHED_LPWORKPERIOD - How often the lower priority worker thread
* checks for work in units of microseconds. Default: 50*1000 (50 MS).
* CONFIG_SCHED_LPWORKSTACKSIZE - The stack size allocated for the lower
@@ -175,6 +177,27 @@
# define CONFIG_SCHED_LPWORKPRIORITY 50
# endif
+# ifndef CONFIG_SCHED_LPWORKPRIOMAX
+# ifdef CONFIG_SCHED_HPWORK
+# define CONFIG_SCHED_LPWORKPRIOMAX (CONFIG_SCHED_WORKPRIORITY-16)
+# else
+# define CONFIG_SCHED_LPWORKPRIOMAX 176
+# endif
+# endif
+
+# ifdef CONFIG_SCHED_HPWORK
+# if CONFIG_SCHED_LPWORKPRIORITY >= CONFIG_SCHED_WORKPRIORITY
+# error CONFIG_SCHED_LPWORKPRIORITY >= CONFIG_SCHED_WORKPRIORITY
+# endif
+# if CONFIG_SCHED_LPWORKPRIOMAX >= CONFIG_SCHED_WORKPRIORITY
+# error CONFIG_SCHED_LPWORKPRIOMAX >= CONFIG_SCHED_WORKPRIORITY
+# endif
+# endif
+
+# if CONFIG_SCHED_LPWORKPRIORITY > CONFIG_SCHED_LPWORKPRIOMAX
+# error CONFIG_SCHED_LPWORKPRIORITY > CONFIG_SCHED_LPWORKPRIOMAX
+# endif
+
# ifndef CONFIG_SCHED_LPWORKPERIOD
# define CONFIG_SCHED_LPWORKPERIOD (50*1000) /* 50 milliseconds */
# endif
diff --git a/nuttx/libc/Kconfig b/nuttx/libc/Kconfig
index 6961cc62c..eba38e0b6 100644
--- a/nuttx/libc/Kconfig
+++ b/nuttx/libc/Kconfig
@@ -412,9 +412,10 @@ config SCHED_HPWORK
bool "High priority (kernel) worker thread"
default y
---help---
- If SCHED_WORKQUEUE is defined, then a single, high priority work queue is
- created by default. This high priority worker thread is intended to serve
- as the "bottom half" for driver interrupt handling.
+ If SCHED_WORKQUEUE is defined, then a single, high priority work
+ queue is created by default. This high priority worker thread is
+ intended to serve as the "bottom half" for driver interrupt
+ handling.
if SCHED_HPWORK
@@ -422,7 +423,20 @@ config SCHED_WORKPRIORITY
int "High priority worker thread priority"
default 192
---help---
- The execution priority of the worker thread. Default: 192
+ The execution priority of the higher priority worker thread.
+
+ The higher priority worker thread is intended to serve as the
+ "bottom" half for device drivers. As a consequence it must run at
+ a very high, fixed priority. Typically, it should be the highest
+ priority thread in your system. Default: 192
+
+ For lower priority, application oriented worker thread support,
+ please consider enabling the lower priority work queue. The lower
+ priority work queue runs at a lower priority, of course, but has
+ the added advantage that it supports "priority inheritance" (if
+ PRIORITY_INHERITANCE is also selected): The priority of the lower
+ priority worker thread can then be adjusted to match the highest
+ priority client.
config SCHED_WORKPERIOD
int "High priority worker thread period"
@@ -445,8 +459,9 @@ config SCHED_LPWORK
If SCHED_WORKQUEUE is defined, then a single work queue is created by
default. If SCHED_LPWORK is also defined then an additional, lower-
priority work queue will also be created. This lower priority work
- queue is better suited for more extended processing (such as file system
- clean-up operations)
+ queue is better suited for more extended, application oriented
+ processing (such as file system clean-up operations or asynchronous
+ I/O)
if SCHED_LPWORK
@@ -454,7 +469,55 @@ config SCHED_LPWORKPRIORITY
int "Low priority worker thread priority"
default 50
---help---
- The execution priority of the lopwer priority worker thread. Default: 50
+ The minimum execution priority of the lower priority worker thread.
+
+ The lower priority worker thread is intended support application-
+ oriented functions. The lower priority work queue runs at a lower
+ priority, of course, but has the added advantage that it supports
+ "priority inheritance" (if PRIORITY_INHERITANCE is also selected):
+ The priority of the lower priority worker thread can then be
+ adjusted to match the highest priority client. Default: 50
+
+ NOTE: This priority inheritance feature is not automatic. The
+ lower priority worker thread will always a fixed priority unless
+ you implement logic that calls lpwork_boostpriority() to raise the
+ priority of the lower priority worker thread (typically called
+ before scheduling the work) and then call the matching
+ lpwork_restorepriority() when the work is completed (typically
+ called within the work handler at the completion of the work).
+ Currently, only the NuttX asynchronous I/O logic uses this dynamic
+ prioritization feature.
+
+ The higher priority worker thread, on the other hand, is intended
+ to serve as the "bottom" half for device drivers. As a consequence
+ it must run at a very high, fixed priority. Typically, it should
+ be the highest priority thread in your system.
+
+config SCHED_LPWORKPRIOMAX
+ int "Low priority worker thread maximum priority"
+ default 176
+ depends on PRIORITY_INHERITANCE
+ ---help---
+ The maximum execution priority of the lower priority worker thread.
+
+ The lower priority worker thread is intended support application-
+ oriented functions. The lower priority work queue runs at a lower
+ priority, of course, but has the added advantage that it supports
+ "priority inheritance" (if PRIORITY_INHERITANCE is also selected):
+ The priority of the lower priority worker thread can then be
+ adjusted to match the highest priority client.
+
+ The higher priority worker thread, on the other hand, is intended
+ to serve as the "bottom" half for device drivers. As a consequence
+ it must run at a very high, fixed priority. Typically, it should
+ be the highest priority thread in your system.
+
+ This function provides an upper limit on the priority of the lower
+ priority worker thread. This would be necessary, for example, if
+ the higher priority worker thread were to defer work to the lower
+ priority thread. Clearly, in such a case, you would want to limit
+ the maximum priority of the lower priority work thread. Default:
+ 176
config SCHED_LPWORKPERIOD
int "Low priority worker thread period"
diff --git a/nuttx/sched/wqueue/work_inherit.c b/nuttx/sched/wqueue/work_inherit.c
index 864fd86bf..14c012ea5 100644
--- a/nuttx/sched/wqueue/work_inherit.c
+++ b/nuttx/sched/wqueue/work_inherit.c
@@ -78,6 +78,13 @@ void lpwork_boostpriority(uint8_t reqprio)
irqstate_t flags;
pid_t wpid;
+ /* Clip to the configured maximum priority */
+
+ if (reqprio > CONFIG_SCHED_LPWORKPRIOMAX)
+ {
+ reqprio = CONFIG_SCHED_LPWORKPRIOMAX;
+ }
+
/* Get the process ID of the low priority worker thread from the low
* priority work queue. Then get the TCB of the low priority worker
* thread from the process ID.
@@ -194,6 +201,13 @@ void lpwork_restorepriority(uint8_t reqprio)
int index;
int selected;
+ /* Clip to the configured maximum priority */
+
+ if (reqprio > CONFIG_SCHED_LPWORKPRIOMAX)
+ {
+ reqprio = CONFIG_SCHED_LPWORKPRIOMAX;
+ }
+
/* Get the process ID of the low priority worker thread from the low
* priority work queue. Then get the TCB of the low priority worker
* thread from the process ID.